Skip to content

Commit

Permalink
[PR] Instrumentation: Initial support for static executables
Browse files Browse the repository at this point in the history
Summary:
This commit introduces static binaries instrumentation
support.  Note that current implementation does not support profile
output on the instrumented binary finalization. So it requires to use
-instrumentation-sleep-time=N (N>0) option usage.  Note: There is
unhandled case with static PIE executable which might have dynamic
header.

Vasily Leonenko,
Advanced Software Technology Lab, Huawei

(cherry picked from FBD30092471)
  • Loading branch information
Vasily Leonenko authored and maksfb committed Jun 20, 2021
1 parent 2ffd6e2 commit 9b39a82
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 1 deletion.
5 changes: 5 additions & 0 deletions bolt/src/MCPlusBuilder.h
Expand Up @@ -1771,6 +1771,11 @@ class MCPlusBuilder {
return std::vector<MCInst>();
}

virtual std::vector<MCInst> createDummyReturnFunction(MCContext *Ctx) const {
llvm_unreachable("not implemented");
return std::vector<MCInst>();
}

/// This method takes an indirect call instruction and splits it up into an
/// equivalent set of instructions that use direct calls for target
/// symbols/addresses that are contained in the Targets vector. This is done
Expand Down
6 changes: 6 additions & 0 deletions bolt/src/Passes/Instrumentation.cpp
Expand Up @@ -651,6 +651,12 @@ void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
createSimpleFunction(
"__bolt_fini_trampoline",
BC.MIB->createSymbolTrampoline(FiniSym, BC.Ctx.get()));
} else {
// Create dummy return function for trampoline to avoid issues
// with unknown symbol in runtime library. E.g. for static PIE
// executable
createSimpleFunction("__bolt_fini_trampoline",
BC.MIB->createDummyReturnFunction(BC.Ctx.get()));
}
}
}
Expand Down
1 change: 1 addition & 0 deletions bolt/src/RewriteInstance.cpp
Expand Up @@ -5075,6 +5075,7 @@ void RewriteInstance::readELFDynamic(ELFObjectFile<ELFT> *File) {

if (!DynamicPhdr) {
outs() << "BOLT-INFO: static input executable detected\n";
// TODO: static PIE executable might have dynamic header
BC->IsStaticExecutable = true;
return;
}
Expand Down
9 changes: 8 additions & 1 deletion bolt/src/RuntimeLibs/InstrumentationRuntimeLibrary.cpp
Expand Up @@ -59,7 +59,7 @@ void InstrumentationRuntimeLibrary::adjustCommandLineOptions(
"the input binary\n";
exit(1);
}
if (!BC.FiniFunctionAddress) {
if (!BC.FiniFunctionAddress && !BC.IsStaticExecutable) {
errs() << "BOLT-ERROR: input binary lacks DT_FINI entry in the dynamic "
"section but instrumentation currently relies on patching "
"DT_FINI to write the profile\n";
Expand All @@ -86,6 +86,13 @@ void InstrumentationRuntimeLibrary::emitBinary(BinaryContext &BC,
"__BOLT", "__counters", MachO::S_REGULAR,
SectionKind::getData()));

if (BC.IsStaticExecutable && !opts::InstrumentationSleepTime) {
errs() << "BOLT-ERROR: instrumentation of static binary currently does not "
"support profile output on binary finalization, so it "
"requires -instrumentation-sleep-time=N (N>0) usage\n";
exit(1);
}

Section->setAlignment(llvm::Align(BC.RegularPageSize));
Streamer.SwitchSection(Section);

Expand Down
6 changes: 6 additions & 0 deletions bolt/src/Target/X86/X86MCPlusBuilder.cpp
Expand Up @@ -3316,6 +3316,12 @@ class X86MCPlusBuilder : public MCPlusBuilder {
return Insts;
}

std::vector<MCInst> createDummyReturnFunction(MCContext *Ctx) const override {
std::vector<MCInst> Insts(1);
createReturn(Insts[0]);
return Insts;
}

BlocksVectorTy indirectCallPromotion(
const MCInst &CallInst,
const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
Expand Down

0 comments on commit 9b39a82

Please sign in to comment.