Inject a hook into the entry point on MachO

Summary:
This diff is a preparation for loading the runtime on MachO.
The proposed schema is the following:

1/  Function "bolt_instr_setup" is placed into the predefined section "setup" (in the final setting this function will be coming from the instrumentation runtime but we still will be placing it into this section).

2/ In the instrumentation pass we create a symbol "bolt_instr_setup" and inject the corresponding call into the beginning of the function representing the entry point of the binary.

(cherry picked from FBD24329530)
This commit is contained in:
Alexander Shaposhnikov 2020-10-15 01:39:35 -07:00 committed by Maksim Panchenko
parent f15532c2aa
commit 6133d2598b
1 changed files with 38 additions and 0 deletions

View File

@ -534,6 +534,25 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
createAuxiliaryFunctions(BC);
if (BC.isMachO() && BC.StartFunctionAddress) {
BinaryFunction *Main =
BC.getBinaryFunctionAtAddress(*BC.StartFunctionAddress);
assert(Main && "Entry point function not found");
BinaryBasicBlock &BB = Main->front();
ErrorOr<BinarySection &> SetupSection =
BC.getUniqueSectionByName("I__setup");
if (!SetupSection) {
llvm::errs() << "Cannot find I__setup section\n";
exit(1);
}
MCSymbol *Target = BC.registerNameAtAddress(
"__bolt_instr_setup", SetupSection->getAddress(), 0, 0);
MCInst NewInst;
BC.MIB->createCall(NewInst, Target, BC.Ctx.get());
BB.insertInstruction(BB.begin(), std::move(NewInst));
}
setupRuntimeLibrary(BC);
}
@ -561,6 +580,25 @@ void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
Summary->InitialIndTailCallHandlerFunction =
createSimpleFunction("__bolt_instr_default_ind_tailcall_handler",
BC.MIB->createInstrumentedNoopIndTailCallHandler());
// TODO: Remove this code once we start loading the runtime library for OSX.
if (BC.isMachO()) {
std::vector<MCInst> Instrs(8);
for (MCInst &Instruction : Instrs)
BC.MIB->createNoop(Instruction);
BC.MIB->createReturn(Instrs.back());
BinaryFunction *Placeholder = createSimpleFunction(
"__bolt_instr_setup_placeholder", std::move(Instrs));
ErrorOr<BinarySection &> SetupSection =
BC.getUniqueSectionByName("I__setup");
if (!SetupSection) {
llvm::errs() << "Cannot find I__setup section\n";
exit(1);
}
Placeholder->setOutputAddress(SetupSection->getAddress());
Placeholder->setFileOffset(SetupSection->getInputFileOffset());
Placeholder->setOriginSection(&*SetupSection);
}
}
void Instrumentation::setupRuntimeLibrary(BinaryContext &BC) {