В LINUX определить, является ли библиотека / архив .a 32-разрядной или 64-разрядной?

87

Мы распространяем в Linux статические библиотеки как в 64-битной, так и в 32-битной версиях. При устранении неполадок клиента я хотел бы, чтобы мой сценарий диагностической оболочки быстро устранял проблему, проверяя файл архива .a, чтобы определить, является ли он 32-разрядным или 64-разрядным. Методы, которые мне приходят в голову, менее чем элегантны:

  1. извлеките член .o и задайте команду "file" (например, 32-битный ELF и т. д.)

  2. start, включая фиктивный член, закодированный для указания, например, 32bit.o / 64bit.o, и используйте "ar -t" для проверки

Я пробовал "strings xyz.a | grep 32", но это не работает с версиями. Это не страшная проблема, но если вы знаете элегантное решение, я хотел бы знать.

cvsdave
источник
Я знаю о stackoverflow.com/questions/184502/… , ищу лучшее решение.
cvsdave
2
Решение в другом вопросе, кажется, решает проблему довольно четко, но быстрый способ - это nm foo.a | grep '^ 0' | голова -1 | wc -c - если результат 17 (16 + 1 == 8 байтов + 1 символ для возврата строки), это 64 бит, если 9, это 32 бит (8 + 1 == 4 байта + 1 символ для возврата строки)
Питеш,
Что, если я получу 14? o_0
Almo

Ответы:

123

objdump кажется лучшим способом:

objdump -f libfoo.a | grep ^architecture
кафе
источник
1
fileлегче читать, как указано ниже stackoverflow.com/a/8909086/233906
Cerber
1
Я понимаю architecture: i386:x86-64, flags 0x00000039:.. Значит ли это, что и то, и другое ..? это маловероятно. помогите пожалуйста: D
graywolf
10
@Paladin: Это 64-разрядная версия - архитектуры x86 описываются objdump как i386(простой старый IA32), i386:x86-64(AMD64) и i386:x64-32(архитектура X32 с 32-разрядным адресным пространством в длинном режиме).
кафе
1
Флаг '-f' в 'objdump' указывает на отображение содержимого общего заголовка файла библиотеки libfoo.a. Этот вывод из objdump затем передается в команду grep, которая ищет слово «архитектура». Символ «^» означает, что строка должна начинаться с «архитектуры».
Люк Пурнелл
3
Очистите его и удалите дубли: objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u:)
legends2k
33

Самый простой способ - использовать команду file.

$file <.so file or .a file>
панкадж капур
источник
31
в среде msys это просто повторяет <файл>: текущий архив ar , а не целевую архитектуру.
scones
11
Точно так же в моей текущей среде Linux (Ubuntu).
Ашера
4
аналогично в centos7
Хаим Герец
Он отлично работает на 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
Файл .so и файл .a - это не одно и то же. Показать, что это работает для общей библиотеки, не то же самое, что показать, что это работает со статической библиотекой. Исходный вопрос касается статической библиотеки (файл .a). В моем случае (с использованием MSYS) решение objdump, опубликованное caf, работает, где использование файла просто печатает 'ar archive', как и scones.
Шон Бертон,
17

Просто используйте команду file; т.е.file library.so

Эрик
источник
Вопрос конкретно по статическим библиотекам.
pooya13
3

Упс, отсутствие команды sed означает, что она отображалась для многих элементов.

Просто в ответ:

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

Как это должно работать:

  • nm - получить символы из библиотеки
  • grep - получить строки, начинающиеся с шестнадцатеричной строки (адрес символа в файле)
  • голова - получить первую строку
  • sed - удалить все, кроме пробелов, включая пробелы
  • wc - посчитать количество символов.

В 32-битной среде вы получаете адреса, состоящие из 8 шестнадцатеричных цифр, добавление новой строки дает вам. 9В 64-битной среде вы получаете адреса, состоящие из 16 шестнадцатеричных цифр, добавление новой строки дает вам 17.

Питеш
источник
1
Может, захотите добавить туда sed -e 's /. * //'
kowey
Кстати, я получаю 73. Не хотите объяснять, почему это должно работать?
Francesco Dondi
упс, этот отсутствующий sed был важен. Ответ обновлен, с объяснением того, как он должен работать
Питеш
1

Если есть функции, специфичные для конкретной версии, вы можете попробовать nm, а затем grep для функции.

ColWhi
источник
Возможно, вы сможете написать код, который ищет определенные байты в библиотеке. Вы можете попробовать использовать od для обоих файлов и найти различия между ними.
ColWhi
1
Другое решение - переименовать библиотеки.
ColWhi