}
// Write leading padding.
- SmallVector<InputSection *, 0> sections = getInputSections(*this);
+ SmallVector<InputSection *, 0> storage;
+ ArrayRef<InputSection *> sections = getInputSections(*this, storage);
std::array<uint8_t, 4> filler = getFiller();
bool nonZeroFiller = read32(filler.data()) != 0;
if (nonZeroFiller)
return nullptr;
}
-SmallVector<InputSection *, 0> elf::getInputSections(const OutputSection &os) {
- SmallVector<InputSection *, 0> ret;
- for (SectionCommand *cmd : os.commands)
- if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
- ret.insert(ret.end(), isd->sections.begin(), isd->sections.end());
- return ret;
+ArrayRef<InputSection *>
+elf::getInputSections(const OutputSection &os,
+ SmallVector<InputSection *, 0> &storage) {
+ ArrayRef<InputSection *> ret;
+ storage.clear();
+ for (SectionCommand *cmd : os.commands) {
+ auto *isd = dyn_cast<InputSectionDescription>(cmd);
+ if (!isd)
+ continue;
+ if (ret.empty()) {
+ ret = isd->sections;
+ } else {
+ if (storage.empty())
+ storage.assign(ret.begin(), ret.end());
+ storage.insert(storage.end(), isd->sections.begin(), isd->sections.end());
+ }
+ }
+ return storage.empty() ? ret : makeArrayRef(storage);
}
// Sorts input sections by section name suffixes, so that .foo.N comes
void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
assert(config->writeAddends && config->checkDynamicRelocs);
assert(type == SHT_REL || type == SHT_RELA);
- SmallVector<InputSection *, 0> sections = getInputSections(*this);
+ SmallVector<InputSection *, 0> storage;
+ ArrayRef<InputSection *> sections = getInputSections(*this, storage);
parallelFor(0, sections.size(), [&](size_t i) {
// When linking with -r or --emit-relocs we might also call this function
// for input .rel[a].<sec> sections which we simply pass through to the
int getPriority(StringRef s);
InputSection *getFirstInputSection(const OutputSection *os);
-SmallVector<InputSection *, 0> getInputSections(const OutputSection &os);
+llvm::ArrayRef<InputSection *>
+getInputSections(const OutputSection &os,
+ SmallVector<InputSection *, 0> &storage);
// All output sections that are handled by the linker specially are
// globally accessible. Writer initializes them, so don't use them
// option is used.
template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
assert(config->optimizeBBJumps);
+ SmallVector<InputSection *, 0> storage;
script->assignAddresses();
// For every output section that has executable input sections, this
for (OutputSection *osec : outputSections) {
if (!(osec->flags & SHF_EXECINSTR))
continue;
- SmallVector<InputSection *, 0> sections = getInputSections(*osec);
+ ArrayRef<InputSection *> sections = getInputSections(*osec, storage);
size_t numDeleted = 0;
// Delete all fall through jump instructions. Also, check if two
// consecutive jump instructions can be flipped so that a fall
fixSymbolsAfterShrinking();
for (OutputSection *osec : outputSections)
- for (InputSection *is : getInputSections(*osec))
+ for (InputSection *is : getInputSections(*osec, storage))
is->trim();
}
if (!config->executeOnly)
return;
+ SmallVector<InputSection *, 0> storage;
for (OutputSection *osec : outputSections)
if (osec->flags & SHF_EXECINSTR)
- for (InputSection *isec : getInputSections(*osec))
+ for (InputSection *isec : getInputSections(*osec, storage))
if (!(isec->flags & SHF_EXECINSTR))
error("cannot place " + toString(isec) + " into " +
toString(osec->name) +