Определение целевой архитектуры двоичного файла в Linux (библиотека или исполняемый файл)

У нас есть проблема, связанная с приложением Java, работающим под (довольно старым) FC3 на плате Advantech POS с процессором Via C3. Приложение java имеет несколько скомпилированных разделяемых библиотек, доступ к которым осуществляется через JNI.

Через процессор C3 предполагается, что он совместим с i686. Некоторое время назад после установки Ubuntu 6.10 на плату MiniItx с тем же процессором я узнал, что предыдущий оператор не соответствует 100%. Ядро Ubuntu зависало при запуске из-за отсутствия некоторых конкретных и дополнительных инструкций i686, установленных в процессоре C3. Эти инструкции, отсутствующие в реализации C3 i686, используются по умолчанию компилятором GCC при использовании оптимизаций i686. Решение в этом случае состояло в том, чтобы перейти с i386 скомпилированной версией дистрибутива Ubuntu.

Основная проблема с приложением Java заключается в том, что дистрибутив FC3 был установлен на HD путем клонирования с изображения HD другого ПК, на этот раз Intel P4. После этого дистрибутивам необходимо было немного взломать его, например, заменить некоторые пакеты (например, ядро) на скомпилированную версию i383.

Проблема заключается в том, что после работы какое-то время система полностью висит без следа. Я боюсь, что некоторый код i686 оставлен где-то в системе и может быть выполнен случайным образом в любой момент (например, после восстановления из режима приостановки или что-то в этом роде).

Мой вопрос:

  • Есть ли какой-либо инструмент или способ узнать, какая конкретная архитектура представляет собой двоичный файл (исполняемый файл или библиотеку), при условии, что " файл" не дает столько информации?

Ответ 1

Я думаю, вам нужен инструмент, который проверяет каждую инструкцию, чтобы точно определить, к какому набору она принадлежит. Есть ли даже официальное название для конкретного набора инструкций, реализованных процессором C3? Если нет, это даже более волосатое.

Вариантом quick'n'dirty может быть необработанный поиск в файле, если вы можете определить бит-шаблон запрещенных инструкций. Просто проверьте их непосредственно, можно сделать, например, простой цепочкой objdump | grep.

Ответ 2

Команда unix.linux 'file' отлично подходит для этого. Он может, как правило, определять целевую архитектуру и операционную систему для данного двоичного файла (и поддерживался с 1973 года. Wow!)

Конечно, если вы не работаете под UNIX/Linux, вы немного застряли. В настоящее время я пытаюсь найти порт на основе java, который я могу вызвать во время выполнения. Но такой удачи не было.

Команда unix 'file' предоставляет следующую информацию:

hex: ELF 32-разрядный исполняемый файл LSB, ARM, версия 1 (SYSV), динамически связанный (использует общие библиотеки), для GNU/Linux 2.4.17, не раздевается

Более подробную информацию о деталях архитектуры намекают на команду (unix) 'objdump -f', которая возвращает:

архитектура: рука, флаги 0x00000112: EXEC_P, HAS_SYMS, D_PAGED начальный адрес 0x0000876c

Этот исполняемый файл был скомпилирован кросс-компилятором gcc (скомпилирован на машине i86 для процессора ARM в качестве цели)

Ответ 3

Я решил добавить еще одно решение для любого, кто пришел сюда: лично в моем случае информация, предоставленная file и objdump, была недостаточной, а grep не очень помогает - Я разрешаю свое дело через readelf -a -W.

Обратите внимание, что это дает вам довольно много информации. Информация, связанная с аркой, находится в самом начале и в самом конце. Вот пример:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2 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

Ответ 4

Чтобы ответить на неоднозначность того, является ли Via C3 процессором класса i686: он не является процессором класса i586.

Cyrix никогда не выпускала настоящий процессор класса 686, несмотря на свои маркетинговые претензии с частями 6x86MX и MII. Среди других отсутствующих инструкций два важных из них у них не были: CMPXCHG8b и CPUID, которые должны были запускать Windows XP и выше.

National Semiconductor, AMD и VIA создали все процессоры на базе ядра Cyrix 5x86/6x86 (NxP MediaGX, AMD Geode, VIA C3/C7, VIA Corefusion и т.д.), которые привели к созданию нечетных моделей, в которых у вас есть 586 с наборами инструкций SSE1/2/3.

Моя рекомендация, если вы столкнетесь с одним из перечисленных выше процессоров, и это не для старинного компьютерного проекта (то есть Windows 98SE и ранее), а затем запустите крик от него. Вы застряли на медленном i386/486 Linux или должны перекомпилировать все свое программное обеспечение с оптимизацией Cyrix.

Ответ 5

Расширяясь при ответе @Hi-Angel, я нашел простой способ проверить ширину бита статической библиотеки:

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

Где libsomefile.a - моя статическая библиотека. Должен работать и для других файлов ELF.

Ответ 6

Быстрее всего найти архитектуру:

objdump -f testFile | grep architecture

Это работает даже для двоичных файлов.