Preciso vincular o programa C em um objeto compartilhado sem cabeçalhos de seção
-
22-09-2019 - |
Pergunta
Escrevi uma interface para o gerador de código que me permite produzir objetos compartilhados. Embora eu não queira implementar o suporte para a tabela de cabeçalho da seção, porque é aí que a complexidade da maioria do formato de arquivo ELF permanece.
O GNU LD usa cabeçalhos de seção para vincular objetos compartilhados. Isso significa que, quando tento colocar o link do GCC no meu objeto compartilhado sem cabeçalhos de seção, ele falha porque o LD não encontra os símbolos, mesmo que existam na biblioteca.
Existe algum truque que eu poderia usar para enganar o compilador para fazer com que a ligação seja bem -sucedida, mesmo que não encontrasse certos símbolos?
Aqui estão alguns esclarecimentos sobre o problema:
cheery@ruttunen:~/Documents/g386$ gcc dev/shared_test.c -L. -lshared -m32
/tmp/cc6qBViY.o: In function `main':
shared_test.c:(.text+0xa): undefined reference to `example_function'
collect2: ld returned 1 exit status
cheery@ruttunen:~/Documents/g386$ cat dev/shared_test.c
// gcc shared_test.c -L. -lshared -m32
// LD_LIBRARY_PATH=. ./a.out
#include <stdio.h>
extern int example_function();
int main(){
printf("hello %d\n", example_function());
}
cheery@ruttunen:~/Documents/g386$ readelf -D -s libshared.so
Symbol table for image:
Num Buc: Value Size Type Bind Vis Ndx Name
2 0: 00800164 0 FUNC GLOBAL DEFAULT ABS example_function
1 0: 008000ac 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
Solução 2
A melhor abordagem aqui é adicionar as tabelas de seção exigidas pelo GCC. Se você possui um mecanismo dinâmico de vinculação dinâmico em seu gerador, ele requer todas as mesmas informações que você inseriria nas tabelas de seção.
Para a preguiça, escrevi um arquivo de montagem compartilhado e usei o comando de strip para obter um ponto de referência. ´readFelf - -Sections 'mostra algumas seções, mas você não precisa de todas elas. Trabalhei com isso e implementei seções para começar a funcionar corretamente. Aqui está o que eu tinha que acrescentar:
cheery@ruttunen:~/Documents/g386$ readelf --sections dynamic_hello.app
There are 5 section headers, starting at offset 0x1b9:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .shstrndx STRTAB 00000000 000281 000024 00 0 0 1
[ 2] .dynamic DYNAMIC 00000000 0000b0 000050 08 WA 3 0 4
[ 3] .dynstr STRTAB 00000000 000158 000020 00 A 0 0 1
[ 4] .dynsym DYNSYM 00000000 000100 000040 10 A 3 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Não dói se você colocar mais seções do que essas, mas isso é suficiente para obter a ligação dinâmica funcionando.
Outras dicas
O GCC (ou seja, LD atrás do GCC) possui uma opção de linha de comando para ignorar externos não resolvidos. Isso suprimirá a mensagem de erro que você recebe do GCC. Não tenho certeza se isso vai te fazer feliz.