如何在 LLVM 的 LowerTypeTests Pass 中设置断点?
How can I set a breakpoint in LLVM's LowerTypeTests Pass?
我试图在 LLVM 代码中设置一个断点,该代码生成跳转 tables 以响应 -fsanitize=cfi-icall
标志。
我已经通过 clang -flto -fsanitize=cfi-icall indirect.c -o indirect
尝试了下面的 运行 indirect.c,生成的目标文件显然包含 x86 中的跳转 tables。此外,发出的中间位码文件包含字符串 "CFI Canonical Jump Tables,",它仅出现在 llvm/lib/Transforms/IPO/LowerTypeTests.cpp
和 llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
中。但是,我已经使用调试符号构建了 clang 和 opt from source,并且无法在 GDB 或 LLDB 的文件中找到相关代码。代码更有可能在 LowerTypeTests.cpp
中,因为那是跳转 table 构造代码发生的地方。这是我正在使用的代码:
indirect.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 中的跳转 tables:
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 中触发此代码,我将不胜感激!
如果您在 clang
中设置断点,首先 运行 您的命令带有 -v
标志。它会给你正确的咒语 -cc1
:
"/usr/bin/clang" -cc1 -triple x86_64-unknown-freebsd12.0 ... <very long command line>
将此行传递给 GDB 并在任意位置中断。
我试图在 LLVM 代码中设置一个断点,该代码生成跳转 tables 以响应 -fsanitize=cfi-icall
标志。
我已经通过 clang -flto -fsanitize=cfi-icall indirect.c -o indirect
尝试了下面的 运行 indirect.c,生成的目标文件显然包含 x86 中的跳转 tables。此外,发出的中间位码文件包含字符串 "CFI Canonical Jump Tables,",它仅出现在 llvm/lib/Transforms/IPO/LowerTypeTests.cpp
和 llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
中。但是,我已经使用调试符号构建了 clang 和 opt from source,并且无法在 GDB 或 LLDB 的文件中找到相关代码。代码更有可能在 LowerTypeTests.cpp
中,因为那是跳转 table 构造代码发生的地方。这是我正在使用的代码:
indirect.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 中的跳转 tables:
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 中触发此代码,我将不胜感激!
如果您在 clang
中设置断点,首先 运行 您的命令带有 -v
标志。它会给你正确的咒语 -cc1
:
"/usr/bin/clang" -cc1 -triple x86_64-unknown-freebsd12.0 ... <very long command line>
将此行传递给 GDB 并在任意位置中断。