diff options
author | Vladimir Marko <vmarko@google.com> | 2015-02-25 12:02:49 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2015-03-02 18:07:03 +0000 |
commit | 5c42c29b89286e5efa4a4613132b09051ce5945b (patch) | |
tree | 5db25a4f62c5583f2f6fc42b9a2ff47362eeed5c /compiler/elf_builder.h | |
parent | 242026e246a8b9efe098a0cce008fd525e011e5b (diff) | |
download | art-5c42c29b89286e5efa4a4613132b09051ce5945b.tar.gz art-5c42c29b89286e5efa4a4613132b09051ce5945b.tar.bz2 art-5c42c29b89286e5efa4a4613132b09051ce5945b.zip |
Add support for .bss section in oat files.
Change-Id: I779b80b8139d9afdc28373f8c68edff5df7726ce
Diffstat (limited to 'compiler/elf_builder.h')
-rw-r--r-- | compiler/elf_builder.h | 109 |
1 files changed, 86 insertions, 23 deletions
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h index 94268de07..9ab360260 100644 --- a/compiler/elf_builder.h +++ b/compiler/elf_builder.h @@ -538,6 +538,8 @@ class ElfBuilder FINAL { Elf_Word rodata_size, Elf_Word text_relative_offset, Elf_Word text_size, + Elf_Word bss_relative_offset, + Elf_Word bss_size, const bool add_symbols, bool debug = false) : oat_writer_(oat_writer), @@ -547,6 +549,7 @@ class ElfBuilder FINAL { text_builder_(".text", text_size, text_relative_offset, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR), rodata_builder_(".rodata", rodata_size, rodata_relative_offset, SHT_PROGBITS, SHF_ALLOC), + bss_builder_(".bss", bss_size, bss_relative_offset, SHT_NOBITS, SHF_ALLOC), dynsym_builder_(".dynsym", SHT_DYNSYM, ".dynstr", SHT_STRTAB, true), symtab_builder_(".symtab", SHT_SYMTAB, ".strtab", SHT_STRTAB, false), hash_builder_(".hash", SHT_HASH, SHF_ALLOC, &dynsym_builder_, 0, sizeof(Elf_Word), @@ -569,6 +572,11 @@ class ElfBuilder FINAL { } bool Init() { + // Since the .text section of an oat file contains relative references to .rodata + // and (optionally) .bss, we keep these 2 or 3 sections together. This creates + // a non-traditional layout where the .bss section is mapped independently of the + // .dynamic section and needs its own program header with LOAD RW. + // // The basic layout of the elf file. Order may be different in final output. // +-------------------------+ // | Elf_Ehdr | @@ -576,6 +584,7 @@ class ElfBuilder FINAL { // | Elf_Phdr PHDR | // | Elf_Phdr LOAD R | .dynsym .dynstr .hash .rodata // | Elf_Phdr LOAD R X | .text + // | Elf_Phdr LOAD RW | .bss (Optional) // | Elf_Phdr LOAD RW | .dynamic // | Elf_Phdr DYNAMIC | .dynamic // +-------------------------+ @@ -584,6 +593,8 @@ class ElfBuilder FINAL { // | Elf_Sym oatdata | // | Elf_Sym oatexec | // | Elf_Sym oatlastword | + // | Elf_Sym oatbss | (Optional) + // | Elf_Sym oatbsslastword | (Optional) // +-------------------------+ // | .dynstr | // | \0 | @@ -631,6 +642,7 @@ class ElfBuilder FINAL { // | .hash\0 | // | .rodata\0 | // | .text\0 | + // | .bss\0 | (Optional) // | .shstrtab\0 | // | .symtab\0 | (Optional) // | .strtab\0 | (Optional) @@ -654,8 +666,9 @@ class ElfBuilder FINAL { // | Elf_Shdr .dynsym | // | Elf_Shdr .dynstr | // | Elf_Shdr .hash | - // | Elf_Shdr .text | // | Elf_Shdr .rodata | + // | Elf_Shdr .text | + // | Elf_Shdr .bss | (Optional) // | Elf_Shdr .dynamic | // | Elf_Shdr .shstrtab | // | Elf_Shdr .debug_info | (Optional) @@ -694,8 +707,11 @@ class ElfBuilder FINAL { program_headers_[PH_LOAD_R_X].p_type = PT_LOAD; program_headers_[PH_LOAD_R_X].p_flags = PF_R | PF_X; - program_headers_[PH_LOAD_RW_].p_type = PT_LOAD; - program_headers_[PH_LOAD_RW_].p_flags = PF_R | PF_W; + program_headers_[PH_LOAD_RW_BSS].p_type = PT_LOAD; + program_headers_[PH_LOAD_RW_BSS].p_flags = PF_R | PF_W; + + program_headers_[PH_LOAD_RW_DYNAMIC].p_type = PT_LOAD; + program_headers_[PH_LOAD_RW_DYNAMIC].p_flags = PF_R | PF_W; program_headers_[PH_DYNAMIC].p_type = PT_DYNAMIC; program_headers_[PH_DYNAMIC].p_flags = PF_R | PF_W; @@ -760,6 +776,14 @@ class ElfBuilder FINAL { text_builder_.SetSectionIndex(section_index_); section_index_++; + // Setup .bss + if (bss_builder_.GetSize() != 0u) { + section_ptrs_.push_back(bss_builder_.GetSection()); + AssignSectionStr(&bss_builder_, &shstrtab_); + bss_builder_.SetSectionIndex(section_index_); + section_index_++; + } + // Setup .dynamic section_ptrs_.push_back(dynamic_builder_.GetSection()); AssignSectionStr(&dynamic_builder_, &shstrtab_); @@ -820,10 +844,20 @@ class ElfBuilder FINAL { CHECK_ALIGNED(rodata_builder_.GetSection()->sh_offset + rodata_builder_.GetSection()->sh_size, kPageSize); + // Get the layout of the .bss section. + bss_builder_.GetSection()->sh_offset = + NextOffset<Elf_Word, Elf_Shdr>(*bss_builder_.GetSection(), + *text_builder_.GetSection()); + bss_builder_.GetSection()->sh_addr = bss_builder_.GetSection()->sh_offset; + bss_builder_.GetSection()->sh_size = bss_builder_.GetSize(); + bss_builder_.GetSection()->sh_link = bss_builder_.GetLink(); + // Get the layout of the dynamic section. - dynamic_builder_.GetSection()->sh_offset = - NextOffset<Elf_Word, Elf_Shdr>(*dynamic_builder_.GetSection(), *text_builder_.GetSection()); - dynamic_builder_.GetSection()->sh_addr = dynamic_builder_.GetSection()->sh_offset; + CHECK(IsAlignedParam(bss_builder_.GetSection()->sh_offset, + dynamic_builder_.GetSection()->sh_addralign)); + dynamic_builder_.GetSection()->sh_offset = bss_builder_.GetSection()->sh_offset; + dynamic_builder_.GetSection()->sh_addr = + NextOffset<Elf_Word, Elf_Shdr>(*dynamic_builder_.GetSection(), *bss_builder_.GetSection()); dynamic_builder_.GetSection()->sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn); dynamic_builder_.GetSection()->sh_link = dynamic_builder_.GetLink(); @@ -987,16 +1021,23 @@ class ElfBuilder FINAL { program_headers_[PH_LOAD_R_X].p_memsz = load_rx_size; program_headers_[PH_LOAD_R_X].p_align = text_builder_.GetSection()->sh_addralign; - program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.GetSection()->sh_offset; - program_headers_[PH_LOAD_RW_].p_vaddr = dynamic_builder_.GetSection()->sh_offset; - program_headers_[PH_LOAD_RW_].p_paddr = dynamic_builder_.GetSection()->sh_offset; - program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.GetSection()->sh_size; - program_headers_[PH_LOAD_RW_].p_memsz = dynamic_builder_.GetSection()->sh_size; - program_headers_[PH_LOAD_RW_].p_align = dynamic_builder_.GetSection()->sh_addralign; + program_headers_[PH_LOAD_RW_BSS].p_offset = bss_builder_.GetSection()->sh_offset; + program_headers_[PH_LOAD_RW_BSS].p_vaddr = bss_builder_.GetSection()->sh_offset; + program_headers_[PH_LOAD_RW_BSS].p_paddr = bss_builder_.GetSection()->sh_offset; + program_headers_[PH_LOAD_RW_BSS].p_filesz = 0; + program_headers_[PH_LOAD_RW_BSS].p_memsz = bss_builder_.GetSection()->sh_size; + program_headers_[PH_LOAD_RW_BSS].p_align = bss_builder_.GetSection()->sh_addralign; + + program_headers_[PH_LOAD_RW_DYNAMIC].p_offset = dynamic_builder_.GetSection()->sh_offset; + program_headers_[PH_LOAD_RW_DYNAMIC].p_vaddr = dynamic_builder_.GetSection()->sh_addr; + program_headers_[PH_LOAD_RW_DYNAMIC].p_paddr = dynamic_builder_.GetSection()->sh_addr; + program_headers_[PH_LOAD_RW_DYNAMIC].p_filesz = dynamic_builder_.GetSection()->sh_size; + program_headers_[PH_LOAD_RW_DYNAMIC].p_memsz = dynamic_builder_.GetSection()->sh_size; + program_headers_[PH_LOAD_RW_DYNAMIC].p_align = dynamic_builder_.GetSection()->sh_addralign; program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.GetSection()->sh_offset; - program_headers_[PH_DYNAMIC].p_vaddr = dynamic_builder_.GetSection()->sh_offset; - program_headers_[PH_DYNAMIC].p_paddr = dynamic_builder_.GetSection()->sh_offset; + program_headers_[PH_DYNAMIC].p_vaddr = dynamic_builder_.GetSection()->sh_addr; + program_headers_[PH_DYNAMIC].p_paddr = dynamic_builder_.GetSection()->sh_addr; program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.GetSection()->sh_size; program_headers_[PH_DYNAMIC].p_memsz = dynamic_builder_.GetSection()->sh_size; program_headers_[PH_DYNAMIC].p_align = dynamic_builder_.GetSection()->sh_addralign; @@ -1004,15 +1045,29 @@ class ElfBuilder FINAL { // Finish setup of the Ehdr values. elf_header_.e_phoff = PHDR_OFFSET; elf_header_.e_shoff = sections_offset; - elf_header_.e_phnum = PH_NUM; + elf_header_.e_phnum = (bss_builder_.GetSection()->sh_size != 0u) ? PH_NUM : PH_NUM - 1; elf_header_.e_shnum = section_ptrs_.size(); elf_header_.e_shstrndx = shstrtab_builder_.GetSectionIndex(); // Add the rest of the pieces to the list. pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Elf Header", 0, &elf_header_, sizeof(elf_header_))); - pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET, - &program_headers_, sizeof(program_headers_))); + if (bss_builder_.GetSection()->sh_size != 0u) { + pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET, + &program_headers_[0], + elf_header_.e_phnum * sizeof(Elf_Phdr))); + } else { + // Skip PH_LOAD_RW_BSS. + Elf_Word part1_size = PH_LOAD_RW_BSS * sizeof(Elf_Phdr); + Elf_Word part2_size = (PH_NUM - PH_LOAD_RW_BSS - 1) * sizeof(Elf_Phdr); + CHECK_EQ(part1_size + part2_size, elf_header_.e_phnum * sizeof(Elf_Phdr)); + pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET, + &program_headers_[0], part1_size)); + pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers part 2", + PHDR_OFFSET + part1_size, + &program_headers_[PH_LOAD_RW_BSS + 1], + part2_size)); + } pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynamic", dynamic_builder_.GetSection()->sh_offset, dynamic.data(), @@ -1175,6 +1230,12 @@ class ElfBuilder FINAL { text_builder_.GetSize(), STB_GLOBAL, STT_OBJECT); dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.GetSize() - 4, true, 4, STB_GLOBAL, STT_OBJECT); + if (bss_builder_.GetSize() != 0u) { + dynsym_builder_.AddSymbol("oatbss", &bss_builder_, 0, true, + bss_builder_.GetSize(), STB_GLOBAL, STT_OBJECT); + dynsym_builder_.AddSymbol("oatbsslastword", &bss_builder_, bss_builder_.GetSize() - 4, + true, 4, STB_GLOBAL, STT_OBJECT); + } } void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* builder, @@ -1213,12 +1274,13 @@ class ElfBuilder FINAL { // What phdr is. static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr); enum : uint8_t { - PH_PHDR = 0, - PH_LOAD_R__ = 1, - PH_LOAD_R_X = 2, - PH_LOAD_RW_ = 3, - PH_DYNAMIC = 4, - PH_NUM = 5, + PH_PHDR = 0, + PH_LOAD_R__ = 1, + PH_LOAD_R_X = 2, + PH_LOAD_RW_BSS = 3, + PH_LOAD_RW_DYNAMIC = 4, + PH_DYNAMIC = 5, + PH_NUM = 6, }; static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM; Elf_Phdr program_headers_[PH_NUM]; @@ -1236,6 +1298,7 @@ class ElfBuilder FINAL { ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_; ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_builder_; + ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> bss_builder_; ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> dynsym_builder_; ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> symtab_builder_; ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> hash_builder_; |