[LLD][COFF] Set OrdinalBase to 1 for export table
Before this, LLD sets OrdinalBase to 0, which deviates from usual practices. This technically would allow LLD to export a symbol using ordinal 0, however LLD never use export ordinal 0, which results in binaries with export tables always having an empty export at ordinal 0. This change makes LLD set OrdinalBase to 1 and not create the empty export with ordinal 0, which makes its behaviour more in line with both the MSVC linker and the GNU linker. Reviewed By: mstorsjo Differential Revision: https://reviews.llvm.org/D134140
This commit is contained in:
parent
dd9dfb57da
commit
e2e132c5d9
@ -491,8 +491,8 @@ public:
|
||||
|
||||
auto *e = (export_directory_table_entry *)(buf);
|
||||
e->NameRVA = dllName->getRVA();
|
||||
e->OrdinalBase = 0;
|
||||
e->AddressTableEntries = maxOrdinal + 1;
|
||||
e->OrdinalBase = 1;
|
||||
e->AddressTableEntries = maxOrdinal;
|
||||
e->NumberOfNamePointers = nameTabSize;
|
||||
e->ExportAddressTableRVA = addressTab->getRVA();
|
||||
e->NamePointerRVA = nameTab->getRVA();
|
||||
@ -509,14 +509,16 @@ public:
|
||||
|
||||
class AddressTableChunk : public NonSectionChunk {
|
||||
public:
|
||||
explicit AddressTableChunk(size_t maxOrdinal) : size(maxOrdinal + 1) {}
|
||||
explicit AddressTableChunk(size_t maxOrdinal) : size(maxOrdinal) {}
|
||||
size_t getSize() const override { return size * 4; }
|
||||
|
||||
void writeTo(uint8_t *buf) const override {
|
||||
memset(buf, 0, getSize());
|
||||
|
||||
for (const Export &e : config->exports) {
|
||||
uint8_t *p = buf + e.ordinal * 4;
|
||||
assert(e.ordinal != 0 && "Export symbol has invalid ordinal");
|
||||
// OrdinalBase is 1, so subtract 1 to get the index.
|
||||
uint8_t *p = buf + (e.ordinal - 1) * 4;
|
||||
uint32_t bit = 0;
|
||||
// Pointer to thumb code must have the LSB set, so adjust it.
|
||||
if (config->machine == ARMNT && !e.data)
|
||||
@ -560,7 +562,9 @@ public:
|
||||
for (Export &e : config->exports) {
|
||||
if (e.noname)
|
||||
continue;
|
||||
write16le(buf, e.ordinal);
|
||||
assert(e.ordinal != 0 && "Export symbol has invalid ordinal");
|
||||
// This table stores unbiased indices, so subtract 1 (OrdinalBase).
|
||||
write16le(buf, e.ordinal - 1);
|
||||
buf += 2;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
# CHECK: Export Table:
|
||||
# CHECK: DLL name: directives.s.tmp.dll
|
||||
# CHECK: Ordinal RVA Name
|
||||
# CHECK-NEXT: 0 0
|
||||
# CHECK-NEXT: 1 0x1000 exportfn1
|
||||
# CHECK-NEXT: 2 0x1000 exportfn2
|
||||
# CHECK-NEXT: 3 0x1000 exportfn3
|
||||
|
@ -7,7 +7,6 @@
|
||||
EXPORT: Export Table:
|
||||
EXPORT: DLL name: dll.test.tmp.dll
|
||||
EXPORT: Ordinal RVA Name
|
||||
EXPORT-NEXT: 0 0
|
||||
EXPORT-NEXT: 1 0x1008 exportfn1
|
||||
EXPORT-NEXT: 2 0x1010 exportfn2
|
||||
EXPORT-NEXT: 3 0x1010 exportfn3
|
||||
@ -22,7 +21,6 @@ EXPORT-NEXT: 4 0x1010 mangled
|
||||
EXPORT2: Export Table:
|
||||
EXPORT2: DLL name: dll.test.tmp5.dll
|
||||
EXPORT2: Ordinal RVA Name
|
||||
EXPORT2-NEXT: 0 0
|
||||
EXPORT2-NEXT: 1 0x1010 exportfn3
|
||||
EXPORT2-NEXT: 2 0x101c mangled2
|
||||
|
||||
@ -33,7 +31,6 @@ EXPORT2-NEXT: 2 0x101c mangled2
|
||||
EXPORT-LTO: Export Table:
|
||||
EXPORT-LTO: DLL name: dll.test.tmp.lto.dll
|
||||
EXPORT-LTO: Ordinal RVA Name
|
||||
EXPORT-LTO-NEXT: 0 0
|
||||
EXPORT-LTO-NEXT: 1 0x1010 exportfn1
|
||||
EXPORT-LTO-NEXT: 2 0x1020 exportfn2
|
||||
EXPORT-LTO-NEXT: 3 0x1030 exportfn3
|
||||
|
@ -4,7 +4,6 @@
|
||||
// RUN: lld-link -lldmingw -dll -out:%t.dll %t.o -noentry
|
||||
// RUN: llvm-readobj --coff-exports %t.dll | FileCheck --implicit-check-not=Name: %s
|
||||
|
||||
// CHECK: Name:
|
||||
// CHECK: Name: sym1
|
||||
|
||||
.global _sym1
|
||||
|
@ -4,7 +4,6 @@
|
||||
// RUN: lld-link -lldmingw -dll -out:%t.dll %t.o -noentry -exclude-symbols:sym2,unknownsym -exclude-symbols:unknownsym,sym3
|
||||
// RUN: llvm-readobj --coff-exports %t.dll | FileCheck --implicit-check-not=Name: %s
|
||||
|
||||
// CHECK: Name:
|
||||
// CHECK: Name: sym1
|
||||
|
||||
.global _sym1
|
||||
|
@ -7,8 +7,8 @@
|
||||
# RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s --check-prefix=CHECK-RVA
|
||||
# RUN: llvm-readobj %t.lib | FileCheck -check-prefix=IMPLIB %s
|
||||
|
||||
# CHECK: Name:
|
||||
# CHECK-NEXT: Name: comdatFunc
|
||||
# CHECK: Name:
|
||||
# CHECK-SAME: comdatFunc
|
||||
# CHECK-NEXT: Name: dataSym
|
||||
# CHECK-NEXT: Name: foobar
|
||||
# CHECK-EMPTY:
|
||||
|
@ -8,7 +8,6 @@
|
||||
# CHECK: Export Table:
|
||||
# CHECK: DLL name: export-arm64.yaml.tmp.dll
|
||||
# CHECK: Ordinal RVA Name
|
||||
# CHECK-NEXT: 0 0
|
||||
# CHECK-NEXT: 1 0x1008 exportfn1
|
||||
# CHECK-NEXT: 2 0x1010 exportfn2
|
||||
# CHECK-NEXT: 3 0x1018 exportfn3
|
||||
|
@ -8,7 +8,6 @@
|
||||
# CHECK: Export Table:
|
||||
# CHECK: DLL name: export-armnt.yaml.tmp.dll
|
||||
# CHECK: Ordinal RVA Name
|
||||
# CHECK-NEXT: 0 0
|
||||
# CHECK-NEXT: 1 0x3000 exportdata
|
||||
# CHECK-NEXT: 2 0x1005 exportfn1
|
||||
# CHECK-NEXT: 3 0x1009 exportfn2
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
CHECK: Export Table:
|
||||
CHECK-NEXT: DLL name: export-exe.test.tmp.exe
|
||||
CHECK-NEXT: Ordinal base: 0
|
||||
CHECK-NEXT: Ordinal base: 1
|
||||
CHECK-NEXT: Ordinal RVA Name
|
||||
CHECK-NEXT: 0 0
|
||||
CHECK-NEXT: 1 0x1000 main
|
||||
|
@ -6,7 +6,6 @@
|
||||
CHECK1: Export Table:
|
||||
CHECK1: DLL name: export.test.tmp.dll
|
||||
CHECK1: Ordinal RVA Name
|
||||
CHECK1-NEXT: 0 0
|
||||
CHECK1-NEXT: 1 0x1008 exportfn1
|
||||
CHECK1-NEXT: 2 0x1010 exportfn2
|
||||
|
||||
@ -16,7 +15,6 @@ CHECK1-NEXT: 2 0x1010 exportfn2
|
||||
CHECK2: Export Table:
|
||||
CHECK2: DLL name: export.test.tmp.dll
|
||||
CHECK2: Ordinal RVA Name
|
||||
CHECK2-NEXT: 0 0
|
||||
CHECK2-NEXT: 1 0
|
||||
CHECK2-NEXT: 2 0
|
||||
CHECK2-NEXT: 3 0
|
||||
@ -31,7 +29,6 @@ CHECK2-NEXT: 7 0x1010 exportfn3
|
||||
CHECK3: Export Table:
|
||||
CHECK3: DLL name: export.test.tmp.dll
|
||||
CHECK3: Ordinal RVA Name
|
||||
CHECK3-NEXT: 0 0
|
||||
CHECK3-NEXT: 1 0
|
||||
CHECK3-NEXT: 2 0
|
||||
CHECK3-NEXT: 3 0
|
||||
@ -46,7 +43,6 @@ CHECK3-NEXT: 6 0x1010 exportfn2
|
||||
CHECK4: Export Table:
|
||||
CHECK4: DLL name: export.test.tmp.dll
|
||||
CHECK4: Ordinal RVA Name
|
||||
CHECK4-NEXT: 0 0
|
||||
CHECK4-NEXT: 1 0x1010 exportfn3
|
||||
CHECK4-NEXT: 2 0x1008 f1
|
||||
CHECK4-NEXT: 3 0x1010 f2
|
||||
@ -61,7 +57,6 @@ CHECK4-NM: 00000000 T f2
|
||||
CHECK5: Export Table:
|
||||
CHECK5: DLL name: export.test.tmp.dll
|
||||
CHECK5: Ordinal RVA Name
|
||||
CHECK5-NEXT: 0 0
|
||||
CHECK5-NEXT: 1 0
|
||||
CHECK5-NEXT: 2 0x1010 fn2
|
||||
CHECK5-NEXT: 3 0x1008 exportfn1
|
||||
@ -92,9 +87,8 @@ SYMTAB: exportfn3 in export.test.tmp.DLL
|
||||
|
||||
FORWARDER: Export Table:
|
||||
FORWARDER: DLL name: export.test.tmp.dll
|
||||
FORWARDER: Ordinal base: 0
|
||||
FORWARDER: Ordinal base: 1
|
||||
FORWARDER: Ordinal RVA Name
|
||||
FORWARDER: 0 0
|
||||
FORWARDER: 1 0x1010 exportfn
|
||||
FORWARDER: 2 foo (forwarded to kernel32.foobar)
|
||||
|
||||
@ -103,6 +97,5 @@ FORWARDER: 2 foo (forwarded to kernel32.foobar)
|
||||
|
||||
MERGE: DLL name: export.test.tmp.dll
|
||||
MERGE: Ordinal RVA Name
|
||||
MERGE-NEXT: 0 0
|
||||
MERGE-NEXT: 1 0x1008 exportfn1
|
||||
MERGE-NEXT: 2 0x1010 exportfn2
|
||||
|
@ -10,14 +10,13 @@
|
||||
# CHECK1: Export Table:
|
||||
# CHECK1: DLL name: export32.test.tmp.dll
|
||||
# CHECK1: Ordinal RVA Name
|
||||
# CHECK1-NEXT: 0 0
|
||||
# CHECK1-NEXT: 1 0x1008 exportfn1
|
||||
# CHECK1-NEXT: 2 0x1010 exportfn2
|
||||
|
||||
# HEADER-MERGE: ExportTableRVA: 0x2000
|
||||
# HEADER-MERGE-NEXT: ExportTableSize: 0x7E
|
||||
# HEADER-MERGE-NEXT: ExportTableSize: 0x7A
|
||||
# HEADER-MERGE: Name: .rdata
|
||||
# HEADER-MERGE-NEXT: VirtualSize: 0x7E
|
||||
# HEADER-MERGE-NEXT: VirtualSize: 0x7A
|
||||
# HEADER-MERGE-NEXT: VirtualAddress: 0x2000
|
||||
|
||||
# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
|
||||
@ -27,7 +26,6 @@
|
||||
# CHECK2: Export Table:
|
||||
# CHECK2: DLL name: export32.test.tmp.dll
|
||||
# CHECK2: Ordinal RVA Name
|
||||
# CHECK2-NEXT: 0 0
|
||||
# CHECK2-NEXT: 1 0
|
||||
# CHECK2-NEXT: 2 0
|
||||
# CHECK2-NEXT: 3 0
|
||||
@ -43,7 +41,6 @@
|
||||
# CHECK3: Export Table:
|
||||
# CHECK3: DLL name: export32.test.tmp.dll
|
||||
# CHECK3: Ordinal RVA Name
|
||||
# CHECK3-NEXT: 0 0
|
||||
# CHECK3-NEXT: 1 0
|
||||
# CHECK3-NEXT: 2 0
|
||||
# CHECK3-NEXT: 3 0
|
||||
@ -57,7 +54,6 @@
|
||||
# CHECK4: Export Table:
|
||||
# CHECK4: DLL name: export32.test.tmp.dll
|
||||
# CHECK4: Ordinal RVA Name
|
||||
# CHECK4-NEXT: 0 0
|
||||
# CHECK4-NEXT: 1 0x1010 exportfn3
|
||||
# CHECK4-NEXT: 2 0x1008 f1
|
||||
# CHECK4-NEXT: 3 0x1010 f2
|
||||
@ -75,7 +71,6 @@
|
||||
# CHECK5: Export Table:
|
||||
# CHECK5: DLL name: export32.test.tmp.dll
|
||||
# CHECK5: Ordinal RVA Name
|
||||
# CHECK5-NEXT: 0 0
|
||||
# CHECK5-NEXT: 1 0
|
||||
# CHECK5-NEXT: 2 0x1010 fn2
|
||||
# CHECK5-NEXT: 3 0x1008 exportfn1
|
||||
@ -94,7 +89,6 @@
|
||||
# CHECK7: Export Table:
|
||||
# CHECK7: DLL name: export32.test.tmp.dll
|
||||
# CHECK7: Ordinal RVA Name
|
||||
# CHECK7-NEXT: 0 0
|
||||
# CHECK7-NEXT: 1 0
|
||||
# CHECK7-NEXT: 2 0x1010 foo
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
# There shouldn't be much xdata, because all three .pdata entries (12 bytes
|
||||
# each) should use the same .xdata unwind info.
|
||||
# XDATA: Name: .rdata
|
||||
# XDATA-NEXT: VirtualSize: 0x73
|
||||
# XDATA-NEXT: VirtualSize: 0x6F
|
||||
# XDATA: Name: .pdata
|
||||
# XDATA-NEXT: VirtualSize: 0x24
|
||||
# XDATA: Name: .xdata
|
||||
@ -18,7 +18,7 @@
|
||||
# WARN: warning: .xdata=.rdata: already merged into .xdata
|
||||
#
|
||||
# RDATA: Name: .rdata
|
||||
# RDATA-NEXT: VirtualSize: 0x7C
|
||||
# RDATA-NEXT: VirtualSize: 0x78
|
||||
# RDATA: Name: .pdata
|
||||
# RDATA-NEXT: VirtualSize: 0x24
|
||||
|
||||
|
@ -13,11 +13,6 @@
|
||||
# from the import library.
|
||||
|
||||
EXPORT: Export {
|
||||
EXPORT-NEXT: Ordinal: 0
|
||||
EXPORT-NEXT: Name:
|
||||
EXPORT-NEXT: RVA: 0x0
|
||||
EXPORT-NEXT: }
|
||||
EXPORT-NEXT: Export {
|
||||
EXPORT-NEXT: Ordinal: 1
|
||||
EXPORT-NEXT: Name: main
|
||||
EXPORT-NEXT: RVA: 0x1010
|
||||
|
@ -13,10 +13,8 @@
|
||||
// RUN: llvm-readobj --coff-exports %t-1.dll | FileCheck --implicit-check-not=Name: %s --check-prefix=CHECK-DEFAULT
|
||||
// RUN: llvm-readobj --coff-exports %t-2.dll | FileCheck --implicit-check-not=Name: %s --check-prefix=CHECK-INCLUDEOPTIONAL
|
||||
|
||||
// CHECK-DEFAULT: Name:
|
||||
// CHECK-DEFAULT: Name: myfunc
|
||||
|
||||
// CHECK-INCLUDEOPTIONAL: Name:
|
||||
// CHECK-INCLUDEOPTIONAL: Name: libfunc
|
||||
// CHECK-INCLUDEOPTIONAL: Name: myfunc
|
||||
// CHECK-INCLUDEOPTIONAL: Name: otherlibfunc
|
||||
|
@ -6,7 +6,6 @@
|
||||
; RUN: lld-link -opt:icf -dll -noentry %t.bc -out:%t.dll
|
||||
; RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s
|
||||
|
||||
; CHECK: Export {
|
||||
; CHECK: Export {
|
||||
; CHECK: RVA: 0x[[RVA:.*]]
|
||||
; CHECK: Export {
|
||||
|
Loading…
x
Reference in New Issue
Block a user