diff options
8 files changed, 93 insertions, 16 deletions
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index fb8c8408fc7..e008c7ceb06 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -242,7 +242,7 @@ public: }; // All the sleds to be emitted. - std::vector<XRayFunctionEntry> Sleds; + SmallVector<XRayFunctionEntry, 4> Sleds; // Helper function to record a given XRay sled. void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index b11e30c359b..7f38c27f8a9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2761,37 +2761,63 @@ void AsmPrinter::emitXRayTable() { auto PrevSection = OutStreamer->getCurrentSectionOnly(); auto Fn = MF->getFunction(); - MCSection *Section = nullptr; + MCSection *InstMap = nullptr; + MCSection *FnSledIndex = nullptr; if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) { if (Fn->hasComdat()) { - Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, + InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, Fn->getComdat()->getName()); + FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, + Fn->getComdat()->getName()); } else { - Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, + InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); + FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC); } } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { - Section = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, + InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, SectionKind::getReadOnlyWithRel()); + FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx", 0, + SectionKind::getReadOnlyWithRel()); } else { llvm_unreachable("Unsupported target"); } // Before we switch over, we force a reference to a label inside the - // xray_instr_map section. Since this function is always called just - // before the function's end, we assume that this is happening after - // the last return instruction. - + // xray_instr_map and xray_fn_idx sections. Since this function is always + // called just before the function's end, we assume that this is happening + // after the last return instruction. We also use the synthetic label in the + // xray_inster_map as a delimeter for the range of sleds for this function in + // the index. auto WordSizeBytes = MAI->getCodePointerSize(); - MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true); + MCSymbol *SledsStart = OutContext.createTempSymbol("xray_synthetic_", true); + MCSymbol *IdxRef = OutContext.createTempSymbol("xray_fn_idx_synth_", true); OutStreamer->EmitCodeAlignment(16); - OutStreamer->EmitSymbolValue(Tmp, WordSizeBytes, false); - OutStreamer->SwitchSection(Section); - OutStreamer->EmitLabel(Tmp); + OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false); + OutStreamer->EmitSymbolValue(IdxRef, WordSizeBytes, false); + + // Now we switch to the instrumentation map section. Because this is done + // per-function, we are able to create an index entry that will represent the + // range of sleds associated with a function. + OutStreamer->SwitchSection(InstMap); + OutStreamer->EmitLabel(SledsStart); for (const auto &Sled : Sleds) Sled.emit(WordSizeBytes, OutStreamer.get(), CurrentFnSym); - + MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_synthetic_end", true); + OutStreamer->EmitLabel(SledsEnd); + + // We then emit a single entry in the index per function. We use the symbols + // that bound the instrumentation map as the range for a specific function. + // Each entry here will be 16-byte aligned, as we're writing down two + // pointers. + OutStreamer->SwitchSection(FnSledIndex); + OutStreamer->EmitCodeAlignment(16); + OutStreamer->EmitLabel(IdxRef); + OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes); + OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes); OutStreamer->SwitchSection(PrevSection); Sleds.clear(); } diff --git a/llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll b/llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll index d0f5f40e156..38b62a72a20 100644 --- a/llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll +++ b/llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll @@ -26,6 +26,7 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" } ; CHECK: .p2align 4 ; CHECK-NEXT: .xword .Lxray_synthetic_0 +; CHECK-NEXT: .xword .Lxray_fn_idx_synth_0 ; CHECK-NEXT: .section xray_instr_map,{{.*}} ; CHECK-LABEL: Lxray_synthetic_0: ; CHECK: .xword .Lxray_sled_0 diff --git a/llvm/test/CodeGen/AArch64/xray-tail-call-sled.ll b/llvm/test/CodeGen/AArch64/xray-tail-call-sled.ll index 6ada3ce8d55..fb89950b99c 100644 --- a/llvm/test/CodeGen/AArch64/xray-tail-call-sled.ll +++ b/llvm/test/CodeGen/AArch64/xray-tail-call-sled.ll @@ -29,10 +29,16 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-alway }
; CHECK: .p2align 4
; CHECK-NEXT: .xword .Lxray_synthetic_0
+; CHECK-NEXT: .xword .Lxray_fn_idx_synth_0
; CHECK-NEXT: .section xray_instr_map,{{.*}}
; CHECK-LABEL: Lxray_synthetic_0:
; CHECK: .xword .Lxray_sled_0
; CHECK: .xword .Lxray_sled_1
+; CHECK-LABEL: Lxray_synthetic_end0:
+; CHECK: .section xray_fn_idx,{{.*}}
+; CHECK-LABEL: Lxray_fn_idx_synth_0:
+; CHECK: .xword .Lxray_synthetic_0
+; CHECK-NEXT: .xword .Lxray_synthetic_end0
define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" {
; CHECK: .p2align 2
@@ -63,7 +69,13 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway }
; CHECK: .p2align 4
; CHECK-NEXT: .xword .Lxray_synthetic_1
+; CHECK-NEXT: .xword .Lxray_fn_idx_synth_1
; CHECK-NEXT: .section xray_instr_map,{{.*}}
; CHECK-LABEL: Lxray_synthetic_1:
; CHECK: .xword .Lxray_sled_2
; CHECK: .xword .Lxray_sled_3
+; CHECK-LABEL: Lxray_synthetic_end1:
+; CHECK: .section xray_fn_idx,{{.*}}
+; CHECK-LABEL: Lxray_fn_idx_synth_1:
+; CHECK: .xword .Lxray_synthetic_1
+; CHECK-NEXT: .xword .Lxray_synthetic_end1
diff --git a/llvm/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll b/llvm/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll index 93c3cb14fb7..5e3c45c3454 100644 --- a/llvm/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll +++ b/llvm/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll @@ -25,7 +25,13 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" } ; CHECK: .p2align 4 ; CHECK-NEXT: .long {{.*}}Lxray_synthetic_0 +; CHECK-NEXT: .long {{.*}}Lxray_fn_idx_synth_0 ; CHECK-NEXT: .section {{.*}}xray_instr_map{{.*}} ; CHECK-LABEL: Lxray_synthetic_0: ; CHECK: .long {{.*}}Lxray_sled_0 ; CHECK: .long {{.*}}Lxray_sled_1 +; CHECK-LABEL: Lxray_synthetic_end0: +; CHECK: .section {{.*}}xray_fn_idx{{.*}} +; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK: .long {{.*}}Lxray_synthetic_0 +; CHECK-NEXT: .long {{.*}}Lxray_synthetic_end0 diff --git a/llvm/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll b/llvm/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll index d14590b8867..739151fbdd5 100644 --- a/llvm/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll +++ b/llvm/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll @@ -25,7 +25,14 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" } ; CHECK: .p2align 4 ; CHECK-NEXT: .long {{.*}}Lxray_synthetic_0 +; CHECK-NEXT: .long {{.*}}Lxray_fn_idx_synth_0 ; CHECK-NEXT: .section {{.*}}xray_instr_map{{.*}} ; CHECK-LABEL: Lxray_synthetic_0: ; CHECK: .long {{.*}}Lxray_sled_0 ; CHECK: .long {{.*}}Lxray_sled_1 +; CHECK-LABEL: Lxray_synthetic_end0: +; CHECK: .section {{.*}}xray_fn_idx{{.*}} +; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK: .long {{.*}}xray_synthetic_0 +; CHECK-NEXT: .long {{.*}}xray_synthetic_end0 + diff --git a/llvm/test/CodeGen/X86/xray-attribute-instrumentation.ll b/llvm/test/CodeGen/X86/xray-attribute-instrumentation.ll index c52ccf9356b..7c60327d2c3 100644 --- a/llvm/test/CodeGen/X86/xray-attribute-instrumentation.ll +++ b/llvm/test/CodeGen/X86/xray-attribute-instrumentation.ll @@ -15,10 +15,17 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" } ; CHECK: .p2align 4, 0x90 ; CHECK-NEXT: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_0 ; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_0: ; CHECK: .quad {{.*}}xray_sled_0 ; CHECK: .quad {{.*}}xray_sled_1 +; CHECK-LABEL: Lxray_synthetic_end0: +; CHECK: .section {{.*}}xray_fn_idx +; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_end0 + ; We test multiple returns in a single function to make sure we're getting all ; of them with XRay instrumentation. @@ -46,8 +53,14 @@ NotEqual: } ; CHECK: .p2align 4, 0x90 ; CHECK-NEXT: .quad {{.*}}xray_synthetic_1 +; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_1 ; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_1: ; CHECK: .quad {{.*}}xray_sled_2 ; CHECK: .quad {{.*}}xray_sled_3 ; CHECK: .quad {{.*}}xray_sled_4 +; CHECK-LABEL: Lxray_synthetic_end1: +; CHECK: .section {{.*}}xray_fn_idx +; CHECK-LABEL: Lxray_fn_idx_synth_1: +; CHECK: .quad {{.*}}xray_synthetic_1 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_end1 diff --git a/llvm/test/CodeGen/X86/xray-tail-call-sled.ll b/llvm/test/CodeGen/X86/xray-tail-call-sled.ll index ece786a5e80..b12c78a77b2 100644 --- a/llvm/test/CodeGen/X86/xray-tail-call-sled.ll +++ b/llvm/test/CodeGen/X86/xray-tail-call-sled.ll @@ -14,11 +14,17 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-alway ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_0{{.*}} +; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_0{{.*}} ; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_0: ; CHECK: .quad {{.*}}xray_sled_0 ; CHECK: .quad {{.*}}xray_sled_1 +; CHECK-LABEL: Lxray_synthetic_end0: +; CHECK-NEXT: .section {{.*}}xray_fn_idx +; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_end0 define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 @@ -36,7 +42,13 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway ret i32 %retval } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_synthetic_1 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_1{{.*}} +; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_1{{.*}} ; CHECK-LABEL: Lxray_synthetic_1: ; CHECK: .quad {{.*}}xray_sled_2 ; CHECK: .quad {{.*}}xray_sled_3 +; CHECK-LABEL: Lxray_synthetic_end1: +; CHECK: .section {{.*}}xray_fn_idx +; CHECK-LABEL: Lxray_fn_idx_synth_1: +; CHECK: .quad {{.*}}xray_synthetic_1 +; CHECK: .quad {{.*}}xray_synthetic_end1 |