[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