summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ObjectYAML
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-09-05 14:25:57 +0000
committerFangrui Song <maskray@google.com>2019-09-05 14:25:57 +0000
commitc3bc697974d2d7f3c151cb9853b40cc6bf73ba4b (patch)
tree84f1b811c199c8e32538cb219ea5b9cbc8db633d /llvm/lib/ObjectYAML
parent9cef6400014a3124880e4c87e32acaf0b4c7c415 (diff)
downloadbcm5719-llvm-c3bc697974d2d7f3c151cb9853b40cc6bf73ba4b.tar.gz
bcm5719-llvm-c3bc697974d2d7f3c151cb9853b40cc6bf73ba4b.zip
[yaml2obj] Write the section header table after section contents
Linkers (ld.bfd/gold/lld) place the section header table at the very end. This allows tools to strip it, which is optional in executable/shared objects. In addition, if we add or section, the size of the section header table will change. Placing the section header table in the end keeps section offsets unchanged. yaml2obj currently places the section header table immediately after the program header. Follow what linkers do to make offset updating easier. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D67221 llvm-svn: 371074
Diffstat (limited to 'llvm/lib/ObjectYAML')
-rw-r--r--llvm/lib/ObjectYAML/ELFEmitter.cpp33
1 files changed, 17 insertions, 16 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index cd3a0faa03d..362a9432568 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -116,7 +116,6 @@ template <class ELFT> class ELFState {
bool buildSectionIndex();
bool buildSymbolIndexes();
- void initELFHeader(Elf_Ehdr &Header);
void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,
StringRef SecName, ELFYAML::Section *YAMLSec);
@@ -132,6 +131,7 @@ template <class ELFT> class ELFState {
void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
std::vector<Elf_Shdr> &SHeaders);
void finalizeStrings();
+ void writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS);
bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::RawContentSection &Section,
ContiguousBlobAccumulator &CBA);
@@ -205,8 +205,11 @@ template <class ELFT> ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
}
}
-template <class ELFT> void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
+template <class ELFT>
+void ELFState<ELFT>::writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS) {
using namespace llvm::ELF;
+
+ Elf_Ehdr Header;
zero(Header);
Header.e_ident[EI_MAG0] = 0x7f;
Header.e_ident[EI_MAG1] = 'E';
@@ -230,14 +233,18 @@ template <class ELFT> void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
Header.e_shentsize =
Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);
// Immediately following the ELF header and program headers.
- Header.e_shoff =
- Doc.Header.SHOffset
- ? (typename ELFT::uint)(*Doc.Header.SHOffset)
- : sizeof(Header) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
+ // Align the start of the section header and write the ELF header.
+ uint64_t ShOffset;
+ CBA.getOSAndAlignedOffset(ShOffset, sizeof(typename ELFT::uint));
+ Header.e_shoff = Doc.Header.SHOffset
+ ? typename ELFT::uint(*Doc.Header.SHOffset)
+ : ShOffset;
Header.e_shnum =
Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : Doc.Sections.size();
Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx
: SN2I.get(".shstrtab");
+
+ OS.write((const char *)&Header, sizeof(Header));
}
template <class ELFT>
@@ -1040,19 +1047,13 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
if (!State.buildSectionIndex() || !State.buildSymbolIndexes())
return 1;
- Elf_Ehdr Header;
- State.initELFHeader(Header);
-
- // TODO: Flesh out section header support.
-
std::vector<Elf_Phdr> PHeaders;
State.initProgramHeaders(PHeaders);
// XXX: This offset is tightly coupled with the order that we write
// things to `OS`.
- const size_t SectionContentBeginOffset = Header.e_ehsize +
- Header.e_phentsize * Header.e_phnum +
- Header.e_shentsize * Header.e_shnum;
+ const size_t SectionContentBeginOffset =
+ sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
std::vector<Elf_Shdr> SHeaders;
@@ -1062,10 +1063,10 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
// Now we can decide segment offsets
State.setProgramHeaderLayout(PHeaders, SHeaders);
- OS.write((const char *)&Header, sizeof(Header));
+ State.writeELFHeader(CBA, OS);
writeArrayData(OS, makeArrayRef(PHeaders));
- writeArrayData(OS, makeArrayRef(SHeaders));
CBA.writeBlobToStream(OS);
+ writeArrayData(OS, makeArrayRef(SHeaders));
return 0;
}
OpenPOWER on IntegriCloud