60 votes

Comment lister les dépendances de bibliothèque d'un binaire non natif ?

Lorsque je développe pour une plateforme native, je peux utiliser ldd pour lister toutes les bibliothèques partagées (fichiers .so) qu'un exécutable binaire que je construis essaiera de charger au démarrage. Mais lors de la compilation croisée, je ne sais pas comment obtenir les mêmes informations. Le site ldd n'est pas un utilitaire binutils normal, comme strip o ar qui peuvent être construits à côté de gcc pour la compilation croisée, mais au lieu de cela, c'est un shell cryptique script qui apparemment ne peut être exécuté que sur une plateforme native.

Donc, en utilisant les outils binutils multi-cibles, existe-t-il un moyen d'obtenir une liste des dépendances liées dynamiquement d'un binaire étranger ?

84voto

Employed Russian Points 50479

Existe-t-il un moyen d'obtenir une liste des dépendances liées dynamiquement pour un binaire étranger ?

Vous pouvez énumérer direct dépendances d'un binaire assez facilement :

readelf -d a.out | grep NEEDED

 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Je ne connais aucun moyen de poursuivre récursivement cette opération pour obtenir la liste complète (comme ldd fait). Vous devrez répéter le processus pour chaque NEEDED bibliothèque à la main.

0 votes

readelf -d /home/oglop/Downloads/shadowsocks-libev_2.3.1_mipsel_OpenSSL‌​_dynamic/ss-local There is no dynamic section in this file. Je savais que c'était dynamique, mais pourquoi ?

0 votes

@Shuman Vous êtes probablement en train de regarder un shell script. Si ce n'est pas le cas, vous devriez poser une question distincte.

15voto

Basile Starynkevitch Points 67055

Vous pouvez faire bash -x ldd /bin/ls pour comprendre ce que ldd fait. Le site ldd script n'est pas si "cryptique". En gros, il exécute

LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /bin/ls

donc il utilise le chargeur dynamique du système (car le résultat de ldd dépend de votre environnement et de votre système !) Mais vous pouvez examiner avec objdump -x /bin/ls la section dynamique d'un exécutable, par ex.

% objdump -x /bin/ls
  /bin/ls:     file format elf64-x86-64
  /bin/ls
  architecture: i386:x86-64, flags 0x00000112:
  EXEC_P, HAS_SYMS, D_PAGED
  start address 0x00000000004046d4

  Program Header:
      PHDR off    0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
           filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags r-x
    INTERP off    0x0000000000000200 vaddr 0x0000000000400200 paddr 0x0000000000400200 align 2**0
           filesz 0x000000000000001c memsz 0x000000000000001c flags r--
      LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
           filesz 0x0000000000019ef4 memsz 0x0000000000019ef4 flags r-x
      LOAD off    0x000000000001a000 vaddr 0x000000000061a000 paddr 0x000000000061a000 align 2**21
           filesz 0x000000000000077c memsz 0x0000000000001500 flags rw-
   DYNAMIC off    0x000000000001a028 vaddr 0x000000000061a028 paddr 0x000000000061a028 align 2**3
           filesz 0x00000000000001d0 memsz 0x00000000000001d0 flags rw-
      NOTE off    0x000000000000021c vaddr 0x000000000040021c paddr 0x000000000040021c align 2**2
           filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
  EH_FRAME off    0x0000000000017768 vaddr 0x0000000000417768 paddr 0x0000000000417768 align 2**2
           filesz 0x00000000000006fc memsz 0x00000000000006fc flags r--
     STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
           filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

  Dynamic Section:
    NEEDED               libselinux.so.1
    NEEDED               librt.so.1
    NEEDED               libacl.so.1
    NEEDED               libc.so.6
    INIT                 0x0000000000402148
    FINI                 0x00000000004125f8
    HASH                 0x0000000000400260
    GNU_HASH             0x00000000004005c0
    STRTAB               0x0000000000401100
    SYMTAB               0x0000000000400620
    STRSZ                0x00000000000004d7
    SYMENT               0x0000000000000018
    DEBUG                0x0000000000000000
    PLTGOT               0x000000000061a208
    PLTRELSZ             0x0000000000000990
    PLTREL               0x0000000000000007
    JMPREL               0x00000000004017b8
    RELA                 0x0000000000401740
    RELASZ               0x0000000000000078
    RELAENT              0x0000000000000018
    VERNEED              0x00000000004016c0
    VERNEEDNUM           0x0000000000000003
    VERSYM               0x00000000004015d8

  Version References:
    required from librt.so.1:
      0x09691a75 0x00 05 GLIBC_2.2.5
    required from libacl.so.1:
      0x05822452 0x00 06 ACL_1.2
      0x05822450 0x00 04 ACL_1.0
    required from libc.so.6:
      0x09691a75 0x00 03 GLIBC_2.2.5
      0x0d696913 0x00 02 GLIBC_2.3

