Especifique manualmente o remapeamento de símbolos de vinculação específicos

Sem modificar esses dois arquivos de origem, existe uma maneira de obter os arquivos de objeto produzidos compilando-os e convencendo um vinculador a vincularfoo em main_v1.c parabar em bar.c?

main_v1.c

void foo(void);

int main(void)
{
    foo();
}

bar.c

#include <stdio.h>

void bar(void)
{
    puts("bar()!");
}

Modificar os arquivos dos objetos em si é um jogo justo, mas presumimos que talvez nem tenhamos o código fonte disponível. A plataforma é Linux.

Ao insistir em uma alteração modesta em main_v1.c e vincular um arquivo de objeto "mapeamento" adicional, aqui está uma maneira de obter quase o resultado desejado com apenas o padrão C.

main_v2.c

extern void (*const foo)(void);

int main(void)
{
    foo();
}

bar.c permanece inalterado.

map.c

void bar(void);
void (*const foo)(void) = bar;

Se os arquivos de objeto forem compilados com lto, a desreferência do ponteiro de função é até elidida (usando um gcc recente). Este é um bom resultado, mas semain() é modificado para ter uma chamada direta parabar(), entãobar() em si é incorporado após a vinculação, para que haja espaço para melhorias.

questionAnswers(1)

yourAnswerToTheQuestion