In LINUX feststellen, ob eine .a Bibliothek / Archiv 32-Bit oder 64-Bit?

86

Wir vertreiben unter Linux eine statische Bibliothek sowohl in 64-Bit- als auch in 32-Bit-Versionen. Bei der Fehlerbehebung bei einem Kunden möchte ich, dass mein Diagnose-Shell-Skript das Problem schnell beseitigt, indem die .a-Archivdatei überprüft wird, um festzustellen, ob es sich um 32- oder 64-Bit handelt. Die Methoden, die mir einfallen, sind weniger als elegant:

  1. Extrahieren Sie ein .o-Mitglied und fragen Sie den Befehl "file" (z. B. ELF 32-Bit usw.).

  2. Beginnen Sie mit der Aufnahme eines Dummy-Elements, das codiert ist, um anzuzeigen, z. B. 32bit.o / 64bit.o, und verwenden Sie "ar-t", um dies zu überprüfen

Ich habe "Strings xyz.a | grep 32" ausprobiert, aber dies funktioniert nicht gut über Versionen. Kein Herzensbrecherproblem, aber wenn Sie eine elegante Lösung kennen, würde ich gerne wissen.

cvsdave
quelle
Ich kenne stackoverflow.com/questions/184502/… und suche nach einer besseren Lösung.
cvsdave
2
Die Lösung in der anderen Frage scheint das Problem recht ordentlich anzugehen, aber ein schneller Weg ist nm foo.a | grep '^ 0' | Kopf -1 | wc -c - Wenn das Ergebnis 17 ist (16 + 1 == 8 Byte + 1 Zeichen für Zeilenrückgabe), ist es 64 Bit, wenn es 9 ist, ist es 32 Bit (8 + 1 == 4 Byte + 1 Zeichen für
Zeilenrückgabe
Was ist, wenn ich 14 bekomme? o_0
Almo

Antworten:

123

objdump scheint der beste Weg zu sein:

objdump -f libfoo.a | grep ^architecture
caf
quelle
1
fileist leichter zu lesen, wie unten angegeben stackoverflow.com/a/8909086/233906
Cerber
1
Ich architecture: i386:x86-64, flags 0x00000039:verstehe ... bedeutet das, dass es beides ist ...? das ist unwahrscheinlich Bitte helfen Sie: D
Graywolf
10
@Paladin: Das ist 64-Bit - die x86-Architekturen werden von objdump als i386(einfaches altes IA32), i386:x86-64(AMD64) und i386:x64-32(X32-32-Bit-Adressraum-im-Langmodus-Architektur) beschrieben.
Café
1
Das Flag '-f' in 'objdump' gibt an, dass der Inhalt des gesamten Dateikopfs der Bibliothek 'libfoo.a' angezeigt werden soll. Diese Ausgabe von 'objdump' wird dann in den Befehl grep geleitet, der nach dem Wort 'Architektur' sucht. Das Zeichen '^' bedeutet, dass 'Architektur' die Zeile beginnen soll.
Luke Purnell
3
Bereinige es und entferne Dupes: objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u:)
legends2k
33

Am einfachsten ist es, den Befehl file zu verwenden.

$file <.so file or .a file>
pankaj kapoor
quelle
31
In der msys-Umgebung gibt dies einfach <Datei> wieder: aktuelles Archiv , nicht die Zielarchitektur.
Scones
11
Ebenso in meiner aktuellen Linux (Ubuntu) Umgebung.
Asherah
4
ebenfalls in centos7
Chaim Geretz
Es funktioniert gut unter 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
Eine .so-Datei und eine .a-Datei sind nicht dasselbe. Das Zeigen, dass dies für eine gemeinsam genutzte Bibliothek funktioniert, ist nicht dasselbe wie das Zeigen, dass es mit einer statischen Bibliothek funktioniert. Die ursprüngliche Frage bezieht sich auf eine statische Bibliothek (.a-Datei). In meinem Fall (mit MSYS) funktioniert die von caf veröffentlichte objdump-Lösung, bei der die Verwendung von Dateien nur "ar archive" druckt, wie es Scones tun.
Sean Burton
17

Verwenden Sie einfach den Befehl file. dhfile library.so

Erik
quelle
Die Frage ist speziell für statische Bibliotheken.
pooya13
3

Hoppla, das fehlende Sed bedeutet, dass es vielen Gegenständen angezeigt wurde.

Nur in einer Antwort:

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

Wie es funktionieren soll:

  • nm - holt die Symbole aus der Bibliothek
  • grep - Zeilen abrufen, die mit einer Hex-Zeichenfolge beginnen (Adresse des Symbols in der Datei)
  • Kopf - Holen Sie sich die erste Zeile
  • sed - Entfernen Sie alles hinter dem Leerzeichen, einschließlich des Leerzeichens
  • wc - Zähle die Anzahl der Zeichen.

In einer 32-Bit-Umgebung erhalten Sie Adressen, die aus 8 hexadezimalen Ziffern bestehen. Wenn Sie die neue Zeile hinzufügen 9, erhalten Sie Adressen. In einer 64-Bit-Umgebung erhalten Sie Adressen, die aus 16 hexadezimalen Ziffern bestehen. Wenn Sie die neue Zeile hinzufügen, erhalten Sie 17.

Petesh
quelle
1
Vielleicht möchten Sie ein sed -e 's /. * //' da
reinwerfen
Ich bekomme übrigens 73. Möchten Sie erklären, warum es funktionieren sollte?
Francesco Dondi
Ups, das fehlende Sed war wichtig. Antwort aktualisiert, mit einer Erklärung, wie es funktionieren soll
Petesh
1

Wenn es Funktionen gibt, die für eine bestimmte Version spezifisch sind, können Sie nm ausprobieren und dann nach der Funktion suchen.

ColWhi
quelle
Möglicherweise können Sie Code schreiben, der nach bestimmten Bytes in der Bibliothek sucht. Sie können versuchen, od für beide Dateien zu verwenden und Unterschiede zwischen den beiden zu finden.
ColWhi
1
Eine andere Lösung wäre, die Bibliotheken umzubenennen.
ColWhi