Invocando um script com ld-linux.so?

3

Acabei de fazer o download de um arquivo tar que deve incluir tudo o que é necessário para executar um programa que possamos chamar some_binary . Eu extraí o conteúdo e vejo o seguinte:

  • Um binário (vamos chamá-lo de some_binary )
  • Uma pasta lib com várias bibliotecas dinâmicas (arquivos .so), como /lib/ld-linux-x86-64.so
  • e um script de shell chamado some_binary.sh

O script tem o seguinte conteúdo:

#!/bin/bash
'dirname "$0"'/lib/ld-linux-x86-64.so.2   'dirname "$0"'/some_binary "$@"

e executá-lo como ./some_binary.sh some arguments parece executar ./some_binary corretamente. Curiosamente, executando o seguinte script:

#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"

como ./my_script.sh some arguments não funciona. Isso resulta em erros de realocação (símbolos indefinidos), presumivelmente do carregamento incorreto das bibliotecas em ./lib

Além disso, a execução das duas instruções a seguir a partir da linha de comando resulta em segmentation fault :

> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments

Com isso, minhas perguntas são:

  1. O que o primeiro script faz?
  2. Por que obtenho resultados diferentes nessas três tentativas? e por que não posso simplesmente adicionar $pwd/lib a LD_LIBRARY_PATH e depois executar some_binary diretamente?
por Amelio Vazquez-Reina 24.04.2013 / 01:47

2 respostas

3

O programa vem com seu próprio carregador dinâmico . É muito raro que os programas precisem de seu próprio carregador dinâmico: normalmente, o do seu sistema também funcionará. Isso pode ser necessário se o programa estiver ligado a uma biblioteca padrão diferente do GNU libc ou se estiver ligado a um GNU libc compilado com configurações estranhas.

Pode ser o suficiente para informar ao carregador onde encontrar as bibliotecas preferidas do programa. Sua tentativa quase faz isso, mas não é bem assim. Se LD_LIBRARY_PATH ainda não estiver no ambiente, a atribuição LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH define apenas uma variável de shell, não uma variável de ambiente, portanto, o programa não vê nada. Além disso, $CWD normalmente se expande para a sequência vazia, você provavelmente quis dizer $PWD ou melhor $(dirname "$0") (ou seja, o diretório que contém o script). Tenha também em atenção que utilizou lib e LIB de forma inconsistente na sua pergunta. Experimente

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"

ou melhor, para evitar uma entrada vazia no final de LD_LIBRARY_PATH , se não tiver sido definida antes (isso pode ser ruim porque uma entrada vazia representa o diretório atual, embora no final do caminho seja apenas prejudicial se uma biblioteca não for encontrada onde deveria estar):

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"
    
por 24.04.2013 / 04:05
-1

Use patchelf para definir o intérprete.

patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 <path-to-clang>
    
por 01.10.2018 / 14:49