llvm.org GIT mirror llvm / 0f4c901
[llvm-xray] Support for PIE When the instrumented binary is linked as PIE, we need to apply the relative relocations to sleds. This is handled by the dynamic linker at runtime, but when processing the file we have to do it ourselves. Differential Revision: https://reviews.llvm.org/D55542 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349120 91177308-0d34-0410-b5e6-96231b3b80d8 Petr Hosek 1 year, 5 months ago
3 changed file(s) with 52 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "llvm/XRay/InstrumentationMap.h"
14 #include "llvm/ADT/DenseMap.h"
1415 #include "llvm/ADT/None.h"
1516 #include "llvm/ADT/STLExtras.h"
1617 #include "llvm/ADT/StringRef.h"
1718 #include "llvm/ADT/Triple.h"
1819 #include "llvm/ADT/Twine.h"
1920 #include "llvm/Object/Binary.h"
21 #include "llvm/Object/ELFObjectFile.h"
2022 #include "llvm/Object/ObjectFile.h"
2123 #include "llvm/Support/DataExtractor.h"
2224 #include "llvm/Support/Error.h"
4547 return None;
4648 }
4749
50 using RelocMap = DenseMap;
51
4852 static Error
4953 loadObj(StringRef Filename, object::OwningBinary &ObjFile,
5054 InstrumentationMap::SledContainer &Sleds,
7882 return errorCodeToError(
7983 std::make_error_code(std::errc::executable_format_error));
8084
85 RelocMap Relocs;
86 if (ObjFile.getBinary()->isELF()) {
87 uint32_t RelrRelocationType = [](object::ObjectFile *ObjFile) {
88 if (const auto *ELFObj = dyn_cast(ObjFile))
89 return ELFObj->getELFFile()->getRelrRelocationType();
90 else if (const auto *ELFObj = dyn_cast(ObjFile))
91 return ELFObj->getELFFile()->getRelrRelocationType();
92 else if (const auto *ELFObj = dyn_cast(ObjFile))
93 return ELFObj->getELFFile()->getRelrRelocationType();
94 else if (const auto *ELFObj = dyn_cast(ObjFile))
95 return ELFObj->getELFFile()->getRelrRelocationType();
96 else
97 return static_cast(0);
98 }(ObjFile.getBinary());
99
100 for (const object::SectionRef &Section : Sections) {
101 for (const object::RelocationRef &Reloc : Section.relocations()) {
102 if (Reloc.getType() != RelrRelocationType)
103 continue;
104 if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend())
105 Relocs.insert({Reloc.getOffset(), *AddendOrErr});
106 }
107 }
108 }
109
81110 // Copy the instrumentation map data into the Sleds data structure.
82111 auto C = Contents.bytes_begin();
83112 static constexpr size_t ELF64SledEntrySize = 32;
87116 Twine("Instrumentation map entries not evenly divisible by size of "
88117 "an XRay sled entry in ELF64."),
89118 std::make_error_code(std::errc::executable_format_error));
119
120 auto RelocateOrElse = [&](uint32_t Offset, uint64_t Address) {
121 if (!Address) {
122 uint64_t A = I->getAddress() + C - Contents.bytes_begin() + Offset;
123 RelocMap::const_iterator R = Relocs.find(A);
124 if (R != Relocs.end())
125 return R->second;
126 }
127 return Address;
128 };
90129
91130 int32_t FuncId = 1;
92131 uint64_t CurFn = 0;
97136 Sleds.push_back({});
98137 auto &Entry = Sleds.back();
99138 uint32_t OffsetPtr = 0;
100 Entry.Address = Extractor.getU64(&OffsetPtr);
101 Entry.Function = Extractor.getU64(&OffsetPtr);
139 Entry.Address = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
140 Entry.Function = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
102141 auto Kind = Extractor.getU8(&OffsetPtr);
103142 static constexpr SledEntry::FunctionKinds Kinds[] = {
104143 SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT,
0 ; This test makes sure we can extract the instrumentation map from an
1 ; XRay-instrumented PIE file.
2 ;
3 ; RUN: llvm-xray extract %S/Inputs/elf64-pie.bin -s | FileCheck %s
4
5 ; CHECK: ---
6 ; CHECK-NEXT: - { id: 1, address: 0x00000000000299C0, function: 0x00000000000299C0, kind: function-enter, always-instrument: true, function-name: {{.*foo.*}} }
7 ; CHECK-NEXT: - { id: 1, address: 0x00000000000299D0, function: 0x00000000000299C0, kind: function-exit, always-instrument: true, function-name: {{.*foo.*}} }
8 ; CHECK-NEXT: - { id: 2, address: 0x00000000000299E0, function: 0x00000000000299E0, kind: function-enter, always-instrument: true, function-name: {{.*bar.*}} }
9 ; CHECK-NEXT: - { id: 2, address: 0x00000000000299F6, function: 0x00000000000299E0, kind: function-exit, always-instrument: true, function-name: {{.*bar.*}} }
10 ; CHECK-NEXT: ...