Skip to content

Commit 493a082

Browse files
committed
[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 llvm-svn: 349120
1 parent afa75d7 commit 493a082

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

llvm/lib/XRay/InstrumentationMap.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "llvm/XRay/InstrumentationMap.h"
15+
#include "llvm/ADT/DenseMap.h"
1516
#include "llvm/ADT/None.h"
1617
#include "llvm/ADT/STLExtras.h"
1718
#include "llvm/ADT/StringRef.h"
1819
#include "llvm/ADT/Triple.h"
1920
#include "llvm/ADT/Twine.h"
2021
#include "llvm/Object/Binary.h"
22+
#include "llvm/Object/ELFObjectFile.h"
2123
#include "llvm/Object/ObjectFile.h"
2224
#include "llvm/Support/DataExtractor.h"
2325
#include "llvm/Support/Error.h"
@@ -46,6 +48,8 @@ Optional<uint64_t> InstrumentationMap::getFunctionAddr(int32_t FuncId) const {
4648
return None;
4749
}
4850

51+
using RelocMap = DenseMap<uint64_t, uint64_t>;
52+
4953
static Error
5054
loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
5155
InstrumentationMap::SledContainer &Sleds,
@@ -79,6 +83,31 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
7983
return errorCodeToError(
8084
std::make_error_code(std::errc::executable_format_error));
8185

86+
RelocMap Relocs;
87+
if (ObjFile.getBinary()->isELF()) {
88+
uint32_t RelrRelocationType = [](object::ObjectFile *ObjFile) {
89+
if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(ObjFile))
90+
return ELFObj->getELFFile()->getRelrRelocationType();
91+
else if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(ObjFile))
92+
return ELFObj->getELFFile()->getRelrRelocationType();
93+
else if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(ObjFile))
94+
return ELFObj->getELFFile()->getRelrRelocationType();
95+
else if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(ObjFile))
96+
return ELFObj->getELFFile()->getRelrRelocationType();
97+
else
98+
return static_cast<uint32_t>(0);
99+
}(ObjFile.getBinary());
100+
101+
for (const object::SectionRef &Section : Sections) {
102+
for (const object::RelocationRef &Reloc : Section.relocations()) {
103+
if (Reloc.getType() != RelrRelocationType)
104+
continue;
105+
if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend())
106+
Relocs.insert({Reloc.getOffset(), *AddendOrErr});
107+
}
108+
}
109+
}
110+
82111
// Copy the instrumentation map data into the Sleds data structure.
83112
auto C = Contents.bytes_begin();
84113
static constexpr size_t ELF64SledEntrySize = 32;
@@ -89,6 +118,16 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
89118
"an XRay sled entry in ELF64."),
90119
std::make_error_code(std::errc::executable_format_error));
91120

121+
auto RelocateOrElse = [&](uint32_t Offset, uint64_t Address) {
122+
if (!Address) {
123+
uint64_t A = I->getAddress() + C - Contents.bytes_begin() + Offset;
124+
RelocMap::const_iterator R = Relocs.find(A);
125+
if (R != Relocs.end())
126+
return R->second;
127+
}
128+
return Address;
129+
};
130+
92131
int32_t FuncId = 1;
93132
uint64_t CurFn = 0;
94133
for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) {
@@ -98,8 +137,8 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
98137
Sleds.push_back({});
99138
auto &Entry = Sleds.back();
100139
uint32_t OffsetPtr = 0;
101-
Entry.Address = Extractor.getU64(&OffsetPtr);
102-
Entry.Function = Extractor.getU64(&OffsetPtr);
140+
Entry.Address = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
141+
Entry.Function = RelocateOrElse(OffsetPtr, Extractor.getU64(&OffsetPtr));
103142
auto Kind = Extractor.getU8(&OffsetPtr);
104143
static constexpr SledEntry::FunctionKinds Kinds[] = {
105144
SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT,
Binary file not shown.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; This test makes sure we can extract the instrumentation map from an
2+
; XRay-instrumented PIE file.
3+
;
4+
; RUN: llvm-xray extract %S/Inputs/elf64-pie.bin -s | FileCheck %s
5+
6+
; CHECK: ---
7+
; CHECK-NEXT: - { id: 1, address: 0x00000000000299C0, function: 0x00000000000299C0, kind: function-enter, always-instrument: true, function-name: {{.*foo.*}} }
8+
; CHECK-NEXT: - { id: 1, address: 0x00000000000299D0, function: 0x00000000000299C0, kind: function-exit, always-instrument: true, function-name: {{.*foo.*}} }
9+
; CHECK-NEXT: - { id: 2, address: 0x00000000000299E0, function: 0x00000000000299E0, kind: function-enter, always-instrument: true, function-name: {{.*bar.*}} }
10+
; CHECK-NEXT: - { id: 2, address: 0x00000000000299F6, function: 0x00000000000299E0, kind: function-exit, always-instrument: true, function-name: {{.*bar.*}} }
11+
; CHECK-NEXT: ...

0 commit comments

Comments
 (0)