diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp index 2d7a44525c5ff335f0be18dbd0fbca3529a922d0..705d2249f9178b064798ac7f5d7d8259c5b738fd 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 d1c6a03a8ec9d5559bb610efc40560830c6c770b..b6d2a49bf9da3108a8148658b7364cbe10e4aa4c 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 0845266fe77d77e7d919447b58938f2bca113fb7..b066d9fb6e8da683ff224b40314f0256b2018580 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 fe4f9c18e9a22d4470abc7b41eec0efbc0497134..672707d6236a226265ef4ca872d5cfaeb4bab4f0 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 b01c74320380231e918010f37475d5667d34be61..276f991a51bfee39310a408fab627e356d983ad0 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)