En LINUX determine si una biblioteca / archivo .a de 32 bits o de 64 bits

87

Distribuimos en Linux una biblioteca estática en versiones de 64 y 32 bits. Al solucionar problemas de un cliente, me gustaría que mi script de shell de diagnóstico elimine rápidamente el problema comprobando el archivo .a para determinar si es de 32 o 64 bits. Los métodos que se me ocurren son menos que elegantes:

  1. extraer un miembro .o y pedir el comando "archivo" (por ejemplo, ELF de 32 bits, etc.)

  2. comience a incluir un miembro ficticio codificado para indicar, por ejemplo, 32bit.o / 64bit.o y use "ar -t" para verificar

He probado "strings xyz.a | grep 32" pero esto no funciona bien en versiones. No es un problema rompecorazones, pero si conoces una solución elegante, me gustaría saberlo.

cvsdave
fuente
Conozco stackoverflow.com/questions/184502/… , buscando una mejor solución.
cvsdave
2
La solución en la otra pregunta parece abordar el problema con bastante claridad, pero una forma rápida es nm foo.a | grep '^ 0' | cabeza -1 | wc -c - si el resultado es 17 (16 + 1 == 8bytes + 1 carácter para retorno de línea), es 64 bits, si es 9 es 32 bits (8 + 1 == 4bytes + 1 carácter para retorno de línea)
Petesh
¿Y si obtengo 14? o_0
Almo

Respuestas:

123

objdump parece la mejor manera:

objdump -f libfoo.a | grep ^architecture
coste y flete
fuente
1
filees más fácil de leer como se indica a continuación stackoverflow.com/a/8909086/233906
Cerber
1
Entiendo architecture: i386:x86-64, flags 0x00000039:... ¿significa que son ambos ...? eso es poco probable. por favor ayuda: D
graywolf
10
@Paladin: Eso es 64 bits: objdump describe las arquitecturas x86 como i386(IA32 antiguo simple), i386:x86-64(AMD64) y i386:x64-32(la arquitectura X32 de 32 bits, espacio de direcciones en modo largo).
Café
1
El indicador '-f' en 'objdump' especifica que se muestre el contenido del encabezado general del archivo de la biblioteca 'libfoo.a'. Esta salida de 'objdump' luego se canaliza al comando grep que busca la palabra 'arquitectura'. El carácter '^' significa que 'arquitectura' debe comenzar la línea.
Luke Purnell
3
Límpielo y elimine a los incautos: objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u:)
legends2k
33

La forma más sencilla es utilizar el comando de archivo.

$file <.so file or .a file>
pankaj kapoor
fuente
31
en el entorno msys esto simplemente echos <archivo>: archivo ar actual , no la arquitectura de destino.
bollos
11
Asimismo, en mi entorno actual de Linux (Ubuntu).
Asera
4
igualmente en centos7
Jaim Geretz
Funciona bien en 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 archivo .so y un archivo .a no son lo mismo. Mostrar que esto funciona para una biblioteca compartida no es lo mismo que mostrar que funciona con una biblioteca estática. La pregunta original es sobre una biblioteca estática (archivo .a). En mi caso (usando MSYS), la solución objdump publicada por caf funciona donde el uso de archivos solo imprime 'ar archive' de la misma manera que los scones.
Sean Burton
17

Simplemente use el comando de archivo; es decirfile library.so

Erik
fuente
La pregunta es específicamente para bibliotecas estáticas.
pooya13
3

Vaya, ese sed que falta significa que se estaba mostrando en muchos elementos.

Solo en una respuesta:

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

Cómo se supone que funciona:

  • nm: obtenga los símbolos de la biblioteca
  • grep: obtiene líneas que comienzan con una cadena hexadecimal (dirección del símbolo en el archivo)
  • head - obtén la primera línea
  • sed: elimina todo lo que pasa más allá del espacio en blanco, incluido el espacio en blanco
  • wc - cuente el número de caracteres.

En un entorno de 32 bits, obtiene direcciones compuestas por 8 dígitos hexadecimales, al agregar la nueva línea obtendrá 9, En un entorno de 64 bits, obtiene direcciones compuestas por 16 dígitos hexadecimales, al agregar la nueva línea obtendrá 17.

Petesh
fuente
1
Podría querer lanzar un sed -e 's /. * //' allí
kowey
Por cierto, tengo 73. ¿Te importaría explicar por qué debería funcionar?
Francesco Dondi
Vaya, ese sed que faltaba era importante. Respuesta actualizada, con una explicación de cómo se supone que funciona
Petesh
1

Si hay funciones que son específicas de una versión en particular, puede probar nm y luego grep para la función.

ColWhi
fuente
Es posible que pueda escribir algún código que busque bytes específicos en la biblioteca. Puede intentar usar od en ambos archivos y encontrar diferencias entre los dos.
ColWhi
1
Otra solución sería cambiar el nombre de las bibliotecas.
ColWhi