使用Clang生成带有非法指令的可执行文件

10

我将遇到的问题简化为一个小示例。这是我使用的LLVM汇编器代码(在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

...当我运行它时,会得到以下结果:

Illegal instruction (core dumped)

...所以我启动了调试器,然后看到了这个:

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) 

请注意,如果更改以下任一项,则程序将正常执行:
  • 从clang标志中删除-O1
  • 在foo.ll中声明@foo时删除fastcc
参考,"clang -v"为:
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix

另外,如果有帮助的话,这里是"objdump -d foo"的结果


奇怪。我用一个相当新的 TOT 得到了完全相同的结果。 - Richard Pennington
2个回答

5

1

有一个bug,当优化函数调用时,clang会产生一个未定义的指令ud2(它将引发无效操作码错误),表示它无法处理某些内容。

基本上,为了加快速度,它将返回值放在寄存器中。如果返回值无法适应寄存器(因此将在堆栈上返回),则会发出ud2而不是ret。

这是一个已知的错误(至少在3.2中)。


在跟踪器中是否有相关问题? - brooks94
另外,你说“如果返回值无法适应寄存器”。在这种情况下,它可以适应,对吧? - brooks94
Marshall 写了一些令人困惑的内容,SO 不允许他删除,所以他用这个道歉替换了它。 - Marshall Clow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接