[lld] r189267 - [PECOFF] Add Support for entry point symbol name

Rui Ueyama ruiu at google.com
Mon Aug 26 12:55:10 PDT 2013


Author: ruiu
Date: Mon Aug 26 14:55:09 2013
New Revision: 189267

URL: http://llvm.org/viewvc/llvm-project?rev=189267&view=rev
Log:
[PECOFF] Add Support for entry point symbol name

Patch by Jesús Serrano García.

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.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=189267&r1=189266&r2=189267&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Mon Aug 26 14:55:09 2013
@@ -30,7 +30,7 @@ public:
         _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), _minOSVersion(6, 0),
         _nxCompat(true), _largeAddressAware(false),
         _baseRelocationEnabled(true), _terminalServerAware(true),
-        _dynamicBaseEnabled(true) {}
+        _dynamicBaseEnabled(true), _imageType(ImageType::IMAGE_EXE) {}
 
   struct OSVersion {
     OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {}
@@ -41,6 +41,11 @@ public:
   /// \brief Casting support
   static inline bool classof(const LinkingContext *info) { return true; }
 
+  enum ImageType {
+    IMAGE_EXE,
+    IMAGE_DLL
+  };
+
   virtual error_code
   parseFile(std::unique_ptr<MemoryBuffer> &mb,
             std::vector<std::unique_ptr<File> > &result) const;
@@ -96,6 +101,9 @@ public:
   void setDynamicBaseEnabled(bool val) { _dynamicBaseEnabled = val; }
   bool getDynamicBaseEnabled() const { return _dynamicBaseEnabled; }
 
+  void setImageType(ImageType type) { _imageType = type; }
+  ImageType getImageType() const { return _imageType; }
+
   virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
@@ -128,6 +136,7 @@ private:
   bool _baseRelocationEnabled;
   bool _terminalServerAware;
   bool _dynamicBaseEnabled;
+  ImageType _imageType;
 
   std::vector<StringRef> _inputSearchPaths;
   mutable std::unique_ptr<Reader> _reader;

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=189267&r1=189266&r2=189267&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Aug 26 14:55:09 2013
@@ -162,6 +162,21 @@ void processLibEnv(PECOFFLinkingContext
       context.appendInputSearchPath(context.allocateString(path));
 }
 
+// Sets a default entry point symbol name depending on context image type and
+// subsystem. These default names are MS CRT compliant.
+void setDefaultEntrySymbolName(PECOFFLinkingContext &context) {
+  if (context.getImageType() == PECOFFLinkingContext::ImageType::IMAGE_DLL) {
+    context.setEntrySymbolName("__DllMainCRTStartup");
+  } else {
+    llvm::COFF::WindowsSubsystem subsystem = context.getSubsystem();
+    if (subsystem == llvm::COFF::WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_GUI)
+      context.setEntrySymbolName("_WinMainCRTStartup");
+    else if (subsystem ==
+      llvm::COFF::WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_CUI)
+      context.setEntrySymbolName("_mainCRTStartup");
+  }
+}
+
 // Parses the given command line options and returns the result. Returns NULL if
 // there's an error in the options.
 std::unique_ptr<llvm::opt::InputArgList> parseArgs(int argc, const char *argv[],
@@ -406,6 +421,10 @@ bool WinLinkDriver::parse(int argc, cons
     }
   }
 
+  // Use the default entry name if /entry option is not given.
+  if (!parsedArgs->getLastArg(OPT_entry))
+    setDefaultEntrySymbolName(ctx);
+
   // Arguments after "--" are interpreted as filenames even if they
   // start with a hypen or a slash. This is not compatible with link.exe
   // but useful for us to test lld on Unix.

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=189267&r1=189266&r2=189267&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Mon Aug 26 14:55:09 2013
@@ -248,6 +248,10 @@ public:
 
   virtual void setSizeOfImage(uint32_t size) { _peHeader.SizeOfImage = size; }
 
+  virtual void setAddressOfEntryPoint(uint32_t address) {
+    _peHeader.AddressOfEntryPoint = address;
+  }
+
 private:
   llvm::object::coff_file_header _coffHeader;
   llvm::object::pe32_header _peHeader;
@@ -356,6 +360,13 @@ public:
       layout->_virtualAddr += rva;
   }
 
+  uint64_t getAtomVirtualAddress(StringRef name) {
+    for (auto atomLayout : _atomLayouts)
+      if (atomLayout->_atom->name() == name)
+        return atomLayout->_virtualAddr;
+    return 0;
+  }
+
   static bool classof(const Chunk *c) {
     Kind kind = c->getKind();
     return kind == kindSection || kind == kindDataDirectory;
@@ -794,6 +805,8 @@ public:
     peHeader->setSizeOfUninitializedData(bss->size());
     peHeader->setNumberOfSections(_numSections);
     peHeader->setSizeOfImage(_imageSizeInMemory);
+
+    setAddressOfEntryPoint(text, peHeader);
   }
 
   virtual error_code writeFile(const File &linkedFile, StringRef path) {
@@ -853,6 +866,22 @@ private:
     }
   }
 
+  void setAddressOfEntryPoint(TextSectionChunk *text, PEHeaderChunk *peHeader) {
+    // Find the virtual address of the entry point symbol if any.
+    // PECOFF spec says that entry point for dll images is optional, in which
+    // case it must be set to 0.
+    if (_PECOFFLinkingContext.entrySymbolName().empty() &&
+        _PECOFFLinkingContext.getImageType()
+                              == PECOFFLinkingContext::IMAGE_DLL) {
+      peHeader->setAddressOfEntryPoint(0);
+    } else {
+      uint64_t entryPointAddress = text->getAtomVirtualAddress(
+        _PECOFFLinkingContext.entrySymbolName());
+      if (entryPointAddress != 0)
+        peHeader->setAddressOfEntryPoint(entryPointAddress);
+    }
+  }
+
   std::vector<std::unique_ptr<Chunk>> _chunks;
   const PECOFFLinkingContext &_PECOFFLinkingContext;
   uint32_t _numSections;

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=189267&r1=189266&r2=189267&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Mon Aug 26 14:55:09 2013
@@ -244,4 +244,14 @@ TEST_F(WinLinkParserTest, DashDash) {
   EXPECT_EQ("-c.obj", inputFile(2));
 }
 
+TEST_F(WinLinkParserTest, DefEntryNameConsole) {
+  EXPECT_FALSE(parse("link.exe", "/subsystem:console", "a.obj", nullptr));
+  EXPECT_EQ("_mainCRTStartup", _context.entrySymbolName());
+}
+
+TEST_F(WinLinkParserTest, DefEntryNameWindows) {
+  EXPECT_FALSE(parse("link.exe", "/subsystem:windows", "a.obj", nullptr));
+  EXPECT_EQ("_WinMainCRTStartup", _context.entrySymbolName());
+}
+
 } // end anonymous namespace





More information about the llvm-commits mailing list