Comment puis-je savoir, avec quelque chose comme objdump, si un fichier objet a été construit avec-fPIC?
Comment puis-je savoir, avec quelque chose comme objdump
, si un fichier objet a été construit avec -fPIC
?
6 réponses
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 foo.o
n'a pas été compilé avec -fPIC
, ou foo.o
ne contient aucun code où -fPIC
importe.
j'ai juste eu à le faire sur une cible PowerPC pour trouver quel objet partagé (.donc) a été construit sans-fPIC. Ce que j'ai fait, c'est courir lire moi-même libMyLib1.so and look for TEXTREL. Si vous voyez TEXTREL, un ou plusieurs fichiers source qui composent votre .donc n'ont pas été construits 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 aider les gens à la recherche de solutions, l'erreur que j'ai eue quand j'ai lancé mon exécutable était celle-ci:
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
je suppose, ce que vous voulez vraiment savoir est si oui ou non une bibliothèque partagée est composée à partir de fichiers objets compilés avec-fPIC.
comme déjà mentionné, s'il y a des TEXTRELs, alors-fPIC n'a pas été utilisé.
il y a un grand outil appelé scanelf qui peut vous montrer les symboles qui ont causé .texte de délocalisations.
pour de plus amples informations, veuillez consulter HOWTO Locate and Fix .text Relocations TEXTRELs .
readelf -a *.so | grep Flags Flags: 0x50001007, noreorder, pic, cpic, o32, mips32
Cela devrait fonctionner la plupart du temps.
- fPIC signifie que le code sera capable d'exécuter sous une forme différente l'adresse pour laquelle il a été compilé.
pour le faire , disastrambler ressemblera à ceci....
call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address
maintenant dans ax nous avons un offset que nous devons ajouter à n'importe quel accès à la mémoire.
load bx, [ax + var_address}
une autre option pour distinguer si votre programme est généré wit-fPIC option:
à condition que votre code ait l'option-g3-gdwarf-2 activée lors de la compilation.
autre format de débogage gcc peut également contenir la macro info:
Notez les points suivants $'..'syntaxe est assume 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 le manuel gcc déclare que si-fpic est utilisé, PIC est défini à 1, et si-fPIC utilisé, PIC est 2.
Les réponses ci-dessus en cochant le GOT est la meilleure façon de faire. Parce que le prérequis de-G3-gdwarf-2 je suppose que rarement utilisé.