[llvm-readobj][Object][COFF] Print COFF import library symbol export 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.
This commit is contained in:
Jacek Caban 2024-02-06 13:47:58 +01:00 committed by GitHub
parent 2e3de997ab
commit a2e5287d5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 64 additions and 0 deletions

View File

@ -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

View File

@ -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
@ -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
@ -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
@ -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

View File

@ -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

View File

@ -66,6 +66,7 @@ public:
uint16_t getMachine() const { return getCOFFImportHeader()->Machine; }
StringRef getFileFormatName() const;
StringRef getExportName() const;
private:
bool isData() const {

View File

@ -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:

View File

@ -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

View File

@ -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{{$}}

View File

@ -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

View File

@ -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

View File

@ -36,6 +36,7 @@ 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:
@ -43,6 +44,7 @@ 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:

View File

@ -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:{{.}}

View File

@ -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: ";