When GNU tools create a weak alias, they produce a strong symbol named .weak.<weaksymbol>.<relatedstrongsymbol>. GNU ld allows many such weak alternatives for the same weak symbol, and the linker picks the first one encountered. This can't be reproduced by assembling from .s files, since llvm-mc produces symbols named .weak.<weaksymbol>.default in these cases. Differential Revision: https://reviews.llvm.org/D52601 llvm-svn: 343704
53 lines
1.4 KiB
Plaintext
53 lines
1.4 KiB
Plaintext
RUN: lld-link -lldmingw %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
|
|
|
|
GNU ld can handle several definitions of the same weak symbol, and
|
|
unless there is a strong definition of it, it just picks the first
|
|
weak definition encountered.
|
|
|
|
For each of the weak definitions, GNU tools produce a regular symbol
|
|
named .weak.<weaksymbol>.<othersymbol>, where the other symbol name is
|
|
another symbol defined close by.
|
|
|
|
This can't be reproduced by assembling with llvm-mc, as llvm-mc always
|
|
produces similar regular symbols named .weak.<weaksymbol>.default.
|
|
|
|
The bundled object files can be produced from test code that looks like
|
|
this:
|
|
|
|
$ cat gnu-weak.c
|
|
void weakfunc(void) __attribute__((weak));
|
|
void otherfunc(void);
|
|
|
|
__attribute__((weak)) void weakfunc() {
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
otherfunc();
|
|
weakfunc();
|
|
return 0;
|
|
}
|
|
void mainCRTStartup(void) {
|
|
main(0, (char**)0);
|
|
}
|
|
void __main(void) {
|
|
}
|
|
|
|
$ cat gnu-weak2.c
|
|
void weakfunc(void) __attribute__((weak));
|
|
|
|
__attribute__((weak)) void weakfunc() {
|
|
}
|
|
|
|
void otherfunc(void) {
|
|
}
|
|
|
|
$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak.c
|
|
$ x86_64-w64-mingw32-gcc -c -O2 gnu-weak2.c
|
|
|
|
$ x86_64-w64-mingw32-nm gnu-weak.o | grep weakfunc
|
|
0000000000000000 T .weak.weakfunc.main
|
|
w weakfunc
|
|
$ x86_64-w64-mingw32-nm gnu-weak2.o | grep weakfunc
|
|
0000000000000000 T .weak.weakfunc.otherfunc
|
|
w weakfunc
|