diff options
Diffstat (limited to 'ELF/Writer.cpp')
| -rw-r--r-- | ELF/Writer.cpp | 697 | 
1 files changed, 410 insertions, 287 deletions
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 73a97380b54b..17f4c7961d30 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -53,8 +53,10 @@ private:    void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);    void sortSections();    void resolveShfLinkOrder(); +  void maybeAddThunks();    void sortInputSections();    void finalizeSections(); +  void checkExecuteOnly();    void setReservedSymbolSections();    std::vector<PhdrEntry *> createPhdrs(); @@ -77,7 +79,6 @@ private:    void addRelIpltSymbols();    void addStartEndSymbols();    void addStartStopSymbols(OutputSection *Sec); -  uint64_t getEntryAddr();    std::vector<PhdrEntry *> Phdrs; @@ -114,18 +115,16 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {    // for instance.    if (Config->ZKeepTextSectionPrefix)      for (StringRef V : -         {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) { +         {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})        if (isSectionPrefix(V, S->Name))          return V.drop_back(); -    }    for (StringRef V :         {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",          ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", -        ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { +        ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})      if (isSectionPrefix(V, S->Name))        return V.drop_back(); -  }    // CommonSection is identified as "COMMON" in linker scripts.    // By default, it should go to .bss section. @@ -159,7 +158,7 @@ template <class ELFT> static void combineEhFrameSections() {      if (!ES || !ES->Live)        continue; -    InX::EhFrame->addSection<ELFT>(ES); +    In.EhFrame->addSection<ELFT>(ES);      S = nullptr;    } @@ -173,10 +172,14 @@ static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,    Symbol *S = Symtab->find(Name);    if (!S || S->isDefined())      return nullptr; -  Symbol *Sym = Symtab->addRegular(Name, StOther, STT_NOTYPE, Val, -                                   /*Size=*/0, Binding, Sec, -                                   /*File=*/nullptr); -  return cast<Defined>(Sym); +  return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val, +                            /*Size=*/0, Binding, Sec, +                            /*File=*/nullptr); +} + +static Defined *addAbsolute(StringRef Name) { +  return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL, +                            nullptr, nullptr);  }  // The linker is expected to define some symbols depending on @@ -188,21 +191,19 @@ void elf::addReservedSymbols() {      // to GOT. Default offset is 0x7ff0.      // See "Global Data Symbols" in Chapter 6 in the following document:      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf -    ElfSym::MipsGp = Symtab->addAbsolute("_gp", STV_HIDDEN, STB_GLOBAL); +    ElfSym::MipsGp = addAbsolute("_gp");      // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between      // start of function and 'gp' pointer into GOT.      if (Symtab->find("_gp_disp")) -      ElfSym::MipsGpDisp = -          Symtab->addAbsolute("_gp_disp", STV_HIDDEN, STB_GLOBAL); +      ElfSym::MipsGpDisp = addAbsolute("_gp_disp");      // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'      // pointer. This symbol is used in the code generated by .cpload pseudo-op      // in case of using -mno-shared option.      // https://sourceware.org/ml/binutils/2004-12/msg00094.html      if (Symtab->find("__gnu_local_gp")) -      ElfSym::MipsLocalGp = -          Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); +      ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");    }    // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which @@ -211,9 +212,20 @@ void elf::addReservedSymbols() {    // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to    // represent the TOC base which is offset by 0x8000 bytes from the start of    // the .got section. -  ElfSym::GlobalOffsetTable = addOptionalRegular( -      (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_", -      Out::ElfHeader, Target->GotBaseSymOff); +  // We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the +  // correctness of some relocations depends on its value. +  StringRef GotTableSymName = +      (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_"; +  if (Symbol *S = Symtab->find(GotTableSymName)) { +    if (S->isDefined()) +      error(toString(S->File) + " cannot redefine linker defined symbol '" + +            GotTableSymName + "'"); +    else +      ElfSym::GlobalOffsetTable = Symtab->addDefined( +          GotTableSymName, STV_HIDDEN, STT_NOTYPE, Target->GotBaseSymOff, +          /*Size=*/0, STB_GLOBAL, Out::ElfHeader, +          /*File=*/nullptr); +  }    // __ehdr_start is the location of ELF file headers. Note that we define    // this symbol unconditionally even when using a linker script, which @@ -263,54 +275,52 @@ template <class ELFT> static void createSyntheticSections() {    auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); }; -  InX::DynStrTab = make<StringTableSection>(".dynstr", true); -  InX::Dynamic = make<DynamicSection<ELFT>>(); +  In.DynStrTab = make<StringTableSection>(".dynstr", true); +  In.Dynamic = make<DynamicSection<ELFT>>();    if (Config->AndroidPackDynRelocs) { -    InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>( +    In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(          Config->IsRela ? ".rela.dyn" : ".rel.dyn");    } else { -    InX::RelaDyn = make<RelocationSection<ELFT>>( +    In.RelaDyn = make<RelocationSection<ELFT>>(          Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);    } -  InX::ShStrTab = make<StringTableSection>(".shstrtab", false); +  In.ShStrTab = make<StringTableSection>(".shstrtab", false);    Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);    Out::ProgramHeaders->Alignment = Config->Wordsize;    if (needsInterpSection()) { -    InX::Interp = createInterpSection(); -    Add(InX::Interp); -  } else { -    InX::Interp = nullptr; +    In.Interp = createInterpSection(); +    Add(In.Interp);    }    if (Config->Strip != StripPolicy::All) { -    InX::StrTab = make<StringTableSection>(".strtab", false); -    InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab); -    InX::SymTabShndx = make<SymtabShndxSection>(); +    In.StrTab = make<StringTableSection>(".strtab", false); +    In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab); +    In.SymTabShndx = make<SymtabShndxSection>();    }    if (Config->BuildId != BuildIdKind::None) { -    InX::BuildId = make<BuildIdSection>(); -    Add(InX::BuildId); +    In.BuildId = make<BuildIdSection>(); +    Add(In.BuildId);    } -  InX::Bss = make<BssSection>(".bss", 0, 1); -  Add(InX::Bss); +  In.Bss = make<BssSection>(".bss", 0, 1); +  Add(In.Bss);    // If there is a SECTIONS command and a .data.rel.ro section name use name    // .data.rel.ro.bss so that we match in the .data.rel.ro output section.    // This makes sure our relro is contiguous.    bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro"); -  InX::BssRelRo = +  In.BssRelRo =        make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); -  Add(InX::BssRelRo); +  Add(In.BssRelRo);    // Add MIPS-specific sections.    if (Config->EMachine == EM_MIPS) {      if (!Config->Shared && Config->HasDynSymTab) { -      InX::MipsRldMap = make<MipsRldMapSection>(); -      Add(InX::MipsRldMap); +      In.MipsRldMap = make<MipsRldMapSection>(); +      Add(In.MipsRldMap);      }      if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())        Add(Sec); @@ -321,65 +331,70 @@ template <class ELFT> static void createSyntheticSections() {    }    if (Config->HasDynSymTab) { -    InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab); -    Add(InX::DynSymTab); +    In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab); +    Add(In.DynSymTab); -    In<ELFT>::VerSym = make<VersionTableSection<ELFT>>(); -    Add(In<ELFT>::VerSym); +    InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>(); +    Add(InX<ELFT>::VerSym);      if (!Config->VersionDefinitions.empty()) { -      In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>(); -      Add(In<ELFT>::VerDef); +      In.VerDef = make<VersionDefinitionSection>(); +      Add(In.VerDef);      } -    In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); -    Add(In<ELFT>::VerNeed); +    InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>(); +    Add(InX<ELFT>::VerNeed);      if (Config->GnuHash) { -      InX::GnuHashTab = make<GnuHashTableSection>(); -      Add(InX::GnuHashTab); +      In.GnuHashTab = make<GnuHashTableSection>(); +      Add(In.GnuHashTab);      }      if (Config->SysvHash) { -      InX::HashTab = make<HashTableSection>(); -      Add(InX::HashTab); +      In.HashTab = make<HashTableSection>(); +      Add(In.HashTab);      } -    Add(InX::Dynamic); -    Add(InX::DynStrTab); -    Add(InX::RelaDyn); +    Add(In.Dynamic); +    Add(In.DynStrTab); +    Add(In.RelaDyn);    }    if (Config->RelrPackDynRelocs) { -    InX::RelrDyn = make<RelrSection<ELFT>>(); -    Add(InX::RelrDyn); +    In.RelrDyn = make<RelrSection<ELFT>>(); +    Add(In.RelrDyn);    }    // Add .got. MIPS' .got is so different from the other archs,    // it has its own class.    if (Config->EMachine == EM_MIPS) { -    InX::MipsGot = make<MipsGotSection>(); -    Add(InX::MipsGot); +    In.MipsGot = make<MipsGotSection>(); +    Add(In.MipsGot);    } else { -    InX::Got = make<GotSection>(); -    Add(InX::Got); +    In.Got = make<GotSection>(); +    Add(In.Got);    } -  InX::GotPlt = make<GotPltSection>(); -  Add(InX::GotPlt); -  InX::IgotPlt = make<IgotPltSection>(); -  Add(InX::IgotPlt); +  if (Config->EMachine == EM_PPC64) { +    In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>(); +    Add(In.PPC64LongBranchTarget); +  } + +  In.GotPlt = make<GotPltSection>(); +  Add(In.GotPlt); +  In.IgotPlt = make<IgotPltSection>(); +  Add(In.IgotPlt);    if (Config->GdbIndex) { -    InX::GdbIndex = GdbIndexSection::create<ELFT>(); -    Add(InX::GdbIndex); +    In.GdbIndex = GdbIndexSection::create<ELFT>(); +    Add(In.GdbIndex);    }    // We always need to add rel[a].plt to output if it has entries.    // Even for static linking it can contain R_[*]_IRELATIVE relocations. -  InX::RelaPlt = make<RelocationSection<ELFT>>( +  In.RelaPlt = make<RelocationSection<ELFT>>(        Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/); -  Add(InX::RelaPlt); +  Add(In.RelaPlt);    // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure    // that the IRelative relocations are processed last by the dynamic loader. @@ -387,34 +402,42 @@ template <class ELFT> static void createSyntheticSections() {    // packing is enabled because that would cause a section type mismatch.    // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,    // we can get the desired behaviour by placing the iplt section in .rel.plt. -  InX::RelaIplt = make<RelocationSection<ELFT>>( +  In.RelaIplt = make<RelocationSection<ELFT>>(        (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)            ? ".rel.dyn" -          : InX::RelaPlt->Name, +          : In.RelaPlt->Name,        false /*Sort*/); -  Add(InX::RelaIplt); - -  InX::Plt = make<PltSection>(false); -  Add(InX::Plt); -  InX::Iplt = make<PltSection>(true); -  Add(InX::Iplt); +  Add(In.RelaIplt); + +  In.Plt = make<PltSection>(false); +  Add(In.Plt); +  In.Iplt = make<PltSection>(true); +  Add(In.Iplt); + +  // .note.GNU-stack is always added when we are creating a re-linkable +  // object file. Other linkers are using the presence of this marker +  // section to control the executable-ness of the stack area, but that +  // is irrelevant these days. Stack area should always be non-executable +  // by default. So we emit this section unconditionally. +  if (Config->Relocatable) +    Add(make<GnuStackSection>());    if (!Config->Relocatable) {      if (Config->EhFrameHdr) { -      InX::EhFrameHdr = make<EhFrameHeader>(); -      Add(InX::EhFrameHdr); +      In.EhFrameHdr = make<EhFrameHeader>(); +      Add(In.EhFrameHdr);      } -    InX::EhFrame = make<EhFrameSection>(); -    Add(InX::EhFrame); +    In.EhFrame = make<EhFrameSection>(); +    Add(In.EhFrame);    } -  if (InX::SymTab) -    Add(InX::SymTab); -  if (InX::SymTabShndx) -    Add(InX::SymTabShndx); -  Add(InX::ShStrTab); -  if (InX::StrTab) -    Add(InX::StrTab); +  if (In.SymTab) +    Add(In.SymTab); +  if (In.SymTabShndx) +    Add(In.SymTabShndx); +  Add(In.ShStrTab); +  if (In.StrTab) +    Add(In.StrTab);    if (Config->EMachine == EM_ARM && !Config->Relocatable)      // Add a sentinel to terminate .ARM.exidx. It helps an unwinder @@ -451,6 +474,7 @@ template <class ELFT> void Writer<ELFT>::run() {    // to the string table, and add entries to .got and .plt.    // finalizeSections does that.    finalizeSections(); +  checkExecuteOnly();    if (errorCount())      return; @@ -476,10 +500,9 @@ template <class ELFT> void Writer<ELFT>::run() {    setPhdrs(); -  if (Config->Relocatable) { +  if (Config->Relocatable)      for (OutputSection *Sec : OutputSections)        Sec->Addr = 0; -  }    if (Config->CheckSections)      checkSections(); @@ -548,9 +571,11 @@ static bool includeInSymtab(const Symbol &B) {      if (!Sec)        return true;      Sec = Sec->Repl; +      // Exclude symbols pointing to garbage-collected sections.      if (isa<InputSectionBase>(Sec) && !Sec->Live)        return false; +      if (auto *S = dyn_cast<MergeInputSection>(Sec))        if (!S->getSectionPiece(D->Value)->Live)          return false; @@ -562,7 +587,7 @@ static bool includeInSymtab(const Symbol &B) {  // Local symbols are not in the linker's symbol table. This function scans  // each object file's symbol table to copy local symbols to the output.  template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { -  if (!InX::SymTab) +  if (!In.SymTab)      return;    for (InputFile *File : ObjectFiles) {      ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File); @@ -581,16 +606,16 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {        SectionBase *Sec = DR->Section;        if (!shouldKeepInSymtab(Sec, B->getName(), *B))          continue; -      InX::SymTab->addSymbol(B); +      In.SymTab->addSymbol(B);      }    }  } +// Create a section symbol for each output section so that we can represent +// relocations that point to the section. If we know that no relocation is +// referring to a section (that happens if the section is a synthetic one), we +// don't create a section symbol for that section.  template <class ELFT> void Writer<ELFT>::addSectionSymbols() { -  // Create a section symbol for each output section so that we can represent -  // relocations that point to the section. If we know that no relocation is -  // referring to a section (that happens if the section is a synthetic one), we -  // don't create a section symbol for that section.    for (BaseCommand *Base : Script->SectionCommands) {      auto *Sec = dyn_cast<OutputSection>(Base);      if (!Sec) @@ -617,7 +642,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {      auto *Sym =          make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,                        /*Value=*/0, /*Size=*/0, IS); -    InX::SymTab->addSymbol(Sym); +    In.SymTab->addSymbol(Sym);    }  } @@ -662,9 +687,14 @@ static bool isRelroSection(const OutputSection *Sec) {    // .got contains pointers to external symbols. They are resolved by    // the dynamic linker when a module is loaded into memory, and after    // that they are not expected to change. So, it can be in RELRO. -  if (InX::Got && Sec == InX::Got->getParent()) +  if (In.Got && Sec == In.Got->getParent())      return true; +  // .toc is a GOT-ish section for PowerPC64. Their contents are accessed +  // through r2 register, which is reserved for that purpose. Since r2 is used +  // for accessing .got as well, .got and .toc need to be close enough in the +  // virtual address space. Usually, .toc comes just after .got. Since we place +  // .got into RELRO, .toc needs to be placed into RELRO too.    if (Sec->Name.equals(".toc"))      return true; @@ -672,13 +702,13 @@ static bool isRelroSection(const OutputSection *Sec) {    // by default resolved lazily, so we usually cannot put it into RELRO.    // However, if "-z now" is given, the lazy symbol resolution is    // disabled, which enables us to put it into RELRO. -  if (Sec == InX::GotPlt->getParent()) +  if (Sec == In.GotPlt->getParent())      return Config->ZNow;    // .dynamic section contains data for the dynamic linker, and    // there's no need to write to it at runtime, so it's better to put    // it into RELRO. -  if (Sec == InX::Dynamic->getParent()) +  if (Sec == In.Dynamic->getParent())      return true;    // Sections with some special names are put into RELRO. This is a @@ -700,17 +730,17 @@ static bool isRelroSection(const OutputSection *Sec) {  // * It is easy two see how similar two ranks are (see getRankProximity).  enum RankFlags {    RF_NOT_ADDR_SET = 1 << 18, -  RF_NOT_INTERP = 1 << 17, -  RF_NOT_ALLOC = 1 << 16, -  RF_WRITE = 1 << 15, -  RF_EXEC_WRITE = 1 << 14, -  RF_EXEC = 1 << 13, -  RF_RODATA = 1 << 12, -  RF_NON_TLS_BSS = 1 << 11, -  RF_NON_TLS_BSS_RO = 1 << 10, -  RF_NOT_TLS = 1 << 9, -  RF_BSS = 1 << 8, -  RF_NOTE = 1 << 7, +  RF_NOT_ALLOC = 1 << 17, +  RF_NOT_INTERP = 1 << 16, +  RF_NOT_NOTE = 1 << 15, +  RF_WRITE = 1 << 14, +  RF_EXEC_WRITE = 1 << 13, +  RF_EXEC = 1 << 12, +  RF_RODATA = 1 << 11, +  RF_NON_TLS_BSS = 1 << 10, +  RF_NON_TLS_BSS_RO = 1 << 9, +  RF_NOT_TLS = 1 << 8, +  RF_BSS = 1 << 7,    RF_PPC_NOT_TOCBSS = 1 << 6,    RF_PPC_TOCL = 1 << 5,    RF_PPC_TOC = 1 << 4, @@ -729,16 +759,24 @@ static unsigned getSectionRank(const OutputSection *Sec) {      return Rank;    Rank |= RF_NOT_ADDR_SET; +  // Allocatable sections go first to reduce the total PT_LOAD size and +  // so debug info doesn't change addresses in actual code. +  if (!(Sec->Flags & SHF_ALLOC)) +    return Rank | RF_NOT_ALLOC; +    // Put .interp first because some loaders want to see that section    // on the first page of the executable file when loaded into memory.    if (Sec->Name == ".interp")      return Rank;    Rank |= RF_NOT_INTERP; -  // Allocatable sections go first to reduce the total PT_LOAD size and -  // so debug info doesn't change addresses in actual code. -  if (!(Sec->Flags & SHF_ALLOC)) -    return Rank | RF_NOT_ALLOC; +  // Put .note sections (which make up one PT_NOTE) at the beginning so that +  // they are likely to be included in a core file even if core file size is +  // limited. In particular, we want a .note.gnu.build-id and a .note.tag to be +  // included in a core to match core files with executables. +  if (Sec->Type == SHT_NOTE) +    return Rank; +  Rank |= RF_NOT_NOTE;    // Sort sections based on their access permission in the following    // order: R, RX, RWX, RW.  This order is based on the following @@ -802,12 +840,6 @@ static unsigned getSectionRank(const OutputSection *Sec) {    if (IsNoBits)      Rank |= RF_BSS; -  // We create a NOTE segment for contiguous .note sections, so make -  // them contigous if there are more than one .note section with the -  // same attributes. -  if (Sec->Type == SHT_NOTE) -    Rank |= RF_NOTE; -    // Some architectures have additional ordering restrictions for sections    // within the same PT_LOAD.    if (Config->EMachine == EM_PPC64) { @@ -850,8 +882,10 @@ static unsigned getSectionRank(const OutputSection *Sec) {  static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {    const OutputSection *A = cast<OutputSection>(ACmd);    const OutputSection *B = cast<OutputSection>(BCmd); +    if (A->SortRank != B->SortRank)      return A->SortRank < B->SortRank; +    if (!(A->SortRank & RF_NOT_ADDR_SET))      return Config->SectionStartMap.lookup(A->Name) <             Config->SectionStartMap.lookup(B->Name); @@ -874,14 +908,20 @@ void PhdrEntry::add(OutputSection *Sec) {  // need these symbols, since IRELATIVE relocs are resolved through GOT  // and PLT. For details, see http://www.airs.com/blog/archives/403.  template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { -  if (needsInterpSection()) +  if (Config->Relocatable || needsInterpSection())      return; -  StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; -  addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); -  S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; -  ElfSym::RelaIpltEnd = -      addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); +  // By default, __rela_iplt_{start,end} belong to a dummy section 0 +  // because .rela.plt might be empty and thus removed from output. +  // We'll override Out::ElfHeader with In.RelaIplt later when we are +  // sure that .rela.plt exists in output. +  ElfSym::RelaIpltStart = addOptionalRegular( +      Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start", +      Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK); + +  ElfSym::RelaIpltEnd = addOptionalRegular( +      Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end", +      Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);  }  template <class ELFT> @@ -895,7 +935,7 @@ void Writer<ELFT>::forEachRelSec(    for (InputSectionBase *IS : InputSections)      if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))        Fn(*IS); -  for (EhInputSection *ES : InX::EhFrame->Sections) +  for (EhInputSection *ES : In.EhFrame->Sections)      Fn(*ES);  } @@ -908,15 +948,19 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {    if (ElfSym::GlobalOffsetTable) {      // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually      // to the start of the .got or .got.plt section. -    InputSection *GotSection = InX::GotPlt; +    InputSection *GotSection = In.GotPlt;      if (!Target->GotBaseSymInGotPlt) -      GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot) -                                : cast<InputSection>(InX::Got); +      GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot) +                              : cast<InputSection>(In.Got);      ElfSym::GlobalOffsetTable->Section = GotSection;    } -  if (ElfSym::RelaIpltEnd) -    ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize(); +  // .rela_iplt_{start,end} mark the start and the end of .rela.plt section. +  if (ElfSym::RelaIpltStart && !In.RelaIplt->empty()) { +    ElfSym::RelaIpltStart->Section = In.RelaIplt; +    ElfSym::RelaIpltEnd->Section = In.RelaIplt; +    ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize(); +  }    PhdrEntry *Last = nullptr;    PhdrEntry *LastRO = nullptr; @@ -1088,7 +1132,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {      SymbolOrderEntry &Ent = It->second;      Ent.Present = true; -    warnUnorderableSymbol(&Sym); +    maybeWarnUnorderableSymbol(&Sym);      if (auto *D = dyn_cast<Defined>(&Sym)) {        if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) { @@ -1097,6 +1141,7 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {        }      }    }; +    // We want both global and local symbols. We get the global ones from the    // symbol table and iterate the object files for the local ones.    for (Symbol *Sym : Symtab->getSymbols()) @@ -1132,11 +1177,10 @@ sortISDBySectionOrder(InputSectionDescription *ISD,      }      OrderedSections.push_back({IS, I->second});    } -  llvm::sort( -      OrderedSections.begin(), OrderedSections.end(), -      [&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) { -        return A.second < B.second; -      }); +  llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A, +                                  std::pair<InputSection *, int> B) { +    return A.second < B.second; +  });    // Find an insertion point for the ordered section list in the unordered    // section list. On targets with limited-range branches, this is the mid-point @@ -1166,7 +1210,7 @@ sortISDBySectionOrder(InputSectionDescription *ISD,    // we effectively double the amount of code that could potentially call into    // the hot code without a thunk.    size_t InsPt = 0; -  if (Target->ThunkSectionSpacing && !OrderedSections.empty()) { +  if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {      uint64_t UnorderedPos = 0;      for (; InsPt != UnorderedSections.size(); ++InsPt) {        UnorderedPos += UnorderedSections[InsPt]->getSize(); @@ -1342,10 +1386,12 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {    if (A->kind() == InputSectionBase::Synthetic ||        B->kind() == InputSectionBase::Synthetic)      return A->kind() != InputSectionBase::Synthetic; +    InputSection *LA = A->getLinkOrderDep();    InputSection *LB = B->getLinkOrderDep();    OutputSection *AOut = LA->getParent();    OutputSection *BOut = LB->getParent(); +    if (AOut != BOut)      return AOut->SectionIndex < BOut->SectionIndex;    return LA->OutSecOff < LB->OutSecOff; @@ -1392,6 +1438,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {    for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())      if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)        return false; +    // All table entries in this .ARM.exidx Section can be merged into the    // previous Section.    return true; @@ -1423,18 +1470,19 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {          assert(Sections.size() >= 2 &&                 "We should create a sentinel section only if there are "                 "alive regular exidx sections."); +          // The last executable section is required to fill the sentinel.          // Remember it here so that we don't have to find it again.          Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();        } +      // The EHABI for the Arm Architecture permits consecutive identical +      // table entries to be merged. We use a simple implementation that +      // removes a .ARM.exidx Input Section if it can be merged into the +      // previous one. This does not require any rewriting of InputSection +      // contents but misses opportunities for fine grained deduplication +      // where only a subset of the InputSection contents can be merged.        if (Config->MergeArmExidx) { -        // The EHABI for the Arm Architecture permits consecutive identical -        // table entries to be merged. We use a simple implementation that -        // removes a .ARM.exidx Input Section if it can be merged into the -        // previous one. This does not require any rewriting of InputSection -        // contents but misses opportunities for fine grained deduplication -        // where only a subset of the InputSection contents can be merged.          size_t Prev = 0;          // The last one is a sentinel entry which should not be removed.          for (size_t I = 1; I < Sections.size() - 1; ++I) { @@ -1456,11 +1504,49 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {    }  } -static void applySynthetic(const std::vector<SyntheticSection *> &Sections, -                           llvm::function_ref<void(SyntheticSection *)> Fn) { -  for (SyntheticSection *SS : Sections) -    if (SS && SS->getParent() && !SS->empty()) -      Fn(SS); +// For most RISC ISAs, we need to generate content that depends on the address +// of InputSections. For example some architectures such as AArch64 use small +// displacements for jump instructions that is the linker's responsibility for +// creating range extension thunks for. As the generation of the content may +// also alter InputSection addresses we must converge to a fixed point. +template <class ELFT> void Writer<ELFT>::maybeAddThunks() { +  if (!Target->NeedsThunks && !Config->AndroidPackDynRelocs && +      !Config->RelrPackDynRelocs) +    return; + +  ThunkCreator TC; +  AArch64Err843419Patcher A64P; + +  for (;;) { +    bool Changed = false; + +    Script->assignAddresses(); + +    if (Target->NeedsThunks) +      Changed |= TC.createThunks(OutputSections); + +    if (Config->FixCortexA53Errata843419) { +      if (Changed) +        Script->assignAddresses(); +      Changed |= A64P.createFixes(); +    } + +    if (In.MipsGot) +      In.MipsGot->updateAllocSize(); + +    Changed |= In.RelaDyn->updateAllocSize(); + +    if (In.RelrDyn) +      Changed |= In.RelrDyn->updateAllocSize(); + +    if (!Changed) +      return; +  } +} + +static void finalizeSynthetic(SyntheticSection *Sec) { +  if (Sec && !Sec->empty() && Sec->getParent()) +    Sec->finalizeContents();  }  // In order to allow users to manipulate linker-synthesized sections, @@ -1500,6 +1586,7 @@ static void removeUnusedSyntheticSections() {  // with the same name defined in other ELF executable or DSO.  static bool computeIsPreemptible(const Symbol &B) {    assert(!B.isLocal()); +    // Only symbols that appear in dynsym can be preempted.    if (!B.includeInDynsym())      return false; @@ -1528,7 +1615,6 @@ static bool computeIsPreemptible(const Symbol &B) {  // Create output section objects and add them to OutputSections.  template <class ELFT> void Writer<ELFT>::finalizeSections() { -  Out::DebugInfo = findSection(".debug_info");    Out::PreinitArray = findSection(".preinit_array");    Out::InitArray = findSection(".init_array");    Out::FiniArray = findSection(".fini_array"); @@ -1547,46 +1633,51 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    // It should be okay as no one seems to care about the type.    // Even the author of gold doesn't remember why gold behaves that way.    // https://sourceware.org/ml/binutils/2002-03/msg00360.html -  if (InX::DynSymTab) -    Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/, -                       /*Size=*/0, STB_WEAK, InX::Dynamic, +  if (In.Dynamic->Parent) +    Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/, +                       /*Size=*/0, STB_WEAK, In.Dynamic,                         /*File=*/nullptr);    // Define __rel[a]_iplt_{start,end} symbols if needed.    addRelIpltSymbols(); +  // RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined. +  if (Config->EMachine == EM_RISCV) +    if (!dyn_cast_or_null<Defined>(Symtab->find("__global_pointer$"))) +      addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800); +    // This responsible for splitting up .eh_frame section into    // pieces. The relocation scan uses those pieces, so this has to be    // earlier. -  applySynthetic({InX::EhFrame}, -                 [](SyntheticSection *SS) { SS->finalizeContents(); }); +  finalizeSynthetic(In.EhFrame);    for (Symbol *S : Symtab->getSymbols()) -    S->IsPreemptible |= computeIsPreemptible(*S); +    if (!S->IsPreemptible) +      S->IsPreemptible = computeIsPreemptible(*S);    // Scan relocations. This must be done after every symbol is declared so that    // we can correctly decide if a dynamic relocation is needed.    if (!Config->Relocatable)      forEachRelSec(scanRelocations<ELFT>); -  if (InX::Plt && !InX::Plt->empty()) -    InX::Plt->addSymbols(); -  if (InX::Iplt && !InX::Iplt->empty()) -    InX::Iplt->addSymbols(); +  if (In.Plt && !In.Plt->empty()) +    In.Plt->addSymbols(); +  if (In.Iplt && !In.Iplt->empty()) +    In.Iplt->addSymbols();    // Now that we have defined all possible global symbols including linker-    // synthesized ones. Visit all symbols to give the finishing touches.    for (Symbol *Sym : Symtab->getSymbols()) {      if (!includeInSymtab(*Sym))        continue; -    if (InX::SymTab) -      InX::SymTab->addSymbol(Sym); +    if (In.SymTab) +      In.SymTab->addSymbol(Sym); -    if (InX::DynSymTab && Sym->includeInDynsym()) { -      InX::DynSymTab->addSymbol(Sym); +    if (Sym->includeInDynsym()) { +      In.DynSymTab->addSymbol(Sym);        if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))          if (File->IsNeeded && !Sym->isUndefined()) -          In<ELFT>::VerNeed->addSymbol(Sym); +          InX<ELFT>::VerNeed->addSymbol(Sym);      }    } @@ -1594,8 +1685,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    if (errorCount())      return; -  if (InX::MipsGot) -    InX::MipsGot->build<ELFT>(); +  if (In.MipsGot) +    In.MipsGot->build<ELFT>();    removeUnusedSyntheticSections(); @@ -1607,15 +1698,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {      if (auto *Sec = dyn_cast<OutputSection>(Base))        OutputSections.push_back(Sec); -  // Ensure data sections are not mixed with executable sections when -  // -execute-only is used. -  if (Config->ExecuteOnly) -    for (OutputSection *OS : OutputSections) -      if (OS->Flags & SHF_EXECINSTR) -        for (InputSection *IS : getInputSections(OS)) -          if (!(IS->Flags & SHF_EXECINSTR)) -            error("-execute-only does not support intermingling data and code"); -    // Prefer command line supplied address over other constraints.    for (OutputSection *Sec : OutputSections) {      auto I = Config->SectionStartMap.find(Sec->Name); @@ -1628,10 +1710,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    // particularly relevant.    Out::ElfHeader->SectionIndex = 1; -  unsigned I = 1; -  for (OutputSection *Sec : OutputSections) { -    Sec->SectionIndex = I++; -    Sec->ShName = InX::ShStrTab->addString(Sec->Name); +  for (size_t I = 0, E = OutputSections.size(); I != E; ++I) { +    OutputSection *Sec = OutputSections[I]; +    Sec->SectionIndex = I + 1; +    Sec->ShName = In.ShStrTab->addString(Sec->Name);    }    // Binary and relocatable output does not have PHDRS. @@ -1641,6 +1723,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {      Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();      addPtArmExid(Phdrs);      Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size(); + +    // Find the TLS segment. This happens before the section layout loop so that +    // Android relocation packing can look up TLS symbol addresses. +    for (PhdrEntry *P : Phdrs) +      if (P->p_type == PT_TLS) +        Out::TlsPhdr = P;    }    // Some symbols are defined in term of program headers. Now that we @@ -1649,15 +1737,30 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    // Dynamic section must be the last one in this list and dynamic    // symbol table section (DynSymTab) must be the first one. -  applySynthetic( -      {InX::DynSymTab, InX::Bss,         InX::BssRelRo,    InX::GnuHashTab, -       InX::HashTab,   InX::SymTab,      InX::SymTabShndx, InX::ShStrTab, -       InX::StrTab,    In<ELFT>::VerDef, InX::DynStrTab,   InX::Got, -       InX::MipsGot,   InX::IgotPlt,     InX::GotPlt,      InX::RelaDyn, -       InX::RelrDyn,   InX::RelaIplt,    InX::RelaPlt,     InX::Plt, -       InX::Iplt,      InX::EhFrameHdr,  In<ELFT>::VerSym, In<ELFT>::VerNeed, -       InX::Dynamic}, -      [](SyntheticSection *SS) { SS->finalizeContents(); }); +  finalizeSynthetic(In.DynSymTab); +  finalizeSynthetic(In.Bss); +  finalizeSynthetic(In.BssRelRo); +  finalizeSynthetic(In.GnuHashTab); +  finalizeSynthetic(In.HashTab); +  finalizeSynthetic(In.SymTabShndx); +  finalizeSynthetic(In.ShStrTab); +  finalizeSynthetic(In.StrTab); +  finalizeSynthetic(In.VerDef); +  finalizeSynthetic(In.DynStrTab); +  finalizeSynthetic(In.Got); +  finalizeSynthetic(In.MipsGot); +  finalizeSynthetic(In.IgotPlt); +  finalizeSynthetic(In.GotPlt); +  finalizeSynthetic(In.RelaDyn); +  finalizeSynthetic(In.RelrDyn); +  finalizeSynthetic(In.RelaIplt); +  finalizeSynthetic(In.RelaPlt); +  finalizeSynthetic(In.Plt); +  finalizeSynthetic(In.Iplt); +  finalizeSynthetic(In.EhFrameHdr); +  finalizeSynthetic(InX<ELFT>::VerSym); +  finalizeSynthetic(InX<ELFT>::VerNeed); +  finalizeSynthetic(In.Dynamic);    if (!Script->HasSectionsCommand && !Config->Relocatable)      fixSectionAlignments(); @@ -1666,37 +1769,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    // needs to be resolved before any other address dependent operation.    resolveShfLinkOrder(); -  // Some architectures need to generate content that depends on the address -  // of InputSections. For example some architectures use small displacements -  // for jump instructions that is the linker's responsibility for creating -  // range extension thunks for. As the generation of the content may also -  // alter InputSection addresses we must converge to a fixed point. -  if (Target->NeedsThunks || Config->AndroidPackDynRelocs || -      Config->RelrPackDynRelocs) { -    ThunkCreator TC; -    AArch64Err843419Patcher A64P; -    bool Changed; -    do { -      Script->assignAddresses(); -      Changed = false; -      if (Target->NeedsThunks) -        Changed |= TC.createThunks(OutputSections); -      if (Config->FixCortexA53Errata843419) { -        if (Changed) -          Script->assignAddresses(); -        Changed |= A64P.createFixes(); -      } -      if (InX::MipsGot) -        InX::MipsGot->updateAllocSize(); -      Changed |= InX::RelaDyn->updateAllocSize(); -      if (InX::RelrDyn) -        Changed |= InX::RelrDyn->updateAllocSize(); -    } while (Changed); -  } +  // Jump instructions in many ISAs have small displacements, and therefore they +  // cannot jump to arbitrary addresses in memory. For example, RISC-V JAL +  // instruction can target only +-1 MiB from PC. It is a linker's +  // responsibility to create and insert small pieces of code between sections +  // to extend the ranges if jump targets are out of range. Such code pieces are +  // called "thunks". +  // +  // We add thunks at this stage. We couldn't do this before this point because +  // this is the earliest point where we know sizes of sections and their +  // layouts (that are needed to determine if jump targets are in range). +  maybeAddThunks(); -  // createThunks may have added local symbols to the static symbol table -  applySynthetic({InX::SymTab}, -                 [](SyntheticSection *SS) { SS->postThunkContents(); }); +  // maybeAddThunks may have added local symbols to the static symbol table. +  finalizeSynthetic(In.SymTab); +  finalizeSynthetic(In.PPC64LongBranchTarget);    // Fill other section headers. The dynamic table is finalized    // at the end because some tags like RELSZ depend on result @@ -1705,6 +1792,21 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {      Sec->finalize<ELFT>();  } +// Ensure data sections are not mixed with executable sections when +// -execute-only is used. -execute-only is a feature to make pages executable +// but not readable, and the feature is currently supported only on AArch64. +template <class ELFT> void Writer<ELFT>::checkExecuteOnly() { +  if (!Config->ExecuteOnly) +    return; + +  for (OutputSection *OS : OutputSections) +    if (OS->Flags & SHF_EXECINSTR) +      for (InputSection *IS : getInputSections(OS)) +        if (!(IS->Flags & SHF_EXECINSTR)) +          error("cannot place " + toString(IS) + " into " + toString(OS->Name) + +                ": -execute-only does not support intermingling data and code"); +} +  // The linker is expected to define SECNAME_start and SECNAME_end  // symbols for a few sections. This function defines them.  template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { @@ -1721,9 +1823,13 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {    // program to fail to link due to relocation overflow, if their    // program text is above 2 GiB. We use the address of the .text    // section instead to prevent that failure. +  // +  // In a rare sitaution, .text section may not exist. If that's the +  // case, use the image base address as a last resort.    OutputSection *Default = findSection(".text");    if (!Default)      Default = Out::ElfHeader; +    auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {      if (OS) {        addOptionalRegular(Start, OS, 0); @@ -1763,7 +1869,7 @@ static bool needsPtLoad(OutputSection *Sec) {    // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is    // responsible for allocating space for them, not the PT_LOAD that    // contains the TLS initialization image. -  if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS) +  if ((Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS)      return false;    return true;  } @@ -1815,12 +1921,14 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {      // Segments are contiguous memory regions that has the same attributes      // (e.g. executable or writable). There is one phdr for each segment.      // Therefore, we need to create a new phdr when the next section has -    // different flags or is loaded at a discontiguous address using AT linker -    // script command. At the same time, we don't want to create a separate -    // load segment for the headers, even if the first output section has -    // an AT attribute. +    // different flags or is loaded at a discontiguous address or memory +    // region using AT or AT> linker script command, respectively. At the same +    // time, we don't want to create a separate load segment for the headers, +    // even if the first output section has an AT or AT> attribute.      uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); -    if ((Sec->LMAExpr && Load->LastSec != Out::ProgramHeaders) || +    if (((Sec->LMAExpr || +          (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) && +         Load->LastSec != Out::ProgramHeaders) ||          Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {        Load = AddHdr(PT_LOAD, NewFlags); @@ -1839,9 +1947,8 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {      Ret.push_back(TlsHdr);    // Add an entry for .dynamic. -  if (InX::DynSymTab) -    AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags()) -        ->add(InX::Dynamic->getParent()); +  if (OutputSection *Sec = In.Dynamic->getParent()) +    AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);    // PT_GNU_RELRO includes all sections that should be marked as    // read-only by dynamic linker after proccessing relocations. @@ -1869,10 +1976,10 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {      Ret.push_back(RelRo);    // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr. -  if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() && -      InX::EhFrameHdr->getParent()) -    AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags()) -        ->add(InX::EhFrameHdr->getParent()); +  if (!In.EhFrame->empty() && In.EhFrameHdr && In.EhFrame->getParent() && +      In.EhFrameHdr->getParent()) +    AddHdr(PT_GNU_EH_FRAME, In.EhFrameHdr->getParent()->getPhdrFlags()) +        ->add(In.EhFrameHdr->getParent());    // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes    // the dynamic linker fill the segment with random data. @@ -1943,77 +2050,77 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {    for (const PhdrEntry *P : Phdrs) {      if (P->p_type != PT_GNU_RELRO)        continue; +      if (P->FirstSec)        PageAlign(P->FirstSec); +      // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we      // have to align it to a page.      auto End = OutputSections.end();      auto I = std::find(OutputSections.begin(), End, P->LastSec);      if (I == End || (I + 1) == End)        continue; +      OutputSection *Cmd = (*(I + 1));      if (needsPtLoad(Cmd))        PageAlign(Cmd);    }  } -// Adjusts the file alignment for a given output section and returns -// its new file offset. The file offset must be the same with its -// virtual address (modulo the page size) so that the loader can load -// executables without any address adjustment. -static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) { -  OutputSection *First = Cmd->PtLoad ? Cmd->PtLoad->FirstSec : nullptr; -  // The first section in a PT_LOAD has to have congruent offset and address -  // module the page size. -  if (Cmd == First) -    return alignTo(Off, std::max<uint64_t>(Cmd->Alignment, Config->MaxPageSize), -                   Cmd->Addr); - -  // For SHT_NOBITS we don't want the alignment of the section to impact the -  // offset of the sections that follow. Since nothing seems to care about the -  // sh_offset of the SHT_NOBITS section itself, just ignore it. -  if (Cmd->Type == SHT_NOBITS) +// Compute an in-file position for a given section. The file offset must be the +// same with its virtual address modulo the page size, so that the loader can +// load executables without any address adjustment. +static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) { +  // File offsets are not significant for .bss sections. By convention, we keep +  // section offsets monotonically increasing rather than setting to zero. +  if (OS->Type == SHT_NOBITS)      return Off;    // If the section is not in a PT_LOAD, we just have to align it. -  if (!Cmd->PtLoad) -    return alignTo(Off, Cmd->Alignment); +  if (!OS->PtLoad) +    return alignTo(Off, OS->Alignment); + +  // The first section in a PT_LOAD has to have congruent offset and address +  // module the page size. +  OutputSection *First = OS->PtLoad->FirstSec; +  if (OS == First) { +    uint64_t Alignment = std::max<uint64_t>(OS->Alignment, Config->MaxPageSize); +    return alignTo(Off, Alignment, OS->Addr); +  }    // If two sections share the same PT_LOAD the file offset is calculated    // using this formula: Off2 = Off1 + (VA2 - VA1). -  return First->Offset + Cmd->Addr - First->Addr; +  return First->Offset + OS->Addr - First->Addr;  } -static uint64_t setOffset(OutputSection *Cmd, uint64_t Off) { -  Off = getFileAlignment(Off, Cmd); -  Cmd->Offset = Off; +// Set an in-file position to a given section and returns the end position of +// the section. +static uint64_t setFileOffset(OutputSection *OS, uint64_t Off) { +  Off = computeFileOffset(OS, Off); +  OS->Offset = Off; -  // For SHT_NOBITS we should not count the size. -  if (Cmd->Type == SHT_NOBITS) +  if (OS->Type == SHT_NOBITS)      return Off; - -  return Off + Cmd->Size; +  return Off + OS->Size;  }  template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {    uint64_t Off = 0;    for (OutputSection *Sec : OutputSections)      if (Sec->Flags & SHF_ALLOC) -      Off = setOffset(Sec, Off); +      Off = setFileOffset(Sec, Off);    FileSize = alignTo(Off, Config->Wordsize);  }  static std::string rangeToString(uint64_t Addr, uint64_t Len) { -  if (Len == 0) -    return "<empty range at 0x" + utohexstr(Addr) + ">";    return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";  }  // Assign file offsets to output sections.  template <class ELFT> void Writer<ELFT>::assignFileOffsets() {    uint64_t Off = 0; -  Off = setOffset(Out::ElfHeader, Off); -  Off = setOffset(Out::ProgramHeaders, Off); +  Off = setFileOffset(Out::ElfHeader, Off); +  Off = setFileOffset(Out::ProgramHeaders, Off);    PhdrEntry *LastRX = nullptr;    for (PhdrEntry *P : Phdrs) @@ -2021,9 +2128,10 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {        LastRX = P;    for (OutputSection *Sec : OutputSections) { -    Off = setOffset(Sec, Off); +    Off = setFileOffset(Sec, Off);      if (Script->HasSectionsCommand)        continue; +      // If this is a last section of the last executable segment and that      // segment is the last loadable segment, align the offset of the      // following section to avoid loading non-segments parts of the file. @@ -2048,7 +2156,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {        continue;      if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))        error("unable to place section " + Sec->Name + " at file offset " + -            rangeToString(Sec->Offset, Sec->Offset + Sec->Size) + +            rangeToString(Sec->Offset, Sec->Size) +              "; check your linker script for overflows");    }  } @@ -2059,19 +2167,23 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {    for (PhdrEntry *P : Phdrs) {      OutputSection *First = P->FirstSec;      OutputSection *Last = P->LastSec; +      if (First) {        P->p_filesz = Last->Offset - First->Offset;        if (Last->Type != SHT_NOBITS)          P->p_filesz += Last->Size; +        P->p_memsz = Last->Addr + Last->Size - First->Addr;        P->p_offset = First->Offset;        P->p_vaddr = First->Addr; +        if (!P->HasLMA)          P->p_paddr = First->getLMA();      } -    if (P->p_type == PT_LOAD) + +    if (P->p_type == PT_LOAD) {        P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize); -    else if (P->p_type == PT_GNU_RELRO) { +    } else if (P->p_type == PT_GNU_RELRO) {        P->p_align = 1;        // The glibc dynamic loader rounds the size down, so we need to round up        // to protect the last page. This is a no-op on FreeBSD which always @@ -2079,12 +2191,22 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {        P->p_memsz = alignTo(P->p_memsz, Target->PageSize);      } -    // The TLS pointer goes after PT_TLS. At least glibc will align it, -    // so round up the size to make sure the offsets are correct. -    if (P->p_type == PT_TLS) { -      Out::TlsPhdr = P; -      if (P->p_memsz) -        P->p_memsz = alignTo(P->p_memsz, P->p_align); +    if (P->p_type == PT_TLS && P->p_memsz) { +      if (!Config->Shared && +          (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) { +        // On ARM/AArch64, reserve extra space (8 words) between the thread +        // pointer and an executable's TLS segment by overaligning the segment. +        // This reservation is needed for backwards compatibility with Android's +        // TCB, which allocates several slots after the thread pointer (e.g. +        // TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also +        // done on other operating systems. +        P->p_align = std::max<uint64_t>(P->p_align, Config->Wordsize * 8); +      } + +      // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc +      // will align it, so round up the size to make sure the offsets are +      // correct. +      P->p_memsz = alignTo(P->p_memsz, P->p_align);      }    }  } @@ -2101,10 +2223,9 @@ struct SectionOffset {  // load and virtual adresses).  static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,                           bool IsVirtualAddr) { -  llvm::sort(Sections.begin(), Sections.end(), -             [=](const SectionOffset &A, const SectionOffset &B) { -               return A.Offset < B.Offset; -             }); +  llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) { +    return A.Offset < B.Offset; +  });    // Finding overlap is easy given a vector is sorted by start position.    // If an element starts before the end of the previous element, they overlap. @@ -2148,7 +2269,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {    // file so we skip any non-allocated sections in that case.    std::vector<SectionOffset> FileOffs;    for (OutputSection *Sec : OutputSections) -    if (0 < Sec->Size && Sec->Type != SHT_NOBITS && +    if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&          (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))        FileOffs.push_back({Sec, Sec->Offset});    checkOverlap("file", FileOffs, false); @@ -2166,7 +2287,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {    // ranges in the file.    std::vector<SectionOffset> VMAs;    for (OutputSection *Sec : OutputSections) -    if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS)) +    if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))        VMAs.push_back({Sec, Sec->Addr});    checkOverlap("virtual address", VMAs, true); @@ -2175,7 +2296,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {    // script with AT().    std::vector<SectionOffset> LMAs;    for (OutputSection *Sec : OutputSections) -    if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS)) +    if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))        LMAs.push_back({Sec, Sec->getLMA()});    checkOverlap("load address", LMAs, false);  } @@ -2188,7 +2309,7 @@ template <class ELFT> void Writer<ELFT>::checkSections() {  // 4. the number represented by the entry symbol, if it is a number;  // 5. the address of the first byte of the .text section, if present;  // 6. the address 0. -template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() { +static uint64_t getEntryAddr() {    // Case 1, 2 or 3    if (Symbol *B = Symtab->find(Config->Entry))      return B->getVA(); @@ -2231,6 +2352,7 @@ static uint8_t getAbiVersion() {  template <class ELFT> void Writer<ELFT>::writeHeader() {    uint8_t *Buf = Buffer->getBufferStart(); +    // For executable segments, the trap instructions are written before writing    // the header. Setting Elf header bytes to zero ensures that any unused bytes    // in header are zero-cleared, instead of having trap instructions. @@ -2289,7 +2411,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {    else      EHdr->e_shnum = Num; -  uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex; +  uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;    if (StrTabIndex >= SHN_LORESERVE) {      SHdrs->sh_link = StrTabIndex;      EHdr->e_shstrndx = SHN_XINDEX; @@ -2303,7 +2425,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {  // Open a result file.  template <class ELFT> void Writer<ELFT>::openFile() { -  if (!Config->Is64 && FileSize > UINT32_MAX) { +  uint64_t MaxSize = Config->Is64 ? INT64_MAX : UINT32_MAX; +  if (MaxSize < FileSize) {      error("output file too large: " + Twine(FileSize) + " bytes");      return;    } @@ -2368,8 +2491,8 @@ template <class ELFT> void Writer<ELFT>::writeSections() {    uint8_t *Buf = Buffer->getBufferStart();    OutputSection *EhFrameHdr = nullptr; -  if (InX::EhFrameHdr && !InX::EhFrameHdr->empty()) -    EhFrameHdr = InX::EhFrameHdr->getParent(); +  if (In.EhFrameHdr && !In.EhFrameHdr->empty()) +    EhFrameHdr = In.EhFrameHdr->getParent();    // In -r or -emit-relocs mode, write the relocation sections first as in    // ELf_Rel targets we might find out that we need to modify the relocated @@ -2389,13 +2512,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {  }  template <class ELFT> void Writer<ELFT>::writeBuildId() { -  if (!InX::BuildId || !InX::BuildId->getParent()) +  if (!In.BuildId || !In.BuildId->getParent())      return;    // Compute a hash of all sections of the output file.    uint8_t *Start = Buffer->getBufferStart();    uint8_t *End = Start + FileSize; -  InX::BuildId->writeBuildId({Start, End}); +  In.BuildId->writeBuildId({Start, End});  }  template void elf::writeResult<ELF32LE>();  | 
