[PECOFF] Support export-only-by-ordinal exports.

If NONAME option is given for an export, that symbol will be exported only by
its ordinal. LLD will not emit the symbol name to the export table.

llvm-svn: 197371
This commit is contained in:
Rui Ueyama 2013-12-16 09:02:43 +00:00
parent 1aedf6c9e6
commit 64d491d118
3 changed files with 28 additions and 9 deletions

View File

@ -46,7 +46,7 @@ static bool getExportedAtoms(const PECOFFLinkingContext &ctx, MutableFile *file,
return false;
}
const DefinedAtom *atom = it->second;
ret.push_back(TableEntry(desc.name, desc.ordinal, atom));
ret.push_back(TableEntry(desc.name, desc.ordinal, atom, desc.noname));
}
std::sort(ret.begin(), ret.end(), compare);
return true;
@ -109,7 +109,7 @@ EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx,
}
edata::EdataAtom *EdataPass::createExportDirectoryTable(
const std::vector<edata::TableEntry> &entries, int ordinalBase,
const std::vector<edata::TableEntry> &namedEntries, int ordinalBase,
int maxOrdinal) {
EdataAtom *ret =
new (_alloc) EdataAtom(_file, sizeof(export_directory_table_entry));
@ -117,7 +117,7 @@ edata::EdataAtom *EdataPass::createExportDirectoryTable(
data->TimeDateStamp = time(nullptr);
data->OrdinalBase = ordinalBase;
data->AddressTableEntries = maxOrdinal - ordinalBase + 1;
data->NumberOfNamePointers = entries.size();
data->NumberOfNamePointers = namedEntries.size();
return ret;
}
@ -143,8 +143,13 @@ void EdataPass::perform(std::unique_ptr<MutableFile> &file) {
int ordinalBase, maxOrdinal;
llvm::tie(ordinalBase, maxOrdinal) = assignOrdinals(entries);
std::vector<TableEntry> namedEntries;
for (TableEntry &e : entries)
if (!e.noname)
namedEntries.push_back(e);
EdataAtom *table =
createExportDirectoryTable(entries, ordinalBase, maxOrdinal);
createExportDirectoryTable(namedEntries, ordinalBase, maxOrdinal);
file->addAtom(*table);
COFFStringAtom *dllName =
@ -161,12 +166,12 @@ void EdataPass::perform(std::unique_ptr<MutableFile> &file) {
ExportAddressTableRVA));
EdataAtom *namePointerTable =
createNamePointerTable(_ctx, entries, file.get());
createNamePointerTable(_ctx, namedEntries, file.get());
file->addAtom(*namePointerTable);
addDir32NBReloc(table, namePointerTable,
offsetof(export_directory_table_entry, NamePointerRVA));
EdataAtom *ordinalTable = createOrdinalTable(entries, ordinalBase);
EdataAtom *ordinalTable = createOrdinalTable(namedEntries, ordinalBase);
file->addAtom(*ordinalTable);
addDir32NBReloc(table, ordinalTable,
offsetof(export_directory_table_entry, OrdinalTableRVA));

View File

@ -36,11 +36,13 @@ namespace pecoff {
namespace edata {
struct TableEntry {
TableEntry(StringRef exportName, int ordinal, const DefinedAtom *atom)
: exportName(exportName), ordinal(ordinal), atom(atom) {}
TableEntry(StringRef exportName, int ordinal, const DefinedAtom *atom,
bool noname)
: exportName(exportName), ordinal(ordinal), atom(atom), noname(noname) {}
StringRef exportName;
int ordinal;
const DefinedAtom *atom;
bool noname;
};
/// The root class of all edata atoms.
@ -71,7 +73,7 @@ public:
private:
edata::EdataAtom *
createExportDirectoryTable(const std::vector<edata::TableEntry> &entries,
createExportDirectoryTable(const std::vector<edata::TableEntry> &namedEntries,
int ordinalBase, int maxOrdinal);
edata::EdataAtom *

View File

@ -25,3 +25,15 @@ 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
# RUN: lld -flavor link /out:%t3.dll /dll /subsystem:console /entry:_init \
# RUN: /export:exportfn1,@5,noname /export:exportfn2 -- %t.obj
# RUN: llvm-objdump -s %t3.dll | FileCheck -check-prefix=CHECK3 %s
CHECK3: Contents of section .edata:
CHECK3-NEXT: 1000 00000000 {{........}} 00000000 36100000
CHECK3-NEXT: 1010 05000000 02000000 01000000 28100000
CHECK3-NEXT: 1020 30100000 34100000 08200000 10200000
CHECK3-NEXT: 1030 4b100000 01006578 706f7274 2e746573
CHECK3-NEXT: 1040 742e746d 70332e64 6c6c0065 78706f72
CHECK3-NEXT: 1050 74666e32 00