Skip to content

Commit

Permalink
[LLD][COFF] Add support for IMPORT_NAME_EXPORTAS import library names. (
Browse files Browse the repository at this point in the history
#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.
  • Loading branch information
cjacek committed Mar 10, 2024
1 parent fe1645e commit 7b275aa
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
17 changes: 11 additions & 6 deletions lld/COFF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,18 +944,20 @@ ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
: 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:
Expand All @@ -971,6 +973,9 @@ void ImportFile::parse() {
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;
Expand Down
19 changes: 19 additions & 0 deletions lld/test/COFF/exportas.test
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7b275aa

Please sign in to comment.