web-dev-qa-db-fra.com

Comment savoir, avec quelque chose comme objdump, si un fichier objet a été construit avec -fPIC?

Comment savoir, avec quelque chose comme objdump, si un fichier objet a été construit avec -fPIC?

47
Crazy Chenz

La réponse dépend de la plate-forme. Sur la plupart des plateformes, si sortie de

readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'

est vide, alors soit foo.o n'a pas été compilé avec -fPIC, soit foo.o ne contient aucun code où -fPIC est important.

56
Employed Russian

Je devais simplement faire ceci sur une cible PowerPC pour trouver quel objet partagé (.so) était construit sans -fPIC. Ce que j'ai fait était de lancer readelf -d libMyLib1.so et de rechercher TEXTREL. Si vous voyez TEXTREL, un ou plusieurs fichiers source constituant votre .so n'ont pas été générés avec -fPIC. Vous pouvez remplacer readelf par elfdump si nécessaire.

Par exemple.,

[user@Host lib]$ readelf -d libMyLib1.so | grep TEXT   # Bad, not -fPIC
 0x00000016 (TEXTREL)
[user@Host lib]$ readelf -d libMyLib2.so | grep TEXT   # Good, -fPIC
[user@Host lib]$

Et pour aider les personnes à la recherche de solutions, l’erreur que j’obtenais lorsque j’exécutais mon exécutable était la suivante:

root@target:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so:  R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range

Je ne sais pas si cette information s'applique à toutes les architectures.

Source: blogs.Oracle.com/rie

12
indiv

Je suppose que ce que vous voulez vraiment savoir, c'est si une bibliothèque partagée est composée ou non de fichiers objets compilés avec -fPIC.

Comme déjà mentionné, s'il y a des TEXTREL, alors -fPIC n'a pas été utilisé.

Il existe un excellent outil appelé scanelf qui peut vous montrer les symboles qui ont provoqué les délocalisations .text.

Vous trouverez plus d’informations sur HOWTO. Localiser et réparer les relocalisations .text TEXTRELs .

2
Vanuan
 readelf -a * .so | grep Drapeaux 
 Drapeaux: 0x50001007, noreorder, pic, cpic, o32, mips32 

Cela devrait fonctionner la plupart du temps.

2
Ternvein

-fPIC signifie que le code pourra exécuter des adresses différentes de l'adresse pour laquelle elle a été compilée.

Pour ce faire, disasambler ressemblera à ceci ....

call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address

maintenant, nous avons un décalage que nous devons ajouter à tout accès à la mémoire.

load bx, [ax + var_address}
2
CodeWizard

Une autre option pour distinguer si votre programme est généré avec l'option -fPIC:

à condition que votre code ait l'option -g3 -gdwarf-2 activée lors de la compilation.

d'autres formats de débogage gcc peuvent également contenir les informations de macro:

Notez que la syntaxe $ '..' suivante est supposée bash

echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3 
-gdwarf-2 -o test -x c -

readelf --debug-dump=macro ./test | grep __PIC__

une telle méthode fonctionne parce que gcc manual déclare que si -fpic est utilisé,PICest défini sur 1, et si -fPIC est utilisé,PICest égal à 2.

Les réponses ci-dessus en vérifiant que le GOT est le meilleur moyen. Parce que la pré-requête de -g3 -gdwarf-2, je suppose, est rarement utilisée.

0
zhaorufei