diff options
author | Dean Michael Berris <dberris@google.com> | 2017-08-23 04:49:41 +0000 |
---|---|---|
committer | Dean Michael Berris <dberris@google.com> | 2017-08-23 04:49:41 +0000 |
commit | 0884b732202d043af4755d05aeb7fd3da8951a24 (patch) | |
tree | d0c2971364fbc3858cb0f2a72cb3f2f58901e42a /llvm/lib/CodeGen/AsmPrinter | |
parent | 71f88a955d30645d082ddd42d2215226f3ea8744 (diff) | |
download | bcm5719-llvm-0884b732202d043af4755d05aeb7fd3da8951a24.tar.gz bcm5719-llvm-0884b732202d043af4755d05aeb7fd3da8951a24.zip |
[XRay][CodeGen] Use PIC-friendly code in XRay sleds; remove synthetic references in .text
Summary:
This change achieves two things:
- Redefine the Custom Event handling instrumentation points emitted by
the compiler to not require dynamic relocation of references to the
__xray_CustomEvent trampoline.
- Remove the synthetic reference we emit at the end of a function that
we used to keep auxiliary sections alive in favour of SHF_LINK_ORDER
associated with the section where the function is defined.
To achieve the custom event handling change, we've had to introduce the
concept of sled versioning -- this will need to be supported by the
runtime to allow us to understand how to turn on/off the new version of
the custom event handling sleds. That change has to land first before we
change the way we write the sleds.
To remove the synthetic reference, we rely on a relatively new linker
feature that preserves the sections that are associated with each other.
This allows us to limit the effects on the .text section of ELF
binaries.
Because we're still using absolute references that are resolved at
runtime for the instrumentation map (and function index) maps, we mark
these sections write-able. In the future we can re-define the entries in
the map to use relative relocations instead that can be statically
determined by the linker. That change will be a bit more invasive so we
defer this for later.
Depends on D36816.
Reviewers: dblaikie, echristo, pcc
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36615
llvm-svn: 311525
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 5e002e70929..87399354945 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2767,10 +2767,13 @@ void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out, Out->EmitSymbolValue(Sled, Bytes); Out->EmitSymbolValue(CurrentFnSym, Bytes); auto Kind8 = static_cast<uint8_t>(Kind); - Out->EmitBytes(StringRef(reinterpret_cast<const char *>(&Kind8), 1)); - Out->EmitBytes( + Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1)); + Out->EmitBinaryData( StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1)); - Out->EmitZeros(2 * Bytes - 2); // Pad the previous two entries + Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1)); + auto Padding = (4 * Bytes) - ((2 * Bytes) + 3); + assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size"); + Out->EmitZeros(Padding); } void AsmPrinter::emitXRayTable() { @@ -2782,19 +2785,22 @@ void AsmPrinter::emitXRayTable() { MCSection *InstMap = nullptr; MCSection *FnSledIndex = nullptr; if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) { + auto Associated = dyn_cast<MCSymbolELF>(PrevSection->getBeginSymbol()); + assert(Associated != nullptr); + auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER; + std::string GroupName; if (Fn->hasComdat()) { - 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 { - InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); - FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); + Flags |= ELF::SHF_GROUP; + GroupName = Fn->getComdat()->getName(); } + + auto UniqueID = ++XRayFnUniqueID; + InstMap = + OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); + FnSledIndex = + OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, SectionKind::getReadOnlyWithRel()); @@ -2804,15 +2810,7 @@ void AsmPrinter::emitXRayTable() { llvm_unreachable("Unsupported target"); } - // Before we switch over, we force a reference to a label inside the - // xray_fn_idx sections. This makes sure that the xray_fn_idx section is kept - // live by the linker if the function is not garbage-collected. Since this - // function is always called just before the function's end, we assume that - // this is happening after the last return instruction. auto WordSizeBytes = MAI->getCodePointerSize(); - MCSymbol *IdxRef = OutContext.createTempSymbol("xray_fn_idx_synth_", true); - OutStreamer->EmitCodeAlignment(16); - 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 @@ -2831,15 +2829,14 @@ void AsmPrinter::emitXRayTable() { // pointers. This should work for both 32-bit and 64-bit platforms. OutStreamer->SwitchSection(FnSledIndex); OutStreamer->EmitCodeAlignment(2 * WordSizeBytes); - OutStreamer->EmitLabel(IdxRef); - OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes); - OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes); + OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false); + OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes, false); OutStreamer->SwitchSection(PrevSection); Sleds.clear(); } void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, - SledKind Kind) { + SledKind Kind, uint8_t Version) { auto Fn = MI.getParent()->getParent()->getFunction(); auto Attr = Fn->getFnAttribute("function-instrument"); bool LogArgs = Fn->hasFnAttribute("xray-log-args"); @@ -2847,8 +2844,8 @@ void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always"; if (Kind == SledKind::FUNCTION_ENTER && LogArgs) Kind = SledKind::LOG_ARGS_ENTER; - Sleds.emplace_back( - XRayFunctionEntry{ Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn }); + Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind, + AlwaysInstrument, Fn, Version}); } uint16_t AsmPrinter::getDwarfVersion() const { |