2015-09-11 2 views
1

Veuillez suivre l'exemple suivant. J'ai un code C++ que je veux compiler sous powerpc et générer le code binaire.Où sont stockées les entrées de relocalisation dans les binaires plats?

#include <stdio.h> 

int function(int x); 
int myfunction(int x); 

int main() 
{ 
    int x = function(2); 
    int y = myfunction(2); 

    return x + y; 
} 

int function(int x) 
{ 
    return x * myfunction(x); 
} 

int myfunction(int x) 
{ 
    return x; 
} 

J'ai deux appels de fonctions: call function(2) et call myfunction(2). Je compile ce code C++ sous powerpc‍‍‍. Donc, maintenant j'utilise le objdump pour obtenir l'assemblage derrière le fichier objet et qui est la suivante:

00000000 <main>: 
    0: 94 21 ff e0  stwu r1,-32(r1) 
    4: 7c 08 02 a6  mflr r0 
    8: 93 e1 00 1c  stw r31,28(r1) 
    c: 90 01 00 24  stw r0,36(r1) 
    10: 7c 3f 0b 78  mr r31,r1 
    14: 38 60 00 02  li r3,2 
    18: 48 00 00 01  bl 18 <main+0x18> 
    1c: 7c 60 1b 78  mr r0,r3 
    20: 90 1f 00 08  stw r0,8(r31) 
    24: 38 60 00 02  li r3,2 
    28: 48 00 00 01  bl 28 <main+0x28> 
    2c: 7c 60 1b 78  mr r0,r3 
    30: 90 1f 00 0c  stw r0,12(r31) 
    34: 80 1f 00 08  lwz r0,8(r31) 
    38: 81 3f 00 0c  lwz r9,12(r31) 
    3c: 7c 00 4a 14  add r0,r0,r9 
    40: 7c 03 03 78  mr r3,r0 
    44: 48 00 00 0c  b 50 <main+0x50> 
    48: 38 60 00 00  li r3,0 
    4c: 48 00 00 04  b 50 <main+0x50> 
    50: 81 61 00 00  lwz r11,0(r1) 
    54: 80 0b 00 04  lwz r0,4(r11) 
    58: 7c 08 03 a6  mtlr r0 
    5c: 83 eb ff fc  lwz r31,-4(r11) 
    60: 7d 61 5b 78  mr r1,r11 
    64: 4e 80 00 20  blr 

00000068 <function__Fi>: 
    68: 94 21 ff e0  stwu r1,-32(r1) 
    6c: 7c 08 02 a6  mflr r0 
    70: 93 e1 00 1c  stw r31,28(r1) 
    74: 90 01 00 24  stw r0,36(r1) 
    78: 7c 3f 0b 78  mr r31,r1 
    7c: 90 7f 00 08  stw r3,8(r31) 
    80: 80 7f 00 08  lwz r3,8(r31) 
    84: 48 00 00 01  bl 84 <function__Fi+0x1c> 
    88: 7c 60 1b 78  mr r0,r3 
    8c: 81 3f 00 08  lwz r9,8(r31) 
    90: 7c 00 49 d6  mullw r0,r0,r9 
    94: 7c 03 03 78  mr r3,r0 
    98: 48 00 00 0c  b a4 <function__Fi+0x3c> 
    9c: 48 00 00 08  b a4 <function__Fi+0x3c> 
    a0: 48 00 00 04  b a4 <function__Fi+0x3c> 
    a4: 81 61 00 00  lwz r11,0(r1) 
    a8: 80 0b 00 04  lwz r0,4(r11) 
    ac: 7c 08 03 a6  mtlr r0 
    b0: 83 eb ff fc  lwz r31,-4(r11) 
    b4: 7d 61 5b 78  mr r1,r11 
    b8: 4e 80 00 20  blr 

000000bc <myfunction__Fi>: 
    bc: 94 21 ff e0  stwu r1,-32(r1) 
    c0: 93 e1 00 1c  stw r31,28(r1) 
    c4: 7c 3f 0b 78  mr r31,r1 
    c8: 90 7f 00 08  stw r3,8(r31) 
    cc: 80 1f 00 08  lwz r0,8(r31) 
    d0: 7c 03 03 78  mr r3,r0 
    d4: 48 00 00 04  b d8 <myfunction__Fi+0x1c> 
    d8: 81 61 00 00  lwz r11,0(r1) 
    dc: 83 eb ff fc  lwz r31,-4(r11) 
    e0: 7d 61 5b 78  mr r1,r11 
    e4: 4e 80 00 20  blr 

