Index: llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -39,6 +39,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" @@ -155,10 +156,12 @@ // code duplication as it is now for x86_64, ARM32 and AArch64. if (Sleds.empty()) return; + + auto PrevSection = OutStreamer->getCurrentSectionOnly(); + auto Fn = MF->getFunction(); + MCSection *Section; + if (STI->isTargetELF()) { - auto PrevSection = OutStreamer->getCurrentSectionOnly(); - auto Fn = MF->getFunction(); - MCSection *Section; if (Fn->hasComdat()) Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, @@ -166,31 +169,37 @@ else Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); + } else if (STI->isTargetMachO()) { + Section = OutContext.getMachOSection("__DATA", "xray_instr_map", 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 EmitXRayTable() is always called just - // before the function's end, we assume that this is happening after the - // last return instruction. - // - // We then align the reference to 16 byte boundaries, which we determined - // experimentally to be beneficial to avoid causing decoder stalls. - MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true); - OutStreamer->EmitCodeAlignment(16); - OutStreamer->EmitSymbolValue(Tmp, 8, false); - OutStreamer->SwitchSection(Section); - OutStreamer->EmitLabel(Tmp); - for (const auto &Sled : Sleds) { - OutStreamer->EmitSymbolValue(Sled.Sled, 8); - OutStreamer->EmitSymbolValue(CurrentFnSym, 8); - auto Kind = static_cast(Sled.Kind); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Kind), 1)); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); - OutStreamer->EmitZeros(14); - } - OutStreamer->SwitchSection(PrevSection); + // Before we switch over, we force a reference to a label inside the + // xray_instr_map section. Since EmitXRayTable() is always called just + // before the function's end, we assume that this is happening after the + // last return instruction. + // + // We then align the reference to 16 byte boundaries, which we determined + // experimentally to be beneficial to avoid causing decoder stalls. + MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true); + OutStreamer->EmitCodeAlignment(16); + OutStreamer->EmitSymbolValue(Tmp, 8, false); + OutStreamer->SwitchSection(Section); + OutStreamer->EmitLabel(Tmp); + for (const auto &Sled : Sleds) { + OutStreamer->EmitSymbolValue(Sled.Sled, 8); + OutStreamer->EmitSymbolValue(CurrentFnSym, 8); + auto Kind = static_cast(Sled.Kind); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Kind), 1)); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); + OutStreamer->EmitZeros(14); } + OutStreamer->SwitchSection(PrevSection); + Sleds.clear(); } Index: llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp +++ llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCStreamer.h" using namespace llvm; @@ -228,24 +229,33 @@ { if (Sleds.empty()) return; + + MCSection *Section = nullptr; if (Subtarget->isTargetELF()) { - auto *Section = OutContext.getELFSection( - "xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_GROUP | ELF::SHF_MERGE, 0, - CurrentFnSym->getName()); - auto PrevSection = OutStreamer->getCurrentSectionOnly(); - OutStreamer->SwitchSection(Section); - for (const auto &Sled : Sleds) { - OutStreamer->EmitSymbolValue(Sled.Sled, 4); - OutStreamer->EmitSymbolValue(CurrentFnSym, 4); - auto Kind = static_cast(Sled.Kind); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Kind), 1)); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); - OutStreamer->EmitZeros(6); - } - OutStreamer->SwitchSection(PrevSection); + Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_GROUP | + ELF::SHF_MERGE, + 0, CurrentFnSym->getName()); + } else if (Subtarget->isTargetMachO()) { + Section = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, + SectionKind::getReadOnlyWithRel()); + } else { + llvm_unreachable("Unsupported target"); } + + auto PrevSection = OutStreamer->getCurrentSectionOnly(); + OutStreamer->SwitchSection(Section); + for (const auto &Sled : Sleds) { + OutStreamer->EmitSymbolValue(Sled.Sled, 4); + OutStreamer->EmitSymbolValue(CurrentFnSym, 4); + auto Kind = static_cast(Sled.Kind); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Kind), 1)); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); + OutStreamer->EmitZeros(6); + } + OutStreamer->SwitchSection(PrevSection); + Sleds.clear(); } Index: llvm/trunk/lib/Target/X86/X86MCInstLower.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86MCInstLower.cpp +++ llvm/trunk/lib/Target/X86/X86MCInstLower.cpp @@ -41,6 +41,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/ELF.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -1116,10 +1117,11 @@ void X86AsmPrinter::EmitXRayTable() { if (Sleds.empty()) return; + + auto PrevSection = OutStreamer->getCurrentSectionOnly(); + auto Fn = MF->getFunction(); + MCSection *Section = nullptr; if (Subtarget->isTargetELF()) { - auto PrevSection = OutStreamer->getCurrentSectionOnly(); - auto Fn = MF->getFunction(); - MCSection *Section = nullptr; if (Fn->hasComdat()) { Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, @@ -1128,31 +1130,37 @@ Section = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); } + } else if (Subtarget->isTargetMachO()) { + Section = OutContext.getMachOSection("__DATA", "xray_instr_map", 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 EmitXRayTable() is always called just - // before the function's end, we assume that this is happening after the - // last return instruction. - // - // We then align the reference to 16 byte boundaries, which we determined - // experimentally to be beneficial to avoid causing decoder stalls. - MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true); - OutStreamer->EmitCodeAlignment(16); - OutStreamer->EmitSymbolValue(Tmp, 8, false); - OutStreamer->SwitchSection(Section); - OutStreamer->EmitLabel(Tmp); - for (const auto &Sled : Sleds) { - OutStreamer->EmitSymbolValue(Sled.Sled, 8); - OutStreamer->EmitSymbolValue(CurrentFnSym, 8); - auto Kind = static_cast(Sled.Kind); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Kind), 1)); - OutStreamer->EmitBytes( - StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); - OutStreamer->EmitZeros(14); - } - OutStreamer->SwitchSection(PrevSection); + // Before we switch over, we force a reference to a label inside the + // xray_instr_map section. Since EmitXRayTable() is always called just + // before the function's end, we assume that this is happening after the + // last return instruction. + // + // We then align the reference to 16 byte boundaries, which we determined + // experimentally to be beneficial to avoid causing decoder stalls. + MCSymbol *Tmp = OutContext.createTempSymbol("xray_synthetic_", true); + OutStreamer->EmitCodeAlignment(16); + OutStreamer->EmitSymbolValue(Tmp, 8, false); + OutStreamer->SwitchSection(Section); + OutStreamer->EmitLabel(Tmp); + for (const auto &Sled : Sleds) { + OutStreamer->EmitSymbolValue(Sled.Sled, 8); + OutStreamer->EmitSymbolValue(CurrentFnSym, 8); + auto Kind = static_cast(Sled.Kind); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Kind), 1)); + OutStreamer->EmitBytes( + StringRef(reinterpret_cast(&Sled.AlwaysInstrument), 1)); + OutStreamer->EmitZeros(14); } + OutStreamer->SwitchSection(PrevSection); + Sleds.clear(); } Index: llvm/trunk/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll +++ llvm/trunk/test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -o - -mtriple=armv6-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=armv6-apple-ios6.0.0 < %s | FileCheck %s define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK-LABEL: Lxray_sled_0: Index: llvm/trunk/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll +++ llvm/trunk/test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -o - -mtriple=armv7-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=armv7-apple-ios6.0.0 < %s | FileCheck %s define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK-LABEL: Lxray_sled_0: Index: llvm/trunk/test/CodeGen/ARM/xray-tail-call-sled.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/xray-tail-call-sled.ll +++ llvm/trunk/test/CodeGen/ARM/xray-tail-call-sled.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -o - -mtriple=armv7-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=armv7-apple-ios6.0.0 < %s | FileCheck %s define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 2 @@ -48,6 +49,6 @@ ; CHECK-NEXT: nop ; CHECK-LABEL: Ltmp3: %retval = tail call i32 @callee() -; CHECK: b callee +; CHECK: b {{.*}}callee ret i32 %retval } Index: llvm/trunk/test/CodeGen/X86/xray-attribute-instrumentation.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/xray-attribute-instrumentation.ll +++ llvm/trunk/test/CodeGen/X86/xray-attribute-instrumentation.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=x86_64-darwin-unknown < %s | FileCheck %s define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 @@ -13,11 +14,11 @@ ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad .Lxray_synthetic_0 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-NEXT: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_0: -; CHECK: .quad .Lxray_sled_0 -; CHECK: .quad .Lxray_sled_1 +; CHECK: .quad {{.*}}xray_sled_0 +; CHECK: .quad {{.*}}xray_sled_1 ; We test multiple returns in a single function to make sure we're getting all ; of them with XRay instrumentation. @@ -44,9 +45,9 @@ ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad .Lxray_synthetic_1 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-NEXT: .quad {{.*}}xray_synthetic_1 +; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_1: -; CHECK: .quad .Lxray_sled_2 -; CHECK: .quad .Lxray_sled_3 -; CHECK: .quad .Lxray_sled_4 +; CHECK: .quad {{.*}}xray_sled_2 +; CHECK: .quad {{.*}}xray_sled_3 +; CHECK: .quad {{.*}}xray_sled_4 Index: llvm/trunk/test/CodeGen/X86/xray-tail-call-sled.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/xray-tail-call-sled.ll +++ llvm/trunk/test/CodeGen/X86/xray-tail-call-sled.ll @@ -1,4 +1,5 @@ ; RUN: llc -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=x86_64-darwin-unknown < %s | FileCheck %s define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 @@ -13,11 +14,11 @@ ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad .Lxray_synthetic_0 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-NEXT: .quad {{.*}}xray_synthetic_0 +; CHECK-NEXT: .section {{.*}}xray_instr_map ; CHECK-LABEL: Lxray_synthetic_0: -; CHECK: .quad .Lxray_sled_0 -; CHECK: .quad .Lxray_sled_1 +; CHECK: .quad {{.*}}xray_sled_0 +; CHECK: .quad {{.*}}xray_sled_1 define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 @@ -31,11 +32,11 @@ ; CHECK-NEXT: nopw 512(%rax,%rax) ; CHECK-LABEL: Ltmp2: %retval = tail call i32 @callee() -; CHECK: jmp callee # TAILCALL +; CHECK: jmp {{.*}}callee {{.*}}# TAILCALL ret i32 %retval } ; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad .Lxray_synthetic_1 +; CHECK-NEXT: .quad {{.*}}xray_synthetic_1 ; CHECK-LABEL: Lxray_synthetic_1: -; CHECK: .quad .Lxray_sled_2 -; CHECK: .quad .Lxray_sled_3 +; CHECK: .quad {{.*}}xray_sled_2 +; CHECK: .quad {{.*}}xray_sled_3