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

Jesús Serrano García dagonoweda at gmail.com
Tue Jul 30 17:07:07 PDT 2013


So be it, I've changed "_main" for the MSDN documented names, in 
addition to the other corrections. In any case, these names for the 
entry functions are for the multibyte version of CRT, and the names for 
the unicode entry points (wmainCRTStartup and wWinMainCRTStartup) must 
will be handled adequately where appropriate.

ThatOn 31/07/2013 1:19, Rui Ueyama wrote:
> Besides Chandler's comment, here's mine.
>
> > 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
> > @@ -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;
> > +  }
> > +
>
> Nit: you can omit {} for "for" and "if" in this case.
>
> > @@ -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);
> > +      }
> > +    }
> >    }
>
> I'd make this a separate function to keep build() as concise as possible.
>
>
>
> On Tue, Jul 30, 2013 at 4:12 PM, Chandler Carruth 
> <chandlerc at google.com <mailto:chandlerc at google.com>> wrote:
>
>
>     On Tue, Jul 30, 2013 at 3:46 PM, Jesús Serrano García
>     <dagonoweda at gmail.com <mailto:dagonoweda at gmail.com>> wrote:
>
>>         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.
>
>
>     Sorry for the ambiguity, but the goal of all the PECOFF work in
>     LLD is to support linking in a compatible way for Windows. If you
>     have another usecase for linking PECOFF, you should raise that on
>     the discussion list (not the commit list) as it'll need a separate
>     design from what we're currently working on.
>
>     For now, as Rui has said, we should follow the MSDN spec he cited.
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130731/45eab5c1/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..92caf22 100644
--- lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
+++ lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
@@ -76,6 +76,15 @@ bool PECOFFTargetInfo::validateImpl(raw_ostream &diagnostics) {
     return true;
   }
 
+  if (_entrySymbolName.empty()) {
+    if (_imageType == ImageType::IMAGE_EXE)
+      if (_subsystem == llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI) {
+        _entrySymbolName = "mainCRTStartup";
+      } else if (_subsystem == llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI)
+        _entrySymbolName = "WinMainCRTStartup";
+    } else if (_imageType == ImageType::IMAGE_DLL)
+      _entrySymbolName = "_DllMainCRTStartup";
+	  
   _reader = createReaderPECOFF(*this);
   _writer = createWriterPECOFF(*this);
   return false;
diff --git lib/ReaderWriter/PECOFF/WriterPECOFF.cpp lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index 64a1f6c..2c10568 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,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;
@@ -780,6 +791,8 @@ public:
     peHeader->setSizeOfUninitializedData(bss->size());
     peHeader->setNumberOfSections(_numSections);
     peHeader->setSizeOfImage(_imageSizeInMemory);
+
+    setAddressOfEntryPoint(text, peHeader);
   }
 
   virtual error_code writeFile(const File &linkedFile, StringRef path) {
@@ -839,6 +852,21 @@ 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 (_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);
+    }
+  }
+
   std::vector<std::unique_ptr<Chunk>> _chunks;
   const PECOFFTargetInfo &_PECOFFTargetInfo;
   uint32_t _numSections;


More information about the llvm-commits mailing list