[ELF] Choose default segment when it is not specified
Linker scripts may specify PHDRS, but not specify section to
segment assignments, i.e:
PHDRS { seg PT_LOAD; }
SECTIONS {
.sec1 {} : seg
.sec2 {}
}
In such case linker should still choose some segment for .sec2 section.
This patch will add .sec2 to previously opened segments (seg) or to the
very first PT_LOAD segment, if no section-to-segment assignments has been
made
Differential revision: https://reviews.llvm.org/D24795
llvm-svn: 284600
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index fb74541..b7783e4 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -682,6 +682,7 @@
// 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 @@
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;
}