【发布时间】:2017-01-31 20:49:39
【问题描述】:
使用nasm 组装对象时,我发现所有标签都作为符号包含在生成的.o 文件以及最终二进制文件中。
这对于我声明为 GLOBAL 的函数入口点和部分开始部分(例如,对于 .text 部分)来说是有意义的,但标签仅用作循环入口点等等似乎很奇怪附近出现在输出文件中。除了泄露内部实现细节外,还浪费符号表空间。
例如,给定这个简短的汇编程序:
GLOBAL _start
_start:
xor eax, eax
normal_label:
xor eax, eax
.local_label:
xor eax, eax
xor edi, edi
mov eax, 231 ; exit(0)
syscall
...构建使用:
nasm -f elf64 label-test.s
ld label-test.o -o label-test
在目标文件和链接的可执行文件中都产生l(即本地)符号:
objdump --syms label-test.o
label-test.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 label-test.s
0000000000000000 l d .text 0000000000000000 .text
0000000000000002 l .text 0000000000000000 normal_label
0000000000000004 l .text 0000000000000000 normal_label.local_label
0000000000000000 g .text 0000000000000000 _start
请注意,normal_label 和本地标签 local_label 都以符号表结尾。它们也都在可执行文件的符号表中。
我不想将这些符号发送到最终的可执行文件。我可以告诉 nasm 不要包括它们吗?我可以将一些选项传递给ld,例如--strip-all,这将删除这些符号,但也会删除可执行文件中的所有其他 符号。这使它变得非常棒:它消除了我真正想要保留的符号,以用于可读的堆栈跟踪、调试等。
FWIW,正如 Peter Cordes 所说,yasm 没有完全相同的问题。使用与上面完全相同的方式构建的 elf64 .o 文件(但将 yasm 替换为 nasm,我们得到:
objdump --syms label-test-yasm.o
label-test-yasm.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 label-test.s
0000000000000004 l .text 0000000000000000
0000000000000002 l .text 0000000000000000
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 g .text 0000000000000000 _start
仍包含全局_start 标签,但其他两个标签未命名 - 但它们仍然存在,它们是偏移量 4 和 2 处的未命名符号(上面列表中的第 2 行和第 3 行)。这可以通过添加更多标签来确认 - 会产生更多未命名的符号。
【问题讨论】:
-
yasm 默认不这样做。 (如果你使用
-gdwarf2,它会这样做) -
嗯,是的。所以也许这有点怪癖。我将其添加到问题的底部。您提到了
-g的东西,我想到这些是为调试添加的主要内容,但值得注意的是ld命令上的--strip-debug不会删除nasm 构建的二进制文件中的那些(或任何符号)。 -
好吧,这次我用谷歌搜索得更厉害了,似乎它可能只是一个limitation in nasm。
-
对,我的意思是我假设有某种方法可以摆脱
.标签,留下非.标签。即,我认为 nasm 会有某种方式来完成 yasm 的工作(因为它显然很有用),但由于我通常只使用 yasm,所以没有费心去看。 -
对 yasm 的更正,它确实将条目添加到符号表中,但它们是“未命名的”。上面添加了详细信息。
标签: assembly linker x86 nasm elf