使用非法指令生成可执行文件 [英] Clang producing executable with illegal instruction
问题描述
我解决了我看到的一个小例子的问题。这里是我正在使用的LLVM汇编代码(在foo.ll中):
I boiled the problem I'm seeing down to a small example. Here is the LLVM assembler code I'm using (in foo.ll):
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
define fastcc i32 @foo(i32) {
entry:
%x = add i32 %0, 1
ret i32 %x
}
define i32 @main(i32, i8**) {
entry:
%2 = call i32 @foo(i32 %0)
ret i32 %2
}
:
clang -O1 -o foo foo.ll
...当我运行它时,我得到:
... and when I run it I get:
Illegal instruction (core dumped)
...所以我启动我的调试器, >
... so I fire up my debugger, and see this:
Program received signal SIGILL, Illegal instruction.
0x00000000004004d0 in main ()
(gdb) bt
#0 0x00000000004004d0 in main ()
(gdb) disas
Dump of assembler code for function main:
=> 0x00000000004004d0 <+0>: ud2
End of assembler dump.
(gdb)
$ b <
Note that if I change either of the following the program executes fine:
- 从clang标志中移除-O1
- 从foo的@foo声明中移除fastcc .ll
作为参考,clang -v是:
For reference, "clang -v" is:
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
此外,如果有助于这里是objdump -d foo 。
推荐答案
您的被叫方标记为fastcall,但呼叫不是。调用约定需要匹配,否则它是未定义的行为,其依次被优化为ud2,或者可能根本没有。这是一个常见问题: http://llvm.org/docs/FAQ.html#why-does-instcombine-simplifycfg- turn-a-call-to-a-function-with-a-mismatch-calling-convention-convention-into-unreachable-why-not-make-the-verifier-reject- it
Your callee is marked "fastcall" but the call is not. The calling conventions needs to match or else it is undefined behaviour which in turn gets optimized down to "ud2", or perhaps nothing at all. This is a FAQ: http://llvm.org/docs/FAQ.html#why-does-instcombine-simplifycfg-turn-a-call-to-a-function-with-a-mismatched-calling-convention-into-unreachable-why-not-make-the-verifier-reject-it
这篇关于使用非法指令生成可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!