如何将C声明与非标准部分中的符号相关联?

时间:2018-01-19 17:12:35

标签: c linker llvm undefined-symbol

我正在尝试使用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.cclang 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部分解决吗?

2 个答案:

答案 0 :(得分:1)

gnu :: section属性应该这样做。 clang显然也​​支持gcc风格的属性(((&#34; ...&#34;))和msvc-style __declspec(分配(&#34; ...&#34) ;))执行相同操作的语法。

[gnu :: section(&#34; ....&#34;)] void my_func(long,long);

答案 1 :(得分:0)

我想出了这个问题 - 该部分与它无关;只是__LLVM_StackMaps符号是本地符号(nm用类r而不是R报告)。我尝试先将st.ll编译为程序集,然后在汇编之前手动添加.globl,并且链接正常。