All asm tags become characters in the executable

When assembling an object using nasm I find that all tags are included as characters in the resulting .o file, as well as in the final binary.

This makes sense for the entry points of the functions that I declared GLOBAL , and for the initial parts of the section (for example, for the .text section), but it seems strange that labels are simply used as entry points in the loop and all this is nearby to appear in the output . In addition to leaking internal implementation details, it spends space in the symbol table.

For example, given this short build 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 

Results in l (i.e. local) characters in both the object file and the associated executable file:

 objdump --syms label-test.o label-test.o: file format elf64-x86-64 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 label-test.s 0000000000000000 ld .text 0000000000000000 .text 0000000000000002 l .text 0000000000000000 normal_label 0000000000000004 l .text 0000000000000000 normal_label.local_label 0000000000000000 g .text 0000000000000000 _start 

Note that both normal_label and the local label local_label are in the character table. All of them also fall into the symbol table of the executable file.

I do not want to highlight these characters in the final executable. Can I tell nasm to not include them? There are several options that I could pass to ld , for example --strip-all , which will remove these characters, as well as all other characters in the executable. This makes it a pretty cudgel: it removes the characters that I really want to keep for readable stacks, debugging, etc.


FWIW, as Peter Cordes mentioned, yasm doesn't have exactly the same problem. With an elf64 .o file built in exactly the same way as described above (but with replacing yasm with 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 ld .text 0000000000000000 .text 0000000000000000 g .text 0000000000000000 _start 

The global label _start is still enabled, but the other two labels are not named - they are still there, but they are unnamed characters with an offset of 4 and 2 (lines 2 and 3 in the list above). This is confirmed by the addition of additional labels - more unmarked characters are created.

+5
source share
1 answer

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

In my case, it seems to clean up the object file, for example:

 strip --discard-all label-test.o 

gotta do the trick. Despite the name of the parameter --discard-all , it only breaks local characters and leaves only global characters. Here is the character table before deleting the file:

 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 label-test.s 0000000000000000 ld .text 0000000000000000 .text 0000000000000002 l .text 0000000000000000 normal_label 0000000000000004 l .text 0000000000000000 normal_label.local_label 0000000000000000 g .text 0000000000000000 _start 

and after:

 SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 label-test.s 0000000000000000 ld .text 0000000000000000 .text 0000000000000000 g .text 0000000000000000 _start 

Note in particular that it is smart enough to leave a .text section symbol, although it is local. Of course, this strip option cannot distinguish between useless (loop label) and potentially useful symbols, for example, entry points to a local function, which are necessary for proper stack tracing using various tools.

If you wanted to be smarter, you could only selectively remove asm-local (i.e., labels starting with . ) Using the --wildcard and --strip-symbol options to selectively remove only labels with inline . .

I'm still looking for a better answer if there is hiding.

+3
source

All Articles