Я пытаюсь установить точку останова в коде LLVM, который генерирует таблицы переходов в ответ на флаг -fsanitize=cfi-icall
.
Я попытался запустить косвенный файл.c ниже через clang -flto -fsanitize=cfi-icall indirect.c -o indirect
, и полученный объектный файл явно содержит таблицы переходов в x86. Кроме того, промежуточные файлы битовых кодов содержат строку «Таблицы канонических переходов CFI», которая присутствует только в llvm/lib/Transforms/IPO/LowerTypeTests.cpp
и llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
. Тем не менее, я построил clang и opt from source с символами отладки и не смог найти соответствующий код ни в одном файле в GDB или LLDB. Код, скорее всего, будет в LowerTypeTests.cpp
, так как именно здесь происходит код построения таблицы переходов. Вот код, который я использую:
косвенный. C:
int foo (int a) {
return 2 * a;
};
int bar (int a) {
return 3 * a;
}
int main(int argc, char* argv[]) {
int (*func)(int) = foo;
int (*func2)(int) = bar;
int c = func(2);
}
И таблицы переходов в x86:
0000000000400510 <__typeid__ZTSFiiE_global_addr>:
400510: e9 6b ff ff ff jmpq 400480 <foo.cfi>
400515: cc int3
400516: cc int3
400517: cc int3
0000000000400518 <bar>:
400518: e9 73 ff ff ff jmpq 400490 <bar.cfi>
40051d: cc int3
40051e: cc int3
40051f: cc int3
Соответствующий код в LowerTypeTests. cpp:
bool lowertypetests::isJumpTableCanonical(Function *F) {
if (F->isDeclarationForLinker())
return false;
auto *CI = mdconst::extract_or_null<ConstantInt>(
F->getParent()->getModuleFlag("CFI Canonical Jump Tables"));
if (!CI || CI->getZExtValue() != 0)
return true;
return F->hasFnAttribute("cfi-canonical-jump-table");
}
и в CodeGenModule.cpp:
if (LangOpts.Sanitize.has(SanitizerKind::CFIICall)) {
getModule().addModuleFlag(llvm::Module::Override,
"CFI Canonical Jump Tables",
CodeGenOpts.SanitizeCfiCanonicalJumpTables);
}
Буду признателен, если кто-нибудь поможет мне вызвать этот код в GDB или LLDB!