Em sistemas Linux de 32 bits, chamando isso
$ /lib/libc.so.6
e em sistemas de 64 bits isso
$ /lib/x86_64-linux-gnu/libc.so.6
em um shell, fornece uma saída como esta:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
Por que e como isso acontece, e como é possível fazer o mesmo em outras bibliotecas compartilhadas?
Eu olhei /usr/lib
para encontrar executáveis e encontrei /usr/lib/libvlc.so.5.5.0
. A execução levou a uma falha de segmentação . : - /
Respostas:
Essa biblioteca possui uma
main()
função ou ponto de entrada equivalente e foi compilada de tal maneira que é útil como um objeto executável e como um objeto compartilhado.Aqui está uma sugestão sobre como fazer isso, embora não funcione para mim.
Aqui está outro em resposta a uma pergunta semelhante sobre o SO , que plagiarei descaradamente, ajustarei e acrescentarei um pouco de explicação.
Primeiro, fonte para nossa biblioteca de exemplos
test.c
:Compile que:
Aqui, estamos compilando uma biblioteca compartilhada (
-fPIC
), mas informando ao vinculador que é um executável comum (-pie
) e para tornar sua tabela de símbolos exportável (-Wl,-E
), para que possa ser útil utilizá-la.E, embora
file
diga que é um objeto compartilhado, ele funciona como um executável:Agora precisamos ver se ele realmente pode ser vinculado dinamicamente. Um programa de exemplo
program.c
:Usar
extern
nos impede de criar um cabeçalho. Agora compile isso:Antes de podermos executá-lo, precisamos adicionar o caminho
libtest.so
para o carregador dinâmico:Agora:
E
ldd a.out
mostrará a ligação paralibtest.so
.Note que duvido que seja assim que o glibc é realmente compilado, uma vez que provavelmente não é tão portátil quanto o próprio glibc (veja
man gcc
em relação aos switches-fPIC
e-pie
), mas demonstra o mecanismo básico. Para os detalhes reais, você teria que consultar o makefile de origem.fonte
nm
na biblioteca compartilhada, mas não era uma versão de depuração. Então, por quelibvlc
e outros falham?libc
é uma exceção.ld
elibpthread
.ld.so
é especial de outras maneiras. Até certo ponto, é mais um executável real do que um executável vinculado dinamicamente normal.Vamos procurar uma resposta no repositório glibc aleatório no github. Esta versão fornece um "banner" no arquivo
version.c
.No mesmo arquivo, há alguns pontos interessantes:
__libc_print_version
a função que fornece impressão para imprimir o mesmo texto e símbolo,__libc_main (void)
que está documentado como um ponto de entrada. Portanto, esse símbolo é chamado ao executar a biblioteca.Então, como o vinculador / compilador sabe que essa é exatamente a função do ponto de entrada?
Vamos mergulhar no makefile . Nos sinalizadores de vinculador, há um sinalizador interessante:
Portanto, esse é um sinalizador de vinculador para definir o ponto de entrada na biblioteca. Ao criar uma biblioteca, você pode fornecer um
-e function_name
comportamento executável para criação de vinculador. O que realmente faz? Vejamos o manual (um pouco datado, mas ainda válido) :(a documentação atual pode ser encontrada aqui )
Realmente, o
ld
vinculador cria um executável com função de ponto de entrada se você fornecer a opção de linha de comando-e
(solução mais prática), fornecer símbolo de funçãostart
ou injetar endereço de símbolo no assembler.No entanto, observe que claramente não é garantido que funcione com outros vinculadores (não sei se o lld do llvm tem o mesmo sinalizador). Por que isso deve ser útil para outros fins, além de fornecer informações sobre esse arquivo, não sei.
fonte