diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 15c76461a84a9..44aa506d2c35d 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -462,8 +462,10 @@ void SymbolTable::reportUnresolvable() { StringRef name = undef->getName(); if (name.starts_with("__imp_")) { Symbol *imp = find(name.substr(strlen("__imp_"))); - if (imp && isa(imp)) + if (Defined *def = dyn_cast_or_null(imp)) { + def->isUsedInRegularObj = true; continue; + } } if (name.contains("_PchSym_")) continue; diff --git a/lld/test/COFF/lto-dllimport.ll b/lld/test/COFF/lto-dllimport.ll index 74f3f43d8c281..3bef2779ebdef 100644 --- a/lld/test/COFF/lto-dllimport.ll +++ b/lld/test/COFF/lto-dllimport.ll @@ -9,10 +9,7 @@ ; RUN: lld-link %t.main.obj %t.other.obj -entry:main -out:%t.exe ; RUN: lld-link %t.main.bc %t.other.bc -entry:main -out:%t.exe ; RUN: lld-link %t.main.bc %t.other.obj -entry:main -out:%t.exe - -;; This test currently fails if combining the regular object file main.obj -;; with the bitcode object file other.bc. -; RUN-skipped: lld-link %t.main.obj %t.other.bc -entry:main -out:%t.exe +; RUN: lld-link %t.main.obj %t.other.bc -entry:main -out:%t.exe ;--- main.ll target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lld/test/COFF/lto-imp-prefix.ll b/lld/test/COFF/lto-imp-prefix.ll index c0b3bea7841c4..56a7c48cc9d16 100644 --- a/lld/test/COFF/lto-imp-prefix.ll +++ b/lld/test/COFF/lto-imp-prefix.ll @@ -3,18 +3,21 @@ ; RUN: rm -rf %t.dir ; RUN: split-file %s %t.dir ; RUN: llvm-as %t.dir/main.ll -o %t.main.obj -; RUN: llvm-as %t.dir/other.ll -o %t.other.obj +; RUN: llvm-as %t.dir/other1.ll -o %t.other1.obj +; RUN: llvm-as %t.dir/other2.ll -o %t.other2.obj -; RUN: lld-link /entry:entry %t.main.obj %t.other.obj /out:%t.exe /subsystem:console /debug:symtab +; RUN: lld-link /entry:entry %t.main.obj %t.other1.obj /out:%t1.exe /subsystem:console /debug:symtab ;; The current implementation for handling __imp_ symbols retains all of them. ;; Observe that this currently produces __imp_unusedFunc even if nothing ;; references unusedFunc in any form. -; RUN: llvm-nm %t.exe | FileCheck %s +; RUN: llvm-nm %t1.exe | FileCheck %s ; CHECK: __imp_unusedFunc +; RUN: lld-link /entry:entry %t.main.obj %t.other2.obj /out:%t2.exe /subsystem:console + ;--- main.ll target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-w64-windows-gnu" @@ -30,7 +33,7 @@ declare dllimport void @importedFunc() declare void @other() -;--- other.ll +;--- other1.ll target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-w64-windows-gnu" @@ -52,3 +55,21 @@ define void @other() { entry: ret void } + +;--- other2.ll +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-w64-windows-gnu" + +@__imp_importedFunc = global ptr @importedFunc + +; Test with two external symbols with the same name, with/without the __imp_ +; prefix. +define void @importedFunc() { +entry: + ret void +} + +define void @other() { +entry: + ret void +} diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index e111e09681178..05836fd28f528 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -610,13 +610,7 @@ void LTO::addModuleToGlobalRes(ArrayRef Syms, assert(ResI != ResE); SymbolResolution Res = *ResI++; - StringRef Name = Sym.getName(); - // Strip the __imp_ prefix from COFF dllimport symbols (similar to the - // way they are handled by lld), otherwise we can end up with two - // global resolutions (one with and one for a copy of the symbol without). - if (TT.isOSBinFormatCOFF() && Name.startswith("__imp_")) - Name = Name.substr(strlen("__imp_")); - auto &GlobalRes = GlobalResolutions[Name]; + auto &GlobalRes = GlobalResolutions[Sym.getName()]; GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr(); if (Res.Prevailing) { assert(!GlobalRes.Prevailing &&