Adicionando sublinhados à símbolos de montagem com o GCC no Win32?
Eu tenho um pedaço de código C que chama uma função definida na montagem. Por exemplo, digamos que foo.c contenha:
<code>int bar(int x); /* returns 2x */ int main(int argc, char *argv[]) { return bar(7); } </code>
E bar.s contém a implementação de bar () no assembly x86:
<code>.global bar bar: movl 4(%esp), %eax addl %eax, %eax ret </code>
No Linux eu posso facilmente compilar e vincular essas fontes com o GCC da seguinte maneira:
<code>% gcc -o test foo.c bar.s % ./test; echo $? 14 </code>
No Windows com MinGW isso falha com um erro de "referência indefinida para 'bar'". Acontece que a causa disso é que no Windows todos os identificadores de funções com convenção de chamada C são prefixados com um sublinhado, mas como "barra" é definida em assembly, ele não obtém esse prefixo e a vinculação falha. (Então, a mensagem de erro está realmente reclamando de perder o símbolo _bar, não barra.)
Para resumir:
<code>% gcc -c foo.c bar.s % nm foo.o bar.o foo.o: 00000000 b .bss 00000000 d .data 00000000 t .text U ___main U _bar 00000000 T _main bar.o: 00000000 b .bss 00000000 d .data 00000000 t .text 00000000 T bar </code>
A questão agora é: como posso resolver isso bem? Se eu estivesse escrevendo apenas para o Windows, eu poderia apenas adicionar o sublinhado ao identificador em bar.s, mas o código seria interrompido no Linux. Eu olhei para o gcc-fleading-underscore
e-fno-leading-underscore
opções, mas nem parece fazer nada (pelo menos no Windows).
A única alternativa que vejo agora é passar o arquivo assembly através do pré-processador C e redefinir todos os símbolos declarados manualmente se o WIN32 estiver definido, mas isso também não é muito bonito.
Alguém tem uma solução limpa para isso? Talvez uma opção de compilador que eu supervisionei? Talvez o montador GNU suporte uma maneira específica de que este símbolo específico se refira a uma função usando a convenção de chamada C e deve ser mutilado como tal? Alguma outra ideia?