Merge changes from topic 'rebase_r233350'

* changes:
  Fix up mclinker to build with LLVM r233350.
  Update mclinker for llvm rebase to r233350.
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 @@
     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 @@
   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..3474ce6 100644
--- a/include/mcld/Support/CommandLine.h
+++ b/include/mcld/Support/CommandLine.h
@@ -23,9 +23,9 @@
 //===----------------------------------------------------------------------===//
 // SearchDirParser
 //===----------------------------------------------------------------------===//
-class SearchDirParser : public basic_parser<std::string> {
+class SearchDirParser final : 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,
@@ -43,12 +43,13 @@
   void anchor();
 };
 
+#if 0
 //===----------------------------------------------------------------------===//
 // FalseParser
 //===----------------------------------------------------------------------===//
 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) {
@@ -58,14 +59,15 @@
     return false;
   }
 };
+#endif
 
 //===----------------------------------------------------------------------===//
 // parser<mcld::sys::fs::Path>
 //===----------------------------------------------------------------------===//
 template <>
-class parser<mcld::sys::fs::Path> : public basic_parser<mcld::sys::fs::Path> {
+class parser<mcld::sys::fs::Path> final : 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,
@@ -84,9 +86,9 @@
 // parser<mcld::ZOption>
 //===----------------------------------------------------------------------===//
 template <>
-class parser<mcld::ZOption> : public basic_parser<mcld::ZOption> {
+class parser<mcld::ZOption> final : 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 @@
 /// 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 @@
   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 @@
     : 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 @@
     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 @@
           // 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 @@
       (*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 @@
       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 @@
 #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 @@
 
 } /* 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 @@
           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 @@
   const ARMExData& m_ExData;
 
  public:
-  ExIdxFragmentComparator(const ARMExData& pExData)
+  explicit ExIdxFragmentComparator(const ARMExData& pExData)
       : m_ExData(pExData) {
   }
 
@@ -187,6 +194,36 @@
   }
 };
 
+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 @@
   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 @@
   // 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 @@
     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 @@
 
 /// 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 @@
     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 @@
   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 @@
 };
 
 #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 @@
   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::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 @@
       m_ZOptionList(ArgZOptionList),
       m_Dyld(ArgDyld),
       m_EnableNewDTags(ArgEnableNewDTags),
+      m_NumSpareDTags(ArgNumSpareDTags),
       m_Auxiliary(ArgAuxiliary),
       m_Filter(ArgFilter) {
 }
@@ -144,6 +150,9 @@
   // 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();
diff --git a/tools/mcld/lib/OptimizationOptions.cpp b/tools/mcld/lib/OptimizationOptions.cpp
index b3c7f66..50ea73f 100644
--- a/tools/mcld/lib/OptimizationOptions.cpp
+++ b/tools/mcld/lib/OptimizationOptions.cpp
@@ -22,7 +22,7 @@
     llvm::cl::desc("Enable garbage collection of unused input sections."),
     llvm::cl::init(false));
 
-llvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoGCSectionsFlag(
+llvm::cl::opt<bool, true> ArgNoGCSectionsFlag(
     "no-gc-sections",
     llvm::cl::ZeroOrMore,
     llvm::cl::location(ArgGCSections),
@@ -38,7 +38,7 @@
     llvm::cl::desc("List all sections removed by garbage collection."),
     llvm::cl::init(false));
 
-llvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoPrintGCSectionsFlag(
+llvm::cl::opt<bool, true> ArgNoPrintGCSectionsFlag(
     "no-print-gc-sections",
     llvm::cl::ZeroOrMore,
     llvm::cl::location(ArgPrintGCSections),
@@ -47,7 +47,7 @@
 
 bool ArgGenUnwindInfo;
 
-llvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoGenUnwindInfoFlag(
+llvm::cl::opt<bool, true> ArgNoGenUnwindInfoFlag(
     "no-ld-generated-unwind-info",
     llvm::cl::ZeroOrMore,
     llvm::cl::location(ArgGenUnwindInfo),
diff --git a/tools/mcld/lib/PreferenceOptions.cpp b/tools/mcld/lib/PreferenceOptions.cpp
index 852d8fb..ec20d88 100644
--- a/tools/mcld/lib/PreferenceOptions.cpp
+++ b/tools/mcld/lib/PreferenceOptions.cpp
@@ -93,7 +93,7 @@
 
 bool ArgFatalWarnings;
 
-llvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoFatalWarnings(
+llvm::cl::opt<bool, true> ArgNoFatalWarnings(
     "no-fatal-warnings",
     llvm::cl::location(ArgFatalWarnings),
     llvm::cl::desc("do not turn warnings into errors"),