[ELF2] Emit section table.
llvm-svn: 243506
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index d11378f..615a5ef 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -57,6 +57,22 @@
C->setFileOff(Off);
Off += C->getSize();
Header.sh_size = Off;
+ if (auto SC = dyn_cast<SectionChunk<ELF64LE>>(C))
+ Header.sh_type = SC->getSectionHdr()->sh_type;
+}
+
+template <class ELFT>
+void OutputSection::writeHeaderTo(Elf_Shdr_Impl<ELFT> *SHdr) {
+ SHdr->sh_name = Header.sh_name;
+ SHdr->sh_type = Header.sh_type;
+ SHdr->sh_flags = Header.sh_flags;
+ SHdr->sh_addr = Header.sh_addr;
+ SHdr->sh_offset = Header.sh_offset;
+ SHdr->sh_size = Header.sh_size;
+ SHdr->sh_link = Header.sh_link;
+ SHdr->sh_info = Header.sh_info;
+ SHdr->sh_addralign = Header.sh_addralign;
+ SHdr->sh_entsize = Header.sh_entsize;
}
// Create output section objects and add them to OutputSections.
@@ -75,10 +91,7 @@
// Visits all sections to assign incremental, non-overlapping RVAs and
// file offsets.
template <class ELFT> void Writer<ELFT>::assignAddresses() {
- SizeOfHeaders = RoundUpToAlignment(sizeof(Elf_Ehdr_Impl<ELFT>) +
- sizeof(Elf_Shdr_Impl<ELFT>) *
- OutputSections.size(),
- PageSize);
+ SizeOfHeaders = RoundUpToAlignment(sizeof(Elf_Ehdr_Impl<ELFT>), PageSize);
uint64_t VA = 0x1000; // The first page is kept unmapped.
uint64_t FileOff = SizeOfHeaders;
for (OutputSection *Sec : OutputSections) {
@@ -87,7 +100,9 @@
VA += RoundUpToAlignment(Sec->getSize(), PageSize);
FileOff += RoundUpToAlignment(Sec->getSize(), 8);
}
- SizeOfImage = SizeOfHeaders + RoundUpToAlignment(VA - 0x1000, PageSize);
+ // Add space for section headers.
+ SectionHeaderOff = FileOff;
+ FileOff += (OutputSections.size() + 1) * sizeof(Elf_Shdr_Impl<ELFT>);
FileSize = SizeOfHeaders + RoundUpToAlignment(FileOff - SizeOfHeaders, 8);
}
@@ -108,12 +123,12 @@
EHdr->e_version = EV_CURRENT;
EHdr->e_entry = 0x401000;
EHdr->e_phoff = sizeof(Elf_Ehdr_Impl<ELFT>);
- EHdr->e_shoff = 0;
+ EHdr->e_shoff = SectionHeaderOff;
EHdr->e_ehsize = sizeof(Elf_Ehdr_Impl<ELFT>);
EHdr->e_phentsize = sizeof(Elf_Phdr_Impl<ELFT>);
EHdr->e_phnum = 1;
EHdr->e_shentsize = sizeof(Elf_Shdr_Impl<ELFT>);
- EHdr->e_shnum = 0;
+ EHdr->e_shnum = OutputSections.size() + 1;
EHdr->e_shstrndx = 0;
auto PHdrs = reinterpret_cast<Elf_Phdr_Impl<ELFT> *>(Buf + EHdr->e_phoff);
@@ -125,6 +140,12 @@
PHdrs->p_filesz = FileSize;
PHdrs->p_memsz = FileSize;
PHdrs->p_align = 0x4000;
+
+ auto SHdrs = reinterpret_cast<Elf_Shdr_Impl<ELFT> *>(Buf + EHdr->e_shoff);
+ // First entry is null.
+ ++SHdrs;
+ for (OutputSection *Sec : OutputSections)
+ Sec->writeHeaderTo<ELFT>(SHdrs++);
}
template <class ELFT> void Writer<ELFT>::openFile(StringRef Path) {