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.


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

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>

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


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.


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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.