summaryrefslogtreecommitdiff
path: root/ELF/Writer.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-01 20:59:20 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-01 20:59:20 +0000
commit80350c116f86dbb87e055a630b1b2be0c66b244b (patch)
tree022e6b2a1e0e5a03028fa465a30338d8f6dbbf48 /ELF/Writer.cpp
parentcbb560c9ba3c378189c7a438bed9977b482410fb (diff)
Notes
Diffstat (limited to 'ELF/Writer.cpp')
-rw-r--r--ELF/Writer.cpp82
1 files changed, 43 insertions, 39 deletions
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 77d6412f80ad..258d5e26ef7f 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -261,23 +261,26 @@ template <class ELFT> void Writer<ELFT>::run() {
if (!Config->Relocatable)
fixSectionAlignments();
Script->fabricateDefaultCommands();
+ } else {
+ Script->synchronize();
}
for (BaseCommand *Base : Script->Opt.Commands)
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
OutputSectionCommands.push_back(Cmd);
+ clearOutputSections();
// If -compressed-debug-sections is specified, we need to compress
// .debug_* sections. Do it right now because it changes the size of
// output sections.
- parallelForEach(OutputSections.begin(), OutputSections.end(),
- [](OutputSection *S) { S->maybeCompress<ELFT>(); });
+ parallelForEach(
+ OutputSectionCommands.begin(), OutputSectionCommands.end(),
+ [](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); });
if (Config->Relocatable) {
assignFileOffsets();
} else {
- Script->synchronize();
- Script->assignAddresses(Phdrs);
+ Script->assignAddresses(Phdrs, OutputSectionCommands);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
// 0 sized region. This has to be done late since only after assignAddresses
@@ -300,13 +303,13 @@ template <class ELFT> void Writer<ELFT>::run() {
openFile();
if (ErrorCount)
return;
+
if (!Config->OFormatBinary) {
writeHeader();
writeSections();
} else {
writeSectionsBinary();
}
- clearOutputSections();
// Backfill .note.gnu.build-id section content. This is done at last
// because the content is usually a hash value of the entire output file.
@@ -613,27 +616,27 @@ bool elf::isRelroSection(const OutputSection *Sec) {
// .got contains pointers to external symbols. They are resolved by
// the dynamic linker when a module is loaded into memory, and after
// that they are not expected to change. So, it can be in RELRO.
- if (InX::Got && Sec == InX::Got->OutSec)
+ if (InX::Got && Sec == InX::Got->getParent())
return true;
// .got.plt contains pointers to external function symbols. They are
// by default resolved lazily, so we usually cannot put it into RELRO.
// However, if "-z now" is given, the lazy symbol resolution is
// disabled, which enables us to put it into RELRO.
- if (Sec == InX::GotPlt->OutSec)
+ if (Sec == InX::GotPlt->getParent())
return Config->ZNow;
// .dynamic section contains data for the dynamic linker, and
// there's no need to write to it at runtime, so it's better to put
// it into RELRO.
- if (Sec == InX::Dynamic->OutSec)
+ if (Sec == InX::Dynamic->getParent())
return true;
// .bss.rel.ro is used for copy relocations for read-only symbols.
// Since the dynamic linker needs to process copy relocations, the
// section cannot be read-only, but once initialized, they shouldn't
// change.
- if (Sec == InX::BssRelRo->OutSec)
+ if (Sec == InX::BssRelRo->getParent())
return true;
// Sections with some special names are put into RELRO. This is a
@@ -1112,9 +1115,9 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
std::function<void(SyntheticSection *)> Fn) {
for (SyntheticSection *SS : Sections)
- if (SS && SS->OutSec && !SS->empty()) {
+ if (SS && SS->getParent() && !SS->empty()) {
Fn(SS);
- SS->OutSec->assignOffsets();
+ SS->getParent()->assignOffsets();
}
}
@@ -1130,16 +1133,15 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
if (!SS)
return;
- if (!SS->empty() || !SS->OutSec)
+ OutputSection *OS = SS->getParent();
+ if (!SS->empty() || !OS)
continue;
-
- SS->OutSec->Sections.erase(std::find(SS->OutSec->Sections.begin(),
- SS->OutSec->Sections.end(), SS));
+ OS->Sections.erase(std::find(OS->Sections.begin(), OS->Sections.end(), SS));
SS->Live = false;
// If there are no other sections in the output section, remove it from the
// output.
- if (SS->OutSec->Sections.empty())
- V.erase(std::find(V.begin(), V.end(), SS->OutSec));
+ if (OS->Sections.empty())
+ V.erase(std::find(V.begin(), V.end(), OS));
}
}
@@ -1427,8 +1429,8 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// Add an entry for .dynamic.
if (InX::DynSymTab)
- AddHdr(PT_DYNAMIC, InX::Dynamic->OutSec->getPhdrFlags())
- ->add(InX::Dynamic->OutSec);
+ AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
+ ->add(InX::Dynamic->getParent());
// PT_GNU_RELRO includes all sections that should be marked as
// read-only by dynamic linker after proccessing relocations.
@@ -1441,9 +1443,9 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
if (!In<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr &&
- In<ELFT>::EhFrame->OutSec && In<ELFT>::EhFrameHdr->OutSec)
- AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->OutSec->getPhdrFlags())
- ->add(In<ELFT>::EhFrameHdr->OutSec);
+ In<ELFT>::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent())
+ AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags())
+ ->add(In<ELFT>::EhFrameHdr->getParent());
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
// the dynamic linker fill the segment with random data.
@@ -1556,9 +1558,11 @@ static uint64_t setOffset(OutputSection *Sec, uint64_t Off) {
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
uint64_t Off = 0;
- for (OutputSection *Sec : OutputSections)
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *Sec = Cmd->Sec;
if (Sec->Flags & SHF_ALLOC)
Off = setOffset(Sec, Off);
+ }
FileSize = alignTo(Off, Config->Wordsize);
}
@@ -1568,11 +1572,12 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
Off = setOffset(Out::ElfHeader, Off);
Off = setOffset(Out::ProgramHeaders, Off);
- for (OutputSection *Sec : OutputSections)
- Off = setOffset(Sec, Off);
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ Off = setOffset(Cmd->Sec, Off);
SectionHeaderOff = alignTo(Off, Config->Wordsize);
- FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
+ FileSize =
+ SectionHeaderOff + (OutputSectionCommands.size() + 1) * sizeof(Elf_Shdr);
}
// Finalize the program headers. We call this function after we assign
@@ -1695,16 +1700,15 @@ template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
// be equal to the _gp symbol's value.
- if (Config->EMachine == EM_MIPS) {
- if (!ElfSym::MipsGp->Value) {
- // Find GP-relative section with the lowest address
- // and use this address to calculate default _gp value.
- uint64_t Gp = -1;
- for (const OutputSection *OS : OutputSections)
- if ((OS->Flags & SHF_MIPS_GPREL) && OS->Addr < Gp)
- Gp = OS->Addr;
- if (Gp != (uint64_t)-1)
- ElfSym::MipsGp->Value = Gp + 0x7ff0;
+ if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) {
+ // Find GP-relative section with the lowest address
+ // and use this address to calculate default _gp value.
+ for (const OutputSectionCommand *Cmd : OutputSectionCommands) {
+ OutputSection *OS = Cmd->Sec;
+ if (OS->Flags & SHF_MIPS_GPREL) {
+ ElfSym::MipsGp->Value = OS->Addr + 0x7ff0;
+ break;
+ }
}
}
}
@@ -1728,7 +1732,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_phnum = Phdrs.size();
EHdr->e_shentsize = sizeof(Elf_Shdr);
EHdr->e_shnum = OutputSectionCommands.size() + 1;
- EHdr->e_shstrndx = InX::ShStrTab->OutSec->SectionIndex;
+ EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
if (Config->EMachine == EM_ARM)
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
@@ -1804,7 +1808,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
OutputSection *EhFrameHdr =
(In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty())
- ? In<ELFT>::EhFrameHdr->OutSec
+ ? In<ELFT>::EhFrameHdr->getParent()
: nullptr;
// In -r or -emit-relocs mode, write the relocation sections first as in
@@ -1832,7 +1836,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
}
template <class ELFT> void Writer<ELFT>::writeBuildId() {
- if (!InX::BuildId || !InX::BuildId->OutSec)
+ if (!InX::BuildId || !InX::BuildId->getParent())
return;
// Compute a hash of all sections of the output file.