Pergunta

Eu criei uma biblioteca compartilhada (*.so) usando os arquivos de código *.o objeto (código-fonte C) usando o compilador RVDS no Host Windows.

eu ligar este objeto compartilhado com um aplicativo (utilizando gcc para o alvo ARM no host Linux) e obter um executável, que em correr gera falha de segmentação. (Eu sei que tenho de depurá-lo!)

Em vez de criar biblioteca compartilhada, se eu criar uma biblioteca estática com arquivos de origem mesmos, e então ligação com a aplicação, e em seguida, executar o aplicativo funciona bem como esperado.

Então, minhas perguntas são:

  1. Eu preciso exportar símbolos (funções exportados para a aplicação) ou quaisquer outros símbolos, explicitamente, no meu arquivo de origem usando algumas construções para que ele funciona bem quando ligado a uma aplicação? O que é necessário e como posso fazer isso?

  2. Como é compartilhada trabalho biblioteca ?, ou seja, vão os endereços onde as funções serão carregado e executado, será dada na biblioteca ser dado quando a biblioteca é criada. Como o aplicativo (main()) resolver os endereços onde as funções de biblioteca devem ser executadas?

  3. Como funciona uma biblioteca estática, ou seja, como é que esta especificação de endereço e resolver acontecer em caso de biblioteca estática?

Foi útil?

Solução

Este é assim que funciona no Linux:

1) Não, você não precisa fazer nada. Você pode, no entanto, restringir a exportação variáveis ??com o argumento de linha de comando gcc -fvisibility e explicitamente entradas bandeira exportados com o atributo visibilidade.

2) O executável terá uma tabela de todas as funções que importa (estas são todas as funções com visibilidade padrão). O carregador / vinculador irá escolher um endereço para carregar as bibliotecas de e para preencher esta tabela apenas antes de executar, as chamadas para essas funções são chamadas indiretas. (Note que isso vale para objetos compartilhados também)

3) vinculação estática é realizada em ligação em tempo (que é depois de compilar). Os endereços reais são substituídos na assembléia, e eles são chamadas directas.

Nota: Não é a coisa chamada PIC (código independente de posição). AFAIK, este lida com referências a dados / funções no mesmo objeto compartilhado, por isso a necessidade de vinculador não meio de substituição do código da biblioteca ao carregar a biblioteca, da mesma forma que o código não faz quaisquer referências absolutas à sua dados próprios. Você pode tentar experimentar com ele.

Outras dicas

  1. Você não precisa de símbolos de exportação com gcc, já que exporta todos os símbolos por padrão; RVDS pode ou não pode fazer o mesmo, no entanto. Verifique se o seu RVDS documentação do compilador (tentar configurá-lo para ' Relocatable ELF ' output?)

  2. bibliotecas compartilhadas em Linux deve ser relocatable, como o endereço de base é determinado em tempo de execução. Gerando código independente de posição é ideal, uma vez que reduz a quantidade de trabalho necessário para mudar o local da biblioteca. Se sua biblioteca não é Relocatable ele irá acidente (em outras palavras, não tira informações de relocação de seus arquivos de objeto antes de fazer a biblioteca dinâmica). Os símbolos são resolvidos para endereços em tempo de execução após o endereço base é selecionado e referências internas são realocados.

  3. Com bibliotecas estáticas, toda a resolução de símbolo, transferências e atribuição de endereços de carga acontece em tempo de compilação.

Meu único palpite seria que de alguma forma, o código de seu compilador é colocar para fora não é relocatable em tempo de execução. É um mistério para mim como isso poderia acontecer sem quebrar bibliotecas estáticas, bem como, embora ...

Se você está gerando uma biblioteca estática e biblioteca compartilhada diretamente do RVDS, uma opção seria tentar converter essa biblioteca estática para uma biblioteca compartilhada:

gcc -shared -o libfoo.so libfoo.a

Se isto ajudar, então compartilhada vinculador biblioteca de RVDS (ou a sua configuração) é provavelmente quebrado.

Você sabe alguma coisa sobre a causa do acidente?

Uma possibilidade se você estiver carregando a biblioteca compartilhada dinamicamente (por exemplo, via dlopen()) é que você está assumindo que a biblioteca OK carregado quando isso não aconteceu, e, em seguida, está tentando executar funções através de ponteiros nulos.

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