Clang用非法指令生成可执行文件

标签 clang llvm

我把我看到的问题归结为一个小例子。这是我正在使用的 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
    

    另外,如果有帮助here is the result of "objdump -d foo" .

    最佳答案

    您的被叫方被标记为“fastcall”,但调用没有。调用约定需要匹配,否则它是未定义的行为,而后者又会被优化为“ud2”,或者根本没有。这是一个常见问题: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

    关于Clang用非法指令生成可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19845474/

    相关文章:

    unix - 为什么 ELF 可执行文件可以有 4 个 LOAD 段?

    c++ - 在我的项目中使用预编译头文件(clang/llvm,但也包括 gcc)。如何在 make 中部署 -include 选项?

    C 指向负长度数组的指针奇怪的行为 Apple LLVM 编译器

    llvm - 找不到 lffi - 与 llvm 库链接时出错

    rust - 如何获取函数的返回地址?

    c++ - Xcode - 剖析和优化 C++ 编译时间

    linux - GCC 过时时本地安装 clang 的最佳方式

    c++ - 是否允许编译器优化堆内存分配?

    c - 静态与外部内在函数

    c++ - 如何将 llvm::MemoryBuffer 的内容作为 std::string 获取?