diff options
author | Stephen Hines <srhines@google.com> | 2015-04-07 16:30:20 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-04-07 16:30:20 -0700 |
commit | 04c59f3b00def22b7c75f5a490c323cec58a7c71 (patch) | |
tree | 28edce8d679cd33e7bcbd473026755b8ee9d68d6 | |
parent | fdc86e090cd0308ba880937cf55ed162abfd20a0 (diff) | |
download | mclinker-04c59f3b00def22b7c75f5a490c323cec58a7c71.tar.gz |
Update mclinker for llvm rebase to r233350.
Change-Id: Ic2e8c152e881681d6b827f9ace76bcb87b907147
-rw-r--r-- | include/mcld/GeneralOptions.h | 7 | ||||
-rw-r--r-- | include/mcld/Support/CommandLine.h | 8 | ||||
-rw-r--r-- | include/mcld/Target/TargetLDBackend.h | 28 | ||||
-rw-r--r-- | lib/Core/GeneralOptions.cpp | 1 | ||||
-rw-r--r-- | lib/LD/GarbageCollection.cpp | 4 | ||||
-rw-r--r-- | lib/Object/ObjectLinker.cpp | 17 | ||||
-rw-r--r-- | lib/Script/ScriptScanner.ll | 11 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64Relocator.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/ARMException.cpp | 98 | ||||
-rw-r--r-- | lib/Target/ARM/ARMLDBackend.cpp | 5 | ||||
-rw-r--r-- | lib/Target/ELFDynamic.cpp | 10 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonAbsoluteStub.cpp | 2 | ||||
-rw-r--r-- | tools/mcld/include/mcld/DynamicSectionOptions.h | 1 | ||||
-rw-r--r-- | tools/mcld/lib/DynamicSectionOptions.cpp | 9 |
14 files changed, 192 insertions, 20 deletions
diff --git a/include/mcld/GeneralOptions.h b/include/mcld/GeneralOptions.h index 58e4eb3..165c027 100644 --- a/include/mcld/GeneralOptions.h +++ b/include/mcld/GeneralOptions.h @@ -107,6 +107,12 @@ class GeneralOptions { m_NoUndefined = (pEnable ? YES : NO); } + void setNumSpareDTags(uint32_t pNum) { + m_NumSpareDTags = pNum; + } + + unsigned getNumSpareDTags() const { return m_NumSpareDTags; } + void setMulDefs(bool pEnable = true) { m_MulDefs = (pEnable ? YES : NO); } void setEhFrameHdr(bool pEnable = true) { m_bCreateEhFrameHdr = pEnable; } @@ -322,6 +328,7 @@ class GeneralOptions { int8_t m_Verbose; // --verbose[=0,1,2] uint16_t m_MaxErrorNum; // --error-limit=N uint16_t m_MaxWarnNum; // --warning-limit=N + unsigned m_NumSpareDTags; // --spare-dynamic-tags status m_ExecStack; // execstack, noexecstack status m_NoUndefined; // defs, --no-undefined status m_MulDefs; // muldefs, --allow-multiple-definition diff --git a/include/mcld/Support/CommandLine.h b/include/mcld/Support/CommandLine.h index 6911e46..0a67ee8 100644 --- a/include/mcld/Support/CommandLine.h +++ b/include/mcld/Support/CommandLine.h @@ -25,7 +25,7 @@ namespace cl { //===----------------------------------------------------------------------===// class SearchDirParser : public basic_parser<std::string> { public: - SearchDirParser(Option &O) : basic_parser(O) { } + explicit SearchDirParser(Option &O) : basic_parser(O) { } // parse - Return true on error. bool parse(Option& pOption, @@ -48,7 +48,7 @@ class SearchDirParser : public basic_parser<std::string> { //===----------------------------------------------------------------------===// class FalseParser : public parser<bool> { public: - FalseParser(Option &O) : parser<bool>(O) { } + explicit FalseParser(Option &O) : parser<bool>(O) { } // parse - Return true on error. bool parse(cl::Option& O, StringRef ArgName, StringRef Arg, bool& Val) { @@ -65,7 +65,7 @@ class FalseParser : public parser<bool> { template <> class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path> { public: - parser(Option &O) : basic_parser(O) { } + explicit parser(Option &O) : basic_parser(O) { } bool parse(Option& O, StringRef ArgName, @@ -86,7 +86,7 @@ class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path> { template <> class parser<mcld::ZOption> : public basic_parser<mcld::ZOption> { public: - parser(Option &O) : basic_parser(O) { } + explicit parser(Option &O) : basic_parser(O) { } bool parse(Option& O, StringRef ArgName, StringRef Arg, mcld::ZOption& Val); diff --git a/include/mcld/Target/TargetLDBackend.h b/include/mcld/Target/TargetLDBackend.h index c1e4e8e..e774a9c 100644 --- a/include/mcld/Target/TargetLDBackend.h +++ b/include/mcld/Target/TargetLDBackend.h @@ -8,18 +8,21 @@ //===----------------------------------------------------------------------===// #ifndef MCLD_TARGET_TARGETLDBACKEND_H_ #define MCLD_TARGET_TARGETLDBACKEND_H_ +#include "mcld/Fragment/Relocation.h" #include "mcld/LD/GarbageCollection.h" #include "mcld/Support/Compiler.h" +#include "mcld/Support/GCFactoryListTraits.h" #include <llvm/ADT/StringRef.h> +#include <llvm/ADT/ilist.h> #include <llvm/Support/DataTypes.h> namespace mcld { class ArchiveReader; -class BranchIslandFactory; class BinaryReader; class BinaryWriter; +class BranchIslandFactory; class DynObjReader; class DynObjWriter; class ExecWriter; @@ -43,6 +46,11 @@ class StubFactory; /// TargetLDBackend - Generic interface to target specific assembler backends. //===----------------------------------------------------------------------===// class TargetLDBackend { + public: + typedef llvm::iplist<Relocation, GCFactoryListTraits<Relocation> > + ExtraRelocList; + typedef ExtraRelocList::iterator extra_reloc_iterator; + protected: explicit TargetLDBackend(const LinkerConfig& pConfig); @@ -182,12 +190,30 @@ class TargetLDBackend { virtual bool mayHaveUnsafeFunctionPointerAccess( const LDSection& pSection) const = 0; + extra_reloc_iterator extra_reloc_begin() { + return m_ExtraReloc.begin(); + } + + extra_reloc_iterator extra_reloc_end() { + return m_ExtraReloc.end(); + } + protected: const LinkerConfig& config() const { return m_Config; } + /// addExtraRelocation - Add an extra relocation which are automatically + /// generated by the LD backend. + void addExtraRelocation(Relocation* reloc) { + m_ExtraReloc.push_back(reloc); + } + private: const LinkerConfig& m_Config; + /// m_ExtraReloc - Extra relocations that are automatically generated by the + /// linker. + ExtraRelocList m_ExtraReloc; + private: DISALLOW_COPY_AND_ASSIGN(TargetLDBackend); }; diff --git a/lib/Core/GeneralOptions.cpp b/lib/Core/GeneralOptions.cpp index 521ffa5..6f7b57f 100644 --- a/lib/Core/GeneralOptions.cpp +++ b/lib/Core/GeneralOptions.cpp @@ -20,6 +20,7 @@ GeneralOptions::GeneralOptions() : m_Verbose(-1), m_MaxErrorNum(-1), m_MaxWarnNum(-1), + m_NumSpareDTags(1), m_ExecStack(Unknown), m_NoUndefined(Unknown), m_MulDefs(Unknown), diff --git a/lib/LD/GarbageCollection.cpp b/lib/LD/GarbageCollection.cpp index 89a97e2..6236b57 100644 --- a/lib/LD/GarbageCollection.cpp +++ b/lib/LD/GarbageCollection.cpp @@ -240,8 +240,8 @@ void GarbageCollection::getEntrySections(SectionVecTy& pEntry) { if (!m_Config.options().exportDynamic()) { NamePool::syminfo_iterator info_it, info_end = m_Module.getNamePool().syminfo_end(); - for (info_it = m_Module.getNamePool().syminfo_begin(); info_it != info_end; - ++info_it) { + for (info_it = m_Module.getNamePool().syminfo_begin(); + info_it != info_end; ++info_it) { ResolveInfo* info = info_it.getEntry(); if (!info->isDefine() || info->isLocal()) continue; diff --git a/lib/Object/ObjectLinker.cpp b/lib/Object/ObjectLinker.cpp index 0ab7315..801cbaf 100644 --- a/lib/Object/ObjectLinker.cpp +++ b/lib/Object/ObjectLinker.cpp @@ -383,7 +383,8 @@ bool ObjectLinker::mergeSections() { // FIXME: disable debug string merge when doing partial link. if (LinkerConfig::Object == m_Config.codeGenType()) (*sect)->setKind(LDFileFormat::Debug); - } // Fall through + } + // Fall through default: { if (!(*sect)->hasSectionData()) continue; // skip @@ -835,6 +836,13 @@ bool ObjectLinker::relocation() { (*iter)->apply(*m_LDBackend.getRelocator()); } + // apply relocations created by LD backend + for (TargetLDBackend::extra_reloc_iterator + iter = m_LDBackend.extra_reloc_begin(), + end = m_LDBackend.extra_reloc_end(); iter != end; ++iter) { + iter->apply(*m_LDBackend.getRelocator()); + } + return true; } @@ -907,6 +915,13 @@ void ObjectLinker::normalSyncRelocationResult(FileOutputBuffer& pOutput) { writeRelocationResult(*reloc, data); } } + + // sync relocations created by LD backend + for (TargetLDBackend::extra_reloc_iterator + iter = m_LDBackend.extra_reloc_begin(), + end = m_LDBackend.extra_reloc_end(); iter != end; ++iter) { + writeRelocationResult(*iter, data); + } } void ObjectLinker::partialSyncRelocationResult(FileOutputBuffer& pOutput) { diff --git a/lib/Script/ScriptScanner.ll b/lib/Script/ScriptScanner.ll index c1c3f74..97bff76 100644 --- a/lib/Script/ScriptScanner.ll +++ b/lib/Script/ScriptScanner.ll @@ -23,6 +23,13 @@ typedef mcld::ScriptParser::token_type token_type; #define YY_NO_UNISTD_H %} +%{ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif +%} + /* Flex Declarations and Options */ %option c++ %option batch @@ -377,6 +384,10 @@ void ScriptScanner::popLexState() } /* namespace mcld */ +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #ifdef yylex #undef yylex #endif diff --git a/lib/Target/AArch64/AArch64Relocator.cpp b/lib/Target/AArch64/AArch64Relocator.cpp index 5da37b9..9f1e9b9 100644 --- a/lib/Target/AArch64/AArch64Relocator.cpp +++ b/lib/Target/AArch64/AArch64Relocator.cpp @@ -246,11 +246,12 @@ void AArch64Relocator::scanGlobalReloc(Relocation& pReloc, getTarget().checkAndSetHasTextRel(*pSection.getLink()); if (llvm::ELF::R_AARCH64_ABS64 == pReloc.type() && helper_use_relative_reloc(*rsym, *this)) { - Relocation& reloc = helper_DynRela_init(rsym, - *pReloc.targetRef().frag(), - pReloc.targetRef().offset(), - llvm::ELF::R_AARCH64_RELATIVE, - *this); + Relocation& reloc = + helper_DynRela_init(rsym, + *pReloc.targetRef().frag(), + pReloc.targetRef().offset(), + llvm::ELF::R_AARCH64_RELATIVE, + *this); getRelRelMap().record(pReloc, reloc); } else { Relocation& reloc = helper_DynRela_init(rsym, diff --git a/lib/Target/ARM/ARMException.cpp b/lib/Target/ARM/ARMException.cpp index 9b86f98..3893190 100644 --- a/lib/Target/ARM/ARMException.cpp +++ b/lib/Target/ARM/ARMException.cpp @@ -19,6 +19,13 @@ #include <memory> +static const char g_CantUnwindEntry[8] = { + // Relocation to text section. + 0, 0, 0, 0, + // EXIDX_CANTUNWIND (little endian.) + 1, 0, 0, 0, +}; + namespace mcld { void ARMExData::addInputMap(Input* pInput, @@ -168,7 +175,7 @@ class ExIdxFragmentComparator { const ARMExData& m_ExData; public: - ExIdxFragmentComparator(const ARMExData& pExData) + explicit ExIdxFragmentComparator(const ARMExData& pExData) : m_ExData(pExData) { } @@ -187,6 +194,36 @@ class ExIdxFragmentComparator { } }; +static mcld::ResolveInfo* +CreateLocalSymbolToFragmentEnd(mcld::Module& pModule, mcld::Fragment& pFrag) { + // Create and add symbol to the name pool. + mcld::ResolveInfo* resolveInfo = + pModule.getNamePool().createSymbol(/* pName */"", + /* pIsDyn */false, + mcld::ResolveInfo::Section, + mcld::ResolveInfo::Define, + mcld::ResolveInfo::Local, + /* pSize */0, + mcld::ResolveInfo::Hidden); + if (resolveInfo == nullptr) { + return nullptr; + } + + // Create input symbol. + mcld::LDSymbol* inputSym = mcld::LDSymbol::Create(*resolveInfo); + if (inputSym == nullptr) { + return nullptr; + } + + inputSym->setFragmentRef(mcld::FragmentRef::Create(pFrag, pFrag.size())); + inputSym->setValue(/* pValue */0); + + // The output symbol is simply an alias to the input symbol. + resolveInfo->setSymPtr(inputSym); + + return resolveInfo; +} + void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { if (!m_pEXIDX->hasSectionData()) { // Return if this is empty section. @@ -196,7 +233,8 @@ void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { SectionData* sectData = m_pEXIDX->getSectionData(); SectionData::FragmentListType& list = sectData->getFragmentList(); - // Move the first and last fragment to temporary list. + // Move the first fragment (align fragment) and last fragment (null fragment) + // to temporary list because we would only like to sort the region fragment. SectionData::FragmentListType tmp; { SectionData::iterator first = sectData->begin(); @@ -213,7 +251,58 @@ void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { // Sort the region fragments in the .ARM.exidx output section. sort(list, ExIdxFragmentComparator(m_ExData)); - // Add the first and last fragment back. + // Fix the coverage of the .ARM.exidx table. + llvm::StringRef cantUnwindRegion(g_CantUnwindEntry, + sizeof(g_CantUnwindEntry)); + + SectionData::FragmentListType::iterator it = list.begin(); + if (it != list.end()) { + Fragment* prevTextFrag = m_ExData.getTupleByExIdx(it)->getTextFragment(); + uint64_t prevTextEnd = prevTextFrag->getParent()->getSection().addr() + + prevTextFrag->getOffset() + + prevTextFrag->size(); + ++it; + while (it != list.end()) { + Fragment* currTextFrag = m_ExData.getTupleByExIdx(it)->getTextFragment(); + uint64_t currTextBegin = currTextFrag->getParent()->getSection().addr() + + currTextFrag->getOffset(); + + if (currTextBegin > prevTextEnd) { + // Found a gap. Insert a can't unwind entry. + RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); + frag->setParent(sectData); + list.insert(it, frag); + + // Add PREL31 reference to the beginning of the uncovered region. + Relocation* reloc = + Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), + *FragmentRef::Create(*frag, /* pOffset */0), + /* pAddend */0); + reloc->setSymInfo( + CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); + addExtraRelocation(reloc); + } + + prevTextEnd = currTextBegin + currTextFrag->size(); + prevTextFrag = currTextFrag; + ++it; + } + + // Add a can't unwind entry to terminate .ARM.exidx section. + RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr); + frag->setParent(sectData); + list.push_back(frag); + + // Add PREL31 reference to the end of the .text section. + Relocation* reloc = + Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31), + *FragmentRef::Create(*frag, /* pOffset */0), + /* pAddend */0); + reloc->setSymInfo(CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag)); + addExtraRelocation(reloc); + } + + // Add the first and the last fragment back. list.splice(list.begin(), tmp, tmp.begin()); list.splice(list.end(), tmp, tmp.begin()); @@ -225,6 +314,9 @@ void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { offset += it->size(); } + // Update the section size. + m_pEXIDX->setSize(offset); + // Rebuild the section header. setOutputSectionAddress(pModule); } diff --git a/lib/Target/ARM/ARMLDBackend.cpp b/lib/Target/ARM/ARMLDBackend.cpp index db691af..5d7bc56 100644 --- a/lib/Target/ARM/ARMLDBackend.cpp +++ b/lib/Target/ARM/ARMLDBackend.cpp @@ -636,8 +636,11 @@ unsigned int ARMGNULDBackend::getTargetSectionOrder( /// relax - the relaxation pass bool ARMGNULDBackend::relax(Module& pModule, IRBuilder& pBuilder) { + if (!GNULDBackend::relax(pModule, pBuilder)) { + return false; + } rewriteARMExIdxSection(pModule); - return GNULDBackend::relax(pModule, pBuilder); + return true; } /// doRelax diff --git a/lib/Target/ELFDynamic.cpp b/lib/Target/ELFDynamic.cpp index 4318bfa..47005cc 100644 --- a/lib/Target/ELFDynamic.cpp +++ b/lib/Target/ELFDynamic.cpp @@ -183,7 +183,10 @@ void ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) { reserveOne(llvm::ELF::DT_FLAGS_1); } - reserveOne(llvm::ELF::DT_NULL); + unsigned num_spare_dtags = m_Config.options().getNumSpareDTags(); + for (unsigned i = 0; i < num_spare_dtags; ++i) { + reserveOne(llvm::ELF::DT_NULL); + } } /// applyEntries - apply entries @@ -305,7 +308,10 @@ void ELFDynamic::applyEntries(const ELFFileFormat& pFormat) { if (dt_flags_1 != 0x0) applyOne(llvm::ELF::DT_FLAGS_1, dt_flags_1); - applyOne(llvm::ELF::DT_NULL, 0x0); + unsigned num_spare_dtags = m_Config.options().getNumSpareDTags(); + for (unsigned i = 0; i < num_spare_dtags; ++i) { + applyOne(llvm::ELF::DT_NULL, 0x0); + } } /// symbolSize diff --git a/lib/Target/Hexagon/HexagonAbsoluteStub.cpp b/lib/Target/Hexagon/HexagonAbsoluteStub.cpp index 3ddf08b..1d6113c 100644 --- a/lib/Target/Hexagon/HexagonAbsoluteStub.cpp +++ b/lib/Target/Hexagon/HexagonAbsoluteStub.cpp @@ -34,7 +34,7 @@ const uint32_t HexagonAbsoluteStub::TEMPLATE[] = { }; #define FITS_IN_NBITS(D, B) \ - (llvm::abs64(D) < (~(~(int64_t)0 << ((B)-1)) & -(4 * 4))) + (std::abs(D) < (~(~(int64_t)0 << ((B)-1)) & -(4 * 4))) HexagonAbsoluteStub::HexagonAbsoluteStub(bool pIsOutputPIC) : Stub(), m_Name("HexagonTrampoline"), m_pData(NULL), m_Size(0x0) { diff --git a/tools/mcld/include/mcld/DynamicSectionOptions.h b/tools/mcld/include/mcld/DynamicSectionOptions.h index 67e7c40..2902118 100644 --- a/tools/mcld/include/mcld/DynamicSectionOptions.h +++ b/tools/mcld/include/mcld/DynamicSectionOptions.h @@ -34,6 +34,7 @@ class DynamicSectionOptions { llvm::cl::list<ZOption, bool, llvm::cl::parser<ZOption> >& m_ZOptionList; llvm::cl::opt<std::string>& m_Dyld; llvm::cl::opt<bool>& m_EnableNewDTags; + llvm::cl::opt<unsigned>& m_NumSpareDTags; llvm::cl::list<std::string>& m_Auxiliary; llvm::cl::opt<std::string>& m_Filter; diff --git a/tools/mcld/lib/DynamicSectionOptions.cpp b/tools/mcld/lib/DynamicSectionOptions.cpp index 6bd8ccd..958a94d 100644 --- a/tools/mcld/lib/DynamicSectionOptions.cpp +++ b/tools/mcld/lib/DynamicSectionOptions.cpp @@ -66,6 +66,11 @@ llvm::cl::opt<bool> ArgEnableNewDTags( llvm::cl::desc("Enable use of DT_RUNPATH and DT_FLAGS"), llvm::cl::init(false)); +llvm::cl::opt<unsigned> ArgNumSpareDTags( + "spare-dynamic-tags", + llvm::cl::desc("Set the number of spare dyanmic tags (DT_NULL)"), + llvm::cl::init(5)); + // Not supported yet { llvm::cl::list<std::string> ArgAuxiliary( "f", @@ -105,6 +110,7 @@ DynamicSectionOptions::DynamicSectionOptions() m_ZOptionList(ArgZOptionList), m_Dyld(ArgDyld), m_EnableNewDTags(ArgEnableNewDTags), + m_NumSpareDTags(ArgNumSpareDTags), m_Auxiliary(ArgAuxiliary), m_Filter(ArgFilter) { } @@ -144,6 +150,9 @@ bool DynamicSectionOptions::parse(LinkerConfig& pConfig, // set --enable-new-dtags pConfig.options().setNewDTags(m_EnableNewDTags); + // set --spare-dyanmic-tags + pConfig.options().setNumSpareDTags(m_NumSpareDTags); + // set --auxiliary, -f llvm::cl::list<std::string>::iterator aux; llvm::cl::list<std::string>::iterator auxEnd = m_Auxiliary.end(); |