Link 来自 asm/C 的 LLVM StackMaps 错误
Link error with LLVM StackMaps from asm/C
我目前正在尝试使用 LLVM's stackmap feature 编写一个基本的 C 堆栈遍历器。我已经生成了堆栈图,现在我正在尝试将堆栈图传递给 C 函数,以便我可以使用它。
特别是我无法将 __LLVM_StackMaps
传递给我的堆栈查询器。我试过将它作为参数从汇编函数传递:
.text
.globl stackHelper
.extern stackWalker
.extern __LLVM_StackMaps
stackHelper:
mov %rsp, %rdi
mov __LLVM_StackMaps, %rsi
jmp stackWalker
我收到错误
(.text+0x7): undefined reference to ``__LLVM_StackMaps'
.
objdump 说 __LLVM_StackMaps
不在 .text 或 .data 中,而是在自定义 .llvm_stackmaps
部分中。这是 objdump 输出:
factorial.o: file format elf64-x86-64
factorial.o
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000067 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .rodata.str1.1 00000005 0000000000000000 0000000000000000 000000a7 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000ac 2**0
CONTENTS, READONLY
3 .llvm_stackmaps 00000050 0000000000000000 0000000000000000 000000b0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
4 .eh_frame 00000050 0000000000000000 0000000000000000 00000100 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 factorial.ll
0000000000000000 l .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .rodata.str1.1 0000000000000000 .rodata.str1.1
0000000000000030 g F .text 0000000000000037 fact
0000000000000000 g F .text 0000000000000023 main
0000000000000000 *UND* 0000000000000000 printf
0000000000000000 *UND* 0000000000000000 stackHelper
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000011 R_X86_64_32 .rodata.str1.1
000000000000001b R_X86_64_PC32 printf-0x0000000000000004
000000000000004e R_X86_64_PC32 stackHelper-0x0000000000000004
RELOCATION RECORDS FOR [.llvm_stackmaps]:
OFFSET TYPE VALUE
0000000000000010 R_X86_64_64 fact
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
0000000000000034 R_X86_64_PC32 .text+0x0000000000000030
我的猜测是它无法访问此 table 中的符号。有没有办法从我的汇编函数访问这些数据,或者我是否需要在链接阶段做一些事情以允许它正确访问这些数据?
@Jester 指出的问题是该符号标记为本地,因此仅对它出现的文件可见。
0000000000000000 l .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
第一列地址后的l
表示符号为LOCAL。 g
表示它是 GLOBAL 并且对外部对象可见。
如果无法通过源码将factorial中的symbol改为non-static,那么可以使用OBJCOPY改变symbol在object中的可见性直接归档:
objcopy --globalize-symbol=__LLVM_StackMaps factorial.o factorial.o
第一个目标文件factorial.o
是要处理的输入文件,第二个factorial.o
是输出文件。如果您愿意,可以指定不同的输出对象。我的示例用更改覆盖了原来的 factorial.o
。结果 factorial.o
现在应该有一个看起来像这样的条目:
0000000000000000 g .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
选项 --globalize-symbol
在 OBJCOPY documentation 中描述为:
--globalize-symbol=symbolname
Give symbol symbolname global scoping so that it is visible outside of the file in which it is defined. This option may be given more than once.
我目前正在尝试使用 LLVM's stackmap feature 编写一个基本的 C 堆栈遍历器。我已经生成了堆栈图,现在我正在尝试将堆栈图传递给 C 函数,以便我可以使用它。
特别是我无法将 __LLVM_StackMaps
传递给我的堆栈查询器。我试过将它作为参数从汇编函数传递:
.text
.globl stackHelper
.extern stackWalker
.extern __LLVM_StackMaps
stackHelper:
mov %rsp, %rdi
mov __LLVM_StackMaps, %rsi
jmp stackWalker
我收到错误
(.text+0x7): undefined reference to ``__LLVM_StackMaps'
.
objdump 说 __LLVM_StackMaps
不在 .text 或 .data 中,而是在自定义 .llvm_stackmaps
部分中。这是 objdump 输出:
factorial.o: file format elf64-x86-64
factorial.o
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000067 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .rodata.str1.1 00000005 0000000000000000 0000000000000000 000000a7 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000ac 2**0
CONTENTS, READONLY
3 .llvm_stackmaps 00000050 0000000000000000 0000000000000000 000000b0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
4 .eh_frame 00000050 0000000000000000 0000000000000000 00000100 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 factorial.ll
0000000000000000 l .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .rodata.str1.1 0000000000000000 .rodata.str1.1
0000000000000030 g F .text 0000000000000037 fact
0000000000000000 g F .text 0000000000000023 main
0000000000000000 *UND* 0000000000000000 printf
0000000000000000 *UND* 0000000000000000 stackHelper
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000011 R_X86_64_32 .rodata.str1.1
000000000000001b R_X86_64_PC32 printf-0x0000000000000004
000000000000004e R_X86_64_PC32 stackHelper-0x0000000000000004
RELOCATION RECORDS FOR [.llvm_stackmaps]:
OFFSET TYPE VALUE
0000000000000010 R_X86_64_64 fact
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
0000000000000034 R_X86_64_PC32 .text+0x0000000000000030
我的猜测是它无法访问此 table 中的符号。有没有办法从我的汇编函数访问这些数据,或者我是否需要在链接阶段做一些事情以允许它正确访问这些数据?
@Jester 指出的问题是该符号标记为本地,因此仅对它出现的文件可见。
0000000000000000 l .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
第一列地址后的l
表示符号为LOCAL。 g
表示它是 GLOBAL 并且对外部对象可见。
如果无法通过源码将factorial中的symbol改为non-static,那么可以使用OBJCOPY改变symbol在object中的可见性直接归档:
objcopy --globalize-symbol=__LLVM_StackMaps factorial.o factorial.o
第一个目标文件factorial.o
是要处理的输入文件,第二个factorial.o
是输出文件。如果您愿意,可以指定不同的输出对象。我的示例用更改覆盖了原来的 factorial.o
。结果 factorial.o
现在应该有一个看起来像这样的条目:
0000000000000000 g .llvm_stackmaps 0000000000000000 __LLVM_StackMaps
选项 --globalize-symbol
在 OBJCOPY documentation 中描述为:
--globalize-symbol=symbolname
Give symbol symbolname global scoping so that it is visible outside of the file in which it is defined. This option may be given more than once.