aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/COFFImportFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/COFFImportFile.cpp')
-rw-r--r--llvm/lib/Object/COFFImportFile.cpp66
1 files changed, 45 insertions, 21 deletions
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index 03af492..1ddc5d9 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -52,18 +52,12 @@ StringRef COFFImportFile::getFileFormatName() const {
}
}
-StringRef COFFImportFile::getExportName() const {
- const coff_import_header *hdr = getCOFFImportHeader();
- StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
-
+static StringRef applyNameType(ImportNameType Type, StringRef name) {
auto ltrim1 = [](StringRef s, StringRef chars) {
return !s.empty() && chars.contains(s[0]) ? s.substr(1) : s;
};
- switch (hdr->getNameType()) {
- case IMPORT_ORDINAL:
- name = "";
- break;
+ switch (Type) {
case IMPORT_NAME_NOPREFIX:
name = ltrim1(name, "?@_");
break;
@@ -71,6 +65,24 @@ StringRef COFFImportFile::getExportName() const {
name = ltrim1(name, "?@_");
name = name.substr(0, name.find('@'));
break;
+ default:
+ break;
+ }
+ return name;
+}
+
+StringRef COFFImportFile::getExportName() const {
+ const coff_import_header *hdr = getCOFFImportHeader();
+ StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
+
+ switch (hdr->getNameType()) {
+ case IMPORT_ORDINAL:
+ name = "";
+ break;
+ case IMPORT_NAME_NOPREFIX:
+ case IMPORT_NAME_UNDECORATE:
+ name = applyNameType(static_cast<ImportNameType>(hdr->getNameType()), name);
+ break;
case IMPORT_NAME_EXPORTAS: {
// Skip DLL name
name = Data.getBuffer().substr(sizeof(*hdr) + name.size() + 1);
@@ -691,19 +703,6 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
Name.swap(*ReplacedName);
}
- if (!E.ImportName.empty() && Name != E.ImportName) {
- StringRef Prefix = "";
- if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
- Prefix = "_";
-
- if (ImportType == IMPORT_CODE)
- Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
- Name, false, M));
- Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
- Name, true, M));
- continue;
- }
-
ImportNameType NameType;
std::string ExportName;
if (E.Noname) {
@@ -711,6 +710,31 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
} else if (!E.ExportAs.empty()) {
NameType = IMPORT_NAME_EXPORTAS;
ExportName = E.ExportAs;
+ } else if (!E.ImportName.empty()) {
+ // If we need to import from a specific ImportName, we may need to use
+ // a weak alias (which needs another import to point at). But if we can
+ // express ImportName based on the symbol name and a specific NameType,
+ // prefer that over an alias.
+ if (Machine == IMAGE_FILE_MACHINE_I386 &&
+ applyNameType(IMPORT_NAME_UNDECORATE, Name) == E.ImportName)
+ NameType = IMPORT_NAME_UNDECORATE;
+ else if (Machine == IMAGE_FILE_MACHINE_I386 &&
+ applyNameType(IMPORT_NAME_NOPREFIX, Name) == E.ImportName)
+ NameType = IMPORT_NAME_NOPREFIX;
+ else if (Name == E.ImportName)
+ NameType = IMPORT_NAME;
+ else {
+ StringRef Prefix = "";
+ if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
+ Prefix = "_";
+
+ if (ImportType == IMPORT_CODE)
+ Members.push_back(OF.createWeakExternal(
+ (Prefix + E.ImportName).str(), Name, false, M));
+ Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
+ Name, true, M));
+ continue;
+ }
} else {
NameType = getNameType(SymbolName, E.Name, M, MinGW);
}