[lld] r197970 - [PECOFF] Fix /export option in the .drectve section.

Rui Ueyama ruiu at google.com
Tue Dec 24 01:15:57 PST 2013


Author: ruiu
Date: Tue Dec 24 03:15:57 2013
New Revision: 197970

URL: http://llvm.org/viewvc/llvm-project?rev=197970&view=rev
Log:
[PECOFF] Fix /export option in the .drectve section.

/EXPORT option has slightly different semantics if it appears in the .drectve
section. This patch implements it.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Dec 24 03:15:57 2013
@@ -98,6 +98,7 @@ public:
   StringRef searchLibraryFile(StringRef path) const;
 
   StringRef decorateSymbol(StringRef name) const;
+  StringRef undecorateSymbol(StringRef name) const;
 
   void setEntrySymbolName(StringRef name) {
     if (!name.empty())

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Dec 24 03:15:57 2013
@@ -892,6 +892,15 @@ WinLinkDriver::parse(int argc, const cha
                     << inputArg->getValue() << "\n";
         return false;
       }
+
+      // Mangle the symbol name only if it is reading user-supplied command line
+      // arguments. Because the symbol name in the .drectve section is already
+      // mangled by the compiler, we shouldn't add a leading undescore here.
+      // It's odd that the command line option has different semantics in the
+      // .drectve section, but this behavior is needed for compatibility with
+      // MSVC's link.exe.
+      if (!isReadingDirectiveSection)
+        desc.name = ctx.decorateSymbol(desc.name);
       ctx.addDllExport(desc);
       break;
     }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Tue Dec 24 03:15:57 2013
@@ -39,7 +39,7 @@ static bool getExportedAtoms(const PECOF
     definedAtoms[atom->name()] = atom;
 
   for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
-    auto it = definedAtoms.find(ctx.decorateSymbol(desc.name));
+    auto it = definedAtoms.find(desc.name);
     if (it == definedAtoms.end()) {
       llvm::errs() << "Symbol <" << desc.name
                    << "> is exported but not defined.\n";
@@ -86,8 +86,8 @@ EdataPass::createNamePointerTable(const
 
   size_t offset = 0;
   for (const TableEntry &e : entries) {
-    auto *stringAtom = new (_alloc)
-        COFFStringAtom(_file, _stringOrdinal++, ".edata", e.exportName);
+    auto *stringAtom = new (_alloc) COFFStringAtom(
+        _file, _stringOrdinal++, ".edata", ctx.undecorateSymbol(e.exportName));
     file->addAtom(*stringAtom);
     addDir32NBReloc(table, stringAtom, offset);
     offset += sizeof(uint32_t);

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Dec 24 03:15:57 2013
@@ -219,6 +219,13 @@ StringRef PECOFFLinkingContext::decorate
   return allocate(str);
 }
 
+StringRef PECOFFLinkingContext::undecorateSymbol(StringRef name) const {
+  if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386)
+    return name;
+  assert(name.startswith("_"));
+  return name.substr(1);
+}
+
 Writer &PECOFFLinkingContext::writer() const { return *_writer; }
 
 

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp Tue Dec 24 03:15:57 2013
@@ -42,7 +42,7 @@ createModuleDefinitionFile(const PECOFFL
      << "EXPORTS\n";
 
   for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
-    os << "  " << desc.name << " @" << desc.ordinal;
+    os << "  " << ctx.undecorateSymbol(desc.name) << " @" << desc.ordinal;
     if (desc.noname)
       os << " NONAME";
     if (desc.isData)

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=197970&r1=197969&r2=197970&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Dec 24 03:15:57 2013
@@ -161,7 +161,7 @@ TEST_F(WinLinkParserTest, Export) {
   const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
       _context.getDllExports();
   EXPECT_TRUE(exports.size() == 1);
-  EXPECT_EQ("foo", exports[0].name);
+  EXPECT_EQ("_foo", exports[0].name);
   EXPECT_EQ(1, exports[0].ordinal);
   EXPECT_FALSE(exports[0].noname);
   EXPECT_FALSE(exports[0].isData);
@@ -173,11 +173,11 @@ TEST_F(WinLinkParserTest, ExportWithOpti
   const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
       _context.getDllExports();
   EXPECT_TRUE(exports.size() == 2);
-  EXPECT_EQ("foo", exports[0].name);
+  EXPECT_EQ("_foo", exports[0].name);
   EXPECT_EQ(8, exports[0].ordinal);
   EXPECT_TRUE(exports[0].noname);
   EXPECT_TRUE(exports[0].isData);
-  EXPECT_EQ("bar", exports[1].name);
+  EXPECT_EQ("_bar", exports[1].name);
   EXPECT_EQ(10, exports[1].ordinal);
   EXPECT_FALSE(exports[1].noname);
   EXPECT_TRUE(exports[1].isData);





More information about the llvm-commits mailing list