summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp37
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;
}
OpenPOWER on IntegriCloud