Share more output section creation code.
We can do this now that the linker script and the writer agree on which sections should be combined. llvm-svn: 295341
This commit is contained in:
parent
ad3f63986d
commit
8290274c13
|
@ -302,18 +302,6 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) {
|
|||
return Ret;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
|
||||
InputSectionBase<ELFT> *Sec,
|
||||
StringRef Name) {
|
||||
OutputSectionBase *OutSec;
|
||||
bool IsNew;
|
||||
std::tie(OutSec, IsNew) = Factory.create(Sec, Name);
|
||||
if (IsNew)
|
||||
OutputSections->push_back(OutSec);
|
||||
OutSec->addSection(Sec);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
|
||||
for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
|
||||
|
@ -377,7 +365,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
|
|||
|
||||
// Add input sections to an output section.
|
||||
for (InputSectionBase<ELFT> *S : V)
|
||||
addSection(Factory, S, Cmd->Name);
|
||||
Factory.addInputSec(S, Cmd->Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +376,7 @@ void LinkerScript<ELFT>::addOrphanSections(
|
|||
OutputSectionFactory<ELFT> &Factory) {
|
||||
for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections)
|
||||
if (S->Live && !S->OutSec)
|
||||
addSection(Factory, S, getOutputSectionName(S->Name));
|
||||
Factory.addInputSec(S, getOutputSectionName(S->Name));
|
||||
}
|
||||
|
||||
template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
|
||||
|
|
|
@ -277,8 +277,6 @@ public:
|
|||
private:
|
||||
void computeInputSections(InputSectionDescription *);
|
||||
|
||||
void addSection(OutputSectionFactory<ELFT> &Factory,
|
||||
InputSectionBase<ELFT> *Sec, StringRef Name);
|
||||
void discard(ArrayRef<InputSectionBase<ELFT> *> V);
|
||||
|
||||
std::vector<InputSectionBase<ELFT> *>
|
||||
|
|
|
@ -554,10 +554,10 @@ static SectionKey createKey(InputSectionBase<ELFT> *C, StringRef OutsecName) {
|
|||
return SectionKey{OutsecName, Flags, Alignment};
|
||||
}
|
||||
|
||||
template <class ELFT> OutputSectionFactory<ELFT>::OutputSectionFactory() {}
|
||||
|
||||
template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {}
|
||||
|
||||
template <class ELFT>
|
||||
OutputSectionFactory<ELFT>::OutputSectionFactory(
|
||||
std::vector<OutputSectionBase *> &OutputSections)
|
||||
: OutputSections(OutputSections) {}
|
||||
|
||||
static uint64_t getIncompatibleFlags(uint64_t Flags) {
|
||||
return Flags & (SHF_ALLOC | SHF_TLS);
|
||||
|
@ -576,34 +576,43 @@ static bool canMergeToProgbits(unsigned Type) {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::pair<OutputSectionBase *, bool>
|
||||
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName) {
|
||||
SectionKey Key = createKey(C, OutsecName);
|
||||
uintX_t Flags = getOutFlags(C);
|
||||
void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase<ELFT> *IS,
|
||||
StringRef OutsecName) {
|
||||
if (!IS->Live) {
|
||||
reportDiscarded(IS);
|
||||
return;
|
||||
}
|
||||
|
||||
SectionKey Key = createKey(IS, OutsecName);
|
||||
uintX_t Flags = getOutFlags(IS);
|
||||
OutputSectionBase *&Sec = Map[Key];
|
||||
if (Sec) {
|
||||
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags))
|
||||
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
|
||||
error("Section has flags incompatible with others with the same name " +
|
||||
toString(C));
|
||||
if (Sec->Type != C->Type) {
|
||||
if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(C->Type))
|
||||
toString(IS));
|
||||
if (Sec->Type != IS->Type) {
|
||||
if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type))
|
||||
Sec->Type = SHT_PROGBITS;
|
||||
else
|
||||
error("Section has different type from others with the same name " +
|
||||
toString(C));
|
||||
toString(IS));
|
||||
}
|
||||
Sec->Flags |= Flags;
|
||||
return {Sec, false};
|
||||
} else {
|
||||
uint32_t Type = IS->Type;
|
||||
if (IS->kind() == InputSectionBase<ELFT>::EHFrame) {
|
||||
Out<ELFT>::EhFrame->addSection(IS);
|
||||
return;
|
||||
}
|
||||
Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);
|
||||
OutputSections.push_back(Sec);
|
||||
}
|
||||
|
||||
uint32_t Type = C->Type;
|
||||
if (C->kind() == InputSectionBase<ELFT>::EHFrame)
|
||||
return {Out<ELFT>::EhFrame, false};
|
||||
Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);
|
||||
return {Sec, true};
|
||||
Sec->addSection(IS);
|
||||
}
|
||||
|
||||
template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {}
|
||||
|
||||
SectionKey DenseMapInfo<SectionKey>::getEmptyKey() {
|
||||
return SectionKey{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0};
|
||||
}
|
||||
|
|
|
@ -212,12 +212,13 @@ template <class ELFT> class OutputSectionFactory {
|
|||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
OutputSectionFactory();
|
||||
OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections);
|
||||
~OutputSectionFactory();
|
||||
std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName);
|
||||
void addInputSec(InputSectionBase<ELFT> *IS, StringRef OutsecName);
|
||||
|
||||
private:
|
||||
llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map;
|
||||
std::vector<OutputSectionBase *> &OutputSections;
|
||||
};
|
||||
|
||||
template <class ELFT> uint64_t getHeaderSize() {
|
||||
|
|
|
@ -53,7 +53,6 @@ private:
|
|||
void copyLocalSymbols();
|
||||
void addSectionSymbols();
|
||||
void addReservedSymbols();
|
||||
void addInputSec(InputSectionBase<ELFT> *S);
|
||||
void createSections();
|
||||
void forEachRelSec(std::function<void(InputSectionBase<ELFT> &)> Fn);
|
||||
void sortSections();
|
||||
|
@ -79,7 +78,7 @@ private:
|
|||
std::unique_ptr<FileOutputBuffer> Buffer;
|
||||
|
||||
std::vector<OutputSectionBase *> OutputSections;
|
||||
OutputSectionFactory<ELFT> Factory;
|
||||
OutputSectionFactory<ELFT> Factory{OutputSections};
|
||||
|
||||
void addRelIpltSymbols();
|
||||
void addStartEndSymbols();
|
||||
|
@ -918,27 +917,10 @@ void Writer<ELFT>::forEachRelSec(
|
|||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
|
||||
if (!IS)
|
||||
return;
|
||||
|
||||
if (!IS->Live) {
|
||||
reportDiscarded(IS);
|
||||
return;
|
||||
}
|
||||
OutputSectionBase *Sec;
|
||||
bool IsNew;
|
||||
StringRef OutsecName = getOutputSectionName(IS->Name);
|
||||
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
|
||||
if (IsNew)
|
||||
OutputSections.push_back(Sec);
|
||||
Sec->addSection(IS);
|
||||
}
|
||||
|
||||
template <class ELFT> void Writer<ELFT>::createSections() {
|
||||
for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections)
|
||||
addInputSec(IS);
|
||||
if (IS)
|
||||
Factory.addInputSec(IS, getOutputSectionName(IS->Name));
|
||||
|
||||
sortBySymbolsOrder<ELFT>(OutputSections);
|
||||
sortInitFini<ELFT>(findSection(".init_array"));
|
||||
|
|
Loading…
Reference in New Issue