Esta seção é um pouco curta no momento; ela será expandida com o tempo conforme eu estude o Como Fazer ELF
O Linux tem bibliotecas compartilhadas, como você, neste ponto, deve estar cansado de ouvir, se você leu toda a última seção de uma vez só. Uma parte do trabalho de combinar-nomes-com-lugares que era tradicionalmente feito em tempo de linkagem deve ser postergado para o tempo de carregamento.
Envie para mim os seus erros de linkagem! Eu não farei qualquer coisa a respeito deles, mas eu poderia escrevê-los ...
(Somente a.out) Isto significa que você não tem a versão maior correta da biblioteca xxx. Não, você não pode apenas fazer um link simbólico para outra versão que você tem; se você tem sorte isto irá fazer com que seu programa gere uma falha de segmentação. Obtenha a nova versão. Uma situação similar com ELF irá resultar em uma mensagem como
ftp: can't load library 'libreadline.so.2'
|
(Somente a.out) Você tem uma versão menor mais antiga da biblioteca, do que a pessoa que compilou o programa em uso. O programa ainda irá executar. Provavelmente. Uma atualização não doeria, entretanto.
Existe um grupo de variáveis de ambiente às quais o carregador dinâmico irá responder. A maioria delas é mais útil para ldd do que elas são para o usuário médio, e podem ser definidas de forma mais conveniente executando ldd com várias opções. Elas incluem
LD_BIND_NOW --- normalmente, funções não são `pesquisadas' em bibliotecas até que elas sejam chamadas. Definir esta flag faz com que todas as pesquisas aconteçam quando a biblioteca é carregada, resultando em um tempo de inicialização maior. Ela é útil quando você quer testar o programa para ter certeza que tudo está linkado.
LD_PRELOAD pode ser definida com o nome de um arquivo contendo definições de funções `alternativas'. Por exemplo, se você estivesse testando estratégias de alocação de memória, e quisesse substituir `malloc', você poderia escrever a sua rotina de substituição, compilá-la em malloc.o e então
$ LD_PRELOAD=malloc.o; export LD_PRELOAD
$ some_test_program
|
LD_LIBRARY_PATH é uma lista, separada por dois-pontos, de diretórios nos quais deve-se procurar por bibliotecas compartilhadas. Ela não afeta ld; ela tem efeito apenas em tempo de execução. Também, ela é desabilitada para programas que executam setuid ou setgid. Novamente, LD_ELF_LIBRARY_PATH e LD_AOUT_LIBRARY_PATH também podem ser usadas para dirigir a pesquisa de forma distinta para diferentes sabores de binários. LD_LIBRARY_PATH não deveria ser necessária em operação normal; ao invés disso, adicione os diretórios a /etc/ld.so.conf/ e execute novamente ldconfig.
LD_NOWARN aplica-se apenas a a.out. Quando definida (por exemplo com LD_NOWARN=true; export LD_NOWARN) ela impede o carregador de emitir avisos não-fatais (tais como mensagens de incomtabilidade de versão menor).
LD_WARN aplica-se apenas a ELF. Quando definida, ela transforma as mensagens ``Can't find library'', usualmente fatais, em avisos. Ela não é muito útil em operação normal, mas é importante para ldd.
LD_TRACE_LOADED_OBJECTS aplica-se apenas a ELF, e faz com que os programas pensem que estão sendo executados sob ldd:
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
|
Isto é muito próximo da maneira que o suporte a carregamento dinâmico do Solaris 2.x trabalha, se você é familiar com aquele. Ele é coberto extensivamente no documento ELF programming de H. J. Lu, e na página de manual do dlopen(3), a qual pode ser encontrada no pacote ld.so. Aqui está um exemplo singelo entretanto: linke-o com -ldl
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call=dlsym(libc,"printf");
(*printf_call)("hello, world\n");
}
}
|