[PATCH] D114801: [ELF] Prevent internalizing used comdat symbol

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 30 06:52:42 PST 2021


ikudrin created this revision.
ikudrin added reviewers: MaskRay, psmith.
ikudrin added a project: lld.
Herald added subscribers: ormris, steven_wu, hiraditya, arichardson, emaste.
ikudrin requested review of this revision.
Herald added a project: LLVM.

When a comdat symbol is defined in both bitcode and regular object files, which are contained in the same archive, the linker could lose the flag that the symbol is used in the regular object file and allow LTO to internalize it, which led to "error: undefined symbol".

The issue was introduced in D79300 <https://reviews.llvm.org/D79300>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114801

Files:
  lld/ELF/InputFiles.cpp
  lld/test/ELF/lto/comdat-mixed-archive.test


Index: lld/test/ELF/lto/comdat-mixed-archive.test
===================================================================
--- /dev/null
+++ lld/test/ELF/lto/comdat-mixed-archive.test
@@ -0,0 +1,54 @@
+REQUIRES: x86
+
+;; This checks a case when an archive contains a bitcode and a regular object
+;; file and a comdat symbol is defined and used in both of them. Previously, lld
+;; could lose the flag that the symbol is used in a regular object file which
+;; led to the LTO backend internalizing the symbol and the linker reporting an
+;; "undefined symbol" error.
+
+RUN: rm -rf %t.dir
+RUN: split-file %s %t.dir
+RUN: cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=x86_64 start.s -o start.o
+RUN: llvm-mc -filetype=obj -triple=x86_64 obj.s -o obj.o
+RUN: llvm-as bc.ll -o bc.o
+RUN: llvm-ar rc lib.a obj.o bc.o
+RUN: ld.lld start.o lib.a -o /dev/null
+
+;--- start.s
+  .global _start, baz
+_start:
+  call baz
+
+;--- obj.s
+  .weak foo
+  .global bar
+
+  .section .text.foo,"axG", at progbits,foo,comdat
+foo:
+  ret
+
+  .section .text.bar,"ax", at progbits
+bar:
+  call foo
+
+;--- bc.ll
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+$foo = comdat any
+
+declare void @bar()
+
+;; Note. "foo" is defined after declaring "bar" so that loading the regular
+;; object file "obj.o" is triggered before processing the definition of "foo".
+define linkonce_odr void @foo() comdat {
+  ret void
+}
+
+define void @baz() {
+  call void @foo()
+  call void @bar()
+  ret void
+}
Index: lld/ELF/InputFiles.cpp
===================================================================
--- lld/ELF/InputFiles.cpp
+++ lld/ELF/InputFiles.cpp
@@ -1155,9 +1155,11 @@
       if ((sym->symbolKind == Symbol::LazyArchiveKind &&
            !cast<ArchiveFile>(sym->file)->parsed) ||
           (sym->symbolKind == Symbol::LazyObjectKind &&
-           cast<LazyObjFile>(sym->file)->extracted))
+           cast<LazyObjFile>(sym->file)->extracted)) {
         sym->replace(und);
-      else
+        // Prevent possibly internalizing the symbol.
+        sym->isUsedInRegularObj = true;
+      } else
         sym->resolve(und);
       continue;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114801.390701.patch
Type: text/x-patch
Size: 2222 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211130/6fbc3fc9/attachment.bin>


More information about the llvm-commits mailing list