Skip to content

Commit 143133f

Browse files
authored
[LLD] [COFF] Don't preserve unnecessary __imp_ prefixed symbols (#72989)
This redoes the fix from 3ab6209 differently, without the unwanted effect of preserving unnecessary `__imp_` prefixed symbols. If the referencing object is a regular object, the `__imp_` symbol will have `isUsedInRegularObj` set on it from that already. If the referencing object is an LTO object, we set `isUsedInRegularObj` for any symbol starting with `__imp_`. If the object file defining the `__imp_` symbol is a regular object, the `isUsedInRegularObj` flag has no effect. If it is an LTO object, it causes the symbol to be preserved.
1 parent 8dc474c commit 143133f

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

lld/COFF/InputFiles.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,19 @@ void BitcodeFile::parse() {
10421042
sym = ctx.symtab.addUndefined(symName, this, false);
10431043
if (objSym.isWeak())
10441044
sym->deferUndefined = true;
1045+
// If one LTO object file references (i.e. has an undefined reference to)
1046+
// a symbol with an __imp_ prefix, the LTO compilation itself sees it
1047+
// as unprefixed but with a dllimport attribute instead, and doesn't
1048+
// understand the relation to a concrete IR symbol with the __imp_ prefix.
1049+
//
1050+
// For such cases, mark the symbol as used in a regular object (i.e. the
1051+
// symbol must be retained) so that the linker can associate the
1052+
// references in the end. If the symbol is defined in an import library
1053+
// or in a regular object file, this has no effect, but if it is defined
1054+
// in another LTO object file, this makes sure it is kept, to fulfill
1055+
// the reference when linking the output of the LTO compilation.
1056+
if (symName.starts_with("__imp_"))
1057+
sym->isUsedInRegularObj = true;
10451058
} else if (objSym.isCommon()) {
10461059
sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
10471060
} else if (objSym.isWeak() && objSym.isIndirect()) {
@@ -1063,12 +1076,6 @@ void BitcodeFile::parse() {
10631076
} else {
10641077
sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC, 0,
10651078
objSym.isWeak());
1066-
// Model all symbols with the __imp_ prefix as having external
1067-
// references. If one LTO object defines a __imp_<foo> symbol, and
1068-
// another LTO object refers to <foo> with dllimport, make sure the
1069-
// __imp_ symbol is kept.
1070-
if (symName.starts_with("__imp_"))
1071-
sym->isUsedInRegularObj = true;
10721079
}
10731080
symbols.push_back(sym);
10741081
if (objSym.isUsed())

lld/test/COFF/lto-imp-prefix.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,9 @@
88

99
; RUN: lld-link /entry:entry %t.main.obj %t.other1.obj /out:%t1.exe /subsystem:console /debug:symtab
1010

11-
;; The current implementation for handling __imp_ symbols retains all of them.
12-
;; Observe that this currently produces __imp_unusedFunc even if nothing
13-
;; references unusedFunc in any form.
14-
11+
;; Check that we don't retain __imp_ prefixed symbols we don't need.
1512
; RUN: llvm-nm %t1.exe | FileCheck %s
16-
17-
; CHECK: __imp_unusedFunc
13+
; CHECK-NOT: __imp_unusedFunc
1814

1915
; RUN: lld-link /entry:entry %t.main.obj %t.other2.obj /out:%t2.exe /subsystem:console
2016

0 commit comments

Comments
 (0)