[PECOFF] Sort export table properly.
authorRui Ueyama <ruiu@google.com>
Thu, 20 Nov 2014 21:05:05 +0000 (21:05 +0000)
committerRui Ueyama <ruiu@google.com>
Thu, 20 Nov 2014 21:05:05 +0000 (21:05 +0000)
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

lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
lld/test/pecoff/export.test

index 368bb75..4edf112 100644 (file)
@@ -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);
index 3791bdb..cbe8960 100644 (file)
@@ -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