[PATCH] D52601: [LLD] [COFF] Cope with weak aliases produced by GNU tools

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 3 11:36:10 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rLLD343704: [COFF] Cope with weak aliases produced by GNU tools (authored by mstorsjo, committed by ).

Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D52601

Files:
  COFF/InputFiles.cpp
  test/COFF/Inputs/gnu-weak.o
  test/COFF/Inputs/gnu-weak2.o
  test/COFF/gnu-weak.test


Index: test/COFF/gnu-weak.test
===================================================================
--- test/COFF/gnu-weak.test
+++ test/COFF/gnu-weak.test
@@ -0,0 +1,52 @@
+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
Index: COFF/InputFiles.cpp
===================================================================
--- COFF/InputFiles.cpp
+++ COFF/InputFiles.cpp
@@ -54,8 +54,16 @@
 static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
                                  Symbol *Source, Symbol *Target) {
   if (auto *U = dyn_cast<Undefined>(Source)) {
-    if (U->WeakAlias && U->WeakAlias != Target)
+    if (U->WeakAlias && U->WeakAlias != Target) {
+      // Weak aliases as produced by GCC are named in the form
+      // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
+      // of another symbol emitted near the weak symbol.
+      // Just use the definition from the first object file that defined
+      // this weak symbol.
+      if (Config->MinGW)
+        return;
       Symtab->reportDuplicate(Source, F);
+    }
     U->WeakAlias = Target;
   }
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52601.168145.patch
Type: text/x-patch
Size: 2484 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181003/9edb0dbc/attachment.bin>


More information about the llvm-commits mailing list