2016-09-23 7 views
5

Lors de l'assemblage d'un objet en utilisant nasm, je constate que toutes les étiquettes sont incluses en tant que symboles dans le fichier .o résultant, ainsi que le fichier binaire final. Cela a du sens pour les points d'entrée de fonction que j'ai déclarés GLOBAL, et pour les parties de début de section (par exemple, pour la section .text), mais il semble étrange que les étiquettes soient simplement utilisées comme points d'entrée de boucle. dans le fichier de sortie. En plus de la fuite des détails internes d'implémentation, il gaspille de l'espace dans la table de symboles.Toutes les étiquettes asm devenant des symboles dans le fichier exécutable

Par exemple, étant donné ce programme de montage court:

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 

... construit en utilisant:

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

Résultats en l symboles (par exemple, local) tant dans le fichier objet et exécutable lié :

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 

Notez que les deux normal_label et th L'étiquette locale local_label s'est retrouvée dans la table des mnémoniques. Tous se retrouvent dans la table des symboles de l'exécutable aussi. Je ne veux pas émettre ces symboles dans l'exécutable final.

Puis-je dire au nasm de ne pas les inclure? Il y a quelques options que je pourrais passer à ld, telles que --strip-all, qui enlèvera ces symboles, mais aussi tous les autres symboles dans l'exécutable. Cela le rend tout à fait la trique: il élimine les symboles que je veux vraiment garder des traces de pile lisible, le débogage, etc.


FWIW, comme mentionné par Peter Cordes, yasm n'a pas exactement la même question. Avec un fichier ELF64 .o construit exactement de la même façon que ci-dessus (mais avec yasm substitué nasm, nous obtenons:

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 

L'étiquette _start globale est toujours inclus, mais les deux autres labels ne sont pas nommés - ils sont toujours là, ce sont les symboles sans nom aux décalages 4 et 2 (lignes 2 et 3 dans la liste ci-dessus) Ceci est confirmé par l'ajout d'autres étiquettes - plus de symboles non numérotés sont produits

+0

yasm ne le fait pas par défaut. (C'est le cas si vous utilisez '-gdwarf2') –

+1

Euh, ouais. Alors peut-être que c'est un peu bizarre. J'ai ajouté cela au bas de la question. Vous mentionnez le truc '-g' et il m'est apparu que ceux-ci sont ajoutés en primaire pour le débogage, mais il vaut la peine de noter que' --strip-debug' sur la commande 'ld' ne les supprime pas (ou aucun des symboles) sur le binaires construits par nasm. – BeeOnRope

+0

Eh bien, j'ai googlé plus dur cette fois et il semble que ce pourrait être juste une [limitation dans nasm] (https://forum.nasm.us/index.php?topic=1951.0). – BeeOnRope

Répondre

3

Pour autant que je sache , par exemple, this forum post où l'affiche a à peu près le même problème (bien que 32 bits plutôt que ELF 64 bits), et aucune solution n'est fournie autre que l'utilisation d'un outil d'extraction.

Dans mon cas, il semble dépouillant le fichier objet comme:

strip --discard-all label-test.o 

devrait faire l'affaire. Malgré le nom de l'option --discard-all, il ne supprime que les symboles locaux et laisse les symboles globaux seuls.Voici la table des symboles avant de se dénuder le fichier:

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 

et après:

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

note en particulier qu'il était assez intelligent pour laisser seul le symbole de la section .text, même si elle est locale. Bien sûr, cette option de bande ne peut pas vraiment distinguer entre des symboles inutiles (étiquette de boucle) et potentiellement utiles, par exemple des points d'entrée de fonction locale qui sont nécessaires pour donner des traces de pile correctes avec divers outils.

Si vous voulez être plus intelligent à ce sujet, vous pouvez dépouiller de manière sélective uniquement les asm local (à savoir, les étiquettes commençant par un .) en utilisant les options --wildcard et --strip-symbol à bande sélective uniquement des étiquettes avec un . intégré.

Je suis toujours à la recherche d'une meilleure réponse si quelqu'un se cache là-bas.