summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-04-06 07:20:45 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-04-06 07:20:45 +0000
commit7ca0627c51b31650281654dbadf080f1ec6d46ec (patch)
tree947c986ea04cd1de866fa6082df4e93f17a9ed95
parent12fd50410d970f111f4a36d567fac6c0c25d991f (diff)
downloadbcm5719-llvm-7ca0627c51b31650281654dbadf080f1ec6d46ec.tar.gz
bcm5719-llvm-7ca0627c51b31650281654dbadf080f1ec6d46ec.zip
[ELF] - Do not handle ELF and program header as dummy sections.
ELF and program header are not part of OutputSections list anymore. That helps to avoid having and working with functions like dummySectionsNum(). Still keeping them as sections helps to simplify the code. Differential revision: http://reviews.llvm.org/D18743 llvm-svn: 265522
-rw-r--r--lld/ELF/Writer.cpp55
1 files changed, 28 insertions, 27 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4e6b3683da6..e3601f4e7cf 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -28,10 +28,6 @@ using namespace llvm::object;
using namespace lld;
using namespace lld::elf;
-// Usually there are 2 dummies sections: ELF header and program header.
-// Relocatable output does not require program headers to be created.
-static unsigned dummySectionsNum() { return Config->Relocatable ? 1 : 2; }
-
namespace {
// The writer writes a SymbolTable result to a file.
template <class ELFT> class Writer {
@@ -75,6 +71,7 @@ private:
void assignAddresses();
void assignFileOffsets();
void setPhdrs();
+ void fixHeaders();
void fixSectionAlignments();
void fixAbsoluteSymbols();
void openFile();
@@ -103,14 +100,6 @@ private:
std::vector<OutputSectionBase<ELFT> *> OutputSections;
std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
- // We create a section for the ELF header and one for the program headers.
- ArrayRef<OutputSectionBase<ELFT> *> getSections() const {
- return makeArrayRef(OutputSections).slice(dummySectionsNum());
- }
- unsigned getNumSections() const {
- return OutputSections.size() + 1 - dummySectionsNum();
- }
-
void addRelIpltSymbols();
void addStartEndSymbols();
void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
@@ -223,6 +212,7 @@ template <class ELFT> void Writer<ELFT>::run() {
assignFileOffsets();
} else {
createPhdrs();
+ fixHeaders();
fixSectionAlignments();
assignAddresses();
assignFileOffsets();
@@ -983,10 +973,6 @@ template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT> *S) {
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
- OutputSections.push_back(Out<ELFT>::ElfHeader);
- if (!Config->Relocatable)
- OutputSections.push_back(Out<ELFT>::ProgramHeaders);
-
// Add .interp first because some loaders want to see that section
// on the first page of the executable file when loaded into memory.
if (needsInterpSection())
@@ -1075,7 +1061,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
}
}
- for (OutputSectionBase<ELFT> *Sec : getSections())
+ for (OutputSectionBase<ELFT> *Sec : OutputSections)
Sec->assignOffsets();
// Now that we have defined all possible symbols including linker-
@@ -1112,11 +1098,11 @@ template <class ELFT> void Writer<ELFT>::createSections() {
std::stable_sort(OutputSections.begin(), OutputSections.end(),
compareSections<ELFT>);
- for (unsigned I = dummySectionsNum(), N = OutputSections.size(); I < N; ++I)
- OutputSections[I]->SectionIndex = I + 1 - dummySectionsNum();
-
- for (OutputSectionBase<ELFT> *Sec : getSections())
+ unsigned I = 1;
+ for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+ Sec->SectionIndex = I++;
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
+ }
// Finalizers fix each section's size.
// .dynsym is finalized early since that may fill up .gnu.hash.
@@ -1284,6 +1270,7 @@ template <class ELFT> void Writer<ELFT>::createPhdrs() {
uintX_t Flags = PF_R;
Phdr *Load = AddHdr(PT_LOAD, Flags);
AddSec(*Load, Out<ELFT>::ElfHeader);
+ AddSec(*Load, Out<ELFT>::ProgramHeaders);
Phdr TlsHdr(PT_TLS, PF_R);
Phdr RelRo(PT_GNU_RELRO, PF_R);
@@ -1371,11 +1358,23 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
}
}
+// We should set file offsets and VAs for elf header and program headers
+// sections. These are special, we do not include them into output sections
+// list, but have them to simplify the code.
+template <class ELFT> void Writer<ELFT>::fixHeaders() {
+ Out<ELFT>::ElfHeader->setVA(Target->getVAStart());
+ Out<ELFT>::ElfHeader->setFileOffset(0);
+ uintX_t Off = Out<ELFT>::ElfHeader->getSize();
+ Out<ELFT>::ProgramHeaders->setVA(Off + Target->getVAStart());
+ Out<ELFT>::ProgramHeaders->setFileOffset(Off);
+}
+
// Assign VAs (addresses at run-time) to output sections.
template <class ELFT> void Writer<ELFT>::assignAddresses() {
- uintX_t ThreadBssOffset = 0;
- uintX_t VA = Target->getVAStart();
+ uintX_t VA = Target->getVAStart() + Out<ELFT>::ElfHeader->getSize() +
+ Out<ELFT>::ProgramHeaders->getSize();
+ uintX_t ThreadBssOffset = 0;
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
uintX_t Align = Sec->getAlign();
if (Sec->PageAlign)
@@ -1397,7 +1396,9 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
- uintX_t Off = 0;
+ uintX_t Off =
+ Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
if (Sec->getType() == SHT_NOBITS) {
Sec->setFileOffset(Off);
@@ -1411,7 +1412,7 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
Off += Sec->getSize();
}
SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
- FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
+ FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
}
// Finalize the program headers. We call this function after we assign
@@ -1541,7 +1542,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_ehsize = sizeof(Elf_Ehdr);
EHdr->e_phnum = Phdrs.size();
EHdr->e_shentsize = sizeof(Elf_Shdr);
- EHdr->e_shnum = getNumSections();
+ EHdr->e_shnum = OutputSections.size() + 1;
EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
if (Config->EMachine == EM_MIPS)
@@ -1559,7 +1560,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// Write the section header table. Note that the first table entry is null.
auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
- for (OutputSectionBase<ELFT> *Sec : getSections())
+ for (OutputSectionBase<ELFT> *Sec : OutputSections)
Sec->writeHeaderTo(++SHdrs);
}
OpenPOWER on IntegriCloud