[lld] e2e132c - [LLD][COFF] Set OrdinalBase to 1 for export table

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 3 00:59:21 PDT 2022


Author: Alvin Wong
Date: 2022-10-03T10:58:44+03:00
New Revision: e2e132c5d967bb762fa00267337ed47af0163e84

URL: https://github.com/llvm/llvm-project/commit/e2e132c5d967bb762fa00267337ed47af0163e84
DIFF: https://github.com/llvm/llvm-project/commit/e2e132c5d967bb762fa00267337ed47af0163e84.diff

LOG: [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

Added: 
    

Modified: 
    lld/COFF/DLL.cpp
    lld/test/COFF/directives.s
    lld/test/COFF/dll.test
    lld/test/COFF/exclude-symbols-embedded.s
    lld/test/COFF/exclude-symbols.s
    lld/test/COFF/export-all.s
    lld/test/COFF/export-arm64.yaml
    lld/test/COFF/export-armnt.yaml
    lld/test/COFF/export-exe.test
    lld/test/COFF/export.test
    lld/test/COFF/export32.test
    lld/test/COFF/icf-xdata.s
    lld/test/COFF/imports-gnu-autoexport.s
    lld/test/COFF/includeoptional-export.s
    lld/test/COFF/lto-icf.ll

Removed: 
    


################################################################################
diff  --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 5537b142a3ea5..17b20fecfed2c 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -491,8 +491,8 @@ class ExportDirectoryChunk : public NonSectionChunk {
 
     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 @@ class ExportDirectoryChunk : public NonSectionChunk {
 
 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 @@ class ExportOrdinalChunk : public NonSectionChunk {
     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;
     }
   }

diff  --git a/lld/test/COFF/directives.s b/lld/test/COFF/directives.s
index 9c4b7efd1dc93..cc12e391b0f9d 100644
--- a/lld/test/COFF/directives.s
+++ b/lld/test/COFF/directives.s
@@ -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

diff  --git a/lld/test/COFF/dll.test b/lld/test/COFF/dll.test
index 05f6b4fa9c254..3bb328d0cacc3 100644
--- a/lld/test/COFF/dll.test
+++ b/lld/test/COFF/dll.test
@@ -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

diff  --git a/lld/test/COFF/exclude-symbols-embedded.s b/lld/test/COFF/exclude-symbols-embedded.s
index 9ea8ed479d20e..1520bb4b80280 100644
--- a/lld/test/COFF/exclude-symbols-embedded.s
+++ b/lld/test/COFF/exclude-symbols-embedded.s
@@ -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

diff  --git a/lld/test/COFF/exclude-symbols.s b/lld/test/COFF/exclude-symbols.s
index cd358712382d2..77dde77c232e9 100644
--- a/lld/test/COFF/exclude-symbols.s
+++ b/lld/test/COFF/exclude-symbols.s
@@ -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

diff  --git a/lld/test/COFF/export-all.s b/lld/test/COFF/export-all.s
index b370dbe92079e..a932bf0bba427 100644
--- a/lld/test/COFF/export-all.s
+++ b/lld/test/COFF/export-all.s
@@ -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:

diff  --git a/lld/test/COFF/export-arm64.yaml b/lld/test/COFF/export-arm64.yaml
index 72a24d5c01820..43e8205e9af3c 100644
--- a/lld/test/COFF/export-arm64.yaml
+++ b/lld/test/COFF/export-arm64.yaml
@@ -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

diff  --git a/lld/test/COFF/export-armnt.yaml b/lld/test/COFF/export-armnt.yaml
index 456564bd81fa9..a181d1c93667e 100644
--- a/lld/test/COFF/export-armnt.yaml
+++ b/lld/test/COFF/export-armnt.yaml
@@ -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

diff  --git a/lld/test/COFF/export-exe.test b/lld/test/COFF/export-exe.test
index 6d60ce4420353..b5727b0c6fcac 100644
--- a/lld/test/COFF/export-exe.test
+++ b/lld/test/COFF/export-exe.test
@@ -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

diff  --git a/lld/test/COFF/export.test b/lld/test/COFF/export.test
index eb5681cb79ecc..e53e3dea9aa29 100644
--- a/lld/test/COFF/export.test
+++ b/lld/test/COFF/export.test
@@ -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

diff  --git a/lld/test/COFF/export32.test b/lld/test/COFF/export32.test
index 7c8f831d9654e..4e15177c16128 100644
--- a/lld/test/COFF/export32.test
+++ b/lld/test/COFF/export32.test
@@ -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, at 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
 

diff  --git a/lld/test/COFF/icf-xdata.s b/lld/test/COFF/icf-xdata.s
index 959db5134232f..3adbc73d87e3e 100644
--- a/lld/test/COFF/icf-xdata.s
+++ b/lld/test/COFF/icf-xdata.s
@@ -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
 

diff  --git a/lld/test/COFF/imports-gnu-autoexport.s b/lld/test/COFF/imports-gnu-autoexport.s
index e9cd93485afbc..aaca54965c5a2 100644
--- a/lld/test/COFF/imports-gnu-autoexport.s
+++ b/lld/test/COFF/imports-gnu-autoexport.s
@@ -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

diff  --git a/lld/test/COFF/includeoptional-export.s b/lld/test/COFF/includeoptional-export.s
index 4a43109b33a4d..ed84f0b972e4d 100644
--- a/lld/test/COFF/includeoptional-export.s
+++ b/lld/test/COFF/includeoptional-export.s
@@ -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

diff  --git a/lld/test/COFF/lto-icf.ll b/lld/test/COFF/lto-icf.ll
index 0b0c26eb2ad89..156f1d2f12f33 100644
--- a/lld/test/COFF/lto-icf.ll
+++ b/lld/test/COFF/lto-icf.ll
@@ -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 {


        


More information about the llvm-commits mailing list