[XRay] Change ARM/AArch64/powerpc64le to use version 2 sled (PC-relative address)
authorFangrui Song <maskray@google.com>
Tue, 21 Apr 2020 18:31:15 +0000 (11:31 -0700)
committerFangrui Song <maskray@google.com>
Fri, 24 Apr 2020 15:35:43 +0000 (08:35 -0700)
Follow-up of D78082 (x86-64).

This change avoids dynamic relocations in `xray_instr_map` for ARM/AArch64/powerpc64le.

MIPS64 cannot use 64-bit PC-relative addresses because R_MIPS_PC64 is not defined.
Because MIPS32 shares the same code, for simplicity, we don't use PC-relative addresses for MIPS32 as well.

Tested on AArch64 Linux and ppc64le Linux.

Reviewed By: ianlevesque

Differential Revision: https://reviews.llvm.org/D78590

12 files changed:
compiler-rt/lib/xray/xray_AArch64.cpp
compiler-rt/lib/xray/xray_arm.cpp
compiler-rt/lib/xray/xray_interface_internal.h
compiler-rt/lib/xray/xray_powerpc64.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
llvm/lib/Target/ARM/ARMMCInstLower.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/test/CodeGen/AArch64/xray-tail-call-sled.ll
llvm/test/CodeGen/ARM/xray-tail-call-sled.ll
llvm/test/CodeGen/PowerPC/xray-attribute-instrumentation.ll
llvm/test/CodeGen/PowerPC/xray-tail-call-sled.ll

index 081941b..00105d3 100644 (file)
@@ -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);
index 9ad8065..e181855 100644 (file)
@@ -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 =
index 2a18597..cdd1b9c 100644 (file)
@@ -30,16 +30,10 @@ struct XRaySledEntry {
   unsigned char Version;
   unsigned char Padding[13]; // Need 32 bytes
   uint64_t address() const {
-#ifndef __x86_64__
-    // R_MIPS_PC64 does not exist. Use absolute address even for version 2.
-    return Address;
-#else
-    // TODO Eventually all targets but MIPS64 should take this branch.
     if (Version < 2)
       return Address;
     // The target address is relative to the location of the Address variable.
     return reinterpret_cast<uint64_t>(&Address) + Address;
-#endif
   }
 #elif SANITIZER_WORDSIZE == 32
   uint32_t Address;
@@ -48,7 +42,12 @@ struct XRaySledEntry {
   unsigned char AlwaysInstrument;
   unsigned char Version;
   unsigned char Padding[5]; // Need 16 bytes
-  uint32_t address() const { return Address; }
+  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
index 067488b..c3553d8 100644 (file)
@@ -52,7 +52,7 @@ namespace __xray {
 bool patchFunctionEntry(const bool Enable, uint32_t FuncId,
                         const XRaySledEntry &Sled,
                         void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {
-  const uint64_t Address = Sled.Address;
+  const uint64_t Address = Sled.address();
   if (Enable) {
     // lis 0, FuncId[16..32]
     // li 0, FuncId[0..15]
@@ -70,7 +70,7 @@ bool patchFunctionEntry(const bool Enable, uint32_t FuncId,
 
 bool patchFunctionExit(const bool Enable, uint32_t FuncId,
                        const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
-  const uint64_t Address = Sled.Address;
+  const uint64_t Address = Sled.address();
   if (Enable) {
     // lis 0, FuncId[16..32]
     // li 0, FuncId[0..15]
index 9c9cafe..7b9bcb6 100644 (file)
@@ -3201,8 +3201,9 @@ void AsmPrinter::emitXRayTable() {
   MCSection *InstMap = nullptr;
   MCSection *FnSledIndex = nullptr;
   const Triple &TT = TM.getTargetTriple();
-  // Version 2 uses a PC-relative address on all supported targets.
-  bool PCRel = TT.isX86();
+  // Use PC-relative addresses on all targets except MIPS (MIPS64 cannot use
+  // PC-relative addresses because R_MIPS_PC64 does not exist).
+  bool PCRel = !TT.isMIPS();
   if (TT.isOSBinFormatELF()) {
     auto LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);
     auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
index f197808..c450558 100644 (file)
@@ -313,7 +313,7 @@ void AArch64AsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
     EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
 
   OutStreamer->emitLabel(Target);
-  recordSled(CurSled, MI, Kind);
+  recordSled(CurSled, MI, Kind, 2);
 }
 
 void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
index f8f6522..f893faa 100644 (file)
@@ -210,7 +210,7 @@ void ARMAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
   emitNops(NoopsInSledCount);
 
   OutStreamer->emitLabel(Target);
-  recordSled(CurSled, MI, Kind);
+  recordSled(CurSled, MI, Kind, 2);
 }
 
 void ARMAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
index bc2d12f..d4fd0fb 100644 (file)
@@ -1181,7 +1181,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
                            OutContext)));
     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
     OutStreamer->emitLabel(EndOfSled);
-    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
+    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2);
     break;
   }
   case TargetOpcode::PATCHABLE_RET: {
@@ -1269,7 +1269,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
     EmitToStreamer(*OutStreamer, RetInst);
     if (IsConditional)
       OutStreamer->emitLabel(FallthroughLabel);
-    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
+    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2);
     break;
   }
   case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
index f966362..b6f7a4e 100644 (file)
@@ -28,9 +28,11 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-NEXT:  ret\r
 }\r
 ; CHECK-LABEL: xray_instr_map\r
-; CHECK-LABEL: Lxray_sleds_start0:\r
-; CHECK:       .xword .Lxray_sled_0\r
-; CHECK:       .xword .Lxray_sled_1\r
+; CHECK-LABEL: .Lxray_sleds_start0:\r
+; CHECK-NEXT:  .Ltmp2:\r
+; CHECK:       .xword .Lxray_sled_0-.Ltmp2\r
+; CHECK:       .Ltmp3:\r
+; CHECK-NEXT:  .xword .Lxray_sled_1-.Ltmp3\r
 ; CHECK-LABEL: Lxray_sleds_end0:\r
 ; CHECK-LABEL: xray_fn_idx\r
 ; CHECK:       .xword .Lxray_sleds_start0\r
@@ -47,7 +49,7 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-NEXT:  nop\r
 ; CHECK-NEXT:  nop\r
 ; CHECK-NEXT:  nop\r
-; CHECK-LABEL: .Ltmp2:\r
+; CHECK-LABEL: .Ltmp4:\r
 ; CHECK:       .p2align        2\r
 ; CHECK-LABEL: Lxray_sled_3:\r
 ; CHECK-NEXT:  b       #32\r
@@ -58,7 +60,7 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-NEXT:  nop\r
 ; CHECK-NEXT:  nop\r
 ; CHECK-NEXT:  nop\r
-; CHECK-LABEL: .Ltmp3:\r
+; CHECK-LABEL: .Ltmp5:\r
   %retval = tail call i32 @callee()\r
 ; CHECK:       b       callee\r
   ret i32 %retval\r
index f6769c0..2d3af55 100644 (file)
@@ -37,7 +37,7 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-NEXT:  nop
 ; CHECK-NEXT:  nop
 ; CHECK-NEXT:  nop
-; CHECK-LABEL: Ltmp2:
+; CHECK-LABEL: Ltmp4:
 ; CHECK:       .p2align        2
 ; CHECK-LABEL: Lxray_sled_3:
 ; CHECK-NEXT:  b       #20
@@ -47,7 +47,7 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-NEXT:  nop
 ; CHECK-NEXT:  nop
 ; CHECK-NEXT:  nop
-; CHECK-LABEL: Ltmp3:
+; CHECK-LABEL: Ltmp5:
   %retval = tail call i32 @callee()
 ; CHECK:       b       {{.*}}callee
   ret i32 %retval
index 91beadc..63c34be 100644 (file)
@@ -22,19 +22,21 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
 ; CHECK-NEXT:         nop
 ; CHECK-NEXT:         mtlr 0
 }