La chose intéressante qui me demandait est la ligne qui n'appelle la fonction:

18: 48 00 00 01  bl 18 <main+0x18> 
    ... 
    28: 48 00 00 01  bl 28 <main+0x28> 

Comme vous voyez, les deux sont le code binaire "48 00 00 01", mais on appelle function et un autre appelle myfunction. Le problème est que comment nous pouvons trouver le call target. Comme je l'ai trouvé, les cibles d'appel sont écrites sur RELOCATION ENTRIES. Oh, tout va bien, j'utilise la commande ci-dessous pour générer les entrées de réinstallation et est la suivante:

RELOCATION RECORDS FOR [.text]: 
OFFSET TYPE    VALUE 
00000018 R_PPC_REL24  function__Fi 
00000028 R_PPC_REL24  myfunction__Fi 
00000084 R_PPC_REL24  myfunction__Fi 

Cette entrées sont utiles pour trouver la cible d'appel. Maintenant, j'utilise la commande objcopy -O binary pour générer le fichier binaire brut (binaire plat).

objcopy -O binary object-file 

Mon object-file est le elf32-powerpc. Le fichier binaire de sortie représenté dans le bloc suivant:

2564 0000 2564 0a00 93e1 001c 9001 0024 
7c3f 0b78 3860 0002 4800 0001 7c60 1b78 
901f 0008 3860 0002 4800 0001 7c60 1b78 
901f 000c 801f 0008 2c00 0002 4182 003c 
2c00 0002 4181 0010 2c00 0001 4182 0014 
4800 0058 2c00 0003 4182 0038 4800 004c 
3d20 0000 3869 0000 389f 0008 4cc6 3182 
4800 0001 4800 004c 3d20 0000 3869 0004 
3880 0014 4cc6 3182 4800 0001 4800 0034 
3d20 0000 3869 0004 3880 001e 4cc6 3182 
4800 0001 4800 001c 3d20 0000 3869 0004 
3880 0028 4cc6 3182 4800 0001 4800 0004 
3860 0000 4800 0004 8161 0000 800b 0004 
7c08 03a6 83eb fffc 7d61 5b78 4e80 0020 
9421 ffe0 7c08 02a6 93e1 001c 9001 0024 
7c3f 0b78 907f 0008 807f 0008 4800 0001 
7c60 1b78 813f 0008 7c00 49d6 7c03 0378 
4800 000c 4800 0008 4800 0004 8161 0000 
800b 0004 7c08 03a6 83eb fffc 7d61 5b78 
4e80 0020 9421 ffe0 93e1 001c 7c3f 0b78 
907f 0008 801f 0008 7c03 0378 4800 0004 
8161 0000 83eb fffc 7d61 5b78 4e80 0020 

Nous pouvons trouver le 4800 0001 là-dessus. Mais il n'y a pas de relocation entries. Quelqu'un peut-il s'il vous plaît me dire comment puis-je trouver le relocation entries?

Merci à l'avance.

+1

Vous ne pouvez pas, 'objcopy'ing à binaire va les enlever. – slugonamission

+0

Alors, comment est-ce utile? –

Répondre

1

Vos entrées de relocalisation sont ignorées lorsque vous faites l'objcopy. Dans le manuel:

objcopy peut être utilisée pour générer un fichier binaire en utilisant une cible de sortie binaire (par exemple, utiliser -O binaire). Lorsque objcopy génère un fichier binaire brut, il produira essentiellement une image mémoire du contenu du fichier objet d'entrée. Tous les symboles et informations de relocalisation seront mis au rebut . Le vidage de la mémoire commence à l'adresse de chargement de la section la plus basse copiée dans le fichier de sortie.

Pour votre binaire brut soit utile, vous avez quelques options:

Vous pouvez effectuer les réinstallations au cours du processus de construction, de sorte que votre binaire brut est prêt à fonctionner. Cependant, cela signifie que le fichier binaire doit être exécuté à une adresse fixe en mémoire.

Alternativement, vous pouvez produire un fichier objet qui ne nécessite pas de relocalisation - toutes les références d'adresse doivent être relatives. Recherchez "code indépendant de la position" pour plus de détails.Enfin, vous pouvez également utiliser un autre moyen de générer le binaire brut (à la place ou en plus de l'étape objcopy), qui inclut la table de relocalisation dans le fichier de sortie, puis demander à votre code de les traiter manuellement. délocalisations à l'exécution.

Le choix dépendra de ce que vous essayez de faire et des contraintes de votre environnement d'exécution.