que - Determine la arquitectura de destino del archivo binario en Linux(biblioteca o ejecutable)
no se puede ejecutar el fichero binario (6)
Tenemos un problema relacionado con una aplicación Java que se ejecuta bajo un FC3 (bastante antiguo) en una placa POS de Advantech con un procesador Via C3. La aplicación Java tiene varias librerías compiladas compiladas a las que se accede a través de JNI.
Se supone que el procesador Via C3 es compatible con i686. Hace algún tiempo, después de instalar Ubuntu 6.10 en una placa MiniItx con el mismo procesador, descubrí que la declaración anterior no es 100% verdadera. El núcleo de Ubuntu se colgó al inicio debido a la falta de algunas instrucciones específicas y opcionales del i686 en el procesador C3. Estas instrucciones que faltan en la implementación C3 del conjunto i686 son utilizadas por defecto por el compilador GCC cuando se usan optimizaciones i686. La solución en este caso fue ir con una versión compilada i386 de la distribución de Ubuntu.
El problema básico con la aplicación Java es que la distribución de FC3 se instaló en la HD clonando desde una imagen de la HD de otra PC, esta vez una Intel P4. Posteriormente, la distribución necesitó algunos ataques para que se ejecutara, como la sustitución de algunos paquetes (como el kernel) por la versión compilada de i383.
El problema es que después de trabajar por un tiempo, el sistema se cuelga completamente sin dejar rastro. Me temo que algún código de i686 se deja en algún lugar del sistema y se puede ejecutar de forma aleatoria en cualquier momento (por ejemplo, después de la recuperación desde el modo de suspensión o algo así).
Mi pregunta es:
- ¿Hay alguna herramienta o forma de averiguar en qué arquitectura específica se encuentra un archivo binario (ejecutable o biblioteca) siempre que el " archivo " no brinde tanta información?
Creo que necesita una herramienta que verifique cada instrucción, para determinar exactamente a qué conjunto pertenece. ¿Hay incluso un nombre oficial para el conjunto específico de instrucciones implementadas por el procesador C3? Si no, es aún más peludo.
Una variante quick''n''dirty puede ser realizar una búsqueda en bruto en el archivo, si puede determinar el patrón de bits de las instrucciones no permitidas. Solo prueba para ellos directamente, podría hacerse con un simple objdump | grep
objdump | grep
chain, por ejemplo.
El comando ''file'' de unix.linux es ideal para esto. En general, puede detectar la arquitectura de destino y el sistema operativo para un binario determinado (y se ha mantenido activo y desactivado desde 1973. ¡guau!)
Por supuesto, si no estás usando Unix / Linux, estás un poco atascado. Actualmente estoy tratando de encontrar un puerto basado en Java al que pueda llamar en tiempo de ejecución ... pero no tuve tanta suerte.
El comando ''archivo'' de unix proporciona información como esta:
hex: ELF 32 bits LSB ejecutable, ARM, versión 1 (SYSV), enlazado dinámicamente (utiliza bibliotecas compartidas), para GNU / Linux 2.4.17, no eliminado
Se hace alusión a información más detallada sobre los detalles de la arquitectura con el comando (unix) ''objdump -f'' que devuelve:
arquitectura: brazo, indicadores 0x00000112: EXEC_P, HAS_SYMS, D_PAGED dirección de inicio 0x0000876c
Este ejecutable fue compilado por un compilador cruzado gcc (compilado en una máquina i86 para el procesador ARM como un objetivo)
Decido agregar una solución más para cualquiera, que llegó aquí: personalmente, en mi caso, la información proporcionada por el file
y objdump
no fue suficiente, y el grep
no es de mucha ayuda. readelf -a -W
mi caso a través de la readelf -a -W
.
Tenga en cuenta que esto le da bastante información. La información relacionada con el arco reside desde el principio y hasta el final. Aquí hay un ejemplo:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2''s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x83f8
Start of program headers: 52 (bytes into file)
Start of section headers: 2388 (bytes into file)
Flags: 0x5000202, has entry point, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28
...
Displaying notes found at file offset 0x00000148 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.16
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "7-A"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_rounding: Needed
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP
Tag_CPU_unaligned_access: v6
Ampliando la respuesta de @Hy-Angel, encontré una manera fácil de verificar el ancho de bits de una biblioteca estática:
readelf -a -W libsomefile.a | grep Class: | sort | uniq
Donde libsomefile.a
es mi biblioteca estática. Debería funcionar también para otros archivos ELF.
Para responder a la ambigüedad de si un Via C3 es un procesador de clase i686: No lo es, es un procesador de clase i586.
Cyrix nunca produjo un verdadero procesador de clase 686, a pesar de sus reclamos de comercialización con las partes 6x86MX y MII. Entre otras instrucciones faltantes, dos importantes que no tenían eran CMPXCHG8b y CPUID, que eran necesarias para ejecutar Windows XP y más allá.
National Semiconductor, AMD y VIA han producido diseños de CPU basados en el núcleo Cyrix 5x86 / 6x86 (NxP MediaGX, AMD Geode, VIA C3 / C7, VIA Corefusion, etc.) que han dado lugar a diseños raros donde tienes un procesador de clase 586 con conjuntos de instrucciones SSE1 / 2/3.
Mi recomendación si te encuentras con alguna de las CPU mencionadas anteriormente y no es para un proyecto de computadora vintage (es decir, Windows 98SE y anteriores) y luego corres gritando lejos de ella. Te quedarás atrapado en i386 / 486 Linux lento o tendrás que recompilar todo tu software con optimizaciones específicas de Cyrix.
Lo más rápido para encontrar arquitectura sería ejecutar:
objdump -f testFile | grep architecture
Esto funciona incluso para binario.