-; CHECK-LABEL: xray_instr_map,"awo",@progbits,foo{{$}}
+; CHECK-LABEL: xray_instr_map,"ao",@progbits,foo{{$}}
 ; CHECK:      .Lxray_sleds_start0:
-; CHECK-NEXT:         .quad   .Ltmp0
+; CHECK-NEXT: .Ltmp3:
+; CHECK-NEXT:         .quad   .Ltmp0-.Ltmp3
 ; CHECK-NEXT:         .quad   foo
 ; CHECK-NEXT:         .byte   0x00
 ; CHECK-NEXT:         .byte   0x01
-; CHECK-NEXT:         .byte   0x00
+; CHECK-NEXT:         .byte   0x02
 ; CHECK-NEXT:         .space  13
-; CHECK-NEXT:         .quad   .Ltmp2
+; CHECK-NEXT: .Ltmp4:
+; CHECK-NEXT:         .quad   .Ltmp2-.Ltmp4
 ; CHECK-NEXT:         .quad   foo
 ; CHECK-NEXT:         .byte   0x01
 ; CHECK-NEXT:         .byte   0x01
-; CHECK-NEXT:         .byte   0x00
+; CHECK-NEXT:         .byte   0x02
 ; CHECK-NEXT:         .space  13
 ; CHECK-NEXT: .Lxray_sleds_end0:
 ; CHECK-LABEL: xray_fn_idx,"awo",@progbits,foo{{$}}
index 90a928a..e071e8a 100644 (file)
@@ -22,18 +22,18 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-alway
 }
 
 define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" {
-; CHECK-LABEL: .Ltmp3:
-; CHECK:              b .Ltmp4
+; CHECK-LABEL: .Ltmp5:
+; CHECK-NEXT:         b .Ltmp6
 ; CHECK-NEXT:         nop
 ; CHECK-NEXT:         std 0, -8(1)
 ; CHECK-NEXT:         mflr 0
 ; CHECK-NEXT:         bl __xray_FunctionEntry
 ; CHECK-NEXT:         nop
 ; CHECK-NEXT:         mtlr 0
-; CHECK-LABEL: .Ltmp4:
+; CHECK-LABEL: .Ltmp6:
   %retval = tail call i32 @callee()
   ret i32 %retval
-; CHECK-LABEL: .Ltmp5:
+; CHECK-LABEL: .Ltmp7:
 ; CHECK:              blr
 ; CHECK-NEXT:         nop
 ; CHECK-NEXT:         std 0, -8(1)