我如何 link 针对非标准部分中的符号的 C 声明?
How can I link a C declaration against a symbol in a non-standard section?
我正在尝试使用 LLVM's stack map intrinsics,但我无法弄清楚如何处理 C 程序生成的数据。举一个最小的例子,我有以下文件:
st.ll
:
declare void @llvm.experimental.stackmap(i64, i32, ...)
define i32 @some_func(i32 %x) {
%y = add i32 %x, %x
call void(i64, i32, ...) @llvm.experimental.stackmap(i64 3735928559, i32 0, i32 %x, i32 %y)
ret i32 %y
}
ex.c
:
#include <stdio.h>
extern char __LLVM_StackMaps;
int main(void) {
fwrite(&__LLVM_StackMaps, sizeof(char), 10, stdout);
return 0;
}
如果我 运行 clang -c st.ll
然后用 nm -f s st.o
检查生成的目标文件,我得到以下输出:
Symbols from st.o:
Name Value Class Type Size Line Section
__LLVM_StackMaps |0000000000000000| r | NOTYPE| | |.llvm_stackmaps
some_func |0000000000000000| T | FUNC|0000000000000018| |.text
显然,正在生成一个 __LLVM_StackMaps
符号。但是,如果我 运行 clang st.ll ex.c
或 clang st.o ex.c
,我会得到这个错误:
/tmp/ex-06d9d2.o: In function `main':
ex.c:(.text+0xb): undefined reference to `__LLVM_StackMaps'
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
据我所知,问题是符号在 .llvm_stackmaps
部分而不是 .data
或 .bss
.
我该如何解决这个问题?有没有办法在 C 中指定源部分?我可以告诉链接器从 .llvm_stackmaps
部分解析吗?
gnu::section 属性应该可以做到。 clang 显然也支持 gcc-style attribute((section("...")) 和 msvc-style __declspec(allocate("...")) 语法执行相同的操作。
[gnu::section("...")] void my_func(长, 长);
我想通了——该部分与它无关;只是 __LLVM_StackMaps
符号是本地的(nm
用 class r
而不是 R
报告就证明了这一点。我尝试先将 st.ll
编译为汇编,然后在汇编之前手动添加一个 .globl
,并且链接正常。
我正在尝试使用 LLVM's stack map intrinsics,但我无法弄清楚如何处理 C 程序生成的数据。举一个最小的例子,我有以下文件:
st.ll
:
declare void @llvm.experimental.stackmap(i64, i32, ...)
define i32 @some_func(i32 %x) {
%y = add i32 %x, %x
call void(i64, i32, ...) @llvm.experimental.stackmap(i64 3735928559, i32 0, i32 %x, i32 %y)
ret i32 %y
}
ex.c
:
#include <stdio.h>
extern char __LLVM_StackMaps;
int main(void) {
fwrite(&__LLVM_StackMaps, sizeof(char), 10, stdout);
return 0;
}
如果我 运行 clang -c st.ll
然后用 nm -f s st.o
检查生成的目标文件,我得到以下输出:
Symbols from st.o:
Name Value Class Type Size Line Section
__LLVM_StackMaps |0000000000000000| r | NOTYPE| | |.llvm_stackmaps
some_func |0000000000000000| T | FUNC|0000000000000018| |.text
显然,正在生成一个 __LLVM_StackMaps
符号。但是,如果我 运行 clang st.ll ex.c
或 clang st.o ex.c
,我会得到这个错误:
/tmp/ex-06d9d2.o: In function `main':
ex.c:(.text+0xb): undefined reference to `__LLVM_StackMaps'
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
据我所知,问题是符号在 .llvm_stackmaps
部分而不是 .data
或 .bss
.
我该如何解决这个问题?有没有办法在 C 中指定源部分?我可以告诉链接器从 .llvm_stackmaps
部分解析吗?
gnu::section 属性应该可以做到。 clang 显然也支持 gcc-style attribute((section("...")) 和 msvc-style __declspec(allocate("...")) 语法执行相同的操作。
[gnu::section("...")] void my_func(长, 长);
我想通了——该部分与它无关;只是 __LLVM_StackMaps
符号是本地的(nm
用 class r
而不是 R
报告就证明了这一点。我尝试先将 st.ll
编译为汇编,然后在汇编之前手动添加一个 .globl
,并且链接正常。