Skip to content

Commit

Permalink
[llvm-readobj][Object][COFF] Print COFF import library symbol export …
Browse files Browse the repository at this point in the history
…name. (#78769)

getExportName implementation is based on lld-link. In its current form,
it's mostly about convenience, but it will be more useful for EXPORTAS
support, for which export name is not possible to deduce from other
printed properties.
  • Loading branch information
cjacek authored and tstellar committed Mar 16, 2024
1 parent 3a06861 commit 77e1992
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions lld/test/COFF/def-export-cpp.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

# IMPLIB: File: foo.dll
# IMPLIB: Name type: undecorate
# IMPLIB-NEXT: Export name: GetPathOnDisk
# IMPLIB-NEXT: Symbol: __imp_?GetPathOnDisk@@YA_NPEA_W@Z
# IMPLIB-NEXT: Symbol: ?GetPathOnDisk@@YA_NPEA_W@Z

Expand Down
13 changes: 13 additions & 0 deletions lld/test/COFF/def-export-stdcall.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix UNDECORATED-EXPORTS %s

# UNDECORATED-IMPLIB: Name type: noprefix
# UNDECORATED-IMPLIB-NEXT: Export name: _underscored
# UNDECORATED-IMPLIB-NEXT: __imp___underscored
# UNDECORATED-IMPLIB-NEXT: __underscored
# UNDECORATED-IMPLIB: Name type: undecorate
# UNDECORATED-IMPLIB-NEXT: Export name: fastcall
# UNDECORATED-IMPLIB-NEXT: __imp_@fastcall@8
# UNDECORATED-IMPLIB-NEXT: fastcall@8
# UNDECORATED-IMPLIB: Name type: undecorate
# UNDECORATED-IMPLIB-NEXT: Export name: stdcall
# UNDECORATED-IMPLIB-NEXT: __imp__stdcall@8
# UNDECORATED-IMPLIB-NEXT: _stdcall@8
# UNDECORATED-IMPLIB: Name type: undecorate
# UNDECORATED-IMPLIB-NEXT: Export name: vectorcall
# UNDECORATED-IMPLIB-NEXT: __imp_vectorcall@@8
# UNDECORATED-IMPLIB-NEXT: vectorcall@@8

Expand All @@ -30,12 +34,15 @@
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s

# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: @fastcall@8
# DECORATED-IMPLIB-NEXT: __imp_@fastcall@8
# DECORATED-IMPLIB-NEXT: @fastcall@8
# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: _stdcall@8
# DECORATED-IMPLIB-NEXT: __imp__stdcall@8
# DECORATED-IMPLIB-NEXT: _stdcall@8
# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: vectorcall@@8
# DECORATED-IMPLIB-NEXT: __imp_vectorcall@@8
# DECORATED-IMPLIB-NEXT: vectorcall@@8

Expand All @@ -51,14 +58,17 @@
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-MINGW-EXPORTS %s

# DECORATED-MINGW-IMPLIB: Name type: name
# DECORATED-MINGW-IMPLIB-NEXT: Export name: @fastcall@8
# DECORATED-MINGW-IMPLIB-NEXT: __imp_@fastcall@8
# DECORATED-MINGW-IMPLIB-NEXT: fastcall@8
# DECORATED-MINGW-IMPLIB: Name type: noprefix
# DECORATED-MINGW-IMPLIB-NEXT: Export name: stdcall@8
# DECORATED-MINGW-IMPLIB-NEXT: __imp__stdcall@8
# DECORATED-MINGW-IMPLIB-NEXT: _stdcall@8
# GNU tools don't support vectorcall, but this test is just to track that
# lld's behaviour remains consistent over time.
# DECORATED-MINGW-IMPLIB: Name type: name
# DECORATED-MINGW-IMPLIB-NEXT: Export name: vectorcall@@8
# DECORATED-MINGW-IMPLIB-NEXT: __imp_vectorcall@@8
# DECORATED-MINGW-IMPLIB-NEXT: vectorcall@@8

Expand All @@ -75,14 +85,17 @@
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix MINGW-KILL-AT-EXPORTS %s

# MINGW-KILL-AT-IMPLIB: Name type: noprefix
# MINGW-KILL-AT-IMPLIB: Export name: fastcall
# MINGW-KILL-AT-IMPLIB: __imp__fastcall
# MINGW-KILL-AT-IMPLIB-NEXT: _fastcall
# MINGW-KILL-AT-IMPLIB: Name type: noprefix
# MINGW-KILL-AT-IMPLIB-NEXT: Export name: stdcall
# MINGW-KILL-AT-IMPLIB-NEXT: __imp__stdcall
# MINGW-KILL-AT-IMPLIB-NEXT: _stdcall
# GNU tools don't support vectorcall, but this test is just to track that
# lld's behaviour remains consistent over time.
# MINGW-KILL-AT-IMPLIB: Name type: noprefix
# MINGW-KILL-AT-IMPLIB-NEXT: Export name: vectorcall
# MINGW-KILL-AT-IMPLIB-NEXT: __imp__vectorcall
# MINGW-KILL-AT-IMPLIB-NEXT: _vectorcall

Expand Down
4 changes: 4 additions & 0 deletions lld/test/COFF/dllexport.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s

# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: @fastcall@8
# DECORATED-IMPLIB-NEXT: __imp_@fastcall@8
# DECORATED-IMPLIB-NEXT: @fastcall@8
# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: _stdcall@8
# DECORATED-IMPLIB-NEXT: __imp__stdcall@8
# DECORATED-IMPLIB-NEXT: _stdcall@8
# DECORATED-IMPLIB: Name type: noprefix
# DECORATED-IMPLIB-NEXT: Export name: _underscored
# DECORATED-IMPLIB-NEXT: __imp___underscored
# DECORATED-IMPLIB-NEXT: __underscored
# DECORATED-IMPLIB: Name type: name
# DECORATED-IMPLIB-NEXT: Export name: vectorcall@@8
# DECORATED-IMPLIB-NEXT: __imp_vectorcall@@8
# DECORATED-IMPLIB-NEXT: vectorcall@@8

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Object/COFFImportFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class COFFImportFile : public SymbolicFile {
uint16_t getMachine() const { return getCOFFImportHeader()->Machine; }

StringRef getFileFormatName() const;
StringRef getExportName() const;

private:
bool isData() const {
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Object/COFFImportFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,32 @@ StringRef COFFImportFile::getFileFormatName() const {
}
}

StringRef COFFImportFile::getExportName() const {
const coff_import_header *hdr = getCOFFImportHeader();
StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;

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;
case IMPORT_NAME_NOPREFIX:
name = ltrim1(name, "?@_");
break;
case IMPORT_NAME_UNDECORATE:
name = ltrim1(name, "?@_");
name = name.substr(0, name.find('@'));
break;
default:
break;
}

return name;
}

static uint16_t getImgRelRelocation(MachineTypes Machine) {
switch (Machine) {
default:
Expand Down
7 changes: 7 additions & 0 deletions llvm/test/tools/llvm-dlltool/coff-decorated.def
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,32 @@ OtherStdcallExportName@4=CdeclInternalFunction
CdeclExportName=StdcallInternalFunction@4

; CHECK: Name type: noprefix
; CHECK-NEXT: Export name: CdeclFunction
; CHECK-NEXT: Symbol: __imp__CdeclFunction
; CHECK-NEXT: Symbol: _CdeclFunction
; CHECK: Name type: undecorate
; CHECK-NEXT: Export name: StdcallFunction
; CHECK-NEXT: Symbol: __imp__StdcallFunction@4
; CHECK-NEXT: Symbol: _StdcallFunction@4
; CHECK: Name type: undecorate
; CHECK-NEXT: Export name: FastcallFunction
; CHECK-NEXT: Symbol: __imp_@FastcallFunction@4
; CHECK-NEXT: Symbol: @FastcallFunction@4
; CHECK: Name type: name
; CHECK-NEXT: Export name: ??_7exception@@6B@
; CHECK-NEXT: Symbol: __imp_??_7exception@@6B@
; CHECK-NEXT: Symbol: ??_7exception@@6B@
; CHECK-NM: W _StdcallAlias@4
; CHECK-NM: U _StdcallFunction@4
; CHECK: Name type: undecorate
; CHECK-NEXT: Export name: StdcallExportName
; CHECK-NEXT: Symbol: __imp__StdcallExportName@4{{$}}
; CHECK-NEXT: Symbol: _StdcallExportName@4{{$}}
; CHECK: Name type: undecorate
; CHECK-NEXT: Export name: OtherStdcallExportName
; CHECK-NEXT: Symbol: __imp__OtherStdcallExportName@4{{$}}
; CHECK-NEXT: Symbol: _OtherStdcallExportName@4{{$}}
; CHECK: Name type: noprefix
; CHECK-NEXT: Export name: CdeclExportName
; CHECK-NEXT: Symbol: __imp__CdeclExportName
; CHECK-NEXT: Symbol: _CdeclExportName
3 changes: 3 additions & 0 deletions llvm/test/tools/llvm-dlltool/coff-exports.def
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ AnotherFunction
; CHECK-ARM64: Format: COFF-import-file-ARM64
; CHECK: Type: code
; CHECK: Name type: name
; CHECK-NEXT: Export name: TestFunction1
; CHECK-NEXT: Symbol: __imp_TestFunction1
; CHECK-NEXT: Symbol: TestFunction1
; CHECK: Name type: name
; CHECK-NEXT: Export name: TestFunction2
; CHECK-NEXT: Symbol: __imp_TestFunction2{{$}}
; CHECK-NEXT: Symbol: TestFunction2{{$}}
; CHECK: Name type: name
; CHECK-NEXT: Export name: TestFunction3
; CHECK-NEXT: Symbol: __imp_TestFunction3{{$}}
; CHECK-NEXT: Symbol: TestFunction3{{$}}

Expand Down
1 change: 1 addition & 0 deletions llvm/test/tools/llvm-dlltool/coff-noname.def
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ ByNameFunction
; CHECK-NEXT: Symbol: __imp__ByOrdinalFunction
; CHECK-NEXT: Symbol: _ByOrdinalFunction
; CHECK: Name type: noprefix
; CHECK-NEXT: Export name: ByNameFunction
; CHECK-NEXT: Symbol: __imp__ByNameFunction
; CHECK-NEXT: Symbol: _ByNameFunction
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-dlltool/no-leading-underscore.def
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ alias == func
DecoratedFunction@4

; CHECK: Name type: name
; CHECK-NEXT: Export name: func
; CHECK-NEXT: Symbol: __imp_func
; CHECK-NEXT: Symbol: func
; CHECK: Name type: undecorate
; CHECK-NEXT: Export name: DecoratedFunction
; CHECK-NEXT: Symbol: __imp_DecoratedFunction@4
; CHECK-NEXT: Symbol: DecoratedFunction@4

Expand Down
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-lib/arm64ec-implib.test
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ READOBJ-NEXT: File: test.dll
READOBJ-NEXT: Format: COFF-import-file-ARM64EC
READOBJ-NEXT: Type: code
READOBJ-NEXT: Name type: name
READOBJ-NEXT: Export name: funcexp
READOBJ-NEXT: Symbol: __imp_funcexp
READOBJ-NEXT: Symbol: funcexp
READOBJ-EMPTY:
READOBJ-NEXT: File: test.dll
READOBJ-NEXT: Format: COFF-import-file-ARM64EC
READOBJ-NEXT: Type: data
READOBJ-NEXT: Name type: name
READOBJ-NEXT: Export name: dataexp
READOBJ-NEXT: Symbol: __imp_dataexp

Creating a new lib containing the existing lib:
Expand Down
1 change: 1 addition & 0 deletions llvm/test/tools/llvm-readobj/COFF/file-headers.test
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ symbols:
# IMPORTLIB:Format: COFF-import-file-i386
# IMPORTLIB-NEXT:Type: code
# IMPORTLIB-NEXT:Name type: noprefix
# IMPORTLIB-NEXT:Export name: func
# IMPORTLIB-NEXT:Symbol: __imp__func
# IMPORTLIB-NEXT:Symbol: _func
# IMPORTLIB-NOT:{{.}}
3 changes: 3 additions & 0 deletions llvm/tools/llvm-readobj/COFFImportDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ void dumpCOFFImportFile(const COFFImportFile *File, ScopedPrinter &Writer) {
break;
}

if (H->getNameType() != COFF::IMPORT_ORDINAL)
Writer.printString("Export name", File->getExportName());

for (const object::BasicSymbolRef &Sym : File->symbols()) {
raw_ostream &OS = Writer.startLine();
OS << "Symbol: ";
Expand Down

0 comments on commit 77e1992

Please sign in to comment.