From 9488d0cdf45603bc57f109df7cd58a4c598ddb85 Mon Sep 17 00:00:00 2001 From: liuyingying19 Date: Tue, 13 May 2025 04:34:04 +0000 Subject: [PATCH] Support hwasan with emulated-tls options Signed-off-by: liuyingying19 --- compiler-rt/lib/hwasan/hwasan_linux.cpp | 11 ++++++++- compiler-rt/lib/hwasan/hwasan_thread.cpp | 13 +++++++++++ compiler-rt/lib/hwasan/hwasan_thread.h | 3 +++ .../lib/sanitizer_common/sanitizer_linux.h | 13 ++++++++++- .../Instrumentation/HWAddressSanitizer.cpp | 23 ++++++++++++++++--- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp index 2d7a44525c5f..705d2249f917 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -295,11 +295,20 @@ void HwasanTSDInit() {} void HwasanTSDThreadInit() {} # endif +// OHOS_LOCAL begin # if SANITIZER_ANDROID uptr *GetCurrentThreadLongPtr() { return (uptr *)get_android_tls_ptr(); } +# elif SANITIZER_OHOS +// For compatibility reason, we support hwasan_tls at the same time +uptr *GetCurrentThreadLongPtr() { return &__hwasan_tls; } +// Musl doesn't support libc using Tls variables now, +// so musl puts hwasan_tls on the pthread, this interface can return the +// corresponding address. +uptr *GetCurrentThreadLongPtrWithoutTls() { return (uptr *)get_ohos_tls_ptr(); } # else uptr *GetCurrentThreadLongPtr() { return &__hwasan_tls; } -# endif +# endif // SANITIZER_ANDROID || SANITIZER_OHOS +// OHOS_LOCAL end # if SANITIZER_ANDROID void AndroidTestTlsSlot() { diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index d1c6a03a8ec9..b6d2a49bf9da 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -68,6 +68,16 @@ void Thread::InitStackRingBuffer(uptr stack_buffer_start, // The following implicitly sets (this) as the current thread. stack_allocations_ = new (ThreadLong) StackAllocationsRingBuffer((void *)stack_buffer_start, stack_buffer_size); + // OHOS_LOCAL begin + // For compatibility reason, we keep the tls variable hwasan_tls. + // but the problem is both of the thread variable store the stack + // records to the same address but this two action will not synchronize + // with each other. So if there are A.so use hwasan_tls and B.so use + // tp - 144, the stack records will overlap. Currently the stack + // records record by tp - 144 will not be print in the hwasan log. + uptr *ThreadLongWithoutTls = GetCurrentThreadLongPtrWithoutTls(); + *ThreadLongWithoutTls = *ThreadLong; + // OHOS_LOCAL end // Check that it worked. CHECK_EQ(GetCurrentThread(), this); @@ -114,6 +124,9 @@ void Thread::Destroy() { // TSD destructors are done. CHECK_EQ(GetCurrentThread(), this); *GetCurrentThreadLongPtr() = 0; + // OHOS_LOCAL begin + *GetCurrentThreadLongPtrWithoutTls() = 0; + // OHOS_LOCAL end } void Thread::Print(const char *Prefix) { diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 0845266fe77d..b066d9fb6e8d 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -140,6 +140,9 @@ class Thread { Thread *GetCurrentThread(); uptr *GetCurrentThreadLongPtr(); +// OHOS_LOCAL begin +uptr *GetCurrentThreadLongPtrWithoutTls(); +// OHOS_LOCAL end struct ScopedTaggingDisabler { ScopedTaggingDisabler() { GetCurrentThread()->DisableTagging(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index fe4f9c18e9a2..672707d6236a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -168,16 +168,27 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { #error "Unsupported architecture." #endif +#if SANITIZER_ANDROID // The Android Bionic team has allocated a TLS slot for sanitizers starting // with Q, given that Android currently doesn't support ELF TLS. It is used to // store sanitizer thread specific data. static const int TLS_SLOT_SANITIZER = 6; +#elif SANITIZER_OHOS +static const int TLS_SLOT_SANITIZER = 18; // OHOS_LOCAL +#endif // SANITIZER_ANDROID ALWAYS_INLINE uptr *get_android_tls_ptr() { return reinterpret_cast(&__get_tls()[TLS_SLOT_SANITIZER]); } -#endif // SANITIZER_ANDROID +// OHOS_LOCAL begin +#if SANITIZER_OHOS +ALWAYS_INLINE uptr *get_ohos_tls_ptr() { + return reinterpret_cast(__get_tls() - TLS_SLOT_SANITIZER); +} +#endif // SANITIZER_OHOS +// OHOS_LOCAL end +#endif // SANITIZER_ANDROID || SANITIZER_OHOS } // namespace __sanitizer diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index b01c74320380..276f991a51bf 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -90,6 +90,13 @@ static cl::opt ClInstrumentWithCalls( cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false)); +//OHOS_LOCAL begin +static cl::opt ClInstrumentWithoutTLS( + "hwasan-instrument-without-TLS", + cl::desc("instrument without hwasan_tls"), cl::Hidden, + cl::init(false)); +//OHOS_LOCAL end + static cl::opt ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); @@ -613,7 +620,9 @@ void HWAddressSanitizer::initializeModule() { instrumentPersonalityFunctions(); } - if (!TargetTriple.isAndroid()) { + // OHOS_LOCAL begin + if (!(TargetTriple.isAndroid() || (TargetTriple.isOHOSFamily() && + ClInstrumentWithoutTLS))) { Constant *C = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] { auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false, GlobalValue::ExternalLinkage, nullptr, @@ -1116,15 +1125,23 @@ Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) { Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) { Module *M = IRB.GetInsertBlock()->getParent()->getParent(); - if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) { + // OHOS_LOCAL begin + if (TargetTriple.isAArch64() && + (TargetTriple.isAndroid() || (TargetTriple.isOHOSFamily() && + ClInstrumentWithoutTLS))) { // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER // in Bionic's libc/private/bionic_tls.h. + // For OHOS, in order to support hwasan with emulated-tls, we are provides + // a fixed TLS slot for sanitizers. It is 144 byte below the TP. + // hwasan_tls in the pthread struct in Musl's src/internal/pthread_impl.h Function *ThreadPointerFunc = Intrinsic::getDeclaration(M, Intrinsic::thread_pointer); Value *SlotPtr = IRB.CreatePointerCast( IRB.CreateConstGEP1_32(IRB.getInt8Ty(), - IRB.CreateCall(ThreadPointerFunc), 0x30), + IRB.CreateCall(ThreadPointerFunc), + TargetTriple.isAndroid()? 0x30 : -0x90), Ty->getPointerTo(0)); + // OHOS_LOCAL end return SlotPtr; } if (ThreadPtrGlobal) -- Gitee