W LINUX ustal, czy biblioteka / archiwum .a jest 32-bitowa czy 64-bitowa?

87

W systemie Linux dystrybuujemy statyczną bibliotekę w wersji 64-bitowej i 32-bitowej. Podczas rozwiązywania problemów z klientem chciałbym, aby mój diagnostyczny skrypt powłoki szybko wyeliminował problem, sprawdzając plik archiwum .a, aby określić, czy jest to plik 32-, czy 64-bitowy. Metody, które mi przychodzą do głowy, są mniej niż eleganckie:

  1. rozpakuj element .o i zapytaj polecenie "plik" (np. 32-bitowy ELF itp.)

  2. zacznij dołączać fikcyjny element członkowski zakodowany w celu wskazania, np. 32bit.o / 64bit.o i użyj „ar -t”, aby sprawdzić

Próbowałem "strings xyz.a | grep 32", ale to nie działa dobrze w wersjach. Nie jest to problem łamania serc, ale jeśli znasz eleganckie rozwiązanie, chciałbym wiedzieć.

cvsdave
źródło
Wiem o stackoverflow.com/questions/184502/… , szukając lepszego rozwiązania.
cvsdave
2
Rozwiązanie drugiego pytania wydaje się dość dobrze rozwiązywać problem, ale szybkim sposobem jest nm foo.a | grep '^ 0' | głowa -1 | wc -c - jeśli wynik to 17 (16 + 1 == 8 bajtów + 1 znak na powrót linii), to jest 64-bitowy, jeśli jest 9 to 32-bitowy (8 + 1 == 4 bajty + 1 znak na powrót linii)
Petesh
A jeśli dostanę 14? o_0
Almo

Odpowiedzi:

123

objdump wydaje się być najlepszym sposobem:

objdump -f libfoo.a | grep ^architecture
kawiarnia
źródło
1
filejest łatwiejszy do odczytania, jak podano poniżej stackoverflow.com/a/8909086/233906
Cerber
1
Rozumiem architecture: i386:x86-64, flags 0x00000039:… czy to znaczy, że to oba…? to mało prawdopodobne. prosze o pomoc: D
graywolf
10
@Paladin: To jest 64-bit - architektury x86 są opisane przez objdump jako i386(zwykły stary IA32), i386:x86-64(AMD64) i i386:x64-32(architektura 32-bitowej przestrzeni adresowej X32 w trybie długim).
kawiarnia
1
Flaga „-f” w „objdump” wskazuje, że ma być wyświetlana zawartość ogólnego nagłówka pliku biblioteki „libfoo.a”. To wyjście z „objdump” jest następnie przesyłane potokiem do polecenia grep, które szuka słowa „architektura”. Znak „^” oznacza, że ​​wiersz powinien zaczynać się od słowa „architektura”.
Luke Purnell
3
Oczyść to i usuń duplikaty: objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u:)
legends2k
33

Najprostszym sposobem jest użycie polecenia plik.

$file <.so file or .a file>
pankaj kapoor
źródło
31
w środowisku msys po prostu wyświetla <file>: bieżące archiwum ar , a nie architekturę docelową.
bułeczki
11
Podobnie w moim obecnym środowisku Linux (Ubuntu).
Asherah
4
podobnie w centos7
Chaim Geretz
Działa dobrze na 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
Plik .so i plik .a to nie to samo. Pokazanie, że to działa w przypadku biblioteki współdzielonej, nie jest tym samym, co pokazanie, że działa ona z biblioteką statyczną. Pierwotne pytanie dotyczy biblioteki statycznej (plik .a). W moim przypadku (używając MSYS) rozwiązanie objdump opublikowane przez caf działa, gdzie użycie pliku po prostu wypisuje 'archiwum ar' tak samo, jak dostajesz scones.
Sean Burton
17

Po prostu użyj polecenia pliku; to znaczyfile library.so

Erik
źródło
Pytanie dotyczy bibliotek statycznych.
pooya13
3

Ups, brakujący sed oznacza, że ​​wyświetlał się on dla wielu elementów.

Tylko w odpowiedzi:

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

Jak to ma działać:

  • nm - pobierz symbole z biblioteki
  • grep - pobierz linie zaczynające się od ciągu szesnastkowego (adres symbolu w pliku)
  • głowa - zdobądź pierwszą linię
  • sed - usuwa wszystko poza spacjami, w tym spacje
  • wc - policz liczbę znaków.

W środowisku 32-bitowym otrzymujesz adresy składające się z 8 cyfr szesnastkowych, dodanie nowej linii daje ci. 9W środowisku 64-bitowym otrzymujesz adresy złożone z 16 cyfr szesnastkowych, po dodaniu nowej linii otrzymasz 17.

Petesh
źródło
1
Może zechcesz wrzucić tam sed -e 's /. * //'
kowey
Nawiasem mówiąc, mam 73. Zastanów się, dlaczego to powinno działać?
Francesco Dondi
Ups, ten brakujący sed był ważny. Odpowiedź zaktualizowana, z wyjaśnieniem, jak to powinno działać
Petesh
1

Jeśli istnieją funkcje, które są specyficzne dla określonej wersji, możesz wypróbować nm, a następnie grep dla funkcji.

ColWhi
źródło
Możesz napisać kod, który szuka określonych bajtów w bibliotece. Możesz spróbować użyć od na obu plikach i znaleźć różnice między nimi.
ColWhi,
1
Innym rozwiązaniem byłaby zmiana nazw bibliotek.
ColWhi