[lld] r197367 - [PECOFF] Set OrdinalBase field in the export table.

Rui Ueyama ruiu at google.com
Sun Dec 15 23:14:41 PST 2013


Author: ruiu
Date: Mon Dec 16 01:14:40 2013
New Revision: 197367

URL: http://llvm.org/viewvc/llvm-project?rev=197367&view=rev
Log:
[PECOFF] Set OrdinalBase field in the export table.

OrdinalBase is an addend to the ordinals. We used to always set 1 to the field.
Although it produced a valid a DLL export table, it'd be a waste if the first
ordinal does not start with 1 -- we had to have NULL fields at the beginning of
the export address table. By setting the ordinal base, we can eliminate the
NULL fields.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h
    lld/trunk/test/pecoff/export.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=197367&r1=197366&r2=197367&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Mon Dec 16 01:14:40 2013
@@ -16,7 +16,9 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Path.h"
 
+#include <climits>
 #include <ctime>
+#include <utility>
 
 using lld::pecoff::edata::EdataAtom;
 using lld::pecoff::edata::TableEntry;
@@ -26,8 +28,6 @@ using llvm::object::export_directory_tab
 namespace lld {
 namespace pecoff {
 
-static const int ORDINAL_BASE = 1;
-
 static bool compare(const TableEntry &a, const TableEntry &b) {
   return a.exportName.compare(b.exportName) < 0;
 }
@@ -52,31 +52,38 @@ static bool getExportedAtoms(const PECOF
   return true;
 }
 
-static int assignOrdinals(std::vector<TableEntry> &entries) {
+static std::pair<int, int> assignOrdinals(std::vector<TableEntry> &entries) {
+  int ordinalBase = INT_MAX;
   int maxOrdinal = -1;
-  for (TableEntry &e : entries)
+  for (TableEntry &e : entries) {
+    if (e.ordinal > 0)
+      ordinalBase = std::min(ordinalBase, e.ordinal);
     maxOrdinal = std::max(maxOrdinal, e.ordinal);
+  }
+  if (ordinalBase == INT_MAX)
+    ordinalBase = 1;
 
   if (maxOrdinal == -1) {
     int ordinal = 0;
     for (TableEntry &e : entries)
       e.ordinal = ++ordinal;
-    return ordinal;
+    return std::pair<int, int>(ordinalBase, ordinal);
   }
   for (TableEntry &e : entries)
     if (e.ordinal == -1)
       e.ordinal = ++maxOrdinal;
-  return maxOrdinal;
+  return std::pair<int, int>(ordinalBase, maxOrdinal);
 }
 
 edata::EdataAtom *
 EdataPass::createAddressTable(const std::vector<TableEntry> &entries,
-                              int maxOrdinal) {
-  EdataAtom *addressTable = new (_alloc)
-      EdataAtom(_file, sizeof(export_address_table_entry) * maxOrdinal);
+                              int ordinalBase, int maxOrdinal) {
+  EdataAtom *addressTable =
+      new (_alloc) EdataAtom(_file, sizeof(export_address_table_entry) *
+                                        (maxOrdinal - ordinalBase + 1));
 
   for (const TableEntry &e : entries) {
-    int index = e.ordinal - ORDINAL_BASE;
+    int index = e.ordinal - ordinalBase;
     size_t offset = index * sizeof(export_address_table_entry);
     addDir32NBReloc(addressTable, e.atom, offset);
   }
@@ -102,25 +109,27 @@ EdataPass::createNamePointerTable(const
 }
 
 edata::EdataAtom *EdataPass::createExportDirectoryTable(
-    const std::vector<edata::TableEntry> &entries, int maxOrdinal) {
+    const std::vector<edata::TableEntry> &entries, int ordinalBase,
+    int maxOrdinal) {
   EdataAtom *ret =
       new (_alloc) EdataAtom(_file, sizeof(export_directory_table_entry));
   auto *data = ret->getContents<export_directory_table_entry>();
   data->TimeDateStamp = time(nullptr);
-  data->OrdinalBase = ORDINAL_BASE;
-  data->AddressTableEntries = maxOrdinal;
+  data->OrdinalBase = ordinalBase;
+  data->AddressTableEntries = maxOrdinal - ordinalBase + 1;
   data->NumberOfNamePointers = entries.size();
   return ret;
 }
 
 edata::EdataAtom *
-EdataPass::createOrdinalTable(const std::vector<TableEntry> &entries) {
+EdataPass::createOrdinalTable(const std::vector<TableEntry> &entries,
+                              int ordinalBase) {
   EdataAtom *ret =
       new (_alloc) EdataAtom(_file, sizeof(uint16_t) * entries.size());
   uint16_t *data = ret->getContents<uint16_t>();
   int i = 0;
   for (const TableEntry &e : entries)
-    data[i++] = e.ordinal - ORDINAL_BASE;
+    data[i++] = e.ordinal - ordinalBase;
   return ret;
 }
 
@@ -130,9 +139,12 @@ void EdataPass::perform(std::unique_ptr<
     return;
   if (entries.empty())
     return;
-  int maxOrdinal = assignOrdinals(entries);
 
-  EdataAtom *table = createExportDirectoryTable(entries, maxOrdinal);
+  int ordinalBase, maxOrdinal;
+  llvm::tie(ordinalBase, maxOrdinal) = assignOrdinals(entries);
+
+  EdataAtom *table =
+      createExportDirectoryTable(entries, ordinalBase, maxOrdinal);
   file->addAtom(*table);
 
   COFFStringAtom *dllName =
@@ -142,7 +154,8 @@ void EdataPass::perform(std::unique_ptr<
   addDir32NBReloc(table, dllName,
                   offsetof(export_directory_table_entry, NameRVA));
 
-  EdataAtom *addressTable = createAddressTable(entries, maxOrdinal);
+  EdataAtom *addressTable =
+      createAddressTable(entries, ordinalBase, maxOrdinal);
   file->addAtom(*addressTable);
   addDir32NBReloc(table, addressTable, offsetof(export_directory_table_entry,
                                                 ExportAddressTableRVA));
@@ -153,7 +166,7 @@ void EdataPass::perform(std::unique_ptr<
   addDir32NBReloc(table, namePointerTable,
                   offsetof(export_directory_table_entry, NamePointerRVA));
 
-  EdataAtom *ordinalTable = createOrdinalTable(entries);
+  EdataAtom *ordinalTable = createOrdinalTable(entries, ordinalBase);
   file->addAtom(*ordinalTable);
   addDir32NBReloc(table, ordinalTable,
                   offsetof(export_directory_table_entry, OrdinalTableRVA));

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h?rev=197367&r1=197366&r2=197367&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.h Mon Dec 16 01:14:40 2013
@@ -72,11 +72,11 @@ public:
 private:
   edata::EdataAtom *
   createExportDirectoryTable(const std::vector<edata::TableEntry> &entries,
-                             int maxOrdinal);
+                             int ordinalBase, int maxOrdinal);
 
   edata::EdataAtom *
   createAddressTable(const std::vector<edata::TableEntry> &entries,
-                     int maxOrdinal);
+                     int ordinalBase, int maxOrdinal);
 
   edata::EdataAtom *
   createNamePointerTable(const PECOFFLinkingContext &ctx,
@@ -84,7 +84,8 @@ private:
                          MutableFile *file);
 
   edata::EdataAtom *
-  createOrdinalTable(const std::vector<edata::TableEntry> &entries);
+  createOrdinalTable(const std::vector<edata::TableEntry> &entries,
+                     int ordinalBase);
 
   const PECOFFLinkingContext &_ctx;
   VirtualFile _file;

Modified: lld/trunk/test/pecoff/export.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/export.test?rev=197367&r1=197366&r2=197367&view=diff
==============================================================================
--- lld/trunk/test/pecoff/export.test (original)
+++ lld/trunk/test/pecoff/export.test Mon Dec 16 01:14:40 2013
@@ -18,11 +18,10 @@ CHECK1-NEXT:  1060 74666e32 00
 # RUN: llvm-objdump -s %t2.dll | FileCheck -check-prefix=CHECK2 %s
 
 CHECK2:      Contents of section .edata:
-CHECK2-NEXT:  1000 00000000 {{........}} 00000000 4c100000
-CHECK2-NEXT:  1010 01000000 06000000 02000000 28100000
-CHECK2-NEXT:  1020 40100000 48100000 00000000 00000000
-CHECK2-NEXT:  1030 00000000 00000000 08200000 10200000
-CHECK2-NEXT:  1040 61100000 6b100000 04000500 6578706f
-CHECK2-NEXT:  1050 72742e74 6573742e 746d7032 2e646c6c
-CHECK2-NEXT:  1060 00657870 6f727466 6e310065 78706f72
-CHECK2-NEXT:  1070 74666e32 00
+CHECK2-NEXT:  1000 00000000 {{........}} 00000000 3c100000
+CHECK2-NEXT:  1010 05000000 02000000 02000000 28100000
+CHECK2-NEXT:  1020 30100000 38100000 08200000 10200000
+CHECK2-NEXT:  1030 51100000 5b100000 00000100 6578706f
+CHECK2-NEXT:  1040 72742e74 6573742e 746d7032 2e646c6c
+CHECK2-NEXT:  1050 00657870 6f727466 6e310065 78706f72
+CHECK2-NEXT:  1060 74666e32 00





More information about the llvm-commits mailing list