使用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
最终都出现在符号表中。所有这些都最终都在可执行文件的符号表中。
我不想将这些符号发送到最终的可执行文件。我可以告诉他们不要包含它们吗?我可以将一些选项传递给ld
,例如--strip-all
,这将删除这些符号,但也会删除可执行文件中的所有其他符号。这使得它成为了一个笨蛋:它消除了我真正想要保留的符号,用于可读的堆栈跟踪,调试等。
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行)上面的列表)。这可以通过添加更多标签来确认 - 生成更多未经编辑的符号。
答案 0 :(得分:3)
据我所知,这只是一个限制。例如,参见this forum post,其中海报具有大致相同的问题(尽管是32位而不是64位ELF),除了使用剥离工具之外,没有提供任何解决方案。
就我而言,它似乎剥离了对象文件,如:
strip --discard-all label-test.o
应该做的伎俩。尽管--discard-all
选项的名称,它只剥离局部符号并仅留下全局符号。在剥离文件之前,这是符号表:
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
之后:
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 label-test.s
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 g .text 0000000000000000 _start
请特别注意,仅仅保留.text
部分符号就足够聪明,即使它是本地符号。当然,这个条带选项无法真正区分无用(循环标签)和可能有用的符号,例如使用各种工具提供正确堆栈跟踪所需的本地函数入口点。
如果您想更聪明一点,您可以选择性地使用.
和--wildcard
选项仅删除asm-local(即以--strip-symbol
开头的标签)仅剥离嵌入了.
的标签。
如果有人潜伏在那里,我还在寻找更好的答案。
答案 1 :(得分:2)
有点晚了,但是我遇到了这个问题,并为nasm 2.15编写了一个补丁来解决此问题。它添加了一个名为“ -discard-labels”的命令行开关。您可以在这里获取它:https://forum.nasm.us/index.php?topic=2666.0