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
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top