[PATCH][lld][PECOFF] Add Support for entry point symbol name

Jesús Serrano García dagonoweda at gmail.com
Tue Jul 30 15:46:47 PDT 2013


Hi Rui,
Thanks for the corrections, I've attached a new patch. For future 
patches, I'll review the code style guide, which is very different from 
what I'm used to. However, I have some doubts in a couple of things.

>
> Looks like the entry function name should be _mainCRTStartup if 
> subsystem is "console",
> _WinMainCRTStartup if subsystem is "windows", and 
> "__DllMainCRTStartup" for DLL.
> See http://msdn.microsoft.com/en-us/library/f9t8842e(v=vs.80).aspx 
> <http://msdn.microsoft.com/en-us/library/f9t8842e%28v=vs.80%29.aspx>.
I think this is rather a Visual Studio convention for its C runtime 
library, and the PECOFF spec says nothing about it, so I though that 
"_main" is a good default entry point name, taking into account that 
there is currently no CRT guidelines (or at least I'm unaware of them) 
in the lld project. In fact, this functions are defined in the crtexe.c 
and crtdll.c files that you can find in \VC\crt\src subfolder under your 
visual studio installation, and they handle all the static 
initializations, collect the command line arguments, etc. These files 
are silently linked to the image produced by LINK.EXE. Summarizing, I 
though these names are tighly coupled to Visual Studio build system, so 
I choose "_main" for simplicity and generality.

>
> What about returning the address when success and return 0 when fail? 
> Zero can never
> be a valid virtual address so that should be safe.
PECOFF spec says that AddressOfEntryPoint could be zero in the case of 
DLL images, so I've decided return a bool to take into account this 
case. Nevertheless you are right and the virtual address of an atom 
cannot be zero, so I've changed in the new patch.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130731/5535c546/attachment.html>
-------------- next part --------------
diff --git include/lld/ReaderWriter/PECOFFTargetInfo.h include/lld/ReaderWriter/PECOFFTargetInfo.h
index 10337b6..0120524 100644
--- include/lld/ReaderWriter/PECOFFTargetInfo.h
+++ include/lld/ReaderWriter/PECOFFTargetInfo.h
@@ -29,7 +29,7 @@ public:
         _heapReserve(1024 * 1024), _heapCommit(4096),
         _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), _minOSVersion(6, 0),
         _nxCompat(true), _largeAddressAware(false), _baseRelocationEnabled(true),
-        _terminalServerAware(true) {}
+        _terminalServerAware(true), _imageType(ImageType::IMAGE_EXE) {}
 
   struct OSVersion {
     OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {}
@@ -37,6 +37,11 @@ public:
     int minorVersion;
   };
 
+  enum ImageType {
+    IMAGE_EXE,
+    IMAGE_DLL
+  };
+
   virtual error_code parseFile(
       std::unique_ptr<MemoryBuffer> &mb,
       std::vector<std::unique_ptr<File>> &result) const;
@@ -93,6 +98,9 @@ public:
   virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
+  void setImageType(ImageType type) { _imageType = type; }
+  ImageType getImageType() const { return _imageType; }
+
   StringRef allocateString(const StringRef &ref) {
     char *x = _alloc.Allocate<char>(ref.size() + 1);
     memcpy(x, ref.data(), ref.size());
@@ -115,6 +123,7 @@ private:
   bool _largeAddressAware;
   bool _baseRelocationEnabled;
   bool _terminalServerAware;
+  ImageType _imageType;
 
   std::vector<StringRef> _inputSearchPaths;
   mutable std::unique_ptr<Reader> _reader;
diff --git lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
index b1f599c..7c236eb 100644
--- lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
+++ lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
@@ -76,6 +76,10 @@ bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) {
     return true;
   }
 
+  if (_entrySymbolName.empty() && _imageType == ImageType::IMAGE_EXE) {
+    _entrySymbolName = "_main";
+  }
+	  
   _reader = createReaderPECOFF(*this);
   _writer = createWriterPECOFF(*this);
   return false;
diff --git lib/ReaderWriter/PECOFF/WriterPECOFF.cpp lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index 34dc1fb..fb5c3a3 100644
--- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -245,6 +245,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;
@@ -351,6 +355,15 @@ 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;
@@ -747,6 +760,20 @@ public:
     peHeader->setSizeOfInitializedData(rdata->size() + data->size());
     peHeader->setNumberOfSections(_numSections);
     peHeader->setSizeOfImage(_imageSizeInMemory);
+
+    // 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 must be set to 0.
+    if (_PECOFFTargetInfo.entrySymbolName().empty() && 
+        _PECOFFTargetInfo.getImageType() == PECOFFTargetInfo::IMAGE_DLL) {
+      peHeader->setAddressOfEntryPoint(0);
+    } else {
+      uint64_t entryPointAddress = text->getAtomVirtualAddress(
+        _PECOFFTargetInfo.entrySymbolName()); 
+      if (entryPointAddress != 0) {
+        peHeader->setAddressOfEntryPoint(entryPointAddress);
+      }
+    }
   }
 
   virtual error_code writeFile(const File &linkedFile, StringRef path) {


More information about the llvm-commits mailing list