Я пытаюсь написать проход модуля LLVM, который профилирует количество вхождений всех уникальных пар вызывающий / вызываемый функции, которые возникают во время выполнения в данной программе.
Кажется, есть масса примеров онлайн о том, как это сделать, но ни один из них не может учитывать косвенные вызовы функций.
В настоящее время я работаю с самой последней версией LLVM 11, поэтому многие сообщения в Интернете, связанные с этим, также устарели info.
В моей настройке все в настоящее время работает нормально, за исключением случаев, когда есть косвенные вызовы функций.
Basi c настройка кода ...
for (auto &F : M) {
for (auto &BB : F) {
for (auto &I : BB) {
if (auto *CB = dyn_cast<CallBase>(&I)){
caller_name = F->getName().str();
Value *callee = CB->getCalledFunction();
// Indirect Call
if (callee == nullptr){
/* Help needed here! */
}
// Direct Call
else{
callee_name = callee.getName().str()
/* Update caller/callee pair counter */
}
}
}
}
}
Есть ли какой-то известный способ получить имя вызываемого косвенного вызова функции с помощью LLVM? Я знаю, что в LLVM 11 AbstractCallSite
есть новый класс, который, кажется, может быть полезен, но мне не удалось найти никаких примеров того, как его правильно использовать.
Ближайший У меня есть работа, заключающаяся в том, что я вставляю вызов в IR для печати значения вызываемого, когда происходит косвенный вызов.
if (callee == nullptr) {
IRBuilder<> IndirectBuilder(CB);
auto *callee_ptr_val = IndirectBuilder.CreatePtrToInt(
CB->getCalledValue(), Type::getInt64Ty(Ctx));
IndirectBuilder.CreateCall(print_callee_val,
callee_ptr_val);
}
Когда это значение печатается во время выполнения, я могу посмотреть в таблицу символов двоичного файла и посмотрите, что было вызвано, но это действительно раздражает, и было бы замечательно, если бы было лучшее решение.
Заранее спасибо!