Dans LINUX, déterminer si une bibliothèque / archive .a 32 bits ou 64 bits?

87

Nous distribuons sous Linux une bibliothèque statique dans les versions 64 bits et 32 ​​bits. Lors du dépannage d'un client, j'aimerais que mon script shell de diagnostic élimine rapidement le problème en vérifiant le fichier d'archive .a pour déterminer s'il s'agit de 32 ou 64 bits. Les méthodes qui me viennent à l'esprit sont loin d'être élégantes:

  1. extraire un membre .o et demander la commande "file" (par exemple, ELF 32 bits, etc.)

  2. commencez par inclure un membre factice codé pour indiquer, par exemple 32bit.o / 64bit.o et utilisez "ar -t" pour vérifier

J'ai essayé "strings xyz.a | grep 32" mais cela ne fonctionne pas bien avec les versions. Ce n'est pas un problème qui brise le cœur, mais si vous connaissez une solution élégante, j'aimerais savoir.

cvsdave
la source
Je connais stackoverflow.com/questions/184502/… , à la recherche d'une meilleure solution.
cvsdave le
2
La solution dans l'autre question semble aborder le problème assez clairement, mais un moyen rapide est nm foo.a | grep '^ 0' | tête -1 | wc -c - si le résultat est 17 (16 + 1 == 8 octets + 1 caractère pour le retour de ligne), c'est 64 bits, si c'est 9 c'est 32 bits (8 + 1 == 4 octets + 1 caractère pour le retour de ligne)
Petesh
Et si j'en ai 14? o_0
Almo

Réponses:

123

objdump semble être le meilleur moyen:

objdump -f libfoo.a | grep ^architecture
caf
la source
1
fileest plus facile à lire comme indiqué ci-dessous stackoverflow.com/a/8909086/233906
Cerber
1
Je reçois architecture: i386:x86-64, flags 0x00000039:... cela veut dire que c'est les deux ...? c'est peu probable. s'il vous plaît aider: D
graywolf
10
@Paladin: C'est 64 bits - les architectures x86 sont décrites par objdump comme i386(ancien IA32), i386:x86-64(AMD64) et i386:x64-32(l'architecture X32 32-bit-address-space-in-long-mode).
caf
1
L'indicateur '-f' dans 'objdump' spécifie d'afficher le contenu de l'en-tête de fichier global de la bibliothèque 'libfoo.a'. Cette sortie de «objdump» est ensuite envoyée dans la commande grep qui recherche le mot «architecture». Le caractère «^» signifie que «architecture» doit commencer la ligne.
Luke Purnell
3
Nettoyez-le et supprimez les dupes: objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u:)
legends2k
33

Le moyen le plus simple consiste à utiliser la commande file.

$file <.so file or .a file>
Pankaj Kapoor
la source
31
dans l'environnement msys, cela fait simplement écho à <file>: archive ar actuelle , pas l'architecture cible.
scones
11
De même dans mon environnement Linux (Ubuntu) actuel.
Asherah
4
de même dans centos7
Chaim Geretz
Cela fonctionne très bien sur Ubuntu 16.04. (1) file armeabi/libpique.so-> libpique.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped. (2) file x86/libpique.so->libpique.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
rpattabi
5
Un fichier .so et un fichier .a ne sont pas la même chose. Montrer que cela fonctionne pour une bibliothèque partagée n'est pas la même chose que montrer que cela fonctionne avec une bibliothèque statique. La question d'origine concerne une bibliothèque statique (fichier .a). Dans mon cas (en utilisant MSYS), la solution objdump publiée par caf fonctionne où l'utilisation d'un fichier imprime simplement «ar archive» de la même manière que scones.
Sean Burton
17

Utilisez simplement la commande file; c'est à direfile library.so

Erik
la source
La question concerne spécifiquement les bibliothèques statiques.
pooya13
3

oups, ce sed manquant signifie qu'il s'affichait sur de nombreux éléments.

Juste en réponse:

count=$(nm foo.a | grep '^0' | head -1 | sed 's/ .*//' | wc -c)
((count == 17)) && echo 64bit
((count == 9)) && echo 32bit
((count == 0)) && echo '??bit'

Comment ça marche:

  • nm - récupère les symboles de la bibliothèque
  • grep - récupère les lignes commençant par une chaîne hexadécimale (adresse du symbole dans le fichier)
  • head - obtenez la première ligne
  • sed - supprime tout ce qui dépasse l'espace blanc, y compris l'espace blanc
  • wc - compte le nombre de caractères.

Dans un environnement 32 bits, vous obtenez des adresses composées de 8 chiffres hexadécimaux, l'ajout de la nouvelle ligne vous donne 9, Dans un environnement 64 bits, vous obtenez des adresses composées de 16 chiffres hexadécimaux, l'ajout de la nouvelle ligne vous donne 17.

Petesh
la source
1
Pourrait vouloir lancer un sed -e 's /. * //' là
dedans
J'en ai 73 au fait. Voulez-vous expliquer pourquoi cela devrait fonctionner?
Francesco Dondi
oups, ce sed manquant était important. Réponse mise à jour, avec une explication de la façon dont cela est censé fonctionner
Petesh
1

S'il existe des fonctions spécifiques à une version particulière, vous pouvez essayer nm puis grep pour la fonction.

ColWhi
la source
Vous pourrez peut-être écrire du code qui recherche des octets spécifiques dans la bibliothèque. Vous pouvez essayer d'utiliser od sur les deux fichiers et trouver des différences entre les deux.
ColWhi
1
Une autre solution serait de renommer les bibliothèques.
ColWhi