diff options
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index fb745417332..b7783e4785b 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -682,6 +682,7 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { // Process PHDRS and FILEHDR keywords because they are not // real output sections and cannot be added in the following loop. + std::vector<size_t> DefPhdrIds; for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); PhdrEntry<ELFT> &Phdr = Ret.back(); @@ -695,33 +696,33 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { Phdr.H.p_paddr = Cmd.LMAExpr(0); Phdr.HasLMA = true; } + + // If output section command doesn't specify any segments, + // and we haven't previously assigned any section to segment, + // then we simply assign section to the very first load segment. + // Below is an example of such linker script: + // PHDRS { seg PT_LOAD; } + // SECTIONS { .aaa : { *(.aaa) } } + if (DefPhdrIds.empty() && Phdr.H.p_type == PT_LOAD) + DefPhdrIds.push_back(Ret.size() - 1); } // Add output sections to program headers. - PhdrEntry<ELFT> *Load = nullptr; - uintX_t Flags = PF_R; for (OutputSectionBase<ELFT> *Sec : *OutputSections) { if (!(Sec->getFlags() & SHF_ALLOC)) break; std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName()); - if (!PhdrIds.empty()) { - // Assign headers specified by linker script - for (size_t Id : PhdrIds) { - Ret[Id].add(Sec); - if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) - Ret[Id].H.p_flags |= Sec->getPhdrFlags(); - } - } else { - // If we have no load segment or flags've changed then we want new load - // segment. - uintX_t NewFlags = Sec->getPhdrFlags(); - if (Load == nullptr || Flags != NewFlags) { - Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); - Flags = NewFlags; - } - Load->add(Sec); + if (PhdrIds.empty()) + PhdrIds = std::move(DefPhdrIds); + + // Assign headers specified by linker script + for (size_t Id : PhdrIds) { + Ret[Id].add(Sec); + if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) + Ret[Id].H.p_flags |= Sec->getPhdrFlags(); } + DefPhdrIds = std::move(PhdrIds); } return Ret; } |