Skip to content

Commit a86dd9a

Browse files
committed
[BOLT][Instrumentation] Fix indirect call profile in PIE
Because indirect call tables use static addresses for call sites, but pc values recorded by runtime may be subject to ASLR in PIE, we couldn't find indirect call descriptions by their runtime address in PIE. It resulted in [unknown] entries in profile for all indirect calls. We need to substract base address of .text from runtime addresses to get the corresponding static addresses. Here we create a getter for base address of .text and substract it's return value from recorded PC values. It converts them to static addresses, which then may be used to find the corresponding indirect call descriptions. Reviewed By: rafauler Differential Revision: https://reviews.llvm.org/D154121
1 parent a799298 commit a86dd9a

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,8 +1845,9 @@ void RewriteInstance::adjustCommandLineOptions() {
18451845
exit(1);
18461846
}
18471847

1848-
if (opts::ReorderFunctions != ReorderFunctions::RT_NONE &&
1849-
!opts::HotText.getNumOccurrences()) {
1848+
if (opts::Instrument ||
1849+
(opts::ReorderFunctions != ReorderFunctions::RT_NONE &&
1850+
!opts::HotText.getNumOccurrences())) {
18501851
opts::HotText = true;
18511852
} else if (opts::HotText && !BC->HasRelocations) {
18521853
errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n";

bolt/runtime/common.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ int memcmp(const void *s1, const void *s2, size_t n) {
165165
// Anonymous namespace covering everything but our library entry point
166166
namespace {
167167

168+
// Get the difference between runtime addrress of .text section and
169+
// static address in section header table. Can be extracted from arbitrary
170+
// pc value recorded at runtime to get the corresponding static address, which
171+
// in turn can be used to search for indirect call description. Needed because
172+
// indirect call descriptions are read-only non-relocatable data.
173+
uint64_t getTextBaseAddress() {
174+
uint64_t DynAddr;
175+
uint64_t StaticAddr;
176+
__asm__ volatile("leaq __hot_end(%%rip), %0\n\t"
177+
"movabsq $__hot_end, %1\n\t"
178+
: "=r"(DynAddr), "=r"(StaticAddr));
179+
return DynAddr - StaticAddr;
180+
}
181+
168182
constexpr uint32_t BufSize = 10240;
169183

170184
#define _STRINGIFY(x) #x

bolt/runtime/instr.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ class BumpPtrAllocator {
215215
/// __bolt_instr_setup, our initialization routine.
216216
BumpPtrAllocator *GlobalAlloc;
217217

218+
// Base address which we substract from recorded PC values when searching for
219+
// indirect call description entries. Needed because indCall descriptions are
220+
// mapped read-only and contain static addresses. Initialized in
221+
// __bolt_instr_setup.
222+
uint64_t TextBaseAddress = 0;
223+
218224
// Storage for GlobalAlloc which can be shared if not using
219225
// instrumentation-file-append-pid.
220226
void *GlobalMetadataStorage;
@@ -1389,7 +1395,7 @@ void visitIndCallCounter(IndirectCallHashTable::MapEntry &Entry,
13891395
const IndCallDescription *CallsiteDesc =
13901396
&Ctx->IndCallDescriptions[CallsiteID];
13911397
const IndCallTargetDescription *TargetDesc =
1392-
Ctx->lookupIndCallTarget(Entry.Key);
1398+
Ctx->lookupIndCallTarget(Entry.Key - TextBaseAddress);
13931399
if (!TargetDesc) {
13941400
DEBUG(report("Failed to lookup indirect call target\n"));
13951401
char LineBuf[BufSize];
@@ -1609,6 +1615,7 @@ extern "C" void __bolt_instr_indirect_tailcall();
16091615
extern "C" void __attribute((force_align_arg_pointer)) __bolt_instr_setup() {
16101616
__bolt_ind_call_counter_func_pointer = __bolt_instr_indirect_call;
16111617
__bolt_ind_tailcall_counter_func_pointer = __bolt_instr_indirect_tailcall;
1618+
TextBaseAddress = getTextBaseAddress();
16121619

16131620
const uint64_t CountersStart =
16141621
reinterpret_cast<uint64_t>(&__bolt_instr_locations[0]);

0 commit comments

Comments
 (0)