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:
Rafael Espindola 2017-02-16 17:32:26 +00:00
parent ad3f63986d
commit 8290274c13
5 changed files with 38 additions and 60 deletions

View File

@ -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) {

View File

@ -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> *>

View File

@ -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};
}

View File

@ -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() {

View File

@ -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"));