48

Abbiamo un problema relativo a un'applicazione Java in esecuzione su un (piuttosto vecchio) FC3 su una scheda Advantech POS con un processore Via C3. L'applicazione java ha diverse librerie condivise compilate a cui si accede tramite JNI.Determinazione dell'architettura di destinazione del file binario in Linux (libreria o eseguibile)

Il processore Via C3 è compatibile con i686. Qualche tempo fa, dopo aver installato Ubuntu 6.10 su una scheda MiniItx con lo stesso processore, ho scoperto che l'affermazione precedente non è vera al 100%. Il kernel di Ubuntu si è bloccato all'avvio a causa della mancanza di alcune istruzioni specifiche e facoltative del set i686 nel processore C3. Queste istruzioni mancanti nell'implementazione C3 del set i686 vengono utilizzate per impostazione predefinita dal compilatore GCC quando si utilizzano le ottimizzazioni i686. La soluzione in questo caso era di andare con una versione compilata i386 della distribuzione di Ubuntu.

Il problema di base con l'applicazione Java è che la distribuzione FC3 è stata installata sull'HD clonando da un'immagine dell'HD di un altro PC, questa volta un Intel P4. Successivamente la distribuzione aveva bisogno di hacking per farlo funzionare come la sostituzione di alcuni pacchetti (come quello del kernel) con la versione compilata i383.

Il problema è che dopo aver lavorato per un po 'il sistema si blocca completamente senza lasciare traccia. Temo che alcuni codici i686 vengano lasciati da qualche parte nel sistema e possano essere eseguiti in modo casuale in qualsiasi momento (ad esempio dopo il ripristino dalla modalità di sospensione o qualcosa del genere).

La mia domanda è:

  • C'è qualche strumento o un modo per scoprire a quale specifica architettura è un file binario (eseguibile o libreria) finalizzato a condizione che "file di" non dà così tante informazioni ?

risposta

13

Penso che sia necessario uno strumento che controlli ogni istruzione, per determinare esattamente a quale set appartiene. Esiste persino un nome ufficiale per il set specifico di istruzioni implementato dal processore C3? In caso contrario, è ancora più peloso.

Una variante quick'n'dirty potrebbe essere quella di eseguire una ricerca non elaborata nel file, se è possibile determinare il modello di bit delle istruzioni non consentite. Basta provare direttamente per loro, potrebbe essere fatto da una semplice catena objdump | grep, per esempio.

+3

objdump -d dovrebbe ottenere una rappresentazione ASM, quindi è possibile grep per opcode non validi. –

+0

Penso che andrò come ti proponi. Ho solo bisogno di scoprire come decompilare vmlinuz (non posso essere sicuro se il kernel stesso sia la versione i386 o i686). –

+0

+1. Non è molto utile nel mio caso, ma mi piace molto questo modo hacky! –

89

Il comando 'file' di unix.linux è ottimo per questo. In genere è in grado di rilevare l'architettura di destinazione e il sistema operativo per un dato binario (ed è stato mantenuto attivo e disattivato dal 1973. wow!)

Naturalmente, se non si esegue sotto unix/linux - sei un un po 'bloccato Attualmente sto cercando di trovare una porta basata su Java che posso chiamare in fase di runtime .. ma non ho avuto tanta fortuna.

comando Unix 'file' fornisce informazioni in questo modo:

esadecimale: ELF a 32 bit LSB eseguibile, ARM, versione 1 (SYSV), collegato dinamicamente (usa librerie condivise), per GNU/Linux 2.4.17, non spogliato

Informazioni più dettagliate sui dettagli dell'architettura sono accennato con la (unix) comando 'objdump -f' che restituisce:

architettura: braccio, bandiere 0x00000112: EXEC_P, HAS_SYMS, D_PAGED iniziare 0x0000876c indirizzo

Questo eseguibile è stato compilato da un cross compiler GCC (compilato su una macchina I86 per il processore ARM come target)

+2

sono arrivato da una ricerca casuale di Google, ed è stato un grande aiuto, da parte – aaronstacy

+4

La domanda chiede in particolare di andare oltre ** file ** ma sono venuto qui sulla base del titolo e ** file ** è esattamente quello che volevo.Quindi è discutibile se questa è davvero una buona risposta, perché non ha risposto alla reale qeustion, ma ha risposto alla mia e apparentemente anche aaronstacy! – patrickvacek

+2

(Ho aggiunto alcune informazioni su (unix) comando 'objdump -f' che va oltre il comando 'file'. Purtroppo non so cosa significano i bit nelle 'bandiere' - probabilmente è necessario cercare il codice gcc per (o usarli per confrontare l'impostazione su vari computer di destinazione)) – Ribo

26

decido di aggiungere una soluzione in più per qualsiasi, che ha ottenuto qui: personalmente nel mio caso l'informazione provi ded con il file e objdump non era abbastanza, e il grep non è molto di aiuto - Risolvo il mio caso attraverso il readelf -a -W.

Nota, questo ti dà molte informazioni. Le informazioni relative all'arco risiedono proprio all'inizio e alla fine. Ecco un esempio:

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 
+0

Disclaimer: funziona solo se sai già che il file è un file ELF. I binari di Mach-O (che girano su iPhone e MacBook) sono un esempio di un formato binario che non è ELF. – ryanrhee

+0

@ryanrhee bene, se non sai ancora se ELF o no, poi dopo aver eseguito il comando saprai sicuramente ☺ –

+1

Se vuoi solo le informazioni di architettura, puoi usare 'readelf -A' –

4

espansione su @ risposta di Hi-Angel ho trovato un modo semplice per controllare la larghezza po 'di una libreria statica:

readelf -a -W libsomefile.a | grep Class: | sort | uniq 

Dove libsomefile.a è la mia libreria statica. Dovrebbe funzionare anche per altri file ELF.

5

Per rispondere all'ambiguità del fatto che Via C3 sia un processore di classe i686: non lo è, è un processore di classe i586.

Cyrix non ha mai prodotto un vero processore di classe 686, nonostante le loro dichiarazioni di marketing con le parti 6x86MX e MII. Tra le altre istruzioni mancanti, due di quelle importanti che non avevano erano CMPXCHG8b e CPUID, a cui era richiesto di eseguire Windows XP e oltre.

National Semiconductor, AMD e VIA hanno prodotto tutti i progetti di CPU basati sul core Cyrix 5x86/6x86 (NxP MediaGX, AMD Geode, VIA C3/C7, VIA Corefusion, ecc.) Che hanno portato a progetti stravaganti in cui si hanno un processore di classe 586 con set di istruzioni SSE1/2/3.

La mia raccomandazione se si incontra una delle CPU sopra elencate e non è per un progetto di computer vintage (ad esempio Windows 98SE e versioni precedenti) quindi scappare via urlando da esso. Sarai bloccato su lenta i386/486 Linux o dovrai ricompilare tutto il tuo software con le ottimizzazioni specifiche di Cyrix.

1

cosa più rapido per trovare l'architettura sarebbe quello di eseguire:

objdump -f testFile | grep architecture 

questo funziona anche per i binari.