mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 04:14:03 +08:00
The MinGW mode (enabled with the flag -lldmingw) does allow duplicate weak symbols. A test in compiler-rt/test/profile/Windows/coverage-weak-lld.cpp does currently enable the -lldmingw flag in an MSVC context, in order to deal with duplicate weak symbols. Add a new, separate, lld specific flag for enabling this. In MinGW mode, this is enabled by default, otherwise it is disabled. This allows making the MinGW mode more restrictive in adding libpaths from the surrounding environment; in MinGW mode, all libpaths are passed explicitly by the compiler driver to the linker, which is attempted in https://reviews.llvm.org/D144084.
58 lines
1.6 KiB
Plaintext
58 lines
1.6 KiB
Plaintext
RUN: lld-link -lldmingw %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
|
|
RUN: lld-link -lld-allow-duplicate-weak %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe
|
|
RUN: not lld-link %S/Inputs/gnu-weak.o %S/Inputs/gnu-weak2.o -out:%t.exe 2>&1 | FileCheck %s --check-prefix=DEFAULT-ERROR
|
|
|
|
DEFAULT-ERROR: error: duplicate symbol: weakfunc
|
|
|
|
|
|
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
|