Encore une fois, la dépendance réelle dépend du système sur lequel votre binaire est exécuté (par exemple, parce que je pourrais avoir un fichier LD_LIBRARY_PATH avec mon propre libc.so.6 quelque part, ce qui serait une mauvaise idée).

Vous avez donc besoin d'une variante croisée de objdump

0 votes

Votre explication n'a pas expliqué quelle partie d'objdump que le PO doit regarder. De plus, la version native readelf -d peut lire les binaires ELF non natifs, il n'est donc pas nécessaire de construire cross-readelf ou cross-objdump (bien qu'ils soient généralement utilisés dans les cas suivants sont construit dans le cadre de crosstool de toute façon).

5voto

Alors que dans gdb , informations partagées est similaire à ldd . Il donne des informations complètes et lisibles par l'homme sur l'exécution de l'exécutable.
readelf serait chemin de miss et autres informations sur les bibliothèques .
readelf est un très bon outil pour l'étude de l'hôte. Le développeur peut choisir ce qui fonctionne.

1voto

user2220054 Points 31

C'est un peu tard pour cet ajout mais quelqu'un pourrait en bénéficier ou le clarifier. L'option -A de readelf ne donne-t-elle pas le même résultat que ldd ?

    $ readelf -AW /bin/vi

Library list section '.gnu.liblist' contains 8 entries:
     Library              Time Stamp          Checksum   Version Flags
  0: libselinux.so.1      2011-07-25T08:02:58 0x17a7d5f7 0       0
  1: libtermcap.so.2      2011-07-25T08:02:59 0x29ae9ff7 0       0
  2: libacl.so.1          2011-07-25T08:02:58 0x60748842 0       0
  3: libc.so.6            2011-07-25T08:02:58 0x0c2c7eeb 0       0
  4: libdl.so.2           2011-07-25T08:02:58 0xdfbfc467 0       0
  5: libsepol.so.1        2011-07-25T08:02:58 0x857499cb 0       0
  6: /lib64/ld-linux-x86-64.so.2 2011-07-25T08:02:58 0x9e6549b7 0       0
  7: libattr.so.1         2011-07-25T08:02:58 0x862f1546 0       0

La seule information manquante ici semble être le chemin complet où se trouvent ces bibliothèques.

D'autre part, les outils mentionnés jusqu'à présent ne sont utiles qu'une fois que vous avez une installation connue pour fonctionner. Mes problèmes les plus courants sont les suivants :

  1. Installation d'un programme (le plus souvent via rpm) qui ne démarre pas ou se bloque au démarrage. D'une manière ou d'une autre, je pense que cela est lié à des incompatibilités de bibliothèques, mais je n'ai pas trouvé de moyen facile de vérifier ces choses avant d'installer un programme (ni même après).
  2. Pour tenter de surmonter le problème (1), j'ai parfois eu recours au téléchargement des sources et à la compilation locale. Le configure script typique est partiellement utile car il vous indique les bibliothèques qui vous manquent. Cependant, il ne vous dit pas quelle est la version la plus basse de ces bibliothèques.

Quelqu'un peut-il m'éclairer sur ces questions ? BTW, j'ai essayé de lire les instructions d'installation et les notes de mise à jour mais elles sont presque toujours loin d'être suffisantes.

Un exemple robuste peut mettre tout en contexte, alors essayez de compiler Cinelerra .

0voto

Patrice Tisserand Points 331

Pour lister les dépendances des bibliothèques partagées d'un binaire non natif, vous pouvez essayer l'outil suivant : http://www.mathembedded.com/component/k2/item/1-cross-ldd.html

Je l'utilise sur SH4 et MIPS. Comme indiqué dans une autre réponse, vous pouvez réaliser la même chose en utilisant la sortie readelf et une boucle récursive, mais je n'ai jamais essayé par moi-même depuis que cross-ldd existe.

0 votes

C'est une URL morte pour le moment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X