No LINUX, determine se uma biblioteca / arquivo .a de 32 bits ou 64 bits?

87

Distribuímos no Linux uma biblioteca estática nas versões de 64 e 32 bits. Ao solucionar problemas de um cliente, gostaria que meu script de shell de diagnóstico eliminasse rapidamente o problema, verificando o arquivo .a para determinar se ele é de 32 ou 64 bits. Os métodos que me ocorrem são menos que elegantes:

  1. extrair um membro .o e solicitar o comando "arquivo" (por exemplo, ELF de 32 bits etc)

  2. comece incluindo um membro fictício codificado para indicar, por exemplo, 32bit.o / 64bit.o e use "ar -t" para verificar

Eu tentei "strings xyz.a | grep 32", mas isso não funciona bem nas versões. Não é um problema destruidor de corações, mas se você souber de uma solução elegante, eu gostaria de saber.

cvsdave
fonte
Eu sei sobre stackoverflow.com/questions/184502/… , procurando uma solução melhor.
cvsdave
2
A solução na outra questão parece resolver o problema de maneira bastante precisa, mas uma maneira rápida é nm foo.a | grep '^ 0' | head -1 | wc -c - se o resultado for 17 (16 + 1 == 8 bytes + 1 caractere para retorno de linha), é 64 bits, se for 9 é 32 bits (8 + 1 == 4 bytes + 1 caractere para retorno de linha)
Petesh
E se eu obtiver 14? o_0
Almo

Respostas:

123

objdump parece ser a melhor maneira:

objdump -f libfoo.a | grep ^architecture
caf
fonte
1
fileé mais fácil de ler conforme indicado abaixo stackoverflow.com/a/8909086/233906
Cerber
1
Eu entendo architecture: i386:x86-64, flags 0x00000039:.. isso significa que são os dois ..? isso é improvável. por favor ajude: D
graywolf
10
@Paladin: Isso é de 64 bits - as arquiteturas x86 são descritas pelo objdump como i386( IA32 antigo simples), i386:x86-64(AMD64) e i386:x64-32(a arquitetura X32 de espaço de endereço de 32 bits em modo longo).
café de
1
O sinalizador '-f' em 'objdump' especifica a exibição do conteúdo do cabeçalho geral do arquivo da biblioteca 'libfoo.a'. Esta saída de 'objdump' é então canalizada para o comando grep que procura pela palavra 'arquitetura'. O caractere '^' significa que 'arquitetura' deve iniciar a linha.
Luke Purnell
3
Limpe e remova objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u
ingênuos
33

A maneira mais simples é usar o comando file.

$file <.so file or .a file>
pankaj kapoor
fonte
31
no ambiente msys, isso simplesmente echos <file>: arquivo ar atual , não a arquitetura de destino.
scones
11
Da mesma forma em meu ambiente Linux (Ubuntu) atual.
Asherah
4
da mesma forma em centos7
Chaim Geretz
Funciona bem no 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
Um arquivo .so e um arquivo .a não são a mesma coisa. Mostrar que isso funciona para uma biblioteca compartilhada não é o mesmo que mostrar que funciona com uma biblioteca estática. A questão original é sobre uma biblioteca estática (arquivo .a). No meu caso (usando MSYS), a solução objdump postada por caf funciona onde usar arquivo apenas imprime 'ar archive' da mesma forma que scones obtém.
Sean Burton
17

Basta usar o comando file; iefile library.so

Erik
fonte
A questão é especificamente para bibliotecas estáticas.
pooya13, 01 de
3

opa, aquele sed ausente significa que ele estava sendo exibido para muitos itens.

Apenas em uma resposta:

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

Como deve funcionar:

  • nm - obtém os símbolos da biblioteca
  • grep - obtém linhas começando com uma string hexadecimal (endereço do símbolo no arquivo)
  • head - pegue a primeira linha
  • sed - remove tudo além do espaço em branco, incluindo o espaço em branco
  • wc - conta o número de caracteres.

Em um ambiente de 32 bits, você obtém endereços compostos de 8 dígitos hexadecimais, adicionando a nova linha 9, você obtém . Em um ambiente de 64 bits, você obtém endereços compostos de 16 dígitos hexadecimais, adicionando a nova linha 17.

Petesh
fonte
1
Pode querer lançar um sed -e 's /. * //' lá
kowey
A propósito, recebo 73. Importa-se de explicar porque deve funcionar?
Francesco Dondi de
opa, aquele sed ausente era importante. Resposta atualizada, com uma explicação de como deveria funcionar
Petesh de
1

Se houver funções específicas de uma determinada versão, você pode tentar nm e grep para a função.

ColWhi
fonte
Você pode escrever algum código que procure bytes específicos na biblioteca. Você pode tentar usar od em ambos os arquivos e encontrar diferenças entre os dois.
ColWhi
1
Outra solução seria renomear as bibliotecas.
ColWhi