mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 19:49:36 +00:00
[BOLT] Add support for dumping counters on MacOS
Summary: Add support for dumping counters on MacOS (cherry picked from FBD25750516)
This commit is contained in:
parent
6a84124e1d
commit
3b876cc3e7
@ -180,6 +180,17 @@ uint32_t strLen(const char *Str) {
|
||||
return Size;
|
||||
}
|
||||
|
||||
void reportNumber(const char *Msg, uint64_t Num, uint32_t Base) {
|
||||
char Buf[BufSize];
|
||||
char *Ptr = Buf;
|
||||
Ptr = strCopy(Ptr, Msg, BufSize - 23);
|
||||
Ptr = intToStr(Ptr, Num, Base);
|
||||
Ptr = strCopy(Ptr, "\n");
|
||||
__write(2, Buf, Ptr - Buf);
|
||||
}
|
||||
|
||||
void report(const char *Msg) { __write(2, Msg, strLen(Msg)); }
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
// We use a stack-allocated buffer for string manipulation in many pieces of
|
||||
// this code, including the code that prints each line of the fdata file. This
|
||||
@ -332,17 +343,6 @@ void assert(bool Assertion, const char *Msg) {
|
||||
reportError(Buf, Ptr - Buf);
|
||||
}
|
||||
|
||||
void reportNumber(const char *Msg, uint64_t Num, uint32_t Base) {
|
||||
char Buf[BufSize];
|
||||
char *Ptr = Buf;
|
||||
Ptr = strCopy(Ptr, Msg, BufSize - 23);
|
||||
Ptr = intToStr(Ptr, Num, Base);
|
||||
Ptr = strCopy(Ptr, "\n");
|
||||
__write(2, Buf, Ptr - Buf);
|
||||
}
|
||||
|
||||
void report(const char *Msg) { __write(2, Msg, strLen(Msg)); }
|
||||
|
||||
/// 1B mutex accessed by lock xchg
|
||||
class Mutex {
|
||||
volatile bool InUse{false};
|
||||
|
@ -57,7 +57,16 @@
|
||||
{}
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
|
||||
#if defined(__APPLE__)
|
||||
extern "C" {
|
||||
|
||||
extern uint64_t* _bolt_instr_locations_getter();
|
||||
extern uint32_t _bolt_num_counters_getter();
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Main counters inserted by instrumentation, incremented during runtime when
|
||||
// points of interest (locations) in the program are reached. Those are direct
|
||||
@ -1463,17 +1472,45 @@ extern "C" void __bolt_instr_fini() {
|
||||
DEBUG(report("Finished.\n"));
|
||||
}
|
||||
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
// On OSX/iOS the final symbol name of an extern "C" function/variable contains
|
||||
// one extra leading underscore: _bolt_instr_setup -> __bolt_instr_setup.
|
||||
extern "C" __attribute((section("__TEXT,__setup"))) void _bolt_instr_setup() {
|
||||
const char* Message = "Hello!\n";
|
||||
extern "C"
|
||||
__attribute__((section("__TEXT,__setup")))
|
||||
__attribute__((force_align_arg_pointer))
|
||||
void _bolt_instr_setup() {
|
||||
const char *Message = "Hello!\n";
|
||||
__write(2, Message, 7);
|
||||
|
||||
uint32_t NumCounters = _bolt_num_counters_getter();
|
||||
reportNumber("__bolt_instr_setup, number of counters: ", NumCounters, 10);
|
||||
|
||||
uint64_t *Locs = _bolt_instr_locations_getter();
|
||||
reportNumber("__bolt_instr_setup, address of counters: ",
|
||||
reinterpret_cast<uint64_t>(Locs), 10);
|
||||
|
||||
for (size_t I = 0; I < NumCounters; ++I)
|
||||
reportNumber("Counter value: ", Locs[I], 10);
|
||||
}
|
||||
|
||||
extern "C" __attribute((section("__TEXT,__fini"))) void _bolt_instr_fini() {
|
||||
const char* Message = "Bye!\n";
|
||||
extern "C"
|
||||
__attribute__((section("__TEXT,__fini")))
|
||||
__attribute__((force_align_arg_pointer))
|
||||
void _bolt_instr_fini() {
|
||||
uint32_t NumCounters = _bolt_num_counters_getter();
|
||||
reportNumber("__bolt_instr_fini, number of counters: ", NumCounters, 10);
|
||||
|
||||
uint64_t *Locs = _bolt_instr_locations_getter();
|
||||
reportNumber("__bolt_instr_fini, address of counters: ",
|
||||
reinterpret_cast<uint64_t>(Locs), 10);
|
||||
|
||||
for (size_t I = 0; I < NumCounters; ++I)
|
||||
reportNumber("Counter value: ", Locs[I], 10);
|
||||
|
||||
const char *Message = "Bye!\n";
|
||||
__write(2, Message, 5);
|
||||
}
|
||||
|
||||
|
@ -1738,6 +1738,16 @@ public:
|
||||
return std::vector<MCInst>();
|
||||
}
|
||||
|
||||
virtual std::vector<MCInst> createNumCountersGetter(MCContext *Ctx) const {
|
||||
llvm_unreachable("not implemented");
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual std::vector<MCInst> createInstrLocationsGetter(MCContext *Ctx) const {
|
||||
llvm_unreachable("not implemented");
|
||||
return {};
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
@ -344,6 +344,7 @@ void MachORewriteInstance::mapCodeSections(orc::VModuleKey Key) {
|
||||
BOLT->getInputFileOffset());
|
||||
Function->setImageAddress(FuncSection->getAllocAddress());
|
||||
Function->setImageSize(FuncSection->getOutputSize());
|
||||
BC->registerNameAtAddress(Function->getOneName(), Addr, 0, 0);
|
||||
Addr += FuncSection->getOutputSize();
|
||||
}
|
||||
}
|
||||
@ -386,8 +387,6 @@ void MachORewriteInstance::emitAndLink() {
|
||||
auto Resolver = orc::createLegacyLookupResolver(
|
||||
[&](const std::string &Name) -> JITSymbol {
|
||||
llvm::errs() << "looking for " << Name << "\n";
|
||||
assert(!BC->EFMM->ObjectsLoaded &&
|
||||
"Linking multiple objects is unsupported");
|
||||
DEBUG(dbgs() << "BOLT: looking for " << Name << "\n");
|
||||
if (auto *I = BC->getBinaryDataByName(Name)) {
|
||||
const uint64_t Address = I->isMoved() && !I->isJumpTable()
|
||||
|
@ -607,6 +607,11 @@ void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
|
||||
Summary->InitialIndTailCallHandlerFunction =
|
||||
createSimpleFunction("__bolt_instr_default_ind_tailcall_handler",
|
||||
BC.MIB->createInstrumentedNoopIndTailCallHandler());
|
||||
|
||||
createSimpleFunction("__bolt_num_counters_getter",
|
||||
BC.MIB->createNumCountersGetter(BC.Ctx.get()));
|
||||
createSimpleFunction("__bolt_instr_locations_getter",
|
||||
BC.MIB->createInstrLocationsGetter(BC.Ctx.get()));
|
||||
}
|
||||
|
||||
void Instrumentation::setupRuntimeLibrary(BinaryContext &BC) {
|
||||
|
@ -3325,6 +3325,22 @@ public:
|
||||
return Insts;
|
||||
}
|
||||
|
||||
std::vector<MCInst> createNumCountersGetter(MCContext *Ctx) const override {
|
||||
std::vector<MCInst> Insts(2);
|
||||
MCSymbol *NumLocs = Ctx->getOrCreateSymbol("__bolt_num_counters");
|
||||
createMove(Insts[0], NumLocs, X86::EAX, Ctx);
|
||||
createReturn(Insts[1]);
|
||||
return Insts;
|
||||
}
|
||||
|
||||
std::vector<MCInst> createInstrLocationsGetter(MCContext *Ctx) const override {
|
||||
std::vector<MCInst> Insts(2);
|
||||
MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_locations");
|
||||
createLea(Insts[0], Locs, X86::EAX, Ctx);
|
||||
createReturn(Insts[1]);
|
||||
return Insts;
|
||||
}
|
||||
|
||||
BlocksVectorTy indirectCallPromotion(
|
||||
const MCInst &CallInst,
|
||||
const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
|
||||
@ -3627,6 +3643,36 @@ public:
|
||||
return Results;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg,
|
||||
MCContext *Ctx) const {
|
||||
Inst.setOpcode(X86::MOV64rm);
|
||||
Inst.addOperand(MCOperand::createReg(Reg));
|
||||
Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg
|
||||
Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt
|
||||
Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
|
||||
Inst.addOperand(MCOperand::createExpr(
|
||||
MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None,
|
||||
*Ctx))); // Displacement
|
||||
Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg,
|
||||
MCContext *Ctx) const {
|
||||
Inst.setOpcode(X86::LEA64r);
|
||||
Inst.addOperand(MCOperand::createReg(Reg));
|
||||
Inst.addOperand(MCOperand::createReg(X86::RIP)); // BaseReg
|
||||
Inst.addOperand(MCOperand::createImm(1)); // ScaleAmt
|
||||
Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg
|
||||
Inst.addOperand(MCOperand::createExpr(
|
||||
MCSymbolRefExpr::create(Src, MCSymbolRefExpr::VK_None,
|
||||
*Ctx))); // Displacement
|
||||
Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user