ld.so.preload não difere x86_32 e x86_64

1

- É sabido que você pode executar programas x86_32 com o kernel x86_64 se ele foi compilado com suporte para isso. Mas o vinculador dinâmico não fornece nenhuma maneira de definir um conjunto separado de bibliotecas de pré-carregamento para programas de 32 bits, portanto, toda vez que você executar esse programa, tiver x86_64 pré-carregamentos, enfrentará essa mensagem de erro:

ERROR: ld.so: object '… … …' from /etc/ld.so.preload cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.

Caso você coloque lá a mesma lista de bibliotecas x86_32 para pré-carregar, você poderia fazê-lo funcionar, mas todas as execuções x86_64 puras também começariam a reclamar.

A melhor maneira possível é modificar o carregador dinâmico para suportar o pré-carregamento a partir de arquivos separados, obviamente, mas é pelo menos um processo demorado. Você consegue pensar em alguma solução limpa?…

Por enquanto, estou pensando em um pouco de multi-class-pre-load.so , que poderia carregar os arquivos necessários por si só, mas, como eu posso ver, não há suporte para "várias classes" no ELF.

    
por poige 13.09.2014 / 20:44

2 respostas

5

Em seu ld.so.preload, você deseja especificar "$ LIB" em seu caminho, em vez de um "lib" ou "lib64" explícito. Assim, em uma distro no estilo Redhat, "/usr/alternates/$LIB/libfoo.so" se torna "/usr/alternates/lib/libfoo.so" para um processo de 32 bits e "/ usr / alternates / lib64 / libfoo.so "para um processo de 64 bits. Em uma distro no estilo Debian, "/usr/alternates/$LIB/libfoo.so" se torna "/usr/alternates/lib/i386-linux-gnu/libfoo.so" e "/ usr / alternates / x86_64-linux- gnu / libfoo.so "respectivamente. Sua árvore precisa ser preenchida com bibliotecas para as duas arquiteturas.

Veja "expansão do token rpath" na página do manual ld.so (8) para mais sobre isso.

Note, no entanto, que ao invés de pré-carregar uma biblioteca, se você está compilando os binários cujo carregamento você está tentando modificar, você pode achar melhor modificar os caminhos definindo DT_RUNPATH na linha de link (usando os mesmos caminhos de estilo "$ LIB", configurando assim o binário para preferir a localização da sua biblioteca sobre os padrões do sistema.

Como alternativa, como outros notaram, você pode editar um arquivo ELF para definir DT_RUNPATH em binários que não esteja compilando.

O seguinte funciona para mim em uma caixa x86_64 do Centos 6.5:

cd /tmp
mkdir lib lib64
wget http://carrera.databits.net/~ksb/msrc/local/lib/snoopy/snoopy.h
wget http://carrera.databits.net/~ksb/msrc/local/lib/snoopy/snoopy.c
gcc -m64 -shared -fPIC -ldl snoopy.c -o /tmp/lib64/snoopy.so
gcc -m32 -shared -fPIC -ldl snoopy.c -o /tmp/lib/snoopy.so
cat > true.c <<EOF
int main(void)
{ return 0; }
EOF
gcc -m64 true.c -o true64
gcc -m32 true.c -o true32
sudo bash -c "echo '/tmp/\$LIB/snoopy.so' > /etc/ld.so.preload"
strace -fo /tmp/strace64.out /tmp/true64
strace -fo /tmp/strace32.out /tmp/true32
sudo rm /etc/ld.so.preload"

Na saída strace, o strace64.out possui:

open("/tmp/lib64/snoopy.so", O_RDONLY) = 3

enquanto o strace32.out possui:

open("/tmp/lib/snoopy.so", O_RDONLY) = 3

Isto é com um conteúdo ld.so.preload de:

/tmp/$LIB/snoopy.so
    
por 23.09.2014 / 03:36
-1

O pré-carregamento não se destina a fazer parte da operação normal de um sistema. Normalmente, você deve vincular as bibliotecas que deseja usar.

As poucas pessoas que precisam pré-carregar quando executam programas de múltiplos arcos assumem que não se importam com as mensagens de erro inofensivas.

Como alternativa, desde que seus programas não estejam iniciando outros programas de arcos diferentes, você poderá usar melhor LD_PRELOAD apenas em torno dos programas que possuem seções de biblioteca incorretas.

Mas, na verdade, é melhor consertar as bibliotecas conforme listadas no arquivo ELF, de preferência no estágio de compilação, mas existem ferramentas para editar os ELFs mais tarde.

(Nota: no começo eu pensei que sua pergunta seria sobre x64_32, que é completamente diferente e tem alguns bugs interessantes)

    
por 14.09.2014 / 07:21