Skip to content

Commit 4469650

Browse files
authored
[llvm-dlltool] Handle import renaming using other name types, when possible (#98228)
This avoids needing to use weak aliases for these cases. (Weak aliases only work if there's another, regular import entry that provide the desired symbol from the DLL.)
1 parent ad2ff17 commit 4469650

File tree

2 files changed

+61
-21
lines changed

2 files changed

+61
-21
lines changed

llvm/lib/Object/COFFImportFile.cpp

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,37 @@ StringRef COFFImportFile::getFileFormatName() const {
5252
}
5353
}
5454

55-
StringRef COFFImportFile::getExportName() const {
56-
const coff_import_header *hdr = getCOFFImportHeader();
57-
StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
58-
55+
static StringRef applyNameType(ImportNameType Type, StringRef name) {
5956
auto ltrim1 = [](StringRef s, StringRef chars) {
6057
return !s.empty() && chars.contains(s[0]) ? s.substr(1) : s;
6158
};
6259

63-
switch (hdr->getNameType()) {
64-
case IMPORT_ORDINAL:
65-
name = "";
66-
break;
60+
switch (Type) {
6761
case IMPORT_NAME_NOPREFIX:
6862
name = ltrim1(name, "?@_");
6963
break;
7064
case IMPORT_NAME_UNDECORATE:
7165
name = ltrim1(name, "?@_");
7266
name = name.substr(0, name.find('@'));
7367
break;
68+
default:
69+
break;
70+
}
71+
return name;
72+
}
73+
74+
StringRef COFFImportFile::getExportName() const {
75+
const coff_import_header *hdr = getCOFFImportHeader();
76+
StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
77+
78+
switch (hdr->getNameType()) {
79+
case IMPORT_ORDINAL:
80+
name = "";
81+
break;
82+
case IMPORT_NAME_NOPREFIX:
83+
case IMPORT_NAME_UNDECORATE:
84+
name = applyNameType(static_cast<ImportNameType>(hdr->getNameType()), name);
85+
break;
7486
case IMPORT_NAME_EXPORTAS: {
7587
// Skip DLL name
7688
name = Data.getBuffer().substr(sizeof(*hdr) + name.size() + 1);
@@ -691,26 +703,38 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
691703
Name.swap(*ReplacedName);
692704
}
693705

694-
if (!E.ImportName.empty() && Name != E.ImportName) {
695-
StringRef Prefix = "";
696-
if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
697-
Prefix = "_";
698-
699-
if (ImportType == IMPORT_CODE)
700-
Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
701-
Name, false, M));
702-
Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
703-
Name, true, M));
704-
continue;
705-
}
706-
707706
ImportNameType NameType;
708707
std::string ExportName;
709708
if (E.Noname) {
710709
NameType = IMPORT_ORDINAL;
711710
} else if (!E.ExportAs.empty()) {
712711
NameType = IMPORT_NAME_EXPORTAS;
713712
ExportName = E.ExportAs;
713+
} else if (!E.ImportName.empty()) {
714+
// If we need to import from a specific ImportName, we may need to use
715+
// a weak alias (which needs another import to point at). But if we can
716+
// express ImportName based on the symbol name and a specific NameType,
717+
// prefer that over an alias.
718+
if (Machine == IMAGE_FILE_MACHINE_I386 &&
719+
applyNameType(IMPORT_NAME_UNDECORATE, Name) == E.ImportName)
720+
NameType = IMPORT_NAME_UNDECORATE;
721+
else if (Machine == IMAGE_FILE_MACHINE_I386 &&
722+
applyNameType(IMPORT_NAME_NOPREFIX, Name) == E.ImportName)
723+
NameType = IMPORT_NAME_NOPREFIX;
724+
else if (Name == E.ImportName)
725+
NameType = IMPORT_NAME;
726+
else {
727+
StringRef Prefix = "";
728+
if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
729+
Prefix = "_";
730+
731+
if (ImportType == IMPORT_CODE)
732+
Members.push_back(OF.createWeakExternal(
733+
(Prefix + E.ImportName).str(), Name, false, M));
734+
Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
735+
Name, true, M));
736+
continue;
737+
}
714738
} else {
715739
NameType = getNameType(SymbolName, E.Name, M, MinGW);
716740
}

llvm/test/tools/llvm-dlltool/coff-decorated.def

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ StdcallExportName@4=StdcallInternalFunction@4
1313
OtherStdcallExportName@4=CdeclInternalFunction
1414
CdeclExportName=StdcallInternalFunction@4
1515

16+
NoprefixStdcall@4 == NoprefixStdcall@4
17+
DecoratedStdcall@4 == _DecoratedStdcall@4
18+
UndecoratedStdcall@4 == UndecoratedStdcall
19+
1620
; CHECK: Name type: noprefix
1721
; CHECK-NEXT: Export name: CdeclFunction
1822
; CHECK-NEXT: Symbol: __imp__CdeclFunction
@@ -43,3 +47,15 @@ CdeclExportName=StdcallInternalFunction@4
4347
; CHECK-NEXT: Export name: CdeclExportName
4448
; CHECK-NEXT: Symbol: __imp__CdeclExportName
4549
; CHECK-NEXT: Symbol: _CdeclExportName
50+
; CHECK: Name type: noprefix
51+
; CHECK-NEXT: Export name: NoprefixStdcall@4
52+
; CHECK-NEXT: Symbol: __imp__NoprefixStdcall@4
53+
; CHECK-NEXT: Symbol: _NoprefixStdcall@4
54+
; CHECK: Name type: name
55+
; CHECK-NEXT: Export name: _DecoratedStdcall@4
56+
; CHECK-NEXT: Symbol: __imp__DecoratedStdcall@4
57+
; CHECK-NEXT: Symbol: _DecoratedStdcall@4
58+
; CHECK: Name type: undecorate
59+
; CHECK-NEXT: Export name: UndecoratedStdcall
60+
; CHECK-NEXT: Symbol: __imp__UndecoratedStdcall@4
61+
; CHECK-NEXT: Symbol: _UndecoratedStdcall@4

0 commit comments

Comments
 (0)