Assembly 所有asm标签都将成为可执行文件中的符号
当使用Assembly 所有asm标签都将成为可执行文件中的符号,assembly,linker,x86,nasm,elf,Assembly,Linker,X86,Nasm,Elf,当使用nasm组装对象时,我发现所有标签都作为符号包含在生成的.o文件以及最终二进制文件中 这对于我声明的GLOBAL函数入口点和部分开始部分(例如.text部分)来说是有意义的,但是标签仅仅用作循环入口点,并且这些都将出现在输出文件中,这似乎很奇怪。除了泄漏内部实现细节外,它还浪费了符号表中的空间 例如,给定此简短的组装程序: GLOBAL _start _start: xor eax, eax normal_label: xor eax, eax .local_label:
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
,例如--剥离所有
,这将删除这些符号,还将删除可执行文件中的所有其他符号。这使它变得非常困难:它消除了我真正想要保留的用于可读堆栈跟踪、调试等的符号
正如彼得·科尔德斯(Peter Cordes)所提到的那样,FWIW的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
全局
\u start
标签仍然包括在内,但其他两个标签没有命名-尽管它们仍然存在,它们是偏移量4和2处的未命名符号(上面列表中的第2行和第3行)。这通过添加更多标签得到了证实-产生了更多未命名的符号。据我所知,这只是nasm中的一个限制。例如,请参见海报中存在大致相同的问题(虽然是32位ELF而不是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
和--strip symbol
选项选择性地仅剥离asm本地标签(即以
开头的标签),以选择性地仅剥离嵌入
的标签
如果有人潜伏在那里,我仍然在寻找更好的答案。据我所知,这只是nasm中的一个限制。例如,请参见海报中存在的大致相同的问题(尽管是32位ELF而不是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
和--strip symbol
选项选择性地仅剥离asm本地标签(即以
开头的标签),以选择性地仅剥离嵌入
的标签
如果有人潜伏在那里,我仍然在寻找更好的答案。有点晚,但我遇到了这个问题,并为nasm 2.15编写了一个修补程序来解决这个问题。它添加了一个名为-discard labels的命令行开关。您可以在这里找到它:有点晚,但我遇到了这个问题,并为nasm 2.15编写了一个修补程序来解决这个问题。它添加了一个命令行开关,名为-discard labels和名为-discard labels的行开关。您可以在这里获得它:yasm默认情况下不会这样做。(如果您使用
-gdwarf2
,它会这样做)嗯,是的。也许这有点纳什怪癖。我把它添加到了问题的底部。你提到了-g
的东西,我突然想到这些都是为了调试而添加的,但值得注意的是-ld
命令上的-strip debug
并没有删除它们(或任何符号)在nasm构建的二进制文件上。这次我更努力地搜索了一下,看起来它可能只是一个。对,我的意思是我假设有某种方法可以摆脱
标签,留下非
标签。也就是说,我假设nasm会有某种方法来完成yasm所做的事情(因为它显然很有用),但没有费心去看,因为我通常只使用yasm。对yasm进行更正,它会将条目添加到符号表中,但它们是“未命名的”。上面添加的详细信息。默认情况下,yasm不会这样做。(如果使用-gdwarf2
,它会这样做)嗯,是的。也许这有点纳什怪癖。我把它添加到了问题的底部。你提到了-g
的东西,我突然想到这些都是为了调试而添加的,但值得注意的是-ld
命令上的-strip debug
并没有删除它们(或任何符号)在nasm构建的二进制文件上。我在谷歌上搜索了这个