summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-11-20 21:05:05 +0000
committerRui Ueyama <ruiu@google.com>2014-11-20 21:05:05 +0000
commit2343e65b14d3b38d37536d30aa9e77bc3a1449bc (patch)
tree8efbd0344922db6d3de2ccce4809ef297f9b20a9
parent0dcae714493752ed441ee827a7d3abc95c98e499 (diff)
downloadbcm5719-llvm-2343e65b14d3b38d37536d30aa9e77bc3a1449bc.tar.gz
bcm5719-llvm-2343e65b14d3b38d37536d30aa9e77bc3a1449bc.zip
[PECOFF] Sort export table properly.
Export table entries need to be sorted in ASCII-betical order, so that the loader can find an entry for a function by binary search. We sorted the entries by its mangled names. That can be different from their exported names. As a result, LLD produces incorrect export table, from which the loader complains that a function that actually exists in a DLL cannot be found. This patch fixes that issue. llvm-svn: 222452
-rw-r--r--lld/lib/ReaderWriter/PECOFF/EdataPass.cpp9
-rw-r--r--lld/test/pecoff/export.test5
2 files changed, 8 insertions, 6 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
index 368bb75cf9e..4edf1124532 100644
--- a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
@@ -35,7 +35,7 @@ static void assignOrdinals(PECOFFLinkingContext &ctx) {
std::sort(exports.begin(), exports.end(),
[](const PECOFFLinkingContext::ExportDesc &a,
const PECOFFLinkingContext::ExportDesc &b) {
- return a.name.compare(b.name) < 0;
+ return a.getExternalName().compare(b.getExternalName()) < 0;
});
int nextOrdinal = (maxOrdinal == -1) ? 1 : (maxOrdinal + 1);
@@ -62,13 +62,14 @@ static bool getExportedAtoms(PECOFFLinkingContext &ctx, MutableFile *file,
// One can export a symbol with a different name than the symbol
// name used in DLL. If such name is specified, use it in the
// .edata section.
- ret.push_back(TableEntry(desc.getExternalName(), desc.ordinal, atom,
- desc.noname));
+ ret.push_back(TableEntry(ctx.undecorateSymbol(desc.getExternalName()),
+ desc.ordinal, atom, desc.noname));
}
std::sort(ret.begin(), ret.end(),
[](const TableEntry &a, const TableEntry &b) {
return a.exportName.compare(b.exportName) < 0;
});
+
return true;
}
@@ -107,7 +108,7 @@ EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx,
size_t offset = 0;
for (const TableEntry &e : entries) {
auto *stringAtom = new (_alloc) COFFStringAtom(
- _file, _stringOrdinal++, ".edata", ctx.undecorateSymbol(e.exportName));
+ _file, _stringOrdinal++, ".edata", e.exportName);
file->addAtom(*stringAtom);
addDir32NBReloc(table, stringAtom, _ctx.getMachineType(), offset);
offset += sizeof(uint32_t);
diff --git a/lld/test/pecoff/export.test b/lld/test/pecoff/export.test
index 3791bdb8702..cbe8960e26f 100644
--- a/lld/test/pecoff/export.test
+++ b/lld/test/pecoff/export.test
@@ -82,5 +82,6 @@ DUP-NOT: exportfn3@256
EQUAL: Export Table:
EQUAL: DLL name: export.test.tmp1.dll
EQUAL: Ordinal RVA Name
-EQUAL-NEXT: 1 0x2008 f1
-EQUAL-NEXT: 2 0x2010 f2
+EQUAL-NEXT: 1 0x2010 exportfn3@256
+EQUAL-NEXT: 2 0x2008 f1
+EQUAL-NEXT: 3 0x2010 f2
OpenPOWER on IntegriCloud