[LLD][COFF] Add support for IMPORT_NAME_EXPORTAS import library names. (#83211)
This allows handling importlibs produced by llvm-dlltool in #78772.
ARM64EC import libraries use it by default, but it's supported by MSVC
link.exe on other platforms too.
This also avoids assuming null-terminated input, like in #78769.
GitOrigin-RevId: 7b275aa2438c22604505d618dd37ee60052f2800
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index 1ed90d7..037fae4 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -944,18 +944,20 @@
: InputFile(ctx, ImportKind, m), live(!ctx.config.doGC), thunkLive(live) {}
void ImportFile::parse() {
- const char *buf = mb.getBufferStart();
- const auto *hdr = reinterpret_cast<const coff_import_header *>(buf);
+ const auto *hdr =
+ reinterpret_cast<const coff_import_header *>(mb.getBufferStart());
// Check if the total size is valid.
- if (mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
+ if (mb.getBufferSize() < sizeof(*hdr) ||
+ mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
fatal("broken import library");
// Read names and create an __imp_ symbol.
- StringRef name = saver().save(StringRef(buf + sizeof(*hdr)));
+ StringRef buf = mb.getBuffer().substr(sizeof(*hdr));
+ StringRef name = saver().save(buf.split('\0').first);
StringRef impName = saver().save("__imp_" + name);
- const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1;
- dllName = std::string(StringRef(nameStart));
+ buf = buf.substr(name.size() + 1);
+ dllName = buf.split('\0').first;
StringRef extName;
switch (hdr->getNameType()) {
case IMPORT_ORDINAL:
@@ -971,6 +973,9 @@
extName = ltrim1(name, "?@_");
extName = extName.substr(0, extName.find('@'));
break;
+ case IMPORT_NAME_EXPORTAS:
+ extName = buf.substr(dllName.size() + 1).split('\0').first;
+ break;
}
this->hdr = hdr;
diff --git a/test/COFF/exportas.test b/test/COFF/exportas.test
new file mode 100644
index 0000000..c0295c3
--- /dev/null
+++ b/test/COFF/exportas.test
@@ -0,0 +1,19 @@
+REQUIRES: x86
+RUN: split-file %s %t.dir && cd %t.dir
+
+Link to an import library containing EXPORTAS and verify that we use proper name for the import.
+
+RUN: llvm-mc -filetype=obj -triple=x86_64-windows test.s -o test.obj
+RUN: llvm-lib -machine:amd64 -out:test.lib -def:test.def
+RUN: lld-link -out:out1.dll -dll -noentry test.obj test.lib
+RUN: llvm-readobj --coff-imports out1.dll | FileCheck --check-prefix=IMPORT %s
+IMPORT: Symbol: expfunc
+
+#--- test.s
+ .section ".test", "rd"
+ .rva __imp_func
+
+#--- test.def
+LIBRARY test.dll
+EXPORTS
+ func EXPORTAS expfunc