From 6a41fca8565d8273f2a922e36c3a661f45ac9316 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 23 Jul 2013 01:29:50 +0000 Subject: [PATCH] [PECOFF] Support -fixed command line option to disable base relocations. llvm-svn: 186911 --- lld/include/lld/ReaderWriter/PECOFFTargetInfo.h | 8 ++++++-- lld/lib/Driver/WinLinkDriver.cpp | 12 ++++++++---- lld/lib/Driver/WinLinkOptions.td | 5 +++++ lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 16 ++++++++++------ lld/test/pecoff/base-reloc.test | 11 ++++++++--- lld/unittests/DriverTests/WinLinkDriverTest.cpp | 12 ++++++++++++ 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h b/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h index a7a7a8c..5194d1f 100644 --- a/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h +++ b/lld/include/lld/ReaderWriter/PECOFFTargetInfo.h @@ -28,7 +28,7 @@ public: : _baseAddress(0x400000), _stackReserve(1024 * 1024), _stackCommit(4096), _heapReserve(1024 * 1024), _heapCommit(4096), _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), _minOSVersion(6, 0), - _nxCompat(true), _largeAddressAware(false) {} + _nxCompat(true), _largeAddressAware(false), _baseRelocationEnabled(true) {} struct OSVersion { OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {} @@ -78,9 +78,12 @@ public: void setNxCompat(bool nxCompat) { _nxCompat = nxCompat; } bool getNxCompat() const { return _nxCompat; } - void setLargeAddressAware(bool option) { _largeAddressAware = option; } + void setLargeAddressAware(bool val) { _largeAddressAware = val; } bool getLargeAddressAware() const { return _largeAddressAware; } + void setBaseRelocationEnabled(bool val) { _baseRelocationEnabled = val; } + bool getBaseRelocationEnabled() const { return _baseRelocationEnabled; } + virtual ErrorOr relocKindFromString(StringRef str) const; virtual ErrorOr stringFromRelocKind(Reference::Kind kind) const; @@ -104,6 +107,7 @@ private: OSVersion _minOSVersion; bool _nxCompat; bool _largeAddressAware; + bool _baseRelocationEnabled; std::vector _inputSearchPaths; mutable std::unique_ptr _reader; diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index c7a73d1..33689b3 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -324,7 +324,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[], if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_entry)) info.setEntrySymbolName(arg->getValue()); - // Hanlde -libpath + // Handle -libpath for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_libpath), ie = parsedArgs->filtered_end(); it != ie; ++it) { @@ -335,15 +335,19 @@ bool WinLinkDriver::parse(int argc, const char *argv[], if (parsedArgs->getLastArg(OPT_force)) info.setAllowRemainingUndefines(true); - // Hanlde -nxcompat:no + // Handle -nxcompat:no if (parsedArgs->getLastArg(OPT_no_nxcompat)) info.setNxCompat(false); - // Hanlde -largeaddressaware + // Handle -largeaddressaware if (parsedArgs->getLastArg(OPT_largeaddressaware)) info.setLargeAddressAware(true); - // Hanlde -out + // Handle -fixed + if (parsedArgs->getLastArg(OPT_fixed)) + info.setBaseRelocationEnabled(false); + + // Handle -out if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_out)) info.setOutputPath(outpath->getValue()); diff --git a/lld/lib/Driver/WinLinkOptions.td b/lld/lib/Driver/WinLinkOptions.td index e63f83f..f6ef1a8 100644 --- a/lld/lib/Driver/WinLinkOptions.td +++ b/lld/lib/Driver/WinLinkOptions.td @@ -50,5 +50,10 @@ def largeaddressaware : Flag<["-", "/"], "largeaddressaware">, def no_largeaddressaware : Flag<["-", "/"], "largeaddressaware:no">, HelpText<"Disable large addresses">; +def fixed : Flag<["-", "/"], "fixed">, + HelpText<"Disable base relocations">; +def no_fixed : Flag<["-", "/"], "fixed:no">, + HelpText<"Enable base relocations">; + def help : Flag<["-", "/"], "help">; def help_q : Flag<["-", "/"], "?">, Alias; diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index 89f6dbd..2c08b10 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -698,7 +698,9 @@ public: auto *text = new TextSectionChunk(linkedFile); auto *rdata = new RDataSectionChunk(linkedFile); auto *data = new DataSectionChunk(linkedFile); - auto *baseReloc = new BaseRelocChunk(linkedFile); + BaseRelocChunk *baseReloc = nullptr; + if (_PECOFFTargetInfo.getBaseRelocationEnabled()) + baseReloc = new BaseRelocChunk(linkedFile); addChunk(dosStub); addChunk(peHeader); @@ -717,11 +719,13 @@ public: // Now that we know the addresses of all defined atoms that needs to be // relocated. So we can create the ".reloc" section which contains all the // relocation sites. - baseReloc->setContents(_chunks); - if (baseReloc->size()) { - dataDirectory->setBaseRelocField(baseReloc->getSectionRva(), - baseReloc->rawSize()); - addSectionChunk(baseReloc, sectionTable); + if (baseReloc) { + baseReloc->setContents(_chunks); + if (baseReloc->size()) { + dataDirectory->setBaseRelocField(baseReloc->getSectionRva(), + baseReloc->rawSize()); + addSectionChunk(baseReloc, sectionTable); + } } setImageSizeOnDisk(); diff --git a/lld/test/pecoff/base-reloc.test b/lld/test/pecoff/base-reloc.test index 55377c3..a1161de 100644 --- a/lld/test/pecoff/base-reloc.test +++ b/lld/test/pecoff/base-reloc.test @@ -1,7 +1,10 @@ # RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj # # RUN: lld -flavor link -out %t1 -subsystem console -force -- %t.obj \ -# RUN: && llvm-objdump -s %t1 | FileCheck %s +# RUN: && llvm-objdump -s %t1 | FileCheck %s --check-prefix=BASEREL +# +# RUN: lld -flavor link -out %t1 -subsystem console -force -fixed -- %t.obj \ +# RUN: && llvm-objdump -s %t1 | FileCheck %s --check-prefix=NOBASEREL # Because llvm-objdump cannot pretty-print the contents of .reloc section, we # have no choice other than comparing the result with this binary blob. @@ -9,5 +12,7 @@ # TODO: Improve llvm-objdump to pretty print .reloc section as GNU binutil # objdump does. -CHECK: Contents of section .reloc: -CHECK-NEXT: 3000 00100000 0c000000 07300c30 00000000 .........0.0.... +BASEREL: Contents of section .reloc: +BASEREL-NEXT: 3000 00100000 0c000000 07300c30 00000000 .........0.0.... + +NOBASEREL-NOT: Contents of section .reloc: diff --git a/lld/unittests/DriverTests/WinLinkDriverTest.cpp b/lld/unittests/DriverTests/WinLinkDriverTest.cpp index ebf5771..1070399 100644 --- a/lld/unittests/DriverTests/WinLinkDriverTest.cpp +++ b/lld/unittests/DriverTests/WinLinkDriverTest.cpp @@ -42,6 +42,8 @@ TEST_F(WinLinkParserTest, Basic) { EXPECT_EQ("b.obj", inputFile(1)); EXPECT_EQ("c.obj", inputFile(2)); EXPECT_TRUE(_info.getInputSearchPaths().empty()); + + // Unspecified flags will have default values. EXPECT_EQ(6, _info.getMinOSVersion().majorVersion); EXPECT_EQ(0, _info.getMinOSVersion().minorVersion); EXPECT_EQ((uint64_t)0x400000, _info.getBaseAddress()); @@ -50,6 +52,7 @@ TEST_F(WinLinkParserTest, Basic) { EXPECT_FALSE(_info.allowRemainingUndefines()); EXPECT_TRUE(_info.getNxCompat()); EXPECT_FALSE(_info.getLargeAddressAware()); + EXPECT_TRUE(_info.getBaseRelocationEnabled()); } TEST_F(WinLinkParserTest, WindowsStyleOption) { @@ -148,6 +151,15 @@ TEST_F(WinLinkParserTest, NoLargeAddressAware) { EXPECT_FALSE(_info.getLargeAddressAware()); } +TEST_F(WinLinkParserTest, Fixed) { + EXPECT_FALSE(parse("link.exe", "-fixed", "a.out", nullptr)); + EXPECT_FALSE(_info.getBaseRelocationEnabled()); +} + +TEST_F(WinLinkParserTest, NoFixed) { + EXPECT_FALSE(parse("link.exe", "-fixed:no", "a.out", nullptr)); + EXPECT_TRUE(_info.getBaseRelocationEnabled()); +} TEST_F(WinLinkParserTest, NoInputFiles) { EXPECT_TRUE(parse("link.exe", nullptr)); -- 2.7.4