diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1845,8 +1845,9 @@ exit(1); } - if (opts::ReorderFunctions != ReorderFunctions::RT_NONE && - !opts::HotText.getNumOccurrences()) { + if (opts::Instrument || + (opts::ReorderFunctions != ReorderFunctions::RT_NONE && + !opts::HotText.getNumOccurrences())) { opts::HotText = true; } else if (opts::HotText && !BC->HasRelocations) { errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n"; diff --git a/bolt/runtime/common.h b/bolt/runtime/common.h --- a/bolt/runtime/common.h +++ b/bolt/runtime/common.h @@ -165,6 +165,20 @@ // Anonymous namespace covering everything but our library entry point namespace { +// Get the difference between runtime addrress of .text section and +// static address in section header table. Can be extracted from arbitrary +// pc value recorded at runtime to get the corresponding static address, which +// in turn can be used to search for indirect call description. Needed because +// indirect call descriptions are read-only non-relocatable data. +uint64_t getTextBaseAddress() { + uint64_t DynAddr; + uint64_t StaticAddr; + __asm__ volatile("leaq __hot_end(%%rip), %0\n\t" + "movabsq $__hot_end, %1\n\t" + : "=r"(DynAddr), "=r"(StaticAddr)); + return DynAddr - StaticAddr; +} + constexpr uint32_t BufSize = 10240; #define _STRINGIFY(x) #x diff --git a/bolt/runtime/instr.cpp b/bolt/runtime/instr.cpp --- a/bolt/runtime/instr.cpp +++ b/bolt/runtime/instr.cpp @@ -215,6 +215,12 @@ /// __bolt_instr_setup, our initialization routine. BumpPtrAllocator *GlobalAlloc; +// Base address which we substract from recorded PC values when searching for +// indirect call description entries. Needed because indCall descriptions are +// mapped read-only and contain static addresses. Initialized in +// __bolt_instr_setup. +uint64_t TextBaseAddress = 0; + // Storage for GlobalAlloc which can be shared if not using // instrumentation-file-append-pid. void *GlobalMetadataStorage; @@ -1389,7 +1395,7 @@ const IndCallDescription *CallsiteDesc = &Ctx->IndCallDescriptions[CallsiteID]; const IndCallTargetDescription *TargetDesc = - Ctx->lookupIndCallTarget(Entry.Key); + Ctx->lookupIndCallTarget(Entry.Key - TextBaseAddress); if (!TargetDesc) { DEBUG(report("Failed to lookup indirect call target\n")); char LineBuf[BufSize]; @@ -1609,6 +1615,7 @@ extern "C" void __attribute((force_align_arg_pointer)) __bolt_instr_setup() { __bolt_ind_call_counter_func_pointer = __bolt_instr_indirect_call; __bolt_ind_tailcall_counter_func_pointer = __bolt_instr_indirect_tailcall; + TextBaseAddress = getTextBaseAddress(); const uint64_t CountersStart = reinterpret_cast(&__bolt_instr_locations[0]);