所有的asm标签成为可执行文件中的符号 [英] All asm labels becoming symbols in executable file

查看:133
本文介绍了所有的asm标签成为可执行文件中的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 nasm 组装对象时,我发现所有标签都作为符号包含在结果 .o 文件,以及最终的二进制文件。

When assembling an object using nasm, I'm finding that all labels are included as symbols in the resultant .o file, as well as the final binary.

这对于我声明为 GLOBAL ,以及节的开始部分(例如, .text 节),但是标签只是用作循环入口点而几乎全部出现在标签中似乎很奇怪。输出文件。除了泄漏内部实现细节之外,它还浪费了符号表中的空间。

This makes sense for function entry points that I've declared GLOBAL, and for section start parts (e.g., for the .text section), but it seems odd that labels simply used as loop entry points and such all near to appear in the output file. In addition to leaking internal implementation details, it wastes space in the symbol table.

例如,鉴于此简短的汇编程序:

For example, given this short assembly program:

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

...使用以下方式构建:

... built using:

nasm -f elf64 label-test.s
ld label-test.o -o label-test

在目标文件和链接文件中均产生 l (即本地)符号可执行文件:

Results in l (i.e., local) symbols in both the object file and linked executable:

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 都位于符号表中。它们全部也都位于可执行文件的符号表中。

Note that both normal_label and the local label local_label ended up in the symbol table. All of them end up in the symbol table of the executable also.

我不想将这些符号发送给最终的可执行文件。我可以告诉nasm不要包括它们吗?我可以将某些选项传递给 ld ,例如-strip-all ,它将删除这些符号,以及可执行文件中的其他所有符号。这就使它变得很笨拙:它消除了我真正想保留的符号,以进行可读的堆栈跟踪,调试等。

I don't want to emit these symbols to the final executable. Can I tell nasm not to include them? There are some options I could pass to ld, such as --strip-all, which will remove those symbols, but also every other symbol in the executable. That makes it quite the cudgel: it eliminates the symbols I really want to keep for readable stack traces, debugging, etc.

FWIW,正如Peter Cordes所述, yasm 并没有完全相同的问题。使用与上述完全相同的方式构建的elf64 .o 文件(但用 yasm 代替 nasm ,我们得到:

FWIW, as mentioned by Peter Cordes, yasm doesn't have exactly the same issue. With an elf64 .o file built in exactly the same way as above (but with yasm substituted for nasm, we get:

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行),可以通过添加更多标签来确认-会生成更多未命名的符号。

The global _start label is still included, but the other two labels aren't named - they are still there though, they are the unnamed symbols at offset 4 and 2 (lines 2 and 3 in the list above). This is confirmed by adding more labels - more unnammed symbols are produced.

推荐答案

据我所知,这只是n中的限制组装例如,参见此论坛帖子,其中发帖者的问题大致相同(尽管32位而不是64位ELF),并且除了使用剥离工具外,没有提供其他解决方案。

As far as I can tell, it's just a limitation in nasm. See for example this forum post where the poster has approximately the same issue (although 32-bit rather than 64-bit ELF), and no solution is provided other than using a stripping tool.

就我而言,似乎像这样剥离目标文件: / p>

In my case, it seems stripping the object file like:

strip --discard-all label-test.o 

应该可以解决问题。尽管使用了-discard-all 选项的名称,但它仅去除局部符号,而仅保留全局符号。这是剥离文件之前的符号表:

should do the trick. Despite the name of the --discard-all option, it only strips local symbols and leaves global symbols alone. Here's the symbol table before stripping the file:

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 部分符号,即使是本地的。当然,这种剥离选项无法真正区分无用的(循环标签)和潜在有用的符号,例如,使用各种工具提供正确的堆栈跟踪所需的局部函数入口点。

Note in particular that it was smart enough to leave the .text section symbol alone, even though it is local. Of course this strip option can't really distinguish between useless (loop label) and potentially useful symbols, for example local function entry points which are needed to give correct stack traces with various tools.

如果您想变得更聪明,可以使用<$ c $选择性地仅剥离asm-local(即,以开头的标签)。 c>-通配符-strip-symbol 选项可以选择性地仅剥离带有嵌入式的标签。

If you wanted to be smarter about it, you could selectively strip only the asm-local (i.e., labels starting with a .) using the --wildcard and --strip-symbol options to selectively strip only labels with an embedded ..

如果有人潜伏在那里,我还在寻找更好的答案。

I'm still looking for a better answer if one is lurking out there.

这篇关于所有的asm标签成为可执行文件中的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