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.., 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..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