OS << OSec->Name << '\n';
// Dump symbols for each input section.
- for (BaseCommand *Base : OSec->SectionCommands) {
- auto *ISD = dyn_cast<InputSectionDescription>(Base);
- if (!ISD)
- continue;
- for (InputSection *IS : ISD->Sections) {
- writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
- IS->Alignment);
- OS << indent(1) << toString(IS) << '\n';
- for (Symbol *Sym : SectionSyms[IS])
- OS << SymStr[Sym] << '\n';
- }
+ for (InputSection *IS : getInputSections(OSec)) {
+ writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), IS->Alignment);
+ OS << indent(1) << toString(IS) << '\n';
+ for (Symbol *Sym : SectionSyms[IS])
+ OS << SymStr[Sym] << '\n';
}
}
}
}
// Write leading padding.
- std::vector<InputSection *> Sections;
- for (BaseCommand *Cmd : SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
- for (InputSection *IS : ISD->Sections)
- if (IS->Live)
- Sections.push_back(IS);
+ std::vector<InputSection *> Sections = getInputSections(this);
uint32_t Filler = getFiller();
if (Filler)
fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
}
template <class ELFT> void OutputSection::finalize() {
- InputSection *First = nullptr;
- for (BaseCommand *Base : SectionCommands) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
- if (ISD->Sections.empty())
- continue;
- if (First == nullptr)
- First = ISD->Sections.front();
- }
- if (isa<ByteCommand>(Base) && Type == SHT_NOBITS)
- Type = SHT_PROGBITS;
- }
+ if (Type == SHT_NOBITS)
+ for (BaseCommand *Base : SectionCommands)
+ if (isa<ByteCommand>(Base))
+ Type = SHT_PROGBITS;
+
+ std::vector<InputSection *> V = getInputSections(this);
+ InputSection *First = V.empty() ? nullptr : V[0];
if (Flags & SHF_LINK_ORDER) {
// We must preserve the link order dependency of sections with the
return V;
}
+std::vector<InputSection *> elf::getInputSections(OutputSection *OS) {
+ std::vector<InputSection *> Ret;
+ for (BaseCommand *Base : OS->SectionCommands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+ Ret.insert(Ret.end(), ISD->Sections.begin(), ISD->Sections.end());
+ return Ret;
+}
+
// Sorts input sections by section name suffixes, so that .foo.N comes
// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
// We want to keep the original order if the priorities are the same
int getPriority(StringRef S);
+std::vector<InputSection *> getInputSections(OutputSection* OS);
+
// All output sections that are handled by the linker specially are
// globally accessible. Writer initializes them, so don't use them
// until Writer is initialized.
// The sentinel has to be removed if there are no other .ARM.exidx entries.
bool ARMExidxSentinelSection::empty() const {
- OutputSection *OS = getParent();
- for (auto *B : OS->SectionCommands)
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- for (auto *S : ISD->Sections)
- if (!isa<ARMExidxSentinelSection>(S))
- return false;
+ for (InputSection *IS : getInputSections(getParent()))
+ if (!isa<ARMExidxSentinelSection>(IS))
+ return false;
return true;
}
// If there are no other alive sections or commands left in the output
// section description, we remove it from the output.
- bool IsEmpty = llvm::all_of(OS->SectionCommands, [](BaseCommand *B) {
- if (auto *ISD = dyn_cast<InputSectionDescription>(B))
- return ISD->Sections.empty();
- return false;
- });
- if (IsEmpty)
+ if (getInputSections(OS).empty())
OS->Live = false;
}
}