summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2017-12-06 15:18:38 +0000
committer David Srbecky <dsrbecky@google.com> 2017-12-12 11:42:21 +0000
commite155f4b858be42a825e8270f65abb0fdcf6cbc9f (patch)
tree545d99febd61872a7a7c1c8e77e53b104db0ad7a
parentbc96fc6e2d8dd02e9b085b1c7ec03c3f01982816 (diff)
Decouple virtual memory allocation in ElfBuilder.
Multi-boot-image requires knowing the loaded size ahead of time, and calculating that size ended up being fairly hacky. Decouple allocation of virtual memory and allocation of file space, so that we have more flexibility when we do those. Test: The generated boot image is bit-for-bit identical as before. Change-Id: I012b55a71e7625f2310570f9b91447c9db73578b
-rw-r--r--compiler/debug/elf_debug_frame_writer.h7
-rw-r--r--compiler/debug/elf_debug_info_writer.h4
-rw-r--r--compiler/debug/elf_debug_line_writer.h4
-rw-r--r--compiler/debug/elf_gnu_debugdata_writer.h4
-rw-r--r--compiler/linker/elf_builder.h224
-rw-r--r--dex2oat/linker/elf_writer_quick.cc4
-rw-r--r--oatdump/oatdump.cc13
7 files changed, 112 insertions, 148 deletions
diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h
index d0c98a7b79..27b70c8caa 100644
--- a/compiler/debug/elf_debug_frame_writer.h
+++ b/compiler/debug/elf_debug_frame_writer.h
@@ -207,13 +207,12 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder,
}
// Write .eh_frame/.debug_frame section.
- auto* cfi_section = (format == dwarf::DW_DEBUG_FRAME_FORMAT
- ? builder->GetDebugFrame()
- : builder->GetEhFrame());
+ const bool is_debug_frame = format == dwarf::DW_DEBUG_FRAME_FORMAT;
+ auto* cfi_section = (is_debug_frame ? builder->GetDebugFrame() : builder->GetEhFrame());
{
cfi_section->Start();
const bool is64bit = Is64BitInstructionSet(builder->GetIsa());
- const Elf_Addr cfi_address = cfi_section->GetAddress();
+ const Elf_Addr cfi_address = (is_debug_frame ? 0 : cfi_section->GetAddress());
const Elf_Addr cie_address = cfi_address;
Elf_Addr buffer_address = cfi_address;
std::vector<uint8_t> buffer; // Small temporary buffer.
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index d5999941d7..2c5a2f436e 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -296,7 +296,7 @@ class ElfCompilationUnitWriter {
CHECK_EQ(info_.Depth(), 0);
std::vector<uint8_t> buffer;
buffer.reserve(info_.data()->size() + KB);
- const size_t offset = owner_->builder_->GetDebugInfo()->GetSize();
+ const size_t offset = owner_->builder_->GetDebugInfo()->GetPosition();
// All compilation units share single table which is at the start of .debug_abbrev.
const size_t debug_abbrev_offset = 0;
WriteDebugInfoCU(debug_abbrev_offset, info_, offset, &buffer, &owner_->debug_info_patches_);
@@ -461,7 +461,7 @@ class ElfCompilationUnitWriter {
CHECK_EQ(info_.Depth(), 0);
std::vector<uint8_t> buffer;
buffer.reserve(info_.data()->size() + KB);
- const size_t offset = owner_->builder_->GetDebugInfo()->GetSize();
+ const size_t offset = owner_->builder_->GetDebugInfo()->GetPosition();
// All compilation units share single table which is at the start of .debug_abbrev.
const size_t debug_abbrev_offset = 0;
WriteDebugInfoCU(debug_abbrev_offset, info_, offset, &buffer, &owner_->debug_info_patches_);
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index 943e03a765..f8e1bf7a72 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -60,7 +60,7 @@ class ElfDebugLineWriter {
? builder_->GetText()->GetAddress()
: 0;
- compilation_unit.debug_line_offset = builder_->GetDebugLine()->GetSize();
+ compilation_unit.debug_line_offset = builder_->GetDebugLine()->GetPosition();
std::vector<dwarf::FileEntry> files;
std::unordered_map<std::string, size_t> files_map;
@@ -268,7 +268,7 @@ class ElfDebugLineWriter {
}
std::vector<uint8_t> buffer;
buffer.reserve(opcodes.data()->size() + KB);
- size_t offset = builder_->GetDebugLine()->GetSize();
+ size_t offset = builder_->GetDebugLine()->GetPosition();
WriteDebugLineTable(directories, files, opcodes, offset, &buffer, &debug_line_patches_);
builder_->GetDebugLine()->WriteFully(buffer.data(), buffer.size());
return buffer.size();
diff --git a/compiler/debug/elf_gnu_debugdata_writer.h b/compiler/debug/elf_gnu_debugdata_writer.h
index 1cdf6b0ad1..9b8ec35ed1 100644
--- a/compiler/debug/elf_gnu_debugdata_writer.h
+++ b/compiler/debug/elf_gnu_debugdata_writer.h
@@ -91,8 +91,8 @@ static std::vector<uint8_t> MakeMiniDebugInfoInternal(
builder->Start();
// Mirror .rodata and .text as NOBITS sections.
// It is needed to detected relocations after compression.
- builder->GetRoData()->WriteNoBitsSection(rodata_section_size);
- builder->GetText()->WriteNoBitsSection(text_section_size);
+ builder->GetRoData()->AllocateVirtualMemory(rodata_section_size);
+ builder->GetText()->AllocateVirtualMemory(text_section_size);
WriteDebugSymbols(builder.get(), method_infos, false /* with_signature */);
WriteCFISection(builder.get(),
method_infos,
diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h
index b30b55e9b4..3710878ea1 100644
--- a/compiler/linker/elf_builder.h
+++ b/compiler/linker/elf_builder.h
@@ -108,8 +108,6 @@ class ElfBuilder FINAL {
section_index_(0),
name_(name),
link_(link),
- started_(false),
- finished_(false),
phdr_flags_(PF_R),
phdr_type_(0) {
DCHECK_GE(align, 1u);
@@ -120,90 +118,62 @@ class ElfBuilder FINAL {
header_.sh_entsize = entsize;
}
- // Start writing of this section.
- void Start() {
- CHECK(!started_);
- CHECK(!finished_);
- started_ = true;
- auto& sections = owner_->sections_;
- // Check that the previous section is complete.
- CHECK(sections.empty() || sections.back()->finished_);
- // The first ELF section index is 1. Index 0 is reserved for NULL.
- section_index_ = sections.size() + 1;
- // Page-align if we switch between allocated and non-allocated sections,
- // or if we change the type of allocation (e.g. executable vs non-executable).
- if (!sections.empty()) {
- if (header_.sh_flags != sections.back()->header_.sh_flags) {
- header_.sh_addralign = kPageSize;
- }
- }
- // Align file position.
- if (header_.sh_type != SHT_NOBITS) {
- header_.sh_offset = owner_->AlignFileOffset(header_.sh_addralign);
- } else {
- header_.sh_offset = 0;
- }
- // Align virtual memory address.
- if ((header_.sh_flags & SHF_ALLOC) != 0) {
- header_.sh_addr = owner_->AlignVirtualAddress(header_.sh_addralign);
- } else {
- header_.sh_addr = 0;
- }
- // Push this section on the list of written sections.
- sections.push_back(this);
+ // Allocate chunk of virtual memory for this section from the owning ElfBuilder.
+ // This must be done at the start for all SHF_ALLOC sections (i.e. mmaped by linker).
+ // It is fine to allocate section but never call Start/End() (e.g. the .bss section).
+ void AllocateVirtualMemory(Elf_Word size) {
+ AllocateVirtualMemory(owner_->virtual_address_, size);
}
- // Finish writing of this section.
- void End() {
- CHECK(started_);
- CHECK(!finished_);
- finished_ = true;
- if (header_.sh_type == SHT_NOBITS) {
- CHECK_GT(header_.sh_size, 0u);
- } else {
- // Use the current file position to determine section size.
- off_t file_offset = owner_->stream_.Seek(0, kSeekCurrent);
- CHECK_GE(file_offset, (off_t)header_.sh_offset);
- header_.sh_size = file_offset - header_.sh_offset;
- }
- if ((header_.sh_flags & SHF_ALLOC) != 0) {
- owner_->virtual_address_ += header_.sh_size;
- }
+ void AllocateVirtualMemory(Elf_Addr addr, Elf_Word size) {
+ CHECK_NE(header_.sh_flags & SHF_ALLOC, 0u);
+ Elf_Word align = AddSection();
+ CHECK_EQ(header_.sh_addr, 0u);
+ header_.sh_addr = RoundUp(addr, align);
+ CHECK(header_.sh_size == 0u || header_.sh_size == size);
+ header_.sh_size = size;
+ CHECK_LE(owner_->virtual_address_, header_.sh_addr);
+ owner_->virtual_address_ = header_.sh_addr + header_.sh_size;
}
- // Get the location of this section in virtual memory.
- Elf_Addr GetAddress() const {
- CHECK(started_);
- return header_.sh_addr;
+ // Start writing file data of this section.
+ void Start() {
+ CHECK(owner_->current_section_ == nullptr);
+ Elf_Word align = AddSection();
+ CHECK_EQ(header_.sh_offset, 0u);
+ header_.sh_offset = owner_->AlignFileOffset(align);
+ owner_->current_section_ = this;
}
- // Returns the size of the content of this section.
- Elf_Word GetSize() const {
- if (finished_) {
- return header_.sh_size;
- } else {
- CHECK(started_);
- CHECK_NE(header_.sh_type, (Elf_Word)SHT_NOBITS);
- return owner_->stream_.Seek(0, kSeekCurrent) - header_.sh_offset;
- }
+ // Finish writing file data of this section.
+ void End() {
+ CHECK(owner_->current_section_ == this);
+ Elf_Word position = GetPosition();
+ CHECK(header_.sh_size == 0u || header_.sh_size == position);
+ header_.sh_size = position;
+ owner_->current_section_ = nullptr;
+ }
+
+ // Get the number of bytes written so far.
+ // Only valid while writing the section.
+ Elf_Word GetPosition() const {
+ CHECK(owner_->current_section_ == this);
+ off_t file_offset = owner_->stream_.Seek(0, kSeekCurrent);
+ DCHECK_GE(file_offset, (off_t)header_.sh_offset);
+ return file_offset - header_.sh_offset;
}
- // Write this section as "NOBITS" section. (used for the .bss section)
- // This means that the ELF file does not contain the initial data for this section
- // and it will be zero-initialized when the ELF file is loaded in the running program.
- void WriteNoBitsSection(Elf_Word size) {
+ // Get the location of this section in virtual memory.
+ Elf_Addr GetAddress() const {
DCHECK_NE(header_.sh_flags & SHF_ALLOC, 0u);
- header_.sh_type = SHT_NOBITS;
- Start();
- header_.sh_size = size;
- End();
+ DCHECK_NE(header_.sh_addr, 0u);
+ return header_.sh_addr;
}
// This function always succeeds to simplify code.
// Use builder's Good() to check the actual status.
bool WriteFully(const void* buffer, size_t byte_count) OVERRIDE {
- CHECK(started_);
- CHECK(!finished_);
+ CHECK(owner_->current_section_ == this);
return owner_->stream_.WriteFully(buffer, byte_count);
}
@@ -221,19 +191,32 @@ class ElfBuilder FINAL {
}
Elf_Word GetSectionIndex() const {
- DCHECK(started_);
DCHECK_NE(section_index_, 0u);
return section_index_;
}
private:
+ // Add this section to the list of generated ELF sections (if not there already).
+ // It also ensures the alignment is sufficient to generate valid program headers,
+ // since that depends on the previous section. It returns the required alignment.
+ Elf_Word AddSection() {
+ if (section_index_ == 0) {
+ std::vector<Section*>& sections = owner_->sections_;
+ Elf_Word last = sections.empty() ? PF_R : sections.back()->phdr_flags_;
+ if (owner_->write_program_headers_ && phdr_flags_ != last) {
+ header_.sh_addralign = kPageSize; // Page-align if R/W/X flags changed.
+ }
+ sections.push_back(this);
+ section_index_ = sections.size(); // First ELF section has index 1.
+ }
+ return header_.sh_addralign;
+ }
+
ElfBuilder<ElfTypes>* owner_;
Elf_Shdr header_;
Elf_Word section_index_;
const std::string name_;
const Section* const link_;
- bool started_;
- bool finished_;
Elf_Word phdr_flags_;
Elf_Word phdr_type_;
@@ -370,7 +353,7 @@ class ElfBuilder FINAL {
Elf_Word section_index;
if (section != nullptr) {
DCHECK_LE(section->GetAddress(), addr);
- DCHECK_LE(addr, section->GetAddress() + section->GetSize());
+ DCHECK_LE(addr, section->GetAddress() + section->header_.sh_size);
section_index = section->GetSectionIndex();
} else {
section_index = static_cast<Elf_Word>(SHN_ABS);
@@ -479,6 +462,10 @@ class ElfBuilder FINAL {
digest_start_(-1) {
}
+ Elf_Word GetSize() {
+ return 16 + kBuildIdLen;
+ }
+
void Write() {
// The size fields are 32-bit on both 32-bit and 64-bit systems, confirmed
// with the 64-bit linker and libbfd code. The size of name and desc must
@@ -490,6 +477,7 @@ class ElfBuilder FINAL {
digest_start_ = this->Seek(0, kSeekCurrent);
static_assert(kBuildIdLen % 4 == 0, "expecting a mutliple of 4 for build ID length");
this->WriteFully(std::string(kBuildIdLen, '\0').c_str(), kBuildIdLen); // desc.
+ DCHECK_EQ(this->GetPosition(), GetSize());
}
off_t GetDigestStart() {
@@ -530,6 +518,7 @@ class ElfBuilder FINAL {
abiflags_(this, ".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC, nullptr, 0, kPageSize, 0,
isa, features),
build_id_(this, ".note.gnu.build-id", SHT_NOTE, SHF_ALLOC, nullptr, 0, 4, 0),
+ current_section_(nullptr),
started_(false),
write_program_headers_(false),
loaded_size_(0u),
@@ -545,6 +534,7 @@ class ElfBuilder FINAL {
~ElfBuilder() {}
InstructionSet GetIsa() { return isa_; }
+ BuildIdSection* GetBuildId() { return &build_id_; }
Section* GetRoData() { return &rodata_; }
Section* GetText() { return &text_; }
Section* GetBss() { return &bss_; }
@@ -622,6 +612,9 @@ class ElfBuilder FINAL {
if (section->link_ != nullptr) {
section->header_.sh_link = section->link_->GetSectionIndex();
}
+ if (section->header_.sh_offset == 0) {
+ section->header_.sh_type = SHT_NOBITS;
+ }
}
shstrtab_.End();
@@ -680,65 +673,57 @@ class ElfBuilder FINAL {
soname = soname.substr(directory_separator_pos + 1);
}
- // Calculate addresses of .text, .bss and .dynstr.
- DCHECK_EQ(rodata_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
- DCHECK_EQ(text_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
- DCHECK_EQ(bss_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
- DCHECK_EQ(dynstr_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
- Elf_Word rodata_address = rodata_.GetAddress();
- Elf_Word text_address = RoundUp(rodata_address + rodata_size, kPageSize);
- Elf_Word bss_address = RoundUp(text_address + text_size, kPageSize);
- Elf_Word abiflags_address = RoundUp(bss_address + bss_size, kPageSize);
- Elf_Word abiflags_size = 0;
+ // Allocate all pre-dynamic sections.
+ rodata_.AllocateVirtualMemory(rodata_size);
+ text_.AllocateVirtualMemory(text_size);
+ if (bss_size != 0) {
+ bss_.AllocateVirtualMemory(bss_size);
+ }
if (isa_ == InstructionSet::kMips || isa_ == InstructionSet::kMips64) {
- abiflags_size = abiflags_.GetSize();
+ abiflags_.AllocateVirtualMemory(abiflags_.GetSize());
}
- Elf_Word dynstr_address = RoundUp(abiflags_address + abiflags_size, kPageSize);
// Cache .dynstr, .dynsym and .hash data.
dynstr_.Add(""); // dynstr should start with empty string.
- Elf_Word rodata_index = rodata_.GetSectionIndex();
Elf_Word oatdata = dynstr_.Add("oatdata");
- dynsym_.Add(oatdata, rodata_index, rodata_address, rodata_size, STB_GLOBAL, STT_OBJECT);
+ dynsym_.Add(oatdata, &rodata_, rodata_.GetAddress(), rodata_size, STB_GLOBAL, STT_OBJECT);
if (text_size != 0u) {
- Elf_Word text_index = rodata_index + 1u;
Elf_Word oatexec = dynstr_.Add("oatexec");
- dynsym_.Add(oatexec, text_index, text_address, text_size, STB_GLOBAL, STT_OBJECT);
+ dynsym_.Add(oatexec, &text_, text_.GetAddress(), text_size, STB_GLOBAL, STT_OBJECT);
Elf_Word oatlastword = dynstr_.Add("oatlastword");
- Elf_Word oatlastword_address = text_address + text_size - 4;
- dynsym_.Add(oatlastword, text_index, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
+ Elf_Word oatlastword_address = text_.GetAddress() + text_size - 4;
+ dynsym_.Add(oatlastword, &text_, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
} else if (rodata_size != 0) {
// rodata_ can be size 0 for dwarf_test.
Elf_Word oatlastword = dynstr_.Add("oatlastword");
- Elf_Word oatlastword_address = rodata_address + rodata_size - 4;
- dynsym_.Add(oatlastword, rodata_index, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
+ Elf_Word oatlastword_address = rodata_.GetAddress() + rodata_size - 4;
+ dynsym_.Add(oatlastword, &rodata_, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
}
DCHECK_LE(bss_roots_offset, bss_size);
if (bss_size != 0u) {
- Elf_Word bss_index = rodata_index + 1u + (text_size != 0 ? 1u : 0u);
Elf_Word oatbss = dynstr_.Add("oatbss");
- dynsym_.Add(oatbss, bss_index, bss_address, bss_roots_offset, STB_GLOBAL, STT_OBJECT);
+ dynsym_.Add(oatbss, &bss_, bss_.GetAddress(), bss_roots_offset, STB_GLOBAL, STT_OBJECT);
DCHECK_LE(bss_methods_offset, bss_roots_offset);
DCHECK_LE(bss_roots_offset, bss_size);
// Add a symbol marking the start of the methods part of the .bss, if not empty.
if (bss_methods_offset != bss_roots_offset) {
- Elf_Word bss_methods_address = bss_address + bss_methods_offset;
+ Elf_Word bss_methods_address = bss_.GetAddress() + bss_methods_offset;
Elf_Word bss_methods_size = bss_roots_offset - bss_methods_offset;
Elf_Word oatbssroots = dynstr_.Add("oatbssmethods");
dynsym_.Add(
- oatbssroots, bss_index, bss_methods_address, bss_methods_size, STB_GLOBAL, STT_OBJECT);
+ oatbssroots, &bss_, bss_methods_address, bss_methods_size, STB_GLOBAL, STT_OBJECT);
}
// Add a symbol marking the start of the GC roots part of the .bss, if not empty.
if (bss_roots_offset != bss_size) {
- Elf_Word bss_roots_address = bss_address + bss_roots_offset;
+ Elf_Word bss_roots_address = bss_.GetAddress() + bss_roots_offset;
Elf_Word bss_roots_size = bss_size - bss_roots_offset;
Elf_Word oatbssroots = dynstr_.Add("oatbssroots");
dynsym_.Add(
- oatbssroots, bss_index, bss_roots_address, bss_roots_size, STB_GLOBAL, STT_OBJECT);
+ oatbssroots, &bss_, bss_roots_address, bss_roots_size, STB_GLOBAL, STT_OBJECT);
}
Elf_Word oatbsslastword = dynstr_.Add("oatbsslastword");
- Elf_Word bsslastword_address = bss_address + bss_size - 4;
- dynsym_.Add(oatbsslastword, bss_index, bsslastword_address, 4, STB_GLOBAL, STT_OBJECT);
+ Elf_Word bsslastword_address = bss_.GetAddress() + bss_size - 4;
+ dynsym_.Add(oatbsslastword, &bss_, bsslastword_address, 4, STB_GLOBAL, STT_OBJECT);
}
Elf_Word soname_offset = dynstr_.Add(soname);
@@ -759,28 +744,24 @@ class ElfBuilder FINAL {
hash.push_back(0); // Last symbol terminates the chain.
hash_.Add(hash.data(), hash.size() * sizeof(hash[0]));
- // Calculate addresses of .dynsym, .hash and .dynamic.
- DCHECK_EQ(dynstr_.header_.sh_flags, dynsym_.header_.sh_flags);
- DCHECK_EQ(dynsym_.header_.sh_flags, hash_.header_.sh_flags);
- Elf_Word dynsym_address =
- RoundUp(dynstr_address + dynstr_.GetCacheSize(), dynsym_.header_.sh_addralign);
- Elf_Word hash_address =
- RoundUp(dynsym_address + dynsym_.GetCacheSize(), hash_.header_.sh_addralign);
- DCHECK_EQ(dynamic_.header_.sh_addralign, static_cast<Elf_Word>(kPageSize));
- Elf_Word dynamic_address = RoundUp(hash_address + dynsym_.GetCacheSize(), kPageSize);
+ // Allocate all remaining sections.
+ dynstr_.AllocateVirtualMemory(dynstr_.GetCacheSize());
+ dynsym_.AllocateVirtualMemory(dynsym_.GetCacheSize());
+ hash_.AllocateVirtualMemory(hash_.GetCacheSize());
Elf_Dyn dyns[] = {
- { DT_HASH, { hash_address } },
- { DT_STRTAB, { dynstr_address } },
- { DT_SYMTAB, { dynsym_address } },
+ { DT_HASH, { hash_.GetAddress() } },
+ { DT_STRTAB, { dynstr_.GetAddress() } },
+ { DT_SYMTAB, { dynsym_.GetAddress() } },
{ DT_SYMENT, { sizeof(Elf_Sym) } },
{ DT_STRSZ, { dynstr_.GetCacheSize() } },
{ DT_SONAME, { soname_offset } },
{ DT_NULL, { 0 } },
};
dynamic_.Add(&dyns, sizeof(dyns));
+ dynamic_.AllocateVirtualMemory(dynamic_.GetCacheSize());
- loaded_size_ = RoundUp(dynamic_address + dynamic_.GetCacheSize(), kPageSize);
+ loaded_size_ = RoundUp(virtual_address_, kPageSize);
}
void WriteDynamicSection() {
@@ -788,8 +769,6 @@ class ElfBuilder FINAL {
dynsym_.WriteCachedSection();
hash_.WriteCachedSection();
dynamic_.WriteCachedSection();
-
- CHECK_EQ(loaded_size_, RoundUp(dynamic_.GetAddress() + dynamic_.GetSize(), kPageSize));
}
Elf_Word GetLoadedSize() {
@@ -828,10 +807,6 @@ class ElfBuilder FINAL {
return stream_.Seek(RoundUp(stream_.Seek(0, kSeekCurrent), alignment), kSeekSet);
}
- Elf_Addr AlignVirtualAddress(size_t alignment) {
- return virtual_address_ = RoundUp(virtual_address_, alignment);
- }
-
private:
static Elf_Ehdr MakeElfHeader(InstructionSet isa, const InstructionSetFeatures* features) {
Elf_Ehdr elf_header = Elf_Ehdr();
@@ -902,7 +877,6 @@ class ElfBuilder FINAL {
elf_header.e_ehsize = sizeof(Elf_Ehdr);
elf_header.e_phentsize = sizeof(Elf_Phdr);
elf_header.e_shentsize = sizeof(Elf_Shdr);
- elf_header.e_phoff = sizeof(Elf_Ehdr);
return elf_header;
}
@@ -933,6 +907,7 @@ class ElfBuilder FINAL {
for (auto* section : sections_) {
const Elf_Shdr& shdr = section->header_;
if ((shdr.sh_flags & SHF_ALLOC) != 0 && shdr.sh_size != 0) {
+ DCHECK(shdr.sh_addr != 0u) << "Allocate virtual memory for the section";
// PT_LOAD tells the linker to mmap part of the file.
// The linker can only mmap page-aligned sections.
// Single PT_LOAD may contain several ELF sections.
@@ -1010,6 +985,7 @@ class ElfBuilder FINAL {
// List of used section in the order in which they were written.
std::vector<Section*> sections_;
+ Section* current_section_; // The section which is currently being written.
bool started_;
bool write_program_headers_;
diff --git a/dex2oat/linker/elf_writer_quick.cc b/dex2oat/linker/elf_writer_quick.cc
index 5fc33ddf8b..758e21de93 100644
--- a/dex2oat/linker/elf_writer_quick.cc
+++ b/dex2oat/linker/elf_writer_quick.cc
@@ -173,6 +173,7 @@ template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::Start() {
builder_->Start();
if (compiler_options_->GetGenerateBuildId()) {
+ builder_->GetBuildId()->AllocateVirtualMemory(builder_->GetBuildId()->GetSize());
builder_->WriteBuildIdSection();
}
}
@@ -225,9 +226,6 @@ void ElfWriterQuick<ElfTypes>::EndText(OutputStream* text) {
template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::WriteDynamicSection() {
- if (bss_size_ != 0u) {
- builder_->GetBss()->WriteNoBitsSection(bss_size_);
- }
if (builder_->GetIsa() == InstructionSet::kMips ||
builder_->GetIsa() == InstructionSet::kMips64) {
builder_->WriteMIPSabiflagsSection();
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 1b4485b233..1a1d8cc76e 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -146,13 +146,10 @@ class OatSymbolizer FINAL {
auto* rodata = builder_->GetRoData();
auto* text = builder_->GetText();
- auto* bss = builder_->GetBss();
const uint8_t* rodata_begin = oat_file_->Begin();
const size_t rodata_size = oat_file_->GetOatHeader().GetExecutableOffset();
- if (no_bits_) {
- rodata->WriteNoBitsSection(rodata_size);
- } else {
+ if (!no_bits_) {
rodata->Start();
rodata->WriteFully(rodata_begin, rodata_size);
rodata->End();
@@ -160,18 +157,12 @@ class OatSymbolizer FINAL {
const uint8_t* text_begin = oat_file_->Begin() + rodata_size;
const size_t text_size = oat_file_->End() - text_begin;
- if (no_bits_) {
- text->WriteNoBitsSection(text_size);
- } else {
+ if (!no_bits_) {
text->Start();
text->WriteFully(text_begin, text_size);
text->End();
}
- if (oat_file_->BssSize() != 0) {
- bss->WriteNoBitsSection(oat_file_->BssSize());
- }
-
if (isa == InstructionSet::kMips || isa == InstructionSet::kMips64) {
builder_->WriteMIPSabiflagsSection();
}