diff options
author | Rui Ueyama <ruiu@google.com> | 2014-11-20 21:05:05 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2014-11-20 21:05:05 +0000 |
commit | 2343e65b14d3b38d37536d30aa9e77bc3a1449bc (patch) | |
tree | 8efbd0344922db6d3de2ccce4809ef297f9b20a9 | |
parent | 0dcae714493752ed441ee827a7d3abc95c98e499 (diff) | |
download | bcm5719-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.cpp | 9 | ||||
-rw-r--r-- | lld/test/pecoff/export.test | 5 |
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 |