[lld] r220333 - [PECOFF] Fix exported symbol in the import library

Rui Ueyama ruiu at google.com
Tue Oct 21 14:41:28 PDT 2014


Author: ruiu
Date: Tue Oct 21 16:41:28 2014
New Revision: 220333

URL: http://llvm.org/viewvc/llvm-project?rev=220333&view=rev
Log:
[PECOFF] Fix exported symbol in the import library

There are two ways to specify a symbol to be exported in the module
definition file.

1) EXPORT <external name> = <symbol>
2) EXPORT <symbol>

In (1), you give both external name and internal name. In that case,
the linker tries to find a symbol using the internal name, and write
that address to the export table with the external name. Thus, from
the outer world, the symbol seems to be exported as the external name.

In (2), internal name is basically the same as the external name
with an exception: if you give an undecorated symbol to the EXPORT
directive, and if the linker finds a decorated symbol, the external
name for the symbol will become the decorated symbol.

LLD didn't implement that exception correctly. This patch fixes that.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkModuleDef.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
    lld/trunk/test/pecoff/export.test

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Oct 21 16:41:28 2014
@@ -61,8 +61,15 @@ public:
   struct ExportDesc {
     ExportDesc()
         : ordinal(-1), noname(false), isData(false), isPrivate(false) {}
+
     bool operator<(const ExportDesc &other) const {
-      return name.compare(other.name) < 0;
+      return getExternalName().compare(other.getExternalName()) < 0;
+    }
+
+    StringRef getExternalName() const {
+      if (!externalName.empty())
+        return externalName;
+      return name;
     }
 
     std::string name;

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Oct 21 16:41:28 2014
@@ -392,7 +392,6 @@ static bool parseExport(StringRef option
     return false;
   if (name.find('=') == StringRef::npos) {
     ret.name = name;
-    ret.externalName = name;
   } else {
     std::tie(ret.externalName, ret.name) = name.split("=");
     if (ret.name.empty())

Modified: lld/trunk/lib/Driver/WinLinkModuleDef.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkModuleDef.cpp?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkModuleDef.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkModuleDef.cpp Tue Oct 21 16:41:28 2014
@@ -197,13 +197,13 @@ bool Parser::parseExport(PECOFFLinkingCo
     return false;
   }
   result.name = _tok._range;
-  result.externalName = result.name;
 
   consumeToken();
   if (_tok._kind == Kind::equal) {
     consumeToken();
     if (_tok._kind != Kind::identifier)
       return false;
+    result.externalName = result.name;
     result.name = _tok._range;
   } else {
     ungetToken();

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Tue Oct 21 16:41:28 2014
@@ -62,7 +62,8 @@ static bool getExportedAtoms(PECOFFLinki
     // 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.externalName, desc.ordinal, atom, desc.noname));
+    ret.push_back(TableEntry(desc.getExternalName(), desc.ordinal, atom,
+                             desc.noname));
   }
   std::sort(ret.begin(), ret.end(),
             [](const TableEntry &a, const TableEntry &b) {

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp Tue Oct 21 16:41:28 2014
@@ -30,7 +30,7 @@ createModuleDefinitionFile(const PECOFFL
      << "EXPORTS\n";
 
   for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
-    os << "  " << desc.externalName;
+    os << "  " << desc.getExternalName();
     if (!desc.isPrivate)
       os << " @" << desc.ordinal;
     if (desc.noname)

Modified: lld/trunk/test/pecoff/export.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/export.test?rev=220333&r1=220332&r2=220333&view=diff
==============================================================================
--- lld/trunk/test/pecoff/export.test (original)
+++ lld/trunk/test/pecoff/export.test Tue Oct 21 16:41:28 2014
@@ -58,7 +58,7 @@ CHECK5-NEXT:        1   0x2010  exportfn
 CHECK6:      Export Table:
 CHECK6:      DLL name: export.test.tmp6.dll
 CHECK6:       Ordinal      RVA  Name
-CHECK6-NEXT:        1   0x2010  exportfn8
+CHECK6-NEXT:        1   0x2010  ?exportfn8@@YAXXZ
 
 # RUN: lld -flavor link /out:%t6.dll /dll /entry:init \
 # RUN:   /export:exportfn8 /export:exportfn8 -- %t.obj
@@ -67,8 +67,8 @@ CHECK6-NEXT:        1   0x2010  exportfn
 DUP:      Export Table:
 DUP:      DLL name: export.test.tmp6.dll
 DUP:       Ordinal      RVA  Name
-DUP:            1   0x2010  exportfn8
-DUP-NOT:        1   0x2010  exportfn8
+DUP:            1   0x2010  ?exportfn8@@YAXXZ
+DUP-NOT:        1   0x2010  ?exportfn8@@YAXXZ
 
 # RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj
 #





More information about the llvm-commits mailing list