forked from OSchip/llvm-project
Move finalize to OutputSectionCommands. NFC.
This removes a mapping from OutputSection to OutputSectionCommand and is another step in moving clearOutputSections earlier. llvm-svn: 304821
This commit is contained in:
parent
13f412f6a2
commit
8c284acf14
|
|
@ -1071,6 +1071,78 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
|
||||||
llvm_unreachable("unsupported Size argument");
|
llvm_unreachable("unsupported Size argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compareByFilePosition(InputSection *A, InputSection *B) {
|
||||||
|
// Synthetic doesn't have link order dependecy, stable_sort will keep it last
|
||||||
|
if (A->kind() == InputSectionBase::Synthetic ||
|
||||||
|
B->kind() == InputSectionBase::Synthetic)
|
||||||
|
return false;
|
||||||
|
InputSection *LA = A->getLinkOrderDep();
|
||||||
|
InputSection *LB = B->getLinkOrderDep();
|
||||||
|
OutputSection *AOut = LA->getParent();
|
||||||
|
OutputSection *BOut = LB->getParent();
|
||||||
|
if (AOut != BOut)
|
||||||
|
return AOut->SectionIndex < BOut->SectionIndex;
|
||||||
|
return LA->OutSecOff < LB->OutSecOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
|
||||||
|
// sh_link field for SHT_GROUP sections should contain the section index of
|
||||||
|
// the symbol table.
|
||||||
|
Sec->Link = InX::SymTab->getParent()->SectionIndex;
|
||||||
|
|
||||||
|
// sh_info then contain index of an entry in symbol table section which
|
||||||
|
// provides signature of the section group.
|
||||||
|
elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
|
||||||
|
assert(Config->Relocatable && Sec->Sections.size() == 1);
|
||||||
|
ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
|
||||||
|
Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT> void OutputSectionCommand::finalize() {
|
||||||
|
if ((Sec->Flags & SHF_LINK_ORDER) && !Sec->Sections.empty()) {
|
||||||
|
// Link order may be distributed across several InputSectionDescriptions
|
||||||
|
// but sort must consider them all at once.
|
||||||
|
std::vector<InputSection **> ScriptSections;
|
||||||
|
std::vector<InputSection *> Sections;
|
||||||
|
for (BaseCommand *Base : Commands)
|
||||||
|
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
|
||||||
|
for (InputSection *&IS : ISD->Sections) {
|
||||||
|
ScriptSections.push_back(&IS);
|
||||||
|
Sections.push_back(IS);
|
||||||
|
}
|
||||||
|
std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
|
||||||
|
for (int I = 0, N = Sections.size(); I < N; ++I)
|
||||||
|
*ScriptSections[I] = Sections[I];
|
||||||
|
|
||||||
|
// We must preserve the link order dependency of sections with the
|
||||||
|
// SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
|
||||||
|
// need to translate the InputSection sh_link to the OutputSection sh_link,
|
||||||
|
// all InputSections in the OutputSection have the same dependency.
|
||||||
|
if (auto *D = Sec->Sections.front()->getLinkOrderDep())
|
||||||
|
Sec->Link = D->getParent()->SectionIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Type = Sec->Type;
|
||||||
|
if (Type == SHT_GROUP) {
|
||||||
|
finalizeShtGroup<ELFT>(Sec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
InputSection *First = Sec->Sections[0];
|
||||||
|
if (isa<SyntheticSection>(First))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sec->Link = InX::SymTab->getParent()->SectionIndex;
|
||||||
|
// sh_info for SHT_REL[A] sections should contain the section header index of
|
||||||
|
// the section to which the relocation applies.
|
||||||
|
InputSectionBase *S = First->getRelocatedSection();
|
||||||
|
Sec->Info = S->getOutputSection()->SectionIndex;
|
||||||
|
Sec->Flags |= SHF_INFO_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
// Compress section contents if this section contains debug info.
|
// Compress section contents if this section contains debug info.
|
||||||
template <class ELFT> void OutputSectionCommand::maybeCompress() {
|
template <class ELFT> void OutputSectionCommand::maybeCompress() {
|
||||||
typedef typename ELFT::Chdr Elf_Chdr;
|
typedef typename ELFT::Chdr Elf_Chdr;
|
||||||
|
|
@ -1201,3 +1273,8 @@ template void OutputSectionCommand::maybeCompress<ELF32LE>();
|
||||||
template void OutputSectionCommand::maybeCompress<ELF32BE>();
|
template void OutputSectionCommand::maybeCompress<ELF32BE>();
|
||||||
template void OutputSectionCommand::maybeCompress<ELF64LE>();
|
template void OutputSectionCommand::maybeCompress<ELF64LE>();
|
||||||
template void OutputSectionCommand::maybeCompress<ELF64BE>();
|
template void OutputSectionCommand::maybeCompress<ELF64BE>();
|
||||||
|
|
||||||
|
template void OutputSectionCommand::finalize<ELF32LE>();
|
||||||
|
template void OutputSectionCommand::finalize<ELF32BE>();
|
||||||
|
template void OutputSectionCommand::finalize<ELF64LE>();
|
||||||
|
template void OutputSectionCommand::finalize<ELF64BE>();
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ struct OutputSectionCommand : BaseCommand {
|
||||||
std::string Location;
|
std::string Location;
|
||||||
std::string MemoryRegionName;
|
std::string MemoryRegionName;
|
||||||
|
|
||||||
|
template <class ELFT> void finalize();
|
||||||
template <class ELFT> void writeTo(uint8_t *Buf);
|
template <class ELFT> void writeTo(uint8_t *Buf);
|
||||||
template <class ELFT> void maybeCompress();
|
template <class ELFT> void maybeCompress();
|
||||||
uint32_t getFiller();
|
uint32_t getFiller();
|
||||||
|
|
|
||||||
|
|
@ -70,79 +70,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
|
||||||
/*Link*/ 0),
|
/*Link*/ 0),
|
||||||
SectionIndex(INT_MAX) {}
|
SectionIndex(INT_MAX) {}
|
||||||
|
|
||||||
static bool compareByFilePosition(InputSection *A, InputSection *B) {
|
|
||||||
// Synthetic doesn't have link order dependecy, stable_sort will keep it last
|
|
||||||
if (A->kind() == InputSectionBase::Synthetic ||
|
|
||||||
B->kind() == InputSectionBase::Synthetic)
|
|
||||||
return false;
|
|
||||||
InputSection *LA = A->getLinkOrderDep();
|
|
||||||
InputSection *LB = B->getLinkOrderDep();
|
|
||||||
OutputSection *AOut = LA->getParent();
|
|
||||||
OutputSection *BOut = LB->getParent();
|
|
||||||
if (AOut != BOut)
|
|
||||||
return AOut->SectionIndex < BOut->SectionIndex;
|
|
||||||
return LA->OutSecOff < LB->OutSecOff;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
|
|
||||||
// sh_link field for SHT_GROUP sections should contain the section index of
|
|
||||||
// the symbol table.
|
|
||||||
Sec->Link = InX::SymTab->getParent()->SectionIndex;
|
|
||||||
|
|
||||||
// sh_info then contain index of an entry in symbol table section which
|
|
||||||
// provides signature of the section group.
|
|
||||||
elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
|
|
||||||
assert(Config->Relocatable && Sec->Sections.size() == 1);
|
|
||||||
ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
|
|
||||||
Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> void OutputSection::finalize() {
|
|
||||||
if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
|
|
||||||
OutputSectionCommand *Cmd = Script->getCmd(this);
|
|
||||||
// Link order may be distributed across several InputSectionDescriptions
|
|
||||||
// but sort must consider them all at once.
|
|
||||||
std::vector<InputSection **> ScriptSections;
|
|
||||||
std::vector<InputSection *> Sections;
|
|
||||||
for (BaseCommand *Base : Cmd->Commands)
|
|
||||||
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
|
|
||||||
for (InputSection *&IS : ISD->Sections) {
|
|
||||||
ScriptSections.push_back(&IS);
|
|
||||||
Sections.push_back(IS);
|
|
||||||
}
|
|
||||||
std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
|
|
||||||
for (int I = 0, N = Sections.size(); I < N; ++I)
|
|
||||||
*ScriptSections[I] = Sections[I];
|
|
||||||
|
|
||||||
// We must preserve the link order dependency of sections with the
|
|
||||||
// SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
|
|
||||||
// need to translate the InputSection sh_link to the OutputSection sh_link,
|
|
||||||
// all InputSections in the OutputSection have the same dependency.
|
|
||||||
if (auto *D = this->Sections.front()->getLinkOrderDep())
|
|
||||||
this->Link = D->getParent()->SectionIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Type = this->Type;
|
|
||||||
if (Type == SHT_GROUP) {
|
|
||||||
finalizeShtGroup<ELFT>(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
InputSection *First = Sections[0];
|
|
||||||
if (isa<SyntheticSection>(First))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this->Link = InX::SymTab->getParent()->SectionIndex;
|
|
||||||
// sh_info for SHT_REL[A] sections should contain the section header index of
|
|
||||||
// the section to which the relocation applies.
|
|
||||||
InputSectionBase *S = First->getRelocatedSection();
|
|
||||||
Info = S->getOutputSection()->SectionIndex;
|
|
||||||
Flags |= SHF_INFO_LINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t updateOffset(uint64_t Off, InputSection *S) {
|
static uint64_t updateOffset(uint64_t Off, InputSection *S) {
|
||||||
Off = alignTo(Off, S->Alignment);
|
Off = alignTo(Off, S->Alignment);
|
||||||
S->OutSecOff = Off;
|
S->OutSecOff = Off;
|
||||||
|
|
@ -428,8 +355,3 @@ template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
|
||||||
template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
|
template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
|
||||||
template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
|
template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
|
||||||
template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
|
template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
|
||||||
|
|
||||||
template void OutputSection::finalize<ELF32LE>();
|
|
||||||
template void OutputSection::finalize<ELF32BE>();
|
|
||||||
template void OutputSection::finalize<ELF64LE>();
|
|
||||||
template void OutputSection::finalize<ELF64BE>();
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ public:
|
||||||
void sort(std::function<int(InputSectionBase *S)> Order);
|
void sort(std::function<int(InputSectionBase *S)> Order);
|
||||||
void sortInitFini();
|
void sortInitFini();
|
||||||
void sortCtorsDtors();
|
void sortCtorsDtors();
|
||||||
template <class ELFT> void finalize();
|
|
||||||
void assignOffsets();
|
void assignOffsets();
|
||||||
std::vector<InputSection *> Sections;
|
std::vector<InputSection *> Sections;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1271,7 +1271,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
// at the end because some tags like RELSZ depend on result
|
// at the end because some tags like RELSZ depend on result
|
||||||
// of finalizing other sections.
|
// of finalizing other sections.
|
||||||
for (OutputSectionCommand *Cmd : OutputSectionCommands)
|
for (OutputSectionCommand *Cmd : OutputSectionCommands)
|
||||||
Cmd->Sec->finalize<ELFT>();
|
Cmd->finalize<ELFT>();
|
||||||
|
|
||||||
// createThunks may have added local symbols to the static symbol table
|
// createThunks may have added local symbols to the static symbol table
|
||||||
applySynthetic({InX::SymTab, InX::ShStrTab, InX::StrTab},
|
applySynthetic({InX::SymTab, InX::ShStrTab, InX::StrTab},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue