Inject instrumentation's global dtor on MachO
Summary: This diff is a preparation for dumping the profile generated by BOLT's instrumenation on MachO. 1/ Function "bolt_instr_fini" is placed into the predefined section "__fini" 2/ In the instrumentation pass we create a symbol "bolt_instr_fini" and replace the last global destructor with it. This is a temporary solution, in the future we need to register bolt_instr_fini in addition to the existing destructors without dropping the last one. (cherry picked from FBD25071864)
This commit is contained in:
parent
1b258b8908
commit
e067f2adf4
|
@ -1472,4 +1472,9 @@ extern "C" __attribute((section("__TEXT,__setup"))) void _bolt_instr_setup() {
|
|||
__write(2, Message, 7);
|
||||
}
|
||||
|
||||
extern "C" __attribute((section("__TEXT,__fini"))) void _bolt_instr_fini() {
|
||||
const char* Message = "Bye!\n";
|
||||
__write(2, Message, 5);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,8 @@ uint8_t *ExecutableFileMemoryManager::allocateSection(intptr_t Size,
|
|||
.toStringRef(Buf);
|
||||
} else if (BC.isMachO()) {
|
||||
assert((SectionName == "__text" || SectionName == "__data" ||
|
||||
SectionName == "__setup" || SectionName == "__cstring") &&
|
||||
SectionName == "__fini" || SectionName == "__setup" ||
|
||||
SectionName == "__cstring") &&
|
||||
"Unexpected section in the instrumentation library");
|
||||
SectionName = ("I" + Twine(SectionName)).toStringRef(Buf);
|
||||
}
|
||||
|
|
|
@ -429,6 +429,7 @@ void MachORewriteInstance::emitAndLink() {
|
|||
// TODO: Refactor addRuntimeLibSections to work properly on Mach-O
|
||||
// and use it here.
|
||||
mapInstrumentationSection(Key, "I__setup");
|
||||
mapInstrumentationSection(Key, "I__fini");
|
||||
mapInstrumentationSection(Key, "I__data");
|
||||
mapInstrumentationSection(Key, "I__text");
|
||||
mapInstrumentationSection(Key, "I__cstring");
|
||||
|
@ -495,6 +496,7 @@ void MachORewriteInstance::rewriteFile() {
|
|||
// TODO: Refactor addRuntimeLibSections to work properly on Mach-O and
|
||||
// use it here.
|
||||
writeInstrumentationSection("I__setup", OS);
|
||||
writeInstrumentationSection("I__fini", OS);
|
||||
writeInstrumentationSection("I__data", OS);
|
||||
writeInstrumentationSection("I__text", OS);
|
||||
writeInstrumentationSection("I__cstring", OS);
|
||||
|
|
|
@ -283,6 +283,9 @@ void Instrumentation::instrumentFunction(BinaryContext &BC,
|
|||
if (Function.hasUnknownControlFlow())
|
||||
return;
|
||||
|
||||
if (BC.isMachO() && Function.hasName("___GLOBAL_init_65535/1"))
|
||||
return;
|
||||
|
||||
SplitWorklistTy SplitWorklist;
|
||||
SplitInstrsTy SplitInstrs;
|
||||
|
||||
|
@ -533,7 +536,8 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
|
|||
|
||||
createAuxiliaryFunctions(BC);
|
||||
|
||||
if (BC.isMachO() && BC.StartFunctionAddress) {
|
||||
if (BC.isMachO()) {
|
||||
if (BC.StartFunctionAddress) {
|
||||
BinaryFunction *Main =
|
||||
BC.getBinaryFunctionAtAddress(*BC.StartFunctionAddress);
|
||||
assert(Main && "Entry point function not found");
|
||||
|
@ -550,6 +554,30 @@ void Instrumentation::runOnFunctions(BinaryContext &BC) {
|
|||
MCInst NewInst;
|
||||
BC.MIB->createCall(NewInst, Target, BC.Ctx.get());
|
||||
BB.insertInstruction(BB.begin(), std::move(NewInst));
|
||||
} else {
|
||||
llvm::errs() << "BOLT-WARNING: Entry point not found\n";
|
||||
}
|
||||
|
||||
if (BinaryData *BD = BC.getBinaryDataByName("___GLOBAL_init_65535/1")) {
|
||||
BinaryFunction *Ctor = BC.getBinaryFunctionAtAddress(BD->getAddress());
|
||||
assert(Ctor && "___GLOBAL_init_65535 function not found");
|
||||
BinaryBasicBlock &BB = Ctor->front();
|
||||
ErrorOr<BinarySection &> FiniSection =
|
||||
BC.getUniqueSectionByName("I__fini");
|
||||
if (!FiniSection) {
|
||||
llvm::errs() << "Cannot find I__fini section\n";
|
||||
exit(1);
|
||||
}
|
||||
MCSymbol *Target = BC.registerNameAtAddress(
|
||||
"__bolt_instr_fini", FiniSection->getAddress(), 0, 0);
|
||||
auto IsLEA = [&BC](const MCInst &Inst) { return BC.MIB->isLEA64r(Inst); };
|
||||
const auto LEA = std::find_if(std::next(std::find_if(
|
||||
BB.rbegin(), BB.rend(), IsLEA)), BB.rend(), IsLEA);
|
||||
LEA->getOperand(4).setExpr(
|
||||
MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *BC.Ctx));
|
||||
} else {
|
||||
llvm::errs() << "BOLT-WARNING: ___GLOBAL_init_65535 not found\n";
|
||||
}
|
||||
}
|
||||
|
||||
setupRuntimeLibrary(BC);
|
||||
|
@ -579,7 +607,6 @@ void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
|
|||
Summary->InitialIndTailCallHandlerFunction =
|
||||
createSimpleFunction("__bolt_instr_default_ind_tailcall_handler",
|
||||
BC.MIB->createInstrumentedNoopIndTailCallHandler());
|
||||
|
||||
}
|
||||
|
||||
void Instrumentation::setupRuntimeLibrary(BinaryContext &BC) {
|
||||
|
|
Loading…
Reference in a new issue