In LINUX determinare se una libreria / archivio .a 32 bit o 64 bit?


87

Distribuiamo in Linux una libreria statica nelle versioni a 64 bit e 32 bit. Durante la risoluzione dei problemi di un cliente, vorrei che il mio script della shell diagnostica eliminasse rapidamente il problema controllando il file di archivio .a per determinare se è a 32 o 64 bit. I metodi che mi vengono in mente sono meno che eleganti:

  1. estrai un membro .o e chiedi il comando "file" (es. ELF a 32 bit ecc.)

  2. inizia a includere un membro fittizio codificato per indicare, ad esempio 32bit.o / 64bit.o e usa "ar -t" per controllare

Ho provato "strings xyz.a | grep 32" ma non funziona bene con le versioni. Non è un problema che spezza il cuore, ma se conosci una soluzione elegante, mi piacerebbe saperlo.


Conosco stackoverflow.com/questions/184502/… , alla ricerca di una soluzione migliore.
cvsdave

2
La soluzione nell'altra domanda sembra affrontare il problema abbastanza chiaramente, ma un modo rapido è nm foo.a | grep '^ 0' | testa -1 | wc -c - se il risultato è 17 (16 + 1 == 8 byte + 1 carattere per ritorno riga), è 64 bit, se è 9 è 32 bit (8 + 1 == 4 byte + 1 carattere per ritorno riga)
Petesh

E se ottengo 14? o_0
Almo

Risposte:


123

objdump sembra il modo migliore:

objdump -f libfoo.a | grep ^architecture

1
fileè più facile da leggere come indicato di seguito stackoverflow.com/a/8909086/233906
Cerber

1
Capisco architecture: i386:x86-64, flags 0x00000039:.. significa che sono entrambe le cose ..? è improbabile. per favore aiuto: D
graywolf

10
@Paladin: Questo è 64 bit - le architetture x86 sono descritte da objdump come i386(semplice vecchio IA32), i386:x86-64(AMD64) e i386:x64-32(l'architettura X32 a 32 bit-address-space-in-long-mode).
caf

1
Il flag '-f' in 'objdump' specifica di visualizzare il contenuto dell'intestazione complessiva del file della libreria 'libfoo.a'. Questo output di "objdump" viene quindi reindirizzato al comando grep che cerca la parola "architettura". Il carattere "^" significa che "architettura" dovrebbe iniziare la riga.
Luke Purnell

3
objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u
Puliscilo

33

Il modo più semplice è utilizzare il comando file.

$file <.so file or .a file>

31
nell'ambiente msys questo semplicemente echos <file>: l'archivio ar corrente , non l'architettura di destinazione.
focaccine

11
Allo stesso modo nel mio attuale ambiente Linux (Ubuntu).
Asherah

4
allo stesso modo in centos7
Chaim Geretz

Funziona bene su 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 file .so e un file .a non sono la stessa cosa. Dimostrare che questo funziona per una libreria condivisa non è la stessa cosa che mostrare che funziona con una libreria statica. La domanda originale riguarda una libreria statica (file .a). Nel mio caso (utilizzando MSYS) la soluzione objdump pubblicata da caf funziona in cui l'utilizzo di file stampa solo "ar archive" come gli scones.
Sean Burton,

17

Usa semplicemente il comando file; cioèfile library.so


La domanda è specifica per le librerie statiche.
pooya13

3

oops, quel sed mancante significa che veniva visualizzato da molti elementi.

Solo in una risposta:

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

Come dovrebbe funzionare:

  • nm: ottieni i simboli dalla libreria
  • grep - ottiene le righe che iniziano con una stringa esadecimale (indirizzo del simbolo nel file)
  • head - ottieni la prima riga
  • sed - rimuove tutto ciò che è oltre lo spazio bianco, incluso lo spazio bianco
  • wc - conta il numero di caratteri.

In un ambiente a 32 bit, ottieni indirizzi composti da 8 cifre esadecimali, l'aggiunta della nuova riga ti dà 9, In un ambiente a 64 bit, ottieni indirizzi composti da 16 cifre esadecimali, aggiungendo la nuova riga ti dà 17.


1
Potrebbe voler lanciare un sed -e 's /. * //' lì
dentro

A proposito, ottengo 73. Ti interessa spiegare perché dovrebbe funzionare?
Francesco Dondi

oops, quel sed mancante era importante. Risposta aggiornata, con una spiegazione di come dovrebbe funzionare
Petesh

1

Se ci sono funzioni specifiche per una particolare versione potresti provare nm e poi grep per la funzione.


Potresti essere in grado di scrivere del codice che cerca byte specifici nella libreria. Puoi provare a utilizzare od su entrambi i file e trovare differenze tra i due.
ColWhi

1
Un'altra soluzione sarebbe rinominare le librerie.
ColWhi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.