forked from OSchip/llvm-project
[ELF] LinkerScript/OutputSection: change other std::vector members to SmallVector
11+KiB smaller .text with both libc++ and libstdc++ builds.
This commit is contained in:
parent
31cfb3f4f6
commit
a1c2ee0147
|
@ -306,7 +306,7 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
|
|||
// Process INSERT [AFTER|BEFORE] commands. For each command, we move the
|
||||
// specified output section to the designated place.
|
||||
void LinkerScript::processInsertCommands() {
|
||||
std::vector<OutputSection *> moves;
|
||||
SmallVector<OutputSection *, 0> moves;
|
||||
for (const InsertCommand &cmd : insertCommands) {
|
||||
for (StringRef name : cmd.names) {
|
||||
// If base is empty, it may have been discarded by
|
||||
|
@ -490,7 +490,7 @@ SmallVector<InputSectionBase *, 0>
|
|||
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
|
||||
ArrayRef<InputSectionBase *> sections) {
|
||||
SmallVector<InputSectionBase *, 0> ret;
|
||||
std::vector<size_t> indexes;
|
||||
SmallVector<size_t, 0> indexes;
|
||||
DenseSet<size_t> seen;
|
||||
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
|
||||
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
|
||||
|
@ -827,7 +827,7 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
|
|||
// Add sections that didn't match any sections command.
|
||||
void LinkerScript::addOrphanSections() {
|
||||
StringMap<TinyPtrVector<OutputSection *>> map;
|
||||
std::vector<OutputSection *> v;
|
||||
SmallVector<OutputSection *, 0> v;
|
||||
|
||||
std::function<void(InputSectionBase *)> add;
|
||||
add = [&](InputSectionBase *s) {
|
||||
|
@ -1110,7 +1110,7 @@ bool LinkerScript::isDiscarded(const OutputSection *sec) const {
|
|||
}
|
||||
|
||||
static void maybePropagatePhdrs(OutputSection &sec,
|
||||
std::vector<StringRef> &phdrs) {
|
||||
SmallVector<StringRef, 0> &phdrs) {
|
||||
if (sec.phdrs.empty()) {
|
||||
// To match the bfd linker script behaviour, only propagate program
|
||||
// headers to sections that are allocated.
|
||||
|
@ -1144,7 +1144,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
|
|||
// the previous sections. Only a few flags are needed to keep the impact low.
|
||||
uint64_t flags = SHF_ALLOC;
|
||||
|
||||
std::vector<StringRef> defPhdrs;
|
||||
SmallVector<StringRef, 0> defPhdrs;
|
||||
for (SectionCommand *&cmd : sectionCommands) {
|
||||
auto *sec = dyn_cast<OutputSection>(cmd);
|
||||
if (!sec)
|
||||
|
@ -1215,7 +1215,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
|
|||
// Below is an example of such linker script:
|
||||
// PHDRS { seg PT_LOAD; }
|
||||
// SECTIONS { .aaa : { *(.aaa) } }
|
||||
std::vector<StringRef> defPhdrs;
|
||||
SmallVector<StringRef, 0> defPhdrs;
|
||||
auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
|
||||
return cmd.type == PT_LOAD;
|
||||
});
|
||||
|
@ -1245,7 +1245,7 @@ static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
|
|||
// We check if the headers fit below the first allocated section. If there isn't
|
||||
// enough space for these sections, we'll remove them from the PT_LOAD segment,
|
||||
// and we'll also remove the PT_PHDR segment.
|
||||
void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &phdrs) {
|
||||
void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
|
||||
uint64_t min = std::numeric_limits<uint64_t>::max();
|
||||
for (OutputSection *sec : outputSections)
|
||||
if (sec->flags & SHF_ALLOC)
|
||||
|
@ -1329,8 +1329,8 @@ const Defined *LinkerScript::assignAddresses() {
|
|||
}
|
||||
|
||||
// Creates program headers as instructed by PHDRS linker script command.
|
||||
std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
|
||||
std::vector<PhdrEntry *> ret;
|
||||
SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
|
||||
SmallVector<PhdrEntry *, 0> ret;
|
||||
|
||||
// Process PHDRS and FILEHDR keywords because they are not
|
||||
// real output sections and cannot be added in the following loop.
|
||||
|
@ -1412,8 +1412,8 @@ static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
|
|||
|
||||
// Returns indices of ELF headers containing specific section. Each index is a
|
||||
// zero based number of ELF header listed within PHDRS {} script block.
|
||||
std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
|
||||
std::vector<size_t> ret;
|
||||
SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
|
||||
SmallVector<size_t, 0> ret;
|
||||
|
||||
for (StringRef s : cmd->phdrs) {
|
||||
if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
|
||||
|
|
|
@ -244,7 +244,7 @@ struct ByteCommand : SectionCommand {
|
|||
};
|
||||
|
||||
struct InsertCommand {
|
||||
std::vector<StringRef> names;
|
||||
SmallVector<StringRef, 0> names;
|
||||
bool isAfter;
|
||||
StringRef where;
|
||||
};
|
||||
|
@ -287,7 +287,7 @@ class LinkerScript final {
|
|||
|
||||
void discardSynthetic(OutputSection &);
|
||||
|
||||
std::vector<size_t> getPhdrIndices(OutputSection *sec);
|
||||
SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
|
||||
|
||||
std::pair<MemoryRegion *, MemoryRegion *>
|
||||
findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
|
||||
|
@ -321,12 +321,12 @@ public:
|
|||
void adjustSectionsBeforeSorting();
|
||||
void adjustSectionsAfterSorting();
|
||||
|
||||
std::vector<PhdrEntry *> createPhdrs();
|
||||
SmallVector<PhdrEntry *, 0> createPhdrs();
|
||||
bool needsInterpSection();
|
||||
|
||||
bool shouldKeep(InputSectionBase *s);
|
||||
const Defined *assignAddresses();
|
||||
void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
|
||||
void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
|
||||
void processSectionCommands();
|
||||
void processSymbolAssignments();
|
||||
void declareSymbols();
|
||||
|
@ -337,10 +337,10 @@ public:
|
|||
void processInsertCommands();
|
||||
|
||||
// SECTIONS command list.
|
||||
std::vector<SectionCommand *> sectionCommands;
|
||||
SmallVector<SectionCommand *, 0> sectionCommands;
|
||||
|
||||
// PHDRS command list.
|
||||
std::vector<PhdrsCommand> phdrsCommands;
|
||||
SmallVector<PhdrsCommand, 0> phdrsCommands;
|
||||
|
||||
bool hasSectionsCommand = false;
|
||||
bool errorOnMissingSection = false;
|
||||
|
|
|
@ -347,7 +347,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
|
|||
}
|
||||
|
||||
// Write leading padding.
|
||||
std::vector<InputSection *> sections = getInputSections(this);
|
||||
SmallVector<InputSection *, 0> sections = getInputSections(*this);
|
||||
std::array<uint8_t, 4> filler = getFiller();
|
||||
bool nonZeroFiller = read32(filler.data()) != 0;
|
||||
if (nonZeroFiller)
|
||||
|
@ -520,9 +520,9 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<InputSection *> elf::getInputSections(const OutputSection *os) {
|
||||
std::vector<InputSection *> ret;
|
||||
for (SectionCommand *cmd : os->commands)
|
||||
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;
|
||||
|
@ -550,7 +550,7 @@ std::array<uint8_t, 4> OutputSection::getFiller() {
|
|||
void OutputSection::checkDynRelAddends(const uint8_t *bufStart) {
|
||||
assert(config->writeAddends && config->checkDynamicRelocs);
|
||||
assert(type == SHT_REL || type == SHT_RELA);
|
||||
std::vector<InputSection *> sections = getInputSections(this);
|
||||
SmallVector<InputSection *, 0> sections = getInputSections(*this);
|
||||
parallelForEachN(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
|
||||
|
|
|
@ -82,8 +82,8 @@ public:
|
|||
Expr alignExpr;
|
||||
Expr lmaExpr;
|
||||
Expr subalignExpr;
|
||||
std::vector<SectionCommand *> commands;
|
||||
std::vector<StringRef> phdrs;
|
||||
SmallVector<SectionCommand *, 0> commands;
|
||||
SmallVector<StringRef, 0> phdrs;
|
||||
llvm::Optional<std::array<uint8_t, 4>> filler;
|
||||
ConstraintKind constraint = ConstraintKind::NoConstraint;
|
||||
std::string location;
|
||||
|
@ -112,8 +112,8 @@ public:
|
|||
|
||||
private:
|
||||
// Used for implementation of --compress-debug-sections option.
|
||||
std::vector<uint8_t> zDebugHeader;
|
||||
llvm::SmallVector<char, 0> compressedData;
|
||||
SmallVector<uint8_t, 0> zDebugHeader;
|
||||
SmallVector<char, 0> compressedData;
|
||||
|
||||
std::array<uint8_t, 4> getFiller();
|
||||
};
|
||||
|
@ -121,7 +121,7 @@ private:
|
|||
int getPriority(StringRef s);
|
||||
|
||||
InputSection *getFirstInputSection(const OutputSection *os);
|
||||
std::vector<InputSection *> getInputSections(const OutputSection *os);
|
||||
SmallVector<InputSection *, 0> getInputSections(const OutputSection &os);
|
||||
|
||||
// All output sections that are handled by the linker specially are
|
||||
// globally accessible. Writer initializes them, so don't use them
|
||||
|
|
|
@ -94,7 +94,7 @@ private:
|
|||
OutputSection *readOverlaySectionDescription();
|
||||
OutputSection *readOutputSectionDescription(StringRef outSec);
|
||||
std::vector<SectionCommand *> readOverlay();
|
||||
std::vector<StringRef> readOutputSectionPhdrs();
|
||||
SmallVector<StringRef, 0> readOutputSectionPhdrs();
|
||||
std::pair<uint64_t, uint64_t> readInputSectionFlags();
|
||||
InputSectionDescription *readInputSectionDescription(StringRef tok);
|
||||
StringMatcher readFilePatterns();
|
||||
|
@ -597,7 +597,7 @@ void ScriptParser::readSections() {
|
|||
else if (!consume("BEFORE"))
|
||||
setError("expected AFTER/BEFORE, but got '" + next() + "'");
|
||||
StringRef where = next();
|
||||
std::vector<StringRef> names;
|
||||
SmallVector<StringRef, 0> names;
|
||||
for (SectionCommand *cmd : v)
|
||||
if (auto *os = dyn_cast<OutputSection>(cmd))
|
||||
names.push_back(os->name);
|
||||
|
@ -1452,8 +1452,8 @@ Expr ScriptParser::readParenExpr() {
|
|||
return e;
|
||||
}
|
||||
|
||||
std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
|
||||
std::vector<StringRef> phdrs;
|
||||
SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
|
||||
SmallVector<StringRef, 0> phdrs;
|
||||
while (!errorCount() && peek().startswith(":")) {
|
||||
StringRef tok = next();
|
||||
phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
|
||||
|
|
|
@ -1205,7 +1205,7 @@ struct Partition {
|
|||
|
||||
SyntheticSection *elfHeader;
|
||||
SyntheticSection *programHeaders;
|
||||
std::vector<PhdrEntry *> phdrs;
|
||||
SmallVector<PhdrEntry *, 0> phdrs;
|
||||
|
||||
ARMExidxSyntheticSection *armExidx;
|
||||
BuildIdSection *buildId;
|
||||
|
|
|
@ -65,7 +65,7 @@ private:
|
|||
void checkExecuteOnly();
|
||||
void setReservedSymbolSections();
|
||||
|
||||
std::vector<PhdrEntry *> createPhdrs(Partition &part);
|
||||
SmallVector<PhdrEntry *, 0> createPhdrs(Partition &part);
|
||||
void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
|
||||
unsigned pFlags);
|
||||
void assignFileOffsets();
|
||||
|
@ -100,7 +100,7 @@ template <class ELFT> void elf::writeResult() {
|
|||
Writer<ELFT>().run();
|
||||
}
|
||||
|
||||
static void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
|
||||
static void removeEmptyPTLoad(SmallVector<PhdrEntry *, 0> &phdrs) {
|
||||
auto it = std::stable_partition(
|
||||
phdrs.begin(), phdrs.end(), [&](const PhdrEntry *p) {
|
||||
if (p->p_type != PT_LOAD)
|
||||
|
@ -1170,9 +1170,9 @@ static bool shouldSkip(SectionCommand *cmd) {
|
|||
// We want to place orphan sections so that they share as much
|
||||
// characteristics with their neighbors as possible. For example, if
|
||||
// both are rw, or both are tls.
|
||||
static std::vector<SectionCommand *>::iterator
|
||||
findOrphanPos(std::vector<SectionCommand *>::iterator b,
|
||||
std::vector<SectionCommand *>::iterator e) {
|
||||
static SmallVectorImpl<SectionCommand *>::iterator
|
||||
findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
|
||||
SmallVectorImpl<SectionCommand *>::iterator e) {
|
||||
OutputSection *sec = cast<OutputSection>(*e);
|
||||
|
||||
// Find the first element that has as close a rank as possible.
|
||||
|
@ -1332,8 +1332,8 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
|
|||
static void
|
||||
sortISDBySectionOrder(InputSectionDescription *isd,
|
||||
const DenseMap<const InputSectionBase *, int> &order) {
|
||||
std::vector<InputSection *> unorderedSections;
|
||||
std::vector<std::pair<InputSection *, int>> orderedSections;
|
||||
SmallVector<InputSection *, 0> unorderedSections;
|
||||
SmallVector<std::pair<InputSection *, int>, 0> orderedSections;
|
||||
uint64_t unorderedSize = 0;
|
||||
|
||||
for (InputSection *isec : isd->sections) {
|
||||
|
@ -1766,10 +1766,10 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
|
|||
// jump to the following section as it is not required.
|
||||
// 2. If there are two consecutive jump instructions, it checks
|
||||
// if they can be flipped and one can be deleted.
|
||||
for (OutputSection *os : outputSections) {
|
||||
if (!(os->flags & SHF_EXECINSTR))
|
||||
for (OutputSection *osec : outputSections) {
|
||||
if (!(osec->flags & SHF_EXECINSTR))
|
||||
continue;
|
||||
std::vector<InputSection *> sections = getInputSections(os);
|
||||
SmallVector<InputSection *, 0> sections = getInputSections(*osec);
|
||||
std::vector<unsigned> result(sections.size());
|
||||
// Delete all fall through jump instructions. Also, check if two
|
||||
// consecutive jump instructions can be flipped so that a fall
|
||||
|
@ -1790,12 +1790,10 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
|
|||
|
||||
fixSymbolsAfterShrinking();
|
||||
|
||||
for (OutputSection *os : outputSections) {
|
||||
std::vector<InputSection *> sections = getInputSections(os);
|
||||
for (InputSection *is : sections)
|
||||
for (OutputSection *osec : outputSections)
|
||||
for (InputSection *is : getInputSections(*osec))
|
||||
is->trim();
|
||||
}
|
||||
}
|
||||
|
||||
// In order to allow users to manipulate linker-synthesized sections,
|
||||
// we had to add synthetic sections to the input section list early,
|
||||
|
@ -2165,11 +2163,12 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
|
|||
if (!config->executeOnly)
|
||||
return;
|
||||
|
||||
for (OutputSection *os : outputSections)
|
||||
if (os->flags & SHF_EXECINSTR)
|
||||
for (InputSection *isec : getInputSections(os))
|
||||
for (OutputSection *osec : outputSections)
|
||||
if (osec->flags & SHF_EXECINSTR)
|
||||
for (InputSection *isec : getInputSections(*osec))
|
||||
if (!(isec->flags & SHF_EXECINSTR))
|
||||
error("cannot place " + toString(isec) + " into " + toString(os->name) +
|
||||
error("cannot place " + toString(isec) + " into " +
|
||||
toString(osec->name) +
|
||||
": -execute-only does not support intermingling data and code");
|
||||
}
|
||||
|
||||
|
@ -2259,8 +2258,8 @@ static uint64_t computeFlags(uint64_t flags) {
|
|||
// Decide which program headers to create and which sections to include in each
|
||||
// one.
|
||||
template <class ELFT>
|
||||
std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
std::vector<PhdrEntry *> ret;
|
||||
SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
|
||||
SmallVector<PhdrEntry *, 0> ret;
|
||||
auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
|
||||
ret.push_back(make<PhdrEntry>(type, flags));
|
||||
return ret.back();
|
||||
|
|
Loading…
Reference in New Issue