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 | |
parent | 242026e246a8b9efe098a0cce008fd525e011e5b (diff) | |
download | art-5c42c29b89286e5efa4a4613132b09051ce5945b.zip art-5c42c29b89286e5efa4a4613132b09051ce5945b.tar.gz art-5c42c29b89286e5efa4a4613132b09051ce5945b.tar.bz2 |
Add support for .bss section in oat files.
Change-Id: I779b80b8139d9afdc28373f8c68edff5df7726ce
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/common_compiler_test.cc | 1 | ||||
-rw-r--r-- | compiler/elf_builder.h | 109 | ||||
-rw-r--r-- | compiler/elf_writer_quick.cc | 3 | ||||
-rw-r--r-- | compiler/image_writer.cc | 4 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 1 | ||||
-rw-r--r-- | compiler/oat_writer.h | 7 |
6 files changed, 100 insertions, 25 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index e8354b2..09be437 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -253,6 +253,7 @@ void CommonCompilerTest::ReserveImageSpace() { (size_t)100 * 1024 * 1024, // 100MB PROT_NONE, false /* no need for 4gb flag with fixed mmap*/, + false /* not reusing existing reservation */, &error_msg)); CHECK(image_reservation_.get() != nullptr) << error_msg; } diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h index 94268de..9ab3602 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_; diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index 401d5a9..a822b24 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -229,6 +229,7 @@ bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, const OatHeader& oat_header = oat_writer->GetOatHeader(); Elf_Word oat_data_size = oat_header.GetExecutableOffset(); uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; + uint32_t oat_bss_size = oat_writer->GetBssSize(); OatWriterWrapper wrapper(oat_writer); @@ -243,6 +244,8 @@ bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, oat_data_size, oat_data_size, oat_exec_size, + RoundUp(oat_data_size + oat_exec_size, kPageSize), + oat_bss_size, compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(), debug)); diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index c588e1a..f5f9320 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -408,8 +408,8 @@ ImageWriter::BinSlot ImageWriter::GetImageBinSlot(mirror::Object* object) const bool ImageWriter::AllocMemory() { size_t length = RoundUp(Runtime::Current()->GetHeap()->GetTotalMemory(), kPageSize); std::string error_msg; - image_.reset(MemMap::MapAnonymous("image writer image", NULL, length, PROT_READ | PROT_WRITE, - false, &error_msg)); + image_.reset(MemMap::MapAnonymous("image writer image", nullptr, length, PROT_READ | PROT_WRITE, + false, false, &error_msg)); if (UNLIKELY(image_.get() == nullptr)) { LOG(ERROR) << "Failed to allocate memory for image file generation: " << error_msg; return false; diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 8411091..c32a992 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -403,6 +403,7 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files, image_writer_(image_writer), dex_files_(&dex_files), size_(0u), + bss_size_(0u), oat_data_offset_(0u), image_file_location_oat_checksum_(image_file_location_oat_checksum), image_file_location_oat_begin_(image_file_location_oat_begin), diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index 980611f..fd2ccae 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -96,6 +96,10 @@ class OatWriter { return size_; } + size_t GetBssSize() const { + return bss_size_; + } + const std::vector<uintptr_t>& GetAbsolutePatchLocations() const { return absolute_patch_locations_; } @@ -266,6 +270,9 @@ class OatWriter { // Size required for Oat data structures. size_t size_; + // The size of the required .bss section holding the DexCache data. + size_t bss_size_; + // Offset of the oat data from the start of the mmapped region of the elf file. size_t oat_data_offset_; |