diff options
Diffstat (limited to 'compiler-rt/lib/xray')
-rw-r--r-- | compiler-rt/lib/xray/xray_AArch64.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_arm.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_init.cpp | 20 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_interface.cpp | 84 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_interface_internal.h | 24 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_powerpc64.cpp | 16 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_trampoline_AArch64.S | 41 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_trampoline_arm.S | 21 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_trampoline_x86_64.S | 6 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_utils.cpp | 4 | ||||
-rw-r--r-- | compiler-rt/lib/xray/xray_x86_64.cpp | 66 |
11 files changed, 202 insertions, 84 deletions
diff --git a/compiler-rt/lib/xray/xray_AArch64.cpp b/compiler-rt/lib/xray/xray_AArch64.cpp index 081941b70375..00105d30b4db 100644 --- a/compiler-rt/lib/xray/xray_AArch64.cpp +++ b/compiler-rt/lib/xray/xray_AArch64.cpp @@ -61,7 +61,7 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId, // When |Enable|==false, we set back the first instruction in the sled to be // B #32 - uint32_t *FirstAddress = reinterpret_cast<uint32_t *>(Sled.Address); + uint32_t *FirstAddress = reinterpret_cast<uint32_t *>(Sled.address()); uint32_t *CurAddress = FirstAddress + 1; if (Enable) { *CurAddress = uint32_t(PatchOpcodes::PO_LdrW0_12); diff --git a/compiler-rt/lib/xray/xray_arm.cpp b/compiler-rt/lib/xray/xray_arm.cpp index 9ad8065eb886..e1818555906c 100644 --- a/compiler-rt/lib/xray/xray_arm.cpp +++ b/compiler-rt/lib/xray/xray_arm.cpp @@ -102,7 +102,7 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId, // When |Enable|==false, we set back the first instruction in the sled to be // B #20 - uint32_t *FirstAddress = reinterpret_cast<uint32_t *>(Sled.Address); + uint32_t *FirstAddress = reinterpret_cast<uint32_t *>(Sled.address()); uint32_t *CurAddress = FirstAddress + 1; if (Enable) { CurAddress = diff --git a/compiler-rt/lib/xray/xray_init.cpp b/compiler-rt/lib/xray/xray_init.cpp index 408396477975..00ba5fe4a52b 100644 --- a/compiler-rt/lib/xray/xray_init.cpp +++ b/compiler-rt/lib/xray/xray_init.cpp @@ -84,8 +84,24 @@ void __xray_init() XRAY_NEVER_INSTRUMENT { SpinMutexLock Guard(&XRayInstrMapMutex); XRayInstrMap.Sleds = __start_xray_instr_map; XRayInstrMap.Entries = __stop_xray_instr_map - __start_xray_instr_map; - XRayInstrMap.SledsIndex = __start_xray_fn_idx; - XRayInstrMap.Functions = __stop_xray_fn_idx - __start_xray_fn_idx; + if (__start_xray_fn_idx != nullptr) { + XRayInstrMap.SledsIndex = __start_xray_fn_idx; + XRayInstrMap.Functions = __stop_xray_fn_idx - __start_xray_fn_idx; + } else { + size_t CountFunctions = 0; + uint64_t LastFnAddr = 0; + + for (std::size_t I = 0; I < XRayInstrMap.Entries; I++) { + const auto &Sled = XRayInstrMap.Sleds[I]; + const auto Function = Sled.function(); + if (Function != LastFnAddr) { + CountFunctions++; + LastFnAddr = Function; + } + } + + XRayInstrMap.Functions = CountFunctions; + } } atomic_store(&XRayInitialized, true, memory_order_release); diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp index 0d22893eb30f..7669b9ab82be 100644 --- a/compiler-rt/lib/xray/xray_interface.cpp +++ b/compiler-rt/lib/xray/xray_interface.cpp @@ -175,6 +175,33 @@ bool patchSled(const XRaySledEntry &Sled, bool Enable, return Success; } +const XRayFunctionSledIndex +findFunctionSleds(int32_t FuncId, + const XRaySledMap &InstrMap) XRAY_NEVER_INSTRUMENT { + int32_t CurFn = 0; + uint64_t LastFnAddr = 0; + XRayFunctionSledIndex Index = {nullptr, nullptr}; + + for (std::size_t I = 0; I < InstrMap.Entries && CurFn <= FuncId; I++) { + const auto &Sled = InstrMap.Sleds[I]; + const auto Function = Sled.function(); + if (Function != LastFnAddr) { + CurFn++; + LastFnAddr = Function; + } + + if (CurFn == FuncId) { + if (Index.Begin == nullptr) + Index.Begin = &Sled; + Index.End = &Sled; + } + } + + Index.End += 1; + + return Index; +} + XRayPatchingStatus patchFunction(int32_t FuncId, bool Enable) XRAY_NEVER_INSTRUMENT { if (!atomic_load(&XRayInitialized, @@ -205,10 +232,10 @@ XRayPatchingStatus patchFunction(int32_t FuncId, } // Now we patch ths sleds for this specific function. - auto SledRange = InstrMap.SledsIndex[FuncId - 1]; + auto SledRange = InstrMap.SledsIndex ? InstrMap.SledsIndex[FuncId - 1] + : findFunctionSleds(FuncId, InstrMap); auto *f = SledRange.Begin; auto *e = SledRange.End; - bool SucceedOnce = false; while (f != e) SucceedOnce |= patchSled(*f++, Enable, FuncId); @@ -264,14 +291,14 @@ XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT { // now we're assuming we can mprotect the whole section of text between the // minimum sled address and the maximum sled address (+ the largest sled // size). - auto MinSled = InstrMap.Sleds[0]; - auto MaxSled = InstrMap.Sleds[InstrMap.Entries - 1]; + auto *MinSled = &InstrMap.Sleds[0]; + auto *MaxSled = &InstrMap.Sleds[InstrMap.Entries - 1]; for (std::size_t I = 0; I < InstrMap.Entries; I++) { const auto &Sled = InstrMap.Sleds[I]; - if (Sled.Address < MinSled.Address) - MinSled = Sled; - if (Sled.Address > MaxSled.Address) - MaxSled = Sled; + if (Sled.address() < MinSled->address()) + MinSled = &Sled; + if (Sled.address() > MaxSled->address()) + MaxSled = &Sled; } const size_t PageSize = flags()->xray_page_size_override > 0 @@ -283,9 +310,10 @@ XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT { } void *PageAlignedAddr = - reinterpret_cast<void *>(MinSled.Address & ~(PageSize - 1)); + reinterpret_cast<void *>(MinSled->address() & ~(PageSize - 1)); size_t MProtectLen = - (MaxSled.Address - reinterpret_cast<uptr>(PageAlignedAddr)) + cSledLength; + (MaxSled->address() - reinterpret_cast<uptr>(PageAlignedAddr)) + + cSledLength; MProtectHelper Protector(PageAlignedAddr, MProtectLen, PageSize); if (Protector.MakeWriteable() == -1) { Report("Failed mprotect: %d\n", errno); @@ -294,7 +322,7 @@ XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT { for (std::size_t I = 0; I < InstrMap.Entries; ++I) { auto &Sled = InstrMap.Sleds[I]; - auto F = Sled.Function; + auto F = Sled.function(); if (CurFun == 0) CurFun = F; if (F != CurFun) { @@ -334,23 +362,25 @@ XRayPatchingStatus mprotectAndPatchFunction(int32_t FuncId, // Here we compute the minumum sled and maximum sled associated with a // particular function ID. - auto SledRange = InstrMap.SledsIndex[FuncId - 1]; + auto SledRange = InstrMap.SledsIndex ? InstrMap.SledsIndex[FuncId - 1] + : findFunctionSleds(FuncId, InstrMap); auto *f = SledRange.Begin; auto *e = SledRange.End; - auto MinSled = *f; - auto MaxSled = *(SledRange.End - 1); + auto *MinSled = f; + auto *MaxSled = (SledRange.End - 1); while (f != e) { - if (f->Address < MinSled.Address) - MinSled = *f; - if (f->Address > MaxSled.Address) - MaxSled = *f; + if (f->address() < MinSled->address()) + MinSled = f; + if (f->address() > MaxSled->address()) + MaxSled = f; ++f; } void *PageAlignedAddr = - reinterpret_cast<void *>(MinSled.Address & ~(PageSize - 1)); + reinterpret_cast<void *>(MinSled->address() & ~(PageSize - 1)); size_t MProtectLen = - (MaxSled.Address - reinterpret_cast<uptr>(PageAlignedAddr)) + cSledLength; + (MaxSled->address() - reinterpret_cast<uptr>(PageAlignedAddr)) + + cSledLength; MProtectHelper Protector(PageAlignedAddr, MProtectLen, PageSize); if (Protector.MakeWriteable() == -1) { Report("Failed mprotect: %d\n", errno); @@ -461,10 +491,18 @@ int __xray_set_handler_arg1(void (*entry)(int32_t, XRayEntryType, uint64_t)) { int __xray_remove_handler_arg1() { return __xray_set_handler_arg1(nullptr); } uintptr_t __xray_function_address(int32_t FuncId) XRAY_NEVER_INSTRUMENT { - SpinMutexLock Guard(&XRayInstrMapMutex); - if (FuncId <= 0 || static_cast<size_t>(FuncId) > XRayInstrMap.Functions) + XRaySledMap InstrMap; + { + SpinMutexLock Guard(&XRayInstrMapMutex); + InstrMap = XRayInstrMap; + } + + if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions) return 0; - return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Function + const XRaySledEntry *Sled = InstrMap.SledsIndex + ? InstrMap.SledsIndex[FuncId - 1].Begin + : findFunctionSleds(FuncId, InstrMap).Begin; + return Sled->function() // On PPC, function entries are always aligned to 16 bytes. The beginning of a // sled might be a local entry, which is always +8 based on the global entry. // Always return the global entry. diff --git a/compiler-rt/lib/xray/xray_interface_internal.h b/compiler-rt/lib/xray/xray_interface_internal.h index 0fea6377648d..390f389b1dca 100644 --- a/compiler-rt/lib/xray/xray_interface_internal.h +++ b/compiler-rt/lib/xray/xray_interface_internal.h @@ -29,6 +29,18 @@ struct XRaySledEntry { unsigned char AlwaysInstrument; unsigned char Version; unsigned char Padding[13]; // Need 32 bytes + uint64_t function() const { + if (Version < 2) + return Function; + // The target address is relative to the location of the Function variable. + return reinterpret_cast<uint64_t>(&Function) + Function; + } + uint64_t address() const { + if (Version < 2) + return Address; + // The target address is relative to the location of the Address variable. + return reinterpret_cast<uint64_t>(&Address) + Address; + } #elif SANITIZER_WORDSIZE == 32 uint32_t Address; uint32_t Function; @@ -36,6 +48,18 @@ struct XRaySledEntry { unsigned char AlwaysInstrument; unsigned char Version; unsigned char Padding[5]; // Need 16 bytes + uint32_t function() const { + if (Version < 2) + return Function; + // The target address is relative to the location of the Function variable. + return reinterpret_cast<uint32_t>(&Function) + Function; + } + uint32_t address() const { + if (Version < 2) + return Address; + // The target address is relative to the location of the Address variable. + return reinterpret_cast<uint32_t>(&Address) + Address; + } #else #error "Unsupported word size." #endif diff --git a/compiler-rt/lib/xray/xray_powerpc64.cpp b/compiler-rt/lib/xray/xray_powerpc64.cpp index b41f1bce6f21..c3553d848313 100644 --- a/compiler-rt/lib/xray/xray_powerpc64.cpp +++ b/compiler-rt/lib/xray/xray_powerpc64.cpp @@ -52,35 +52,37 @@ namespace __xray { bool patchFunctionEntry(const bool Enable, uint32_t FuncId, const XRaySledEntry &Sled, void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { + const uint64_t Address = Sled.address(); if (Enable) { // lis 0, FuncId[16..32] // li 0, FuncId[0..15] - *reinterpret_cast<uint64_t *>(Sled.Address) = + *reinterpret_cast<uint64_t *>(Address) = (0x3c000000ull + (FuncId >> 16)) + ((0x60000000ull + (FuncId & 0xffff)) << 32); } else { // b +JumpOverInstNum instructions. - *reinterpret_cast<uint32_t *>(Sled.Address) = + *reinterpret_cast<uint32_t *>(Address) = 0x48000000ull + (JumpOverInstNum << 2); } - clearCache(reinterpret_cast<void *>(Sled.Address), 8); + clearCache(reinterpret_cast<void *>(Address), 8); return true; } bool patchFunctionExit(const bool Enable, uint32_t FuncId, const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { + const uint64_t Address = Sled.address(); if (Enable) { // lis 0, FuncId[16..32] // li 0, FuncId[0..15] - *reinterpret_cast<uint64_t *>(Sled.Address) = + *reinterpret_cast<uint64_t *>(Address) = (0x3c000000ull + (FuncId >> 16)) + ((0x60000000ull + (FuncId & 0xffff)) << 32); } else { // Copy the blr/b instruction after JumpOverInstNum instructions. - *reinterpret_cast<uint32_t *>(Sled.Address) = - *(reinterpret_cast<uint32_t *>(Sled.Address) + JumpOverInstNum); + *reinterpret_cast<uint32_t *>(Address) = + *(reinterpret_cast<uint32_t *>(Address) + JumpOverInstNum); } - clearCache(reinterpret_cast<void *>(Sled.Address), 8); + clearCache(reinterpret_cast<void *>(Address), 8); return true; } diff --git a/compiler-rt/lib/xray/xray_trampoline_AArch64.S b/compiler-rt/lib/xray/xray_trampoline_AArch64.S index 4d1b04fb7d90..3bf52cef60fe 100644 --- a/compiler-rt/lib/xray/xray_trampoline_AArch64.S +++ b/compiler-rt/lib/xray/xray_trampoline_AArch64.S @@ -7,6 +7,7 @@ .p2align 2 /* Let C/C++ see the symbol */ .global __xray_FunctionEntry + .hidden __xray_FunctionEntry .type __xray_FunctionEntry, %function /* In C++ it is void extern "C" __xray_FunctionEntry(uint32_t FuncId) with FuncId passed in W0 register. */ @@ -26,10 +27,14 @@ __xray_FunctionEntry: STP Q2, Q3, [SP, #-32]! STP Q4, Q5, [SP, #-32]! STP Q6, Q7, [SP, #-32]! - /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */ - LDR X1, =_ZN6__xray19XRayPatchedFunctionE + /* X8 is the indirect result register and needs to be preserved for the body + of the function to use */ + STP X8, X0, [SP, #-16]! + + /* Load the page address of _ZN6__xray19XRayPatchedFunctionE into X1 */ + ADRP X1, _ZN6__xray19XRayPatchedFunctionE /* Load the handler function pointer into X2 */ - LDR X2, [X1] + LDR X2, [X1, #:lo12:_ZN6__xray19XRayPatchedFunctionE] /* Handler address is nullptr if handler is not set */ CMP X2, #0 BEQ FunctionEntry_restore @@ -40,6 +45,7 @@ __xray_FunctionEntry: BLR X2 FunctionEntry_restore: /* Pop the saved registers */ + LDP X8, X0, [SP], #16 LDP Q6, Q7, [SP], #32 LDP Q4, Q5, [SP], #32 LDP Q2, Q3, [SP], #32 @@ -54,6 +60,7 @@ FunctionEntry_restore: .p2align 2 /* Let C/C++ see the symbol */ .global __xray_FunctionExit + .hidden __xray_FunctionExit .type __xray_FunctionExit, %function /* In C++ it is void extern "C" __xray_FunctionExit(uint32_t FuncId) with FuncId passed in W0 register. */ @@ -69,11 +76,18 @@ __xray_FunctionExit: STP X3, X4, [SP, #-16]! STP X5, X6, [SP, #-16]! STP X7, X30, [SP, #-16]! - STR Q0, [SP, #-16]! - /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */ - LDR X1, =_ZN6__xray19XRayPatchedFunctionE + STP Q0, Q1, [SP, #-32]! + STP Q2, Q3, [SP, #-32]! + STP Q4, Q5, [SP, #-32]! + STP Q6, Q7, [SP, #-32]! + /* X8 is the indirect result register and needs to be preserved for the body + of the function to use */ + STP X8, X0, [SP, #-16]! + + /* Load the page address of _ZN6__xray19XRayPatchedFunctionE into X1 */ + ADRP X1, _ZN6__xray19XRayPatchedFunctionE /* Load the handler function pointer into X2 */ - LDR X2, [X1] + LDR X2, [X1, #:lo12:_ZN6__xray19XRayPatchedFunctionE] /* Handler address is nullptr if handler is not set */ CMP X2, #0 BEQ FunctionExit_restore @@ -83,7 +97,11 @@ __xray_FunctionExit: /* Call the handler with 2 parameters in W0 and X1 */ BLR X2 FunctionExit_restore: - LDR Q0, [SP], #16 + LDP X8, X0, [SP], #16 + LDP Q6, Q7, [SP], #32 + LDP Q4, Q5, [SP], #32 + LDP Q2, Q3, [SP], #32 + LDP Q0, Q1, [SP], #32 LDP X7, X30, [SP], #16 LDP X5, X6, [SP], #16 LDP X3, X4, [SP], #16 @@ -94,6 +112,7 @@ FunctionExit_restore: .p2align 2 /* Let C/C++ see the symbol */ .global __xray_FunctionTailExit + .hidden __xray_FunctionTailExit .type __xray_FunctionTailExit, %function /* In C++ it is void extern "C" __xray_FunctionTailExit(uint32_t FuncId) with FuncId passed in W0 register. */ @@ -114,10 +133,10 @@ __xray_FunctionTailExit: STP Q2, Q3, [SP, #-32]! STP Q4, Q5, [SP, #-32]! STP Q6, Q7, [SP, #-32]! - /* Load the address of _ZN6__xray19XRayPatchedFunctionE into X1 */ - LDR X1, =_ZN6__xray19XRayPatchedFunctionE + /* Load the page address of _ZN6__xray19XRayPatchedFunctionE into X1 */ + ADRP X1, _ZN6__xray19XRayPatchedFunctionE /* Load the handler function pointer into X2 */ - LDR X2, [X1] + LDR X2, [X1, #:lo12:_ZN6__xray19XRayPatchedFunctionE] /* Handler address is nullptr if handler is not set */ CMP X2, #0 BEQ FunctionTailExit_restore diff --git a/compiler-rt/lib/xray/xray_trampoline_arm.S b/compiler-rt/lib/xray/xray_trampoline_arm.S index 71dbee65d825..3ffc1e443761 100644 --- a/compiler-rt/lib/xray/xray_trampoline_arm.S +++ b/compiler-rt/lib/xray/xray_trampoline_arm.S @@ -10,6 +10,7 @@ .p2align 2 @ Let C/C++ see the symbol .global __xray_FunctionEntry + .hidden __xray_FunctionEntry @ It preserves all registers except r0, r12(ip), r14(lr) and r15(pc) @ Assume that "q" part of the floating-point registers is not used @ for passing parameters to C/C++ functions. @@ -20,9 +21,9 @@ __xray_FunctionEntry: PUSH {r1-r3,lr} @ Save floating-point parameters of the instrumented function VPUSH {d0-d7} - MOVW r1,#:lower16:_ZN6__xray19XRayPatchedFunctionE - MOVT r1,#:upper16:_ZN6__xray19XRayPatchedFunctionE - LDR r2, [r1] + MOVW r1, #:lower16:_ZN6__xray19XRayPatchedFunctionE - (. + 16) + MOVT r1, #:upper16:_ZN6__xray19XRayPatchedFunctionE - (. + 12) + LDR r2, [pc, r1] @ Handler address is nullptr if handler is not set CMP r2, #0 BEQ FunctionEntry_restore @@ -40,6 +41,7 @@ FunctionEntry_restore: .p2align 2 @ Let C/C++ see the symbol .global __xray_FunctionExit + .hidden __xray_FunctionExit @ Assume that d1-d7 are not used for the return value. @ Assume that "q" part of the floating-point registers is not used for the @ return value in C/C++. @@ -51,9 +53,9 @@ __xray_FunctionExit: @ Save the floating-point return value of the instrumented function VPUSH {d0} @ Load the handler address - MOVW r1,#:lower16:_ZN6__xray19XRayPatchedFunctionE - MOVT r1,#:upper16:_ZN6__xray19XRayPatchedFunctionE - LDR r2, [r1] + MOVW r1, #:lower16:_ZN6__xray19XRayPatchedFunctionE - (. + 16) + MOVT r1, #:upper16:_ZN6__xray19XRayPatchedFunctionE - (. + 12) + LDR r2, [pc, r1] @ Handler address is nullptr if handler is not set CMP r2, #0 BEQ FunctionExit_restore @@ -71,6 +73,7 @@ FunctionExit_restore: .p2align 2 @ Let C/C++ see the symbol .global __xray_FunctionTailExit + .hidden __xray_FunctionTailExit @ It preserves all registers except r0, r12(ip), r14(lr) and r15(pc) @ Assume that "q" part of the floating-point registers is not used @ for passing parameters to C/C++ functions. @@ -81,9 +84,9 @@ __xray_FunctionTailExit: PUSH {r1-r3,lr} @ Save floating-point parameters of the instrumented function VPUSH {d0-d7} - MOVW r1,#:lower16:_ZN6__xray19XRayPatchedFunctionE - MOVT r1,#:upper16:_ZN6__xray19XRayPatchedFunctionE - LDR r2, [r1] + MOVW r1, #:lower16:_ZN6__xray19XRayPatchedFunctionE - (. + 16) + MOVT r1, #:upper16:_ZN6__xray19XRayPatchedFunctionE - (. + 12) + LDR r2, [pc, r1] @ Handler address is nullptr if handler is not set CMP r2, #0 BEQ FunctionTailExit_restore diff --git a/compiler-rt/lib/xray/xray_trampoline_x86_64.S b/compiler-rt/lib/xray/xray_trampoline_x86_64.S index 1e58362cdc80..12c5a6ccd9a4 100644 --- a/compiler-rt/lib/xray/xray_trampoline_x86_64.S +++ b/compiler-rt/lib/xray/xray_trampoline_x86_64.S @@ -98,6 +98,7 @@ //===----------------------------------------------------------------------===// .globl ASM_SYMBOL(__xray_FunctionEntry) + ASM_HIDDEN(__xray_FunctionEntry) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_FunctionEntry) # LLVM-MCA-BEGIN __xray_FunctionEntry @@ -126,6 +127,7 @@ ASM_SYMBOL(__xray_FunctionEntry): //===----------------------------------------------------------------------===// .globl ASM_SYMBOL(__xray_FunctionExit) + ASM_HIDDEN(__xray_FunctionExit) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_FunctionExit) # LLVM-MCA-BEGIN __xray_FunctionExit @@ -166,6 +168,7 @@ ASM_SYMBOL(__xray_FunctionExit): //===----------------------------------------------------------------------===// .globl ASM_SYMBOL(__xray_FunctionTailExit) + ASM_HIDDEN(__xray_FunctionTailExit) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_FunctionTailExit) # LLVM-MCA-BEGIN __xray_FunctionTailExit @@ -192,6 +195,7 @@ ASM_SYMBOL(__xray_FunctionTailExit): //===----------------------------------------------------------------------===// .globl ASM_SYMBOL(__xray_ArgLoggerEntry) + ASM_HIDDEN(__xray_ArgLoggerEntry) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry) # LLVM-MCA-BEGIN __xray_ArgLoggerEntry @@ -231,6 +235,7 @@ ASM_SYMBOL(__xray_ArgLoggerEntry): //===----------------------------------------------------------------------===// .global ASM_SYMBOL(__xray_CustomEvent) + ASM_HIDDEN(__xray_CustomEvent) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_CustomEvent) # LLVM-MCA-BEGIN __xray_CustomEvent @@ -256,6 +261,7 @@ ASM_SYMBOL(__xray_CustomEvent): //===----------------------------------------------------------------------===// .global ASM_SYMBOL(__xray_TypedEvent) + ASM_HIDDEN(__xray_TypedEvent) .align 16, 0x90 ASM_TYPE_FUNCTION(__xray_TypedEvent) # LLVM-MCA-BEGIN __xray_TypedEvent diff --git a/compiler-rt/lib/xray/xray_utils.cpp b/compiler-rt/lib/xray/xray_utils.cpp index 1036d17a7725..4c8ad5b92be7 100644 --- a/compiler-rt/lib/xray/xray_utils.cpp +++ b/compiler-rt/lib/xray/xray_utils.cpp @@ -69,6 +69,10 @@ void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUME return; } Offset += TotalBytes; + + // Record the data size as a property of the VMO. + _zx_object_set_property(Vmo, ZX_PROP_VMO_CONTENT_SIZE, + &Offset, sizeof(Offset)); } void LogWriter::Flush() XRAY_NEVER_INSTRUMENT { diff --git a/compiler-rt/lib/xray/xray_x86_64.cpp b/compiler-rt/lib/xray/xray_x86_64.cpp index e63ee1b3bd02..f3742ac71290 100644 --- a/compiler-rt/lib/xray/xray_x86_64.cpp +++ b/compiler-rt/lib/xray/xray_x86_64.cpp @@ -151,23 +151,24 @@ bool patchFunctionEntry(const bool Enable, const uint32_t FuncId, // opcode and first operand. // // Prerequisite is to compute the relative offset to the trampoline's address. + const uint64_t Address = Sled.address(); int64_t TrampolineOffset = reinterpret_cast<int64_t>(Trampoline) - - (static_cast<int64_t>(Sled.Address) + 11); + (static_cast<int64_t>(Address) + 11); if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) { - Report("XRay Entry trampoline (%p) too far from sled (%p)\n", - Trampoline, reinterpret_cast<void *>(Sled.Address)); + Report("XRay Entry trampoline (%p) too far from sled (%p)\n", Trampoline, + reinterpret_cast<void *>(Address)); return false; } if (Enable) { - *reinterpret_cast<uint32_t *>(Sled.Address + 2) = FuncId; - *reinterpret_cast<uint8_t *>(Sled.Address + 6) = CallOpCode; - *reinterpret_cast<uint32_t *>(Sled.Address + 7) = TrampolineOffset; + *reinterpret_cast<uint32_t *>(Address + 2) = FuncId; + *reinterpret_cast<uint8_t *>(Address + 6) = CallOpCode; + *reinterpret_cast<uint32_t *>(Address + 7) = TrampolineOffset; std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), MovR10Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), MovR10Seq, std::memory_order_release); } else { std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp9Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), Jmp9Seq, std::memory_order_release); // FIXME: Write out the nops still? } @@ -196,23 +197,24 @@ bool patchFunctionExit(const bool Enable, const uint32_t FuncId, // // Prerequisite is to compute the relative offset fo the // __xray_FunctionExit function's address. + const uint64_t Address = Sled.address(); int64_t TrampolineOffset = reinterpret_cast<int64_t>(__xray_FunctionExit) - - (static_cast<int64_t>(Sled.Address) + 11); + (static_cast<int64_t>(Address) + 11); if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) { Report("XRay Exit trampoline (%p) too far from sled (%p)\n", - __xray_FunctionExit, reinterpret_cast<void *>(Sled.Address)); + __xray_FunctionExit, reinterpret_cast<void *>(Address)); return false; } if (Enable) { - *reinterpret_cast<uint32_t *>(Sled.Address + 2) = FuncId; - *reinterpret_cast<uint8_t *>(Sled.Address + 6) = JmpOpCode; - *reinterpret_cast<uint32_t *>(Sled.Address + 7) = TrampolineOffset; + *reinterpret_cast<uint32_t *>(Address + 2) = FuncId; + *reinterpret_cast<uint8_t *>(Address + 6) = JmpOpCode; + *reinterpret_cast<uint32_t *>(Address + 7) = TrampolineOffset; std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), MovR10Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), MovR10Seq, std::memory_order_release); } else { std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint8_t> *>(Sled.Address), RetOpCode, + reinterpret_cast<std::atomic<uint8_t> *>(Address), RetOpCode, std::memory_order_release); // FIXME: Write out the nops still? } @@ -223,24 +225,25 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { // Here we do the dance of replacing the tail call sled with a similar // sequence as the entry sled, but calls the tail exit sled instead. + const uint64_t Address = Sled.address(); int64_t TrampolineOffset = reinterpret_cast<int64_t>(__xray_FunctionTailExit) - - (static_cast<int64_t>(Sled.Address) + 11); + (static_cast<int64_t>(Address) + 11); if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) { Report("XRay Tail Exit trampoline (%p) too far from sled (%p)\n", - __xray_FunctionTailExit, reinterpret_cast<void *>(Sled.Address)); + __xray_FunctionTailExit, reinterpret_cast<void *>(Address)); return false; } if (Enable) { - *reinterpret_cast<uint32_t *>(Sled.Address + 2) = FuncId; - *reinterpret_cast<uint8_t *>(Sled.Address + 6) = CallOpCode; - *reinterpret_cast<uint32_t *>(Sled.Address + 7) = TrampolineOffset; + *reinterpret_cast<uint32_t *>(Address + 2) = FuncId; + *reinterpret_cast<uint8_t *>(Address + 6) = CallOpCode; + *reinterpret_cast<uint32_t *>(Address + 7) = TrampolineOffset; std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), MovR10Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), MovR10Seq, std::memory_order_release); } else { std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp9Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), Jmp9Seq, std::memory_order_release); // FIXME: Write out the nops still? } @@ -267,26 +270,28 @@ bool patchCustomEvent(const bool Enable, const uint32_t FuncId, // // --- // - // In Version 1: + // In Version 1 or 2: // // The jump offset is now 15 bytes (0x0f), so when restoring the nopw back // to a jmp, use 15 bytes instead. // + const uint64_t Address = Sled.address(); if (Enable) { std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), NopwSeq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), NopwSeq, std::memory_order_release); } else { switch (Sled.Version) { case 1: + case 2: std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp15Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), Jmp15Seq, std::memory_order_release); break; case 0: default: std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp20Seq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), Jmp20Seq, std::memory_order_release); break; } @@ -313,14 +318,15 @@ bool patchTypedEvent(const bool Enable, const uint32_t FuncId, // unstashes the registers and returns. If the arguments are already in // the correct registers, the stashing and unstashing become equivalently // sized nops. + const uint64_t Address = Sled.address(); if (Enable) { std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), NopwSeq, + reinterpret_cast<std::atomic<uint16_t> *>(Address), NopwSeq, std::memory_order_release); } else { - std::atomic_store_explicit( - reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp20Seq, - std::memory_order_release); + std::atomic_store_explicit( + reinterpret_cast<std::atomic<uint16_t> *>(Address), Jmp20Seq, + std::memory_order_release); } return false; } |