summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-10-08 17:27:48 -0700
committerIan Rogers <irogers@google.com>2014-10-09 08:25:34 -0700
commit0279ebb3efd653e6bb255470c99d26949c7bcd95 (patch)
treed58b29754f7b3c88616e6e4d6c19346821d244ae
parentf1f05d303988a5c071c87b760056be8358276c94 (diff)
downloadart-0279ebb3efd653e6bb255470c99d26949c7bcd95.zip
art-0279ebb3efd653e6bb255470c99d26949c7bcd95.tar.gz
art-0279ebb3efd653e6bb255470c99d26949c7bcd95.tar.bz2
Tidy ELF builder.
Don't do "if (ptr)". Use const. Use DISALLOW_COPY_AND_ASSIGN. Avoid public member variables. Move ValueObject to base and use in ELF builder. Tidy VectorOutputStream to not use non-const reference arguments. Change-Id: I2c727c3fc61769c3726de7cfb68b2d6eb4477e53
-rw-r--r--compiler/buffered_output_stream.h2
-rw-r--r--compiler/elf_builder.h534
-rw-r--r--compiler/elf_writer_mclinker.cc2
-rw-r--r--compiler/elf_writer_quick.cc12
-rw-r--r--compiler/file_output_stream.h2
-rw-r--r--compiler/optimizing/builder.h2
-rw-r--r--compiler/optimizing/graph_visualizer.h2
-rw-r--r--compiler/optimizing/locations.h3
-rw-r--r--compiler/optimizing/nodes.h2
-rw-r--r--compiler/optimizing/parallel_move_resolver.h2
-rw-r--r--compiler/optimizing/stack_map_stream.h2
-rw-r--r--compiler/output_stream_test.cc2
-rw-r--r--compiler/utils/arena_object.h (renamed from compiler/utils/allocation.h)17
-rw-r--r--compiler/vector_output_stream.cc6
-rw-r--r--compiler/vector_output_stream.h16
-rw-r--r--oatdump/oatdump.cc21
-rw-r--r--runtime/base/value_object.h37
17 files changed, 381 insertions, 283 deletions
diff --git a/compiler/buffered_output_stream.h b/compiler/buffered_output_stream.h
index 75a3f24..bbc49df 100644
--- a/compiler/buffered_output_stream.h
+++ b/compiler/buffered_output_stream.h
@@ -23,7 +23,7 @@
namespace art {
-class BufferedOutputStream : public OutputStream {
+class BufferedOutputStream FINAL : public OutputStream {
public:
explicit BufferedOutputStream(OutputStream* out);
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 74ee038..c32bdb4 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -18,6 +18,7 @@
#define ART_COMPILER_ELF_BUILDER_H_
#include "base/stl_util.h"
+#include "base/value_object.h"
#include "buffered_output_stream.h"
#include "elf_utils.h"
#include "file_output_stream.h"
@@ -26,11 +27,12 @@
namespace art {
template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfSectionBuilder {
+class ElfSectionBuilder : public ValueObject {
public:
ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link, Elf_Word info,
- Elf_Word align, Elf_Word entsize) : name_(sec_name), link_(link) {
+ Elf_Word align, Elf_Word entsize)
+ : section_index_(0), name_(sec_name), link_(link) {
memset(&section_, 0, sizeof(section_));
section_.sh_type = type;
section_.sh_flags = flags;
@@ -39,23 +41,41 @@ class ElfSectionBuilder {
section_.sh_entsize = entsize;
}
- virtual ~ElfSectionBuilder() {}
+ ~ElfSectionBuilder() {}
- Elf_Shdr section_;
- Elf_Word section_index_ = 0;
+ Elf_Word GetLink() const {
+ return (link_ != nullptr) ? link_->section_index_ : 0;
+ }
- Elf_Word GetLink() {
- return (link_) ? link_->section_index_ : 0;
+ const Elf_Shdr* GetSection() const {
+ return &section_;
}
- const std::string name_;
+ Elf_Shdr* GetSection() {
+ return &section_;
+ }
- protected:
- const ElfSectionBuilder* link_;
+ Elf_Word GetSectionIndex() const {
+ return section_index_;
+ }
+
+ void SetSectionIndex(Elf_Word section_index) {
+ section_index_ = section_index;
+ }
+
+ const std::string& GetName() const {
+ return name_;
+ }
+
+ private:
+ Elf_Shdr section_;
+ Elf_Word section_index_;
+ const std::string name_;
+ const ElfSectionBuilder* const link_;
};
template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr>
-class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfDynamicBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
public:
void AddDynamicTag(Elf_Sword tag, Elf_Word d_un) {
if (tag == DT_NULL) {
@@ -65,7 +85,7 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
}
void AddDynamicTag(Elf_Sword tag, Elf_Word d_un,
- ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
+ const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
if (tag == DT_NULL) {
return;
}
@@ -78,7 +98,7 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
link, 0, kPageSize, sizeof(Elf_Dyn)) {}
~ElfDynamicBuilder() {}
- Elf_Word GetSize() {
+ Elf_Word GetSize() const {
// Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of
// these must be added when we actually put the file together because
// their values are very dependent on state.
@@ -89,13 +109,13 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
// table and soname_off should be the offset of the soname in .dynstr.
// Since niether can be found prior to final layout we will wait until here
// to add them.
- std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname) {
+ std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname) const {
std::vector<Elf_Dyn> ret;
for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
- if (it->section_) {
+ if (it->section_ != nullptr) {
// We are adding an address relative to a section.
ret.push_back(
- {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
+ {it->tag_, {it->off_ + it->section_->GetSection()->sh_addr}});
} else {
ret.push_back({it->tag_, {it->off_}});
}
@@ -106,9 +126,9 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
return ret;
}
- protected:
+ private:
struct ElfDynamicState {
- ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+ const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
Elf_Sword tag_;
Elf_Word off_;
};
@@ -116,39 +136,50 @@ class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr
};
template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfRawSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfRawSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
public:
ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* link, Elf_Word info,
Elf_Word align, Elf_Word entsize)
: ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, link, info, align,
- entsize) {}
+ entsize) {
+ }
+
~ElfRawSectionBuilder() {}
- std::vector<uint8_t>* GetBuffer() { return &buf_; }
- void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; }
- protected:
+ std::vector<uint8_t>* GetBuffer() {
+ return &buf_;
+ }
+
+ void SetBuffer(const std::vector<uint8_t>& buf) {
+ buf_ = buf;
+ }
+
+ private:
std::vector<uint8_t> buf_;
};
template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
-class ElfOatSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfOatSectionBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
public:
ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset,
Elf_Word type, Elf_Word flags)
: ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, nullptr, 0, kPageSize,
- 0), offset_(offset), size_(size) {}
+ 0),
+ offset_(offset), size_(size) {
+ }
+
~ElfOatSectionBuilder() {}
- Elf_Word GetOffset() {
+ Elf_Word GetOffset() const {
return offset_;
}
- Elf_Word GetSize() {
+ Elf_Word GetSize() const {
return size_;
}
- protected:
+ private:
// Offset of the content within the file.
Elf_Word offset_;
// Size of the content within the file.
@@ -175,7 +206,7 @@ static inline unsigned elfhash(const char *_name) {
template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Sym,
typename Elf_Shdr>
-class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+class ElfSymtabBuilder FINAL : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
public:
// Add a symbol with given name to this symtab. The symbol refers to
// 'relative_addr' within the given section and has the given attributes.
@@ -202,10 +233,12 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
strtab_(str_name,
str_type,
((alloc) ? SHF_ALLOC : 0U),
- nullptr, 0, 1, 1) {}
+ nullptr, 0, 1, 1) {
+ }
+
~ElfSymtabBuilder() {}
- std::vector<Elf_Word> GenerateHashContents() {
+ std::vector<Elf_Word> GenerateHashContents() const {
// Here is how The ELF hash table works.
// There are 3 arrays to worry about.
// * The symbol table where the symbol information is.
@@ -295,7 +328,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
tab += it->name_;
tab += '\0';
}
- strtab_.section_.sh_size = tab.size();
+ strtab_.GetSection()->sh_size = tab.size();
return tab;
}
@@ -311,13 +344,13 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
memset(&sym, 0, sizeof(sym));
sym.st_name = it->name_idx_;
if (it->is_relative_) {
- sym.st_value = it->addr_ + it->section_->section_.sh_offset;
+ sym.st_value = it->addr_ + it->section_->GetSection()->sh_offset;
} else {
sym.st_value = it->addr_;
}
sym.st_size = it->size_;
sym.st_other = it->other_;
- sym.st_shndx = it->section_->section_index_;
+ sym.st_shndx = it->section_->GetSectionIndex();
sym.st_info = it->info_;
ret.push_back(sym);
@@ -325,7 +358,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
return ret;
}
- Elf_Word GetSize() {
+ Elf_Word GetSize() const {
// 1 is for the implicit NULL symbol.
return symbols_.size() + 1;
}
@@ -334,7 +367,7 @@ class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>
return &strtab_;
}
- protected:
+ private:
struct ElfSymbolState {
const std::string name_;
const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
@@ -377,18 +410,26 @@ class ElfFilePiece {
protected:
explicit ElfFilePiece(Elf_Word offset) : offset_(offset) {}
- virtual std::string GetDescription() = 0;
+ Elf_Word GetOffset() const {
+ return offset_;
+ }
+
+ virtual const char* GetDescription() const = 0;
virtual bool DoActualWrite(File* elf_file) = 0;
- Elf_Word offset_;
+ private:
+ const Elf_Word offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElfFilePiece);
};
template <typename Elf_Word>
-class ElfFileMemoryPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileMemoryPiece FINAL : public ElfFilePiece<Elf_Word> {
public:
ElfFileMemoryPiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size)
: ElfFilePiece<Elf_Word>(offset), dbg_name_(name), data_(data), size_(size) {}
+ protected:
bool DoActualWrite(File* elf_file) OVERRIDE {
DCHECK(data_ != nullptr || size_ == 0U) << dbg_name_ << " " << size_;
@@ -400,8 +441,8 @@ class ElfFileMemoryPiece : public ElfFilePiece<Elf_Word> {
return true;
}
- std::string GetDescription() OVERRIDE {
- return dbg_name_;
+ const char* GetDescription() const OVERRIDE {
+ return dbg_name_.c_str();
}
private:
@@ -418,13 +459,14 @@ class CodeOutput {
};
template <typename Elf_Word>
-class ElfFileRodataPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileRodataPiece FINAL : public ElfFilePiece<Elf_Word> {
public:
ElfFileRodataPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
output_(output) {}
+ protected:
bool DoActualWrite(File* elf_file) OVERRIDE {
- output_->SetCodeOffset(this->offset_);
+ output_->SetCodeOffset(this->GetOffset());
std::unique_ptr<BufferedOutputStream> output_stream(
new BufferedOutputStream(new FileOutputStream(elf_file)));
if (!output_->Write(output_stream.get())) {
@@ -435,20 +477,23 @@ class ElfFileRodataPiece : public ElfFilePiece<Elf_Word> {
return true;
}
- std::string GetDescription() OVERRIDE {
+ const char* GetDescription() const OVERRIDE {
return ".rodata";
}
private:
- CodeOutput* output_;
+ CodeOutput* const output_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElfFileRodataPiece);
};
template <typename Elf_Word>
-class ElfFileOatTextPiece : public ElfFilePiece<Elf_Word> {
+class ElfFileOatTextPiece FINAL : public ElfFilePiece<Elf_Word> {
public:
ElfFileOatTextPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
output_(output) {}
+ protected:
bool DoActualWrite(File* elf_file) OVERRIDE {
// All data is written by the ElfFileRodataPiece right now, as the oat writer writes in one
// piece. This is for future flexibility.
@@ -456,12 +501,14 @@ class ElfFileOatTextPiece : public ElfFilePiece<Elf_Word> {
return true;
}
- std::string GetDescription() OVERRIDE {
+ const char* GetDescription() const OVERRIDE {
return ".text";
}
private:
- CodeOutput* output_;
+ CodeOutput* const output_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElfFileOatTextPiece);
};
template <typename Elf_Word>
@@ -513,6 +560,14 @@ class ElfBuilder FINAL {
}
~ElfBuilder() {}
+ const ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>& GetTextBuilder() const {
+ return text_builder_;
+ }
+
+ ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* GetSymtabBuilder() {
+ return &symtab_builder_;
+ }
+
bool Init() {
// The basic layout of the elf file. Order may be different in final output.
// +-------------------------+
@@ -676,34 +731,40 @@ class ElfBuilder FINAL {
section_index_ = 1;
// setup .dynsym
- section_ptrs_.push_back(&dynsym_builder_.section_);
+ section_ptrs_.push_back(dynsym_builder_.GetSection());
AssignSectionStr(&dynsym_builder_, &shstrtab_);
- dynsym_builder_.section_index_ = section_index_++;
+ dynsym_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Setup .dynstr
- section_ptrs_.push_back(&dynsym_builder_.GetStrTab()->section_);
+ section_ptrs_.push_back(dynsym_builder_.GetStrTab()->GetSection());
AssignSectionStr(dynsym_builder_.GetStrTab(), &shstrtab_);
- dynsym_builder_.GetStrTab()->section_index_ = section_index_++;
+ dynsym_builder_.GetStrTab()->SetSectionIndex(section_index_);
+ section_index_++;
// Setup .hash
- section_ptrs_.push_back(&hash_builder_.section_);
+ section_ptrs_.push_back(hash_builder_.GetSection());
AssignSectionStr(&hash_builder_, &shstrtab_);
- hash_builder_.section_index_ = section_index_++;
+ hash_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Setup .rodata
- section_ptrs_.push_back(&rodata_builder_.section_);
+ section_ptrs_.push_back(rodata_builder_.GetSection());
AssignSectionStr(&rodata_builder_, &shstrtab_);
- rodata_builder_.section_index_ = section_index_++;
+ rodata_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Setup .text
- section_ptrs_.push_back(&text_builder_.section_);
+ section_ptrs_.push_back(text_builder_.GetSection());
AssignSectionStr(&text_builder_, &shstrtab_);
- text_builder_.section_index_ = section_index_++;
+ text_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Setup .dynamic
- section_ptrs_.push_back(&dynamic_builder_.section_);
+ section_ptrs_.push_back(dynamic_builder_.GetSection());
AssignSectionStr(&dynamic_builder_, &shstrtab_);
- dynamic_builder_.section_index_ = section_index_++;
+ dynamic_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Fill in the hash section.
hash_ = dynsym_builder_.GenerateHashContents();
@@ -718,64 +779,67 @@ class ElfBuilder FINAL {
// Get the layout in the sections.
//
// Get the layout of the dynsym section.
- dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
- dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
- dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
- dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
+ dynsym_builder_.GetSection()->sh_offset =
+ RoundUp(base_offset, dynsym_builder_.GetSection()->sh_addralign);
+ dynsym_builder_.GetSection()->sh_addr = dynsym_builder_.GetSection()->sh_offset;
+ dynsym_builder_.GetSection()->sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
+ dynsym_builder_.GetSection()->sh_link = dynsym_builder_.GetLink();
// Get the layout of the dynstr section.
- dynsym_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (dynsym_builder_.GetStrTab()->section_,
- dynsym_builder_.section_);
- dynsym_builder_.GetStrTab()->section_.sh_addr = dynsym_builder_.GetStrTab()->section_.sh_offset;
- dynsym_builder_.GetStrTab()->section_.sh_size = dynstr_.size();
- dynsym_builder_.GetStrTab()->section_.sh_link = dynsym_builder_.GetStrTab()->GetLink();
+ dynsym_builder_.GetStrTab()->GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*dynsym_builder_.GetStrTab()->GetSection(),
+ *dynsym_builder_.GetSection());
+ dynsym_builder_.GetStrTab()->GetSection()->sh_addr =
+ dynsym_builder_.GetStrTab()->GetSection()->sh_offset;
+ dynsym_builder_.GetStrTab()->GetSection()->sh_size = dynstr_.size();
+ dynsym_builder_.GetStrTab()->GetSection()->sh_link = dynsym_builder_.GetStrTab()->GetLink();
// Get the layout of the hash section
- hash_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (hash_builder_.section_,
- dynsym_builder_.GetStrTab()->section_);
- hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
- hash_builder_.section_.sh_size = hash_.size() * sizeof(Elf_Word);
- hash_builder_.section_.sh_link = hash_builder_.GetLink();
+ hash_builder_.GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*hash_builder_.GetSection(),
+ *dynsym_builder_.GetStrTab()->GetSection());
+ hash_builder_.GetSection()->sh_addr = hash_builder_.GetSection()->sh_offset;
+ hash_builder_.GetSection()->sh_size = hash_.size() * sizeof(Elf_Word);
+ hash_builder_.GetSection()->sh_link = hash_builder_.GetLink();
// Get the layout of the rodata section.
- rodata_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (rodata_builder_.section_,
- hash_builder_.section_);
- rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
- rodata_builder_.section_.sh_size = rodata_builder_.GetSize();
- rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
+ rodata_builder_.GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*rodata_builder_.GetSection(),
+ *hash_builder_.GetSection());
+ rodata_builder_.GetSection()->sh_addr = rodata_builder_.GetSection()->sh_offset;
+ rodata_builder_.GetSection()->sh_size = rodata_builder_.GetSize();
+ rodata_builder_.GetSection()->sh_link = rodata_builder_.GetLink();
// Get the layout of the text section.
- text_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (text_builder_.section_, rodata_builder_.section_);
- text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
- text_builder_.section_.sh_size = text_builder_.GetSize();
- text_builder_.section_.sh_link = text_builder_.GetLink();
- CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
+ text_builder_.GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*text_builder_.GetSection(),
+ *rodata_builder_.GetSection());
+ text_builder_.GetSection()->sh_addr = text_builder_.GetSection()->sh_offset;
+ text_builder_.GetSection()->sh_size = text_builder_.GetSize();
+ text_builder_.GetSection()->sh_link = text_builder_.GetLink();
+ CHECK_ALIGNED(rodata_builder_.GetSection()->sh_offset +
+ rodata_builder_.GetSection()->sh_size, kPageSize);
// Get the layout of the dynamic section.
- dynamic_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (dynamic_builder_.section_,
- text_builder_.section_);
- dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
- dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
- dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
+ 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;
+ dynamic_builder_.GetSection()->sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
+ dynamic_builder_.GetSection()->sh_link = dynamic_builder_.GetLink();
if (debug_logging_) {
- LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
- << " dynsym size=" << dynsym_builder_.section_.sh_size;
- LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->section_.sh_offset
- << " dynstr size=" << dynsym_builder_.GetStrTab()->section_.sh_size;
- LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
- << " hash size=" << hash_builder_.section_.sh_size;
- LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
- << " rodata size=" << rodata_builder_.section_.sh_size;
- LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
- << " text size=" << text_builder_.section_.sh_size;
- LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
- << " dynamic size=" << dynamic_builder_.section_.sh_size;
+ LOG(INFO) << "dynsym off=" << dynsym_builder_.GetSection()->sh_offset
+ << " dynsym size=" << dynsym_builder_.GetSection()->sh_size;
+ LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->GetSection()->sh_offset
+ << " dynstr size=" << dynsym_builder_.GetStrTab()->GetSection()->sh_size;
+ LOG(INFO) << "hash off=" << hash_builder_.GetSection()->sh_offset
+ << " hash size=" << hash_builder_.GetSection()->sh_size;
+ LOG(INFO) << "rodata off=" << rodata_builder_.GetSection()->sh_offset
+ << " rodata size=" << rodata_builder_.GetSection()->sh_size;
+ LOG(INFO) << "text off=" << text_builder_.GetSection()->sh_offset
+ << " text size=" << text_builder_.GetSection()->sh_size;
+ LOG(INFO) << "dynamic off=" << dynamic_builder_.GetSection()->sh_offset
+ << " dynamic size=" << dynamic_builder_.GetSection()->sh_size;
}
return true;
@@ -783,19 +847,21 @@ class ElfBuilder FINAL {
bool Write() {
std::vector<ElfFilePiece<Elf_Word>*> pieces;
- Elf_Shdr prev = dynamic_builder_.section_;
+ Elf_Shdr* prev = dynamic_builder_.GetSection();
std::string strtab;
if (IncludingDebugSymbols()) {
// Setup .symtab
- section_ptrs_.push_back(&symtab_builder_.section_);
+ section_ptrs_.push_back(symtab_builder_.GetSection());
AssignSectionStr(&symtab_builder_, &shstrtab_);
- symtab_builder_.section_index_ = section_index_++;
+ symtab_builder_.SetSectionIndex(section_index_);
+ section_index_++;
// Setup .strtab
- section_ptrs_.push_back(&symtab_builder_.GetStrTab()->section_);
+ section_ptrs_.push_back(symtab_builder_.GetStrTab()->GetSection());
AssignSectionStr(symtab_builder_.GetStrTab(), &shstrtab_);
- symtab_builder_.GetStrTab()->section_index_ = section_index_++;
+ symtab_builder_.GetStrTab()->SetSectionIndex(section_index_);
+ section_index_++;
strtab = symtab_builder_.GenerateStrtab();
if (debug_logging_) {
@@ -810,15 +876,17 @@ class ElfBuilder FINAL {
for (ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder = other_builders_.data(),
*end = builder + other_builders_.size();
builder != end; ++builder) {
- section_ptrs_.push_back(&builder->section_);
+ section_ptrs_.push_back(builder->GetSection());
AssignSectionStr(builder, &shstrtab_);
- builder->section_index_ = section_index_++;
+ builder->SetSectionIndex(section_index_);
+ section_index_++;
}
// Setup shstrtab
- section_ptrs_.push_back(&shstrtab_builder_.section_);
+ section_ptrs_.push_back(shstrtab_builder_.GetSection());
AssignSectionStr(&shstrtab_builder_, &shstrtab_);
- shstrtab_builder_.section_index_ = section_index_++;
+ shstrtab_builder_.SetSectionIndex(section_index_);
+ section_index_++;
if (debug_logging_) {
LOG(INFO) << ".shstrtab size (bytes) =" << shstrtab_.size()
@@ -829,71 +897,71 @@ class ElfBuilder FINAL {
if (IncludingDebugSymbols()) {
// Get the layout of the symtab section.
- symtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (symtab_builder_.section_,
- dynamic_builder_.section_);
- symtab_builder_.section_.sh_addr = 0;
+ symtab_builder_.GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetSection(),
+ *dynamic_builder_.GetSection());
+ symtab_builder_.GetSection()->sh_addr = 0;
// Add to leave space for the null symbol.
- symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
- symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
+ symtab_builder_.GetSection()->sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
+ symtab_builder_.GetSection()->sh_link = symtab_builder_.GetLink();
// Get the layout of the dynstr section.
- symtab_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (symtab_builder_.GetStrTab()->section_,
- symtab_builder_.section_);
- symtab_builder_.GetStrTab()->section_.sh_addr = 0;
- symtab_builder_.GetStrTab()->section_.sh_size = strtab.size();
- symtab_builder_.GetStrTab()->section_.sh_link = symtab_builder_.GetStrTab()->GetLink();
-
- prev = symtab_builder_.GetStrTab()->section_;
+ symtab_builder_.GetStrTab()->GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetStrTab()->GetSection(),
+ *symtab_builder_.GetSection());
+ symtab_builder_.GetStrTab()->GetSection()->sh_addr = 0;
+ symtab_builder_.GetStrTab()->GetSection()->sh_size = strtab.size();
+ symtab_builder_.GetStrTab()->GetSection()->sh_link = symtab_builder_.GetStrTab()->GetLink();
+
+ prev = symtab_builder_.GetStrTab()->GetSection();
if (debug_logging_) {
- LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
- << " symtab size=" << symtab_builder_.section_.sh_size;
- LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->section_.sh_offset
- << " strtab size=" << symtab_builder_.GetStrTab()->section_.sh_size;
+ LOG(INFO) << "symtab off=" << symtab_builder_.GetSection()->sh_offset
+ << " symtab size=" << symtab_builder_.GetSection()->sh_size;
+ LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->GetSection()->sh_offset
+ << " strtab size=" << symtab_builder_.GetStrTab()->GetSection()->sh_size;
}
}
// Get the layout of the extra sections. (This will deal with the debug
// sections if they are there)
for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
- it->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>(it->section_, prev);
- it->section_.sh_addr = 0;
- it->section_.sh_size = it->GetBuffer()->size();
- it->section_.sh_link = it->GetLink();
+ it->GetSection()->sh_offset = NextOffset<Elf_Word, Elf_Shdr>(*it->GetSection(), *prev);
+ it->GetSection()->sh_addr = 0;
+ it->GetSection()->sh_size = it->GetBuffer()->size();
+ it->GetSection()->sh_link = it->GetLink();
// We postpone adding an ElfFilePiece to keep the order in "pieces."
- prev = it->section_;
+ prev = it->GetSection();
if (debug_logging_) {
- LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
- << " size=" << it->section_.sh_size;
+ LOG(INFO) << it->GetName() << " off=" << it->GetSection()->sh_offset
+ << " size=" << it->GetSection()->sh_size;
}
}
// Get the layout of the shstrtab section
- shstrtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
- (shstrtab_builder_.section_, prev);
- shstrtab_builder_.section_.sh_addr = 0;
- shstrtab_builder_.section_.sh_size = shstrtab_.size();
- shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
+ shstrtab_builder_.GetSection()->sh_offset =
+ NextOffset<Elf_Word, Elf_Shdr>(*shstrtab_builder_.GetSection(), *prev);
+ shstrtab_builder_.GetSection()->sh_addr = 0;
+ shstrtab_builder_.GetSection()->sh_size = shstrtab_.size();
+ shstrtab_builder_.GetSection()->sh_link = shstrtab_builder_.GetLink();
if (debug_logging_) {
- LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
- << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
+ LOG(INFO) << "shstrtab off=" << shstrtab_builder_.GetSection()->sh_offset
+ << " shstrtab size=" << shstrtab_builder_.GetSection()->sh_size;
}
// The section list comes after come after.
Elf_Word sections_offset = RoundUp(
- shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
+ shstrtab_builder_.GetSection()->sh_offset + shstrtab_builder_.GetSection()->sh_size,
sizeof(Elf_Word));
// Setup the actual symbol arrays.
std::vector<Elf_Sym> dynsym = dynsym_builder_.GenerateSymtab();
- CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.section_.sh_size);
+ CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.GetSection()->sh_size);
std::vector<Elf_Sym> symtab;
if (IncludingDebugSymbols()) {
symtab = symtab_builder_.GenerateSymtab();
- CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.section_.sh_size);
+ CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.GetSection()->sh_size);
}
// Setup the dynamic section.
@@ -901,43 +969,44 @@ class ElfBuilder FINAL {
// and the soname_offset.
std::vector<Elf_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr_.size(),
dynstr_soname_offset_);
- CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.section_.sh_size);
+ CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.GetSection()->sh_size);
// Finish setup of the program headers now that we know the layout of the
// whole file.
- Elf_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
+ Elf_Word load_r_size =
+ rodata_builder_.GetSection()->sh_offset + rodata_builder_.GetSection()->sh_size;
program_headers_[PH_LOAD_R__].p_filesz = load_r_size;
program_headers_[PH_LOAD_R__].p_memsz = load_r_size;
- program_headers_[PH_LOAD_R__].p_align = rodata_builder_.section_.sh_addralign;
+ program_headers_[PH_LOAD_R__].p_align = rodata_builder_.GetSection()->sh_addralign;
- Elf_Word load_rx_size = text_builder_.section_.sh_size;
- program_headers_[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
- program_headers_[PH_LOAD_R_X].p_vaddr = text_builder_.section_.sh_offset;
- program_headers_[PH_LOAD_R_X].p_paddr = text_builder_.section_.sh_offset;
+ Elf_Word load_rx_size = text_builder_.GetSection()->sh_size;
+ program_headers_[PH_LOAD_R_X].p_offset = text_builder_.GetSection()->sh_offset;
+ program_headers_[PH_LOAD_R_X].p_vaddr = text_builder_.GetSection()->sh_offset;
+ program_headers_[PH_LOAD_R_X].p_paddr = text_builder_.GetSection()->sh_offset;
program_headers_[PH_LOAD_R_X].p_filesz = load_rx_size;
program_headers_[PH_LOAD_R_X].p_memsz = load_rx_size;
- program_headers_[PH_LOAD_R_X].p_align = text_builder_.section_.sh_addralign;
-
- program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_LOAD_RW_].p_vaddr = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_LOAD_RW_].p_paddr = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
- program_headers_[PH_LOAD_RW_].p_memsz = dynamic_builder_.section_.sh_size;
- program_headers_[PH_LOAD_RW_].p_align = dynamic_builder_.section_.sh_addralign;
-
- program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_DYNAMIC].p_vaddr = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_DYNAMIC].p_paddr = dynamic_builder_.section_.sh_offset;
- program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
- program_headers_[PH_DYNAMIC].p_memsz = dynamic_builder_.section_.sh_size;
- program_headers_[PH_DYNAMIC].p_align = dynamic_builder_.section_.sh_addralign;
+ 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_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_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;
// 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_shnum = section_ptrs_.size();
- elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
+ 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_,
@@ -945,33 +1014,33 @@ class ElfBuilder FINAL {
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET,
&program_headers_, sizeof(program_headers_)));
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynamic",
- dynamic_builder_.section_.sh_offset,
+ dynamic_builder_.GetSection()->sh_offset,
dynamic.data(),
- dynamic_builder_.section_.sh_size));
- pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynsym", dynsym_builder_.section_.sh_offset,
+ dynamic_builder_.GetSection()->sh_size));
+ pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynsym", dynsym_builder_.GetSection()->sh_offset,
dynsym.data(),
dynsym.size() * sizeof(Elf_Sym)));
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynstr",
- dynsym_builder_.GetStrTab()->section_.sh_offset,
+ dynsym_builder_.GetStrTab()->GetSection()->sh_offset,
dynstr_.c_str(), dynstr_.size()));
- pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".hash", hash_builder_.section_.sh_offset,
+ pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".hash", hash_builder_.GetSection()->sh_offset,
hash_.data(),
hash_.size() * sizeof(Elf_Word)));
- pieces.push_back(new ElfFileRodataPiece<Elf_Word>(rodata_builder_.section_.sh_offset,
+ pieces.push_back(new ElfFileRodataPiece<Elf_Word>(rodata_builder_.GetSection()->sh_offset,
oat_writer_));
- pieces.push_back(new ElfFileOatTextPiece<Elf_Word>(text_builder_.section_.sh_offset,
+ pieces.push_back(new ElfFileOatTextPiece<Elf_Word>(text_builder_.GetSection()->sh_offset,
oat_writer_));
if (IncludingDebugSymbols()) {
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".symtab",
- symtab_builder_.section_.sh_offset,
+ symtab_builder_.GetSection()->sh_offset,
symtab.data(),
symtab.size() * sizeof(Elf_Sym)));
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".strtab",
- symtab_builder_.GetStrTab()->section_.sh_offset,
+ symtab_builder_.GetStrTab()->GetSection()->sh_offset,
strtab.c_str(), strtab.size()));
}
pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".shstrtab",
- shstrtab_builder_.section_.sh_offset,
+ shstrtab_builder_.GetSection()->sh_offset,
&shstrtab_[0], shstrtab_.size()));
for (uint32_t i = 0; i < section_ptrs_.size(); ++i) {
// Just add all the sections in induvidually since they are all over the
@@ -983,7 +1052,7 @@ class ElfBuilder FINAL {
// Postponed debug info.
for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
- pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(it->name_, it->section_.sh_offset,
+ pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(it->GetName(), it->GetSection()->sh_offset,
it->GetBuffer()->data(),
it->GetBuffer()->size()));
}
@@ -1006,47 +1075,6 @@ class ElfBuilder FINAL {
}
private:
- CodeOutput* oat_writer_;
- File* elf_file_;
- const bool add_symbols_;
- const bool debug_logging_;
-
- bool fatal_error_ = false;
-
- // 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,
- };
- static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
- Elf_Phdr program_headers_[PH_NUM];
-
- Elf_Ehdr elf_header_;
-
- Elf_Shdr null_hdr_;
- std::string shstrtab_;
- uint32_t section_index_;
- std::string dynstr_;
- uint32_t dynstr_soname_offset_;
- std::vector<Elf_Shdr*> section_ptrs_;
- std::vector<Elf_Word> hash_;
-
- public:
- ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_;
- ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_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_;
- ElfDynamicBuilder<Elf_Word, Elf_Sword, Elf_Dyn, Elf_Shdr> dynamic_builder_;
- ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> shstrtab_builder_;
- std::vector<ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>> other_builders_;
-
- private:
void SetISA(InstructionSet isa) {
switch (isa) {
case kArm:
@@ -1141,14 +1169,14 @@ class ElfBuilder FINAL {
true, 4, STB_GLOBAL, STT_OBJECT);
}
- void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder,
+ void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* builder,
std::string* strtab) {
- builder->section_.sh_name = strtab->size();
- *strtab += builder->name_;
+ builder->GetSection()->sh_name = strtab->size();
+ *strtab += builder->GetName();
*strtab += '\0';
if (debug_logging_) {
- LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
- << "to shstrtab at offset " << builder->section_.sh_name;
+ LOG(INFO) << "adding section name \"" << builder->GetName() << "\" "
+ << "to shstrtab at offset " << builder->GetSection()->sh_name;
}
}
@@ -1163,7 +1191,51 @@ class ElfBuilder FINAL {
return true;
}
- bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
+ bool IncludingDebugSymbols() const {
+ return add_symbols_ && symtab_builder_.GetSize() > 1;
+ }
+
+ CodeOutput* const oat_writer_;
+ File* const elf_file_;
+ const bool add_symbols_;
+ const bool debug_logging_;
+
+ bool fatal_error_ = false;
+
+ // 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,
+ };
+ static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
+ Elf_Phdr program_headers_[PH_NUM];
+
+ Elf_Ehdr elf_header_;
+
+ Elf_Shdr null_hdr_;
+ std::string shstrtab_;
+ // The index of the current section being built. The first being 1.
+ uint32_t section_index_;
+ std::string dynstr_;
+ uint32_t dynstr_soname_offset_;
+ std::vector<const Elf_Shdr*> section_ptrs_;
+ std::vector<Elf_Word> hash_;
+
+ ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_;
+ ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_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_;
+ ElfDynamicBuilder<Elf_Word, Elf_Sword, Elf_Dyn, Elf_Shdr> dynamic_builder_;
+ ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> shstrtab_builder_;
+ std::vector<ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>> other_builders_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
};
} // namespace art
diff --git a/compiler/elf_writer_mclinker.cc b/compiler/elf_writer_mclinker.cc
index f017641..7705b9c 100644
--- a/compiler/elf_writer_mclinker.cc
+++ b/compiler/elf_writer_mclinker.cc
@@ -82,7 +82,7 @@ bool ElfWriterMclinker::Write(OatWriter* oat_writer,
}
// Fill oat_contents.
- VectorOutputStream output_stream("oat contents", oat_contents);
+ VectorOutputStream output_stream("oat contents", &oat_contents);
oat_writer->SetOatDataOffset(oat_section->offset());
CHECK(oat_writer->Write(&output_stream));
CHECK_EQ(oat_writer->GetSize(), oat_contents.size());
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index e661324..c75d8f8 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -195,7 +195,7 @@ std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
}
}
-class OatWriterWrapper : public CodeOutput {
+class OatWriterWrapper FINAL : public CodeOutput {
public:
explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
@@ -206,7 +206,7 @@ class OatWriterWrapper : public CodeOutput {
return oat_writer_->Write(out);
}
private:
- OatWriter* oat_writer_;
+ OatWriter* const oat_writer_;
};
template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
@@ -676,14 +676,14 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
std::unique_ptr<std::vector<uint8_t>> cfi_info(
ConstructCIEFrame(compiler_driver->GetInstructionSet()));
- Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
+ Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
// Iterate over the compiled methods.
const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
- ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr,
- Elf_Sym, Elf_Shdr>* symtab = &builder->symtab_builder_;
+ ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
+ builder->GetSymtabBuilder();
for (auto it = method_info.begin(); it != method_info.end(); ++it) {
- symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
+ symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true,
it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
// Include CFI for compiled method, if possible.
diff --git a/compiler/file_output_stream.h b/compiler/file_output_stream.h
index 76b00fe..9dfbd7f 100644
--- a/compiler/file_output_stream.h
+++ b/compiler/file_output_stream.h
@@ -23,7 +23,7 @@
namespace art {
-class FileOutputStream : public OutputStream {
+class FileOutputStream FINAL : public OutputStream {
public:
explicit FileOutputStream(File* file);
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 7d7b188..e68cdb0 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -22,7 +22,7 @@
#include "driver/compiler_driver.h"
#include "driver/dex_compilation_unit.h"
#include "primitive.h"
-#include "utils/allocation.h"
+#include "utils/arena_object.h"
#include "utils/growable_array.h"
#include "nodes.h"
diff --git a/compiler/optimizing/graph_visualizer.h b/compiler/optimizing/graph_visualizer.h
index 6e2c6fd..f17ba3b 100644
--- a/compiler/optimizing/graph_visualizer.h
+++ b/compiler/optimizing/graph_visualizer.h
@@ -17,7 +17,7 @@
#ifndef ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
#define ART_COMPILER_OPTIMIZING_GRAPH_VISUALIZER_H_
-#include "utils/allocation.h"
+#include "base/value_object.h"
namespace art {
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index 5f85b6a..e6b55c7 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -19,7 +19,8 @@
#include "base/bit_field.h"
#include "base/bit_vector.h"
-#include "utils/allocation.h"
+#include "base/value_object.h"
+#include "utils/arena_object.h"
#include "utils/growable_array.h"
#include "utils/managed_register.h"
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index fc5b06d..2010e7e 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -20,7 +20,7 @@
#include "locations.h"
#include "offsets.h"
#include "primitive.h"
-#include "utils/allocation.h"
+#include "utils/arena_object.h"
#include "utils/arena_bit_vector.h"
#include "utils/growable_array.h"
diff --git a/compiler/optimizing/parallel_move_resolver.h b/compiler/optimizing/parallel_move_resolver.h
index fcc1de6..309425e 100644
--- a/compiler/optimizing/parallel_move_resolver.h
+++ b/compiler/optimizing/parallel_move_resolver.h
@@ -17,7 +17,7 @@
#ifndef ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_
#define ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_
-#include "utils/allocation.h"
+#include "base/value_object.h"
#include "utils/growable_array.h"
namespace art {
diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h
index 0ea11ad..5f74c33 100644
--- a/compiler/optimizing/stack_map_stream.h
+++ b/compiler/optimizing/stack_map_stream.h
@@ -18,9 +18,9 @@
#define ART_COMPILER_OPTIMIZING_STACK_MAP_STREAM_H_
#include "base/bit_vector.h"
+#include "base/value_object.h"
#include "memory_region.h"
#include "stack_map.h"
-#include "utils/allocation.h"
#include "utils/growable_array.h"
namespace art {
diff --git a/compiler/output_stream_test.cc b/compiler/output_stream_test.cc
index 315ca09..bba9892 100644
--- a/compiler/output_stream_test.cc
+++ b/compiler/output_stream_test.cc
@@ -90,7 +90,7 @@ TEST_F(OutputStreamTest, Buffered) {
TEST_F(OutputStreamTest, Vector) {
std::vector<uint8_t> output;
- VectorOutputStream output_stream("test vector output", output);
+ VectorOutputStream output_stream("test vector output", &output);
SetOutputStream(output_stream);
GenerateTestOutput();
CheckTestOutput(output);
diff --git a/compiler/utils/allocation.h b/compiler/utils/arena_object.h
index b0947ca..50909f7 100644
--- a/compiler/utils/allocation.h
+++ b/compiler/utils/arena_object.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_ALLOCATION_H_
-#define ART_COMPILER_UTILS_ALLOCATION_H_
+#ifndef ART_COMPILER_UTILS_ARENA_OBJECT_H_
+#define ART_COMPILER_UTILS_ARENA_OBJECT_H_
#include "arena_allocator.h"
#include "base/logging.h"
@@ -34,17 +34,6 @@ class ArenaObject {
}
};
-class ValueObject {
- public:
- void* operator new(size_t size) {
- LOG(FATAL) << "UNREACHABLE";
- abort();
- }
- void operator delete(void*, size_t) {
- LOG(FATAL) << "UNREACHABLE";
- }
-};
-
} // namespace art
-#endif // ART_COMPILER_UTILS_ALLOCATION_H_
+#endif // ART_COMPILER_UTILS_ARENA_OBJECT_H_
diff --git a/compiler/vector_output_stream.cc b/compiler/vector_output_stream.cc
index e5ff729..3d33673 100644
--- a/compiler/vector_output_stream.cc
+++ b/compiler/vector_output_stream.cc
@@ -20,8 +20,8 @@
namespace art {
-VectorOutputStream::VectorOutputStream(const std::string& location, std::vector<uint8_t>& vector)
- : OutputStream(location), offset_(vector.size()), vector_(vector) {}
+VectorOutputStream::VectorOutputStream(const std::string& location, std::vector<uint8_t>* vector)
+ : OutputStream(location), offset_(vector->size()), vector_(vector) {}
off_t VectorOutputStream::Seek(off_t offset, Whence whence) {
CHECK(whence == kSeekSet || whence == kSeekCurrent || whence == kSeekEnd) << whence;
@@ -36,7 +36,7 @@ off_t VectorOutputStream::Seek(off_t offset, Whence whence) {
break;
}
case kSeekEnd: {
- new_offset = vector_.size() + offset;
+ new_offset = vector_->size() + offset;
break;
}
}
diff --git a/compiler/vector_output_stream.h b/compiler/vector_output_stream.h
index 09daa12..3c5877c 100644
--- a/compiler/vector_output_stream.h
+++ b/compiler/vector_output_stream.h
@@ -25,21 +25,21 @@
namespace art {
-class VectorOutputStream : public OutputStream {
+class VectorOutputStream FINAL : public OutputStream {
public:
- VectorOutputStream(const std::string& location, std::vector<uint8_t>& vector);
+ VectorOutputStream(const std::string& location, std::vector<uint8_t>* vector);
virtual ~VectorOutputStream() {}
bool WriteFully(const void* buffer, size_t byte_count) {
- if (static_cast<size_t>(offset_) == vector_.size()) {
+ if (static_cast<size_t>(offset_) == vector_->size()) {
const uint8_t* start = reinterpret_cast<const uint8_t*>(buffer);
- vector_.insert(vector_.end(), &start[0], &start[byte_count]);
+ vector_->insert(vector_->end(), &start[0], &start[byte_count]);
offset_ += byte_count;
} else {
off_t new_offset = offset_ + byte_count;
EnsureCapacity(new_offset);
- memcpy(&vector_[offset_], buffer, byte_count);
+ memcpy(&(*vector_)[offset_], buffer, byte_count);
offset_ = new_offset;
}
return true;
@@ -49,13 +49,13 @@ class VectorOutputStream : public OutputStream {
private:
void EnsureCapacity(off_t new_offset) {
- if (new_offset > static_cast<off_t>(vector_.size())) {
- vector_.resize(new_offset);
+ if (new_offset > static_cast<off_t>(vector_->size())) {
+ vector_->resize(new_offset);
}
}
off_t offset_;
- std::vector<uint8_t>& vector_;
+ std::vector<uint8_t>* const vector_;
DISALLOW_COPY_AND_ASSIGN(VectorOutputStream);
};
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index d5e766f..51b7a98 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -120,10 +120,12 @@ const char* image_roots_descriptions_[] = {
"kClassRoots",
};
-class OatSymbolizer : public CodeOutput {
+class OatSymbolizer FINAL : public CodeOutput {
public:
- explicit OatSymbolizer(const OatFile* oat_file, std::string& output_name) :
- oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr), output_name_(output_name) {}
+ explicit OatSymbolizer(const OatFile* oat_file, const std::string& output_name) :
+ oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr),
+ output_name_(output_name.empty() ? "symbolized.oat" : output_name) {
+ }
bool Init() {
Elf32_Word oat_data_size = oat_file_->GetOatHeader().GetExecutableOffset();
@@ -131,9 +133,6 @@ class OatSymbolizer : public CodeOutput {
uint32_t diff = static_cast<uint32_t>(oat_file_->End() - oat_file_->Begin());
uint32_t oat_exec_size = diff - oat_data_size;
- if (output_name_.empty()) {
- output_name_ = "symbolized.oat";
- }
elf_output_ = OS::CreateEmptyFile(output_name_.c_str());
builder_.reset(new ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
@@ -307,11 +306,11 @@ class OatSymbolizer : public CodeOutput {
}
ElfSymtabBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr,
- Elf32_Sym, Elf32_Shdr>* symtab = &builder_->symtab_builder_;
+ Elf32_Sym, Elf32_Shdr>* symtab = builder_->GetSymtabBuilder();
- symtab->AddSymbol(pretty_name, &builder_->text_builder_, oat_method.GetCodeOffset() -
- oat_file_->GetOatHeader().GetExecutableOffset(), true,
- oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
+ symtab->AddSymbol(pretty_name, &builder_->GetTextBuilder(),
+ oat_method.GetCodeOffset() - oat_file_->GetOatHeader().GetExecutableOffset(),
+ true, oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
}
}
@@ -340,7 +339,7 @@ class OatSymbolizer : public CodeOutput {
Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr> > builder_;
File* elf_output_;
std::unordered_map<uint32_t, uint32_t> state_;
- std::string output_name_;
+ const std::string output_name_;
};
class OatDumperOptions {
diff --git a/runtime/base/value_object.h b/runtime/base/value_object.h
new file mode 100644
index 0000000..ee0e2a0
--- /dev/null
+++ b/runtime/base/value_object.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_VALUE_OBJECT_H_
+#define ART_RUNTIME_BASE_VALUE_OBJECT_H_
+
+#include "base/logging.h"
+
+namespace art {
+
+class ValueObject {
+ public:
+ void* operator new(size_t size) {
+ LOG(FATAL) << "UNREACHABLE";
+ abort();
+ }
+ void operator delete(void*, size_t) {
+ LOG(FATAL) << "UNREACHABLE";
+ }
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_VALUE_OBJECT_H_