2017-08-03 3 views
1

Lors de la disposition de symboles dans l'espace adresse à l'aide d'un script de lien, ld permet de faire référence à un symbole spécifique provenant d'une bibliothèque statique avec la syntaxe suivante:Référence à un symbole spécifique dans une bibliothèque statique avec le linker GNU gold

archive.a:object_file.o(.section.symbol_name) 

en utilisant gold plutôt que ld, il semble qu'une telle directive est ignorée. Le processus de liaison réussit. Toutefois, lorsque vous utilisez cette instruction pour mettre un symbole spécifique à un endroit précis avec gold et la vérification de la mise en page des symboles résultant en utilisant nm ou ayant un regard sur le fichier de la carte, le symbole est pas dans le prévu emplacement.

J'ai fait un petit cas de test en utilisant un programme du monde de bonification bonjour compilé statiquement dans son entrety avec gcc 5.4.0. La librairie C est la bibliothèque libc (dernier commit sur la branche principale du dépôt git officiel). Pour binutils, j'utilise également la dernière validation sur la branche master depuis le dépôt git officiel.

J'utilise le script éditeur de liens pour placer un symbole spécifique (.text.exit) à partir d'une bibliothèque statique (bibliothèque MUSL C: libc.a) à un endroit précis dans l'espace d'adressage qui est: la première position dans la section .text.

Mon script de liaison est:

ENTRY(_start) 
SECTIONS 
{ 
    . = 0x10000; 
    .text : 
    { 
     /* Forcing .text.exit in the first position in .text section */ 
     musl/lib/libc.a:exit.o(.text.exit); 
     *(.text*); 
    } 
    . = 0x8000000; 
    .data : { *(.data*) } 
    .rodata : { *(.rodata*) } 
    .bss : { *(.bss*) } 
} 

Mon Makefile:

# Set this to 1 to link with gold, 0 to link with ld 
GOLD=1 

SRC=test.c 
OBJ=test.o 
LIBS=musl/lib/crt1.o \ 
    musl/lib/libc.a \ 
    musl/lib/crtn.o 
CC=gcc 
CFLAGS=-nostdinc -I musl/include -I musl/obj/include 
BIN=test 
LDFLAGS=-static 
SCRIPT=linker-script.x 
MAP=map 

ifeq ($(GOLD), 1) 
LD=binutils-gdb/gold/ld-new 
else 
LD=binutils-gdb/ld/ld-new 
endif 

all: 
    $(CC) $(CFLAGS) -c $(SRC) -o $(OBJ) 
    $(LD) --output $(BIN) $(LDFLAGS) $(OBJ) $(LIBS) -T $(SCRIPT) \ 
     -Map $(MAP) 

clean: 
    rm -rf $(OBJ) $(BIN) $(MAP) 

Après la compilation et la liaison Je vérifie le fichier de la carte (obtenue en utilisant le -Carte ld/gold drapeau) à Jetez un oeil à l'emplacement de .text.exit. En utilisant ld comme l'éditeur de liens , il est en effet dans la première position de la section de texte. En utilisant gold, le ne l'est pas (il est présent plus loin dans l'espace adresse, comme si ma directive n'était pas prise en compte).

Maintenant, alors qu'aucun de ces travaux avec gold:

musl/lib/libc.a:exit.o(.text.exit); 
musl/lib/libc.a(.text.exit) 

Cela fonctionne:

*(.text.exit); 

Est-ce une fonction manquante dans gold? ou est-ce que je fais quelque chose de mal, peut-être qu'il y a une autre façon de faire référence à un symbole spécifique d'un fichier objet spécifique dans une archive en utilisant gold?

Répondre

0

Lors de la pose des symboles dans l'espace d'adressage à l'aide d'un script de liaison, ld permet de se référer à un symbole spécifique provenant d'un fichier objet spécifique dans une bibliothèque statique avec la syntaxe suivante:

archive. a: fichier_objet.o (.section.symbol_name)

Ce n'est pas tout à fait ce que cette syntaxe signifie. Lorsque vous voyez ".section.symbol_name" dans le script de l'éditeur de liens (ou dans une liste objdump ou objdump), c'est le nom complet de la section, et vous verrez seulement les sections avec des noms comme ça si vous utilisez l'option -function-sections lors de la compilation. Étant donné que votre script fonctionne avec ld, et si vous utilisez juste le nom de fichier complet wild card avec or, il semble que vos bibliothèques musl ont été compilées avec -fonction-sections, mais ce n'est pas quelque chose que vous pouvez toujours supposer est true pour les bibliothèques système. Ainsi, l'éditeur de liens ne cherche pas vraiment une section nommée ".text" qui définit un symbole nommé "exit" - à la place, , elle cherche simplement une section nommée ".text.exit". Subtile différence, mais vous devriez être au courant.

Maintenant, alors qu'aucun de ces travaux d'or: MUSL/lib/libc.a: exit.o (.text.exit); musl/lib/libc.a (.text.exit); Ce code fonctionne: * (. Text.exit);

Est-ce une caractéristique manquante dans l'or? ou est-ce que je fais quelque chose de mal, peut-être qu'il y a une autre façon de faire référence à un symbole spécifique d'un fichier objet spécifique dans une archive en utilisant de l'or?

Si vous regardez le fichier de sortie -Carte résultant, je pense que vous verrez le nom du fichier objet est écrit « MUSL/lib/libc.a (exit.o) ». C'est l'orthographe que vous devez utiliser dans le script, et à cause des parenthèses , vous devez le citer. Ceci:

"musl/lib/libc.a(exit.o)"(.text.exit) 

devrait fonctionner. Si vous voulez quelque chose qui fonctionne dans les deux linkers, essayez quelque chose comme ceci:

"musl/lib/libc.a*exit.o*"(.text.exit) 

ou tout simplement

"*exit.o*"(.text.exit) 
+0

Merci beaucoup, la syntaxe en utilisant des citations a travaillé. J'ai également vérifié les drapeaux de compilation de musl et, en effet, ceux-ci incluent des sections -ffunction. –