summaryrefslogtreecommitdiff
path: root/compiler/elf_builder.h
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2015-11-03 13:43:09 +0000
committerDavid Srbecky <dsrbecky@google.com>2015-11-05 13:42:34 +0000
commit19fcbda1c882a475205b2b14c7a485ce7b8e901b (patch)
treef2fc0f2af366ad9ece050eba2d7e9fb98d645165 /compiler/elf_builder.h
parentb178e11d9eb44fc0ac666049f3aa14f7f14ffd64 (diff)
Move .dynsym ELF section after .text
The main purpose of the dynamic section is to describe where .text is and how large it is. It makes more sense to write this section once we actually know this information. Also write string sections (.dynstr and .strtab) before the corresponding symbol sections because the strings take more space. Neither of these changes is important now since we build the sections in memory first, but it is move towards streaming of the ELF file directly do disk. Due to alignment requirements, the move increases the oat file size by one page (4K) which is insignificant. Change-Id: I61cc9f934b031d26a3a1f6007b51315e1538e3eb
Diffstat (limited to 'compiler/elf_builder.h')
-rw-r--r--compiler/elf_builder.h37
1 files changed, 17 insertions, 20 deletions
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index bbd962fae2..4e2b15d7b0 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -266,8 +266,8 @@ class ElfBuilder FINAL {
// Writer of .dynstr .strtab and .shstrtab sections.
class StrtabSection FINAL : public Section {
public:
- StrtabSection(const std::string& name, Elf_Word flags)
- : Section(name, SHT_STRTAB, flags, nullptr, 0, 1, 0) {
+ StrtabSection(const std::string& name, Elf_Word flags, Elf_Word align)
+ : Section(name, SHT_STRTAB, flags, nullptr, 0, align, 0) {
buffer_.reserve(4 * KB);
// The first entry of strtab must be empty string.
buffer_ += '\0';
@@ -459,16 +459,8 @@ class ElfBuilder FINAL {
private:
Elf_Word GetNumBuckets() const {
const auto& symbols = symtab_->symbols_;
- if (symbols.size() < 8) {
- return 2;
- } else if (symbols.size() < 32) {
- return 4;
- } else if (symbols.size() < 256) {
- return 16;
- } else {
- // Have about 32 ids per bucket.
- return RoundUp(symbols.size()/32, 2);
- }
+ // Have about 32 ids per bucket.
+ return 1 + symbols.size()/32;
}
// from bionic
@@ -495,7 +487,7 @@ class ElfBuilder FINAL {
Elf_Word text_size, CodeOutput* text_writer,
Elf_Word bss_size)
: isa_(isa),
- dynstr_(".dynstr", SHF_ALLOC),
+ dynstr_(".dynstr", SHF_ALLOC, kPageSize),
dynsym_(".dynsym", SHT_DYNSYM, SHF_ALLOC, &dynstr_),
hash_(".hash", SHF_ALLOC, &dynsym_),
rodata_(".rodata", SHT_PROGBITS, SHF_ALLOC,
@@ -504,9 +496,9 @@ class ElfBuilder FINAL {
nullptr, 0, kPageSize, 0, text_size, text_writer),
bss_(".bss", bss_size),
dynamic_(".dynamic", &dynstr_),
- strtab_(".strtab", 0),
+ strtab_(".strtab", 0, kPageSize),
symtab_(".symtab", SHT_SYMTAB, 0, &strtab_),
- shstrtab_(".shstrtab", 0) {
+ shstrtab_(".shstrtab", 0, 1) {
}
~ElfBuilder() {}
@@ -606,18 +598,18 @@ class ElfBuilder FINAL {
// Create a list of all section which we want to write.
// This is the order in which they will be written.
std::vector<Section*> sections;
- sections.push_back(&dynsym_);
- sections.push_back(&dynstr_);
- sections.push_back(&hash_);
sections.push_back(&rodata_);
sections.push_back(&text_);
if (bss_.GetSize() != 0u) {
sections.push_back(&bss_);
}
+ sections.push_back(&dynstr_);
+ sections.push_back(&dynsym_);
+ sections.push_back(&hash_);
sections.push_back(&dynamic_);
if (!symtab_.IsEmpty()) {
- sections.push_back(&symtab_);
sections.push_back(&strtab_);
+ sections.push_back(&symtab_);
}
for (Section* section : other_sections_) {
sections.push_back(section);
@@ -643,7 +635,7 @@ class ElfBuilder FINAL {
// We do not know the number of headers until the final stages of write.
// It is easiest to just reserve a fixed amount of space for them.
- constexpr size_t kMaxProgramHeaders = 8;
+ constexpr size_t kMaxProgramHeaders = 16;
constexpr size_t kProgramHeadersOffset = sizeof(Elf_Ehdr);
// Layout of all sections - determine the final file offsets and addresses.
@@ -694,6 +686,11 @@ class ElfBuilder FINAL {
if (bss_.GetHeader()->sh_size != 0u) {
program_headers.push_back(MakeProgramHeader(PT_LOAD, PF_R | PF_W, bss_));
}
+ program_headers.push_back(MakeProgramHeader(PT_LOAD, PF_R, dynstr_));
+ int dynstr_dynsym_hash_size = hash_.GetHeader()->sh_offset +
+ hash_.GetHeader()->sh_size - dynstr_.GetHeader()->sh_offset;
+ program_headers.back().p_filesz = dynstr_dynsym_hash_size;
+ program_headers.back().p_memsz = dynstr_dynsym_hash_size;
program_headers.push_back(MakeProgramHeader(PT_LOAD, PF_R | PF_W, dynamic_));
program_headers.push_back(MakeProgramHeader(PT_DYNAMIC, PF_R | PF_W, dynamic_));
const Section* eh_frame = FindSection(".eh_frame");