[lld] [lld/mac] Resolve defined symbols before undefined symbols in bitcode (PR #67445)

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 26 08:43:55 PDT 2023


https://github.com/nico created https://github.com/llvm/llvm-project/pull/67445

Ports https://reviews.llvm.org/D106293 to bitcode, or https://github.com/llvm/llvm-project/commit/bd448f01a6 from ELF to MachO.

See also #59162 for some vaguely related discussion.

>From 104ac9302be2cc643db3866000b1154ef8e6c798 Mon Sep 17 00:00:00 2001
From: Nico Weber <thakis at chromium.org>
Date: Tue, 26 Sep 2023 11:41:36 -0400
Subject: [PATCH] [lld/mac] Resolve defined symbols before undefined symbols in
 bitcode

Ports https://reviews.llvm.org/D106293 to bitcode, or
https://github.com/llvm/llvm-project/commit/bd448f01a6 from ELF to MachO.

See also #59162 for some vaguely related discussion.
---
 lld/MachO/InputFiles.cpp                      | 13 +++--
 .../MachO/weak-definition-in-main-file.ll     | 47 +++++++++++++++++++
 2 files changed, 57 insertions(+), 3 deletions(-)
 create mode 100644 lld/test/MachO/weak-definition-in-main-file.ll

diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index a882c96dc221c56..8f737beee768bee 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -2291,9 +2291,16 @@ void BitcodeFile::parse() {
   // Convert LTO Symbols to LLD Symbols in order to perform resolution. The
   // "winning" symbol will then be marked as Prevailing at LTO compilation
   // time.
-  symbols.clear();
-  for (const lto::InputFile::Symbol &objSym : obj->symbols())
-    symbols.push_back(createBitcodeSymbol(objSym, *this));
+  symbols.resize(obj->symbols().size());
+
+  // Process defined symbols first. See the comment at the end of
+  // ObjFile<>::parseSymbols.
+  for (auto it : llvm::enumerate(obj->symbols()))
+    if (!it.value().isUndefined())
+      symbols[it.index()] = createBitcodeSymbol(it.value(), *this);
+  for (auto it : llvm::enumerate(obj->symbols()))
+    if (it.value().isUndefined())
+      symbols[it.index()] = createBitcodeSymbol(it.value(), *this);
 }
 
 void BitcodeFile::parseLazy() {
diff --git a/lld/test/MachO/weak-definition-in-main-file.ll b/lld/test/MachO/weak-definition-in-main-file.ll
new file mode 100644
index 000000000000000..051f4bf67efaebb
--- /dev/null
+++ b/lld/test/MachO/weak-definition-in-main-file.ll
@@ -0,0 +1,47 @@
+; REQUIRES: aarch64
+; RUN: rm -rf %t; split-file %s %t
+
+;; Test that a weak symbol in a direct .o file wins over
+;; a weak symbol in a .a file.
+;; Like weak-definition-in-main-file.s, but in bitcode.
+
+; RUN: llvm-as %t/test.ll -o %t/test.o
+; RUN: llvm-as %t/weakfoo.ll -o %t/weakfoo.o
+
+; RUN: llvm-ar --format=darwin rcs %t/weakfoo.a %t/weakfoo.o
+
+; PREFER-DIRECT-OBJECT-NOT: O __TEXT,weak _foo
+
+; RUN: %lld -lSystem -o %t/out %t/weakfoo.a %t/test.o
+; RUN: llvm-objdump --syms %t/out | FileCheck %s --check-prefix=PREFER-DIRECT-OBJECT
+
+;--- weakfoo.ll
+target triple = "x86_64-apple-macosx10.15.0"
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @baz() noinline optnone {
+  ret void
+}
+
+; XXX put in separate section
+define weak void @foo() noinline optnone section "__TEXT,weak" {
+  ret void
+}
+
+;--- test.ll
+target triple = "x86_64-apple-macosx10.15.0"
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+declare void @baz();
+
+define weak void @foo() noinline optnone {
+  ret void
+}
+
+define void @main() {
+  ; This pulls in weakfoo.a due to the __baz undef, but __foo should
+  ; still be resolved against the weak symbol in this file.
+  call void @baz()
+  call void @foo()
+  ret void
+}



More information about the llvm-commits mailing list