我如何 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.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 部分解析吗?

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,并且链接正常。