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ć.


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

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>

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


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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.