[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