Skip to content

[LLD][COFF] Handle imported weak aliases consistently #109105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2024

Conversation

glandium
Copy link
Contributor

symTab being a DenseMap, the order in which a symbol and its corresponding import symbol are processed is not guaranteed, and when the latter comes first, it is left undefined.

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-lld-coff
@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-lld

Author: Mike Hommey (glandium)

Changes

symTab being a DenseMap, the order in which a symbol and its corresponding import symbol are processed is not guaranteed, and when the latter comes first, it is left undefined.


Full diff: https://github.com/llvm/llvm-project/pull/109105.diff

2 Files Affected:

  • (modified) lld/COFF/SymbolTable.cpp (+8)
  • (added) lld/test/COFF/import_weak_alias.test (+25)
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index efea16ccbbfea0..6b96d8bbda789c 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -502,6 +502,14 @@ void SymbolTable::resolveRemainingUndefines() {
     // This odd rule is for compatibility with MSVC linker.
     if (name.starts_with("__imp_")) {
       Symbol *imp = find(name.substr(strlen("__imp_")));
+      if (imp) {
+         // The unprefixed symbol might come later in symMap, so handle it now
+	 // so that the condition below can be appropriately applied.
+         auto *undef = dyn_cast<Undefined>(imp);
+         if (undef) {
+            undef->resolveWeakAlias();
+         }
+      }
       if (imp && isa<Defined>(imp)) {
         auto *d = cast<Defined>(imp);
         replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
diff --git a/lld/test/COFF/import_weak_alias.test b/lld/test/COFF/import_weak_alias.test
new file mode 100644
index 00000000000000..63df565d5dbc9d
--- /dev/null
+++ b/lld/test/COFF/import_weak_alias.test
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+
+# RUN: split-file %s %t.dir
+# RUN: llc --filetype=obj -o %t.foo.obj %t.dir/foo.ll
+# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/qux.s -o %t.qux.obj
+# RUN: lld-link %t.qux.obj %t.foo.obj -out:%t.dll -dll 2>&1 | FileCheck %s
+#
+# CHECK-NOT: lld-link: error: undefined symbol: __declspec(dllimport) foo
+
+#--- foo.ll
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+@foo = weak alias void(), ptr @bar
+
+define void @bar() {
+  ret void
+}
+
+#--- qux.s
+.text
+.global _DllMainCRTStartup
+_DllMainCRTStartup:
+  call __imp_foo
+  ret

@glandium
Copy link
Contributor Author

I verified that I can (sometimes) get an error with the included testcase on current master, and that the fix makes that go away.

Cc: @mstorsjo

Copy link

github-actions bot commented Sep 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@glandium glandium force-pushed the lld-coff-import-weak-alias branch from cf6ccff to c3f49f9 Compare September 18, 2024 09:08
Copy link
Member

@mstorsjo mstorsjo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good to me overall, thanks! A couple minor comments/discussion on the testcase.

@glandium glandium force-pushed the lld-coff-import-weak-alias branch from c3f49f9 to b477636 Compare September 18, 2024 09:26
@glandium
Copy link
Contributor Author

If you're satisfied with the latest version, could you merge it for me?

@glandium glandium force-pushed the lld-coff-import-weak-alias branch from b477636 to 3705fb3 Compare September 18, 2024 11:22
symTab being a DenseMap, the order in which a symbol and its
corresponding import symbol are processed is not guaranteed, and when
the latter comes first, it is left undefined.
@glandium glandium force-pushed the lld-coff-import-weak-alias branch from 3705fb3 to 272f50e Compare September 18, 2024 11:37
Copy link
Member

@mstorsjo mstorsjo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the updates!

@mstorsjo
Copy link
Member

I'll go ahead and merge this right away, as there's another patch in the queue touching the same areas, to simplify conflicts in that area. (Otherwise I would maybe have left the patch for 24h, for people in other time zones to comment on. But this change feels mostly straightforward to me.)

@mstorsjo mstorsjo merged commit 5e23b66 into llvm:main Sep 18, 2024
5 of 7 checks passed
tmsri pushed a commit to tmsri/llvm-project that referenced this pull request Sep 19, 2024
symTab being a DenseMap, the order in which a symbol and its
corresponding import symbol are processed is not guaranteed, and when
the latter comes first, it is left undefined.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants