如何解决为什么 LLVM 将无意义值传递给 FFI 函数?
我有一个 C++ 头文件,声明如下:
struct Inner {
// ...
};
struct MyStruct {
Inner* _inner;
size_t _x;
size_t _y;
};
extern "C" {
MyStruct my_fn(MyStruct* s,bool flag_1,bool flag_2);
};
...我正在用 clang
编译成一个共享库,我试图从 LLVM 代码调用它的函数:
%"Inner" = type {i64,i64}
%"MyStruct" = type {%"Inner"*,i64,i64}
declare %"MyStruct" @"my_fn"(%"MyStruct"* %".1",i1 %".2",i1 %".3")
define void @"main"()
{
entry:
%".stack_buf_ptr" = alloca %"MyStruct"
; ... assign elements of %.stack_buf_ptr ...
%".15" = call %"MyStruct" @"my_fn"(%"MyStruct"* %".stack_buf_ptr",i1 true,i1 true)
}
程序在 my_fn
内崩溃。然而,奇怪的是传递的参数具有无意义值,当我从 my_fn
打印它们时,或者在调试器中检查它们时,我可以看到这些值。具体来说,第一个参数具有无意义的指针值“0x7”。
从阅读 LLVM IR 来看,我不知道这怎么可能——指针是由 LLVM 自己的 alloca
指令直接提供的。如果我尝试传递全局变量的地址,我会得到类似的行为。更奇怪的是,我的其他一些具有相似(但不相同)签名的被调用函数工作得很好。
我能想到的唯一解释是调用约定不一致,但在任何一种情况下似乎都没有错——函数是在 extern "C" { ... }
中声明的,当我使用 nm
时在编译的共享库上,我可以看到 my_fn
遵守 cdecl
命名约定(它被列为 _my_fn
)。我还从文档中了解到 LLVM 函数声明默认为 cdecl
。
我真的不知道接下来该看什么。我的类型/签名在二进制布局中不匹配是否有某种原因?我应该检查共享库的编译器设置是否可以修复/破坏事情?会发生什么?
为什么上面的 LLVM 代码会将无意义的值传递给 my_fn()
?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。