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

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 1 21:15:02 PST 2021


This revision was automatically updated to reflect the committed changes.
Closed by commit rGb0ac68ccb729: [ELF] Prevent internalizing used comdat symbol (authored by ikudrin).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114801/new/

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,74 @@
+REQUIRES: x86
+
+;; This checks a case when an archive contains a bitcode and a regular object
+;; files, 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.
+
+;; In this test, group "foo" in "obj.o" is rejected in favor of "bc.bc" but we
+;; need to prevent LTO from internalizing "foo" as there is still a reference
+;; from outside the group in "obj.o".
+
+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.bc
+RUN: llvm-nm bc.bc --no-sort | FileCheck %s --check-prefix=BCSYM
+RUN: llvm-ar rc lib.a obj.o bc.bc
+RUN: ld.lld start.o lib.a -y foo -y bar -o /dev/null | FileCheck %s --check-prefix=TRACE
+
+;; "bar" should be encountered before "foo" so that it triggers the loading of
+;; "obj.o" while "foo" is still lazy.
+BCSYM:      U bar
+BCSYM-NEXT: W foo
+
+;; Check that the symbols are handled in the expected order.
+TRACE:      lib.a: lazy definition of foo
+TRACE-NEXT: lib.a: lazy definition of bar
+TRACE-NEXT: lib.a(bc.bc): reference to bar
+TRACE-NEXT: lib.a(obj.o): reference to foo
+TRACE-NEXT: lib.a(obj.o): definition of bar
+TRACE-NEXT: lib.a(bc.bc): definition of foo
+TRACE-NEXT: <internal>: reference to foo
+;; The definition of "foo" is visible outside the LTO result.
+TRACE-NEXT: lto.tmp: definition of foo
+TRACE-NEXT: lto.tmp: reference to bar
+
+;--- 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()
+
+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
@@ -1145,9 +1145,12 @@
       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 LTO from internalizing the symbol in case there is a
+        // reference to this symbol from this file.
+        sym->isUsedInRegularObj = true;
+      } else
         sym->resolve(und);
       continue;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114801.391197.patch
Type: text/x-patch
Size: 3127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211202/3b73c034/attachment.bin>


More information about the llvm-commits mailing list