summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2012-03-20 20:19:26 +0800
committerShih-wei Liao <sliao@google.com>2012-03-26 21:09:55 -0700
commit25ae64082c2583a080b9d0bd005d2efd09e81723 (patch)
tree59a129ce418ff6484f569cac74382b959d978cbd
parentdf57614aa99801a50202e284ee8e8497d8e92621 (diff)
downloadart-25ae64082c2583a080b9d0bd005d2efd09e81723.zip
art-25ae64082c2583a080b9d0bd005d2efd09e81723.tar.gz
art-25ae64082c2583a080b9d0bd005d2efd09e81723.tar.bz2
Write ELF image to Oat file.
(cherry picked from commit 1c84f1fd7570974bec8660cd17e0118be529afce) Change-Id: I322579095009a09ab9ad8d2e7d7c309a5530718c
-rw-r--r--src/oat.cc21
-rw-r--r--src/oat.h6
-rw-r--r--src/oat_writer.cc94
-rw-r--r--src/oat_writer.h34
4 files changed, 155 insertions, 0 deletions
diff --git a/src/oat.cc b/src/oat.cc
index d8d01df..b3333c2 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -29,6 +29,7 @@ OatHeader::OatHeader() {
OatHeader::OatHeader(InstructionSet instruction_set,
const std::vector<const DexFile*>* dex_files,
+ uint32_t elf_image_count,
uint32_t image_file_location_checksum,
const std::string& image_file_location) {
memcpy(magic_, kOatMagic, sizeof(kOatMagic));
@@ -42,6 +43,9 @@ OatHeader::OatHeader(InstructionSet instruction_set,
dex_file_count_ = dex_files->size();
UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
+ elf_image_count_ = elf_image_count;
+ UpdateChecksum(&elf_image_count_, sizeof(elf_image_count_));
+
image_file_location_checksum_ = image_file_location_checksum;
UpdateChecksum(&image_file_location_checksum_, sizeof(image_file_location_checksum_));
@@ -49,6 +53,7 @@ OatHeader::OatHeader(InstructionSet instruction_set,
UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
UpdateChecksum(image_file_location.data(), image_file_location_size_);
+ elf_image_table_offset_ = 0;
executable_offset_ = 0;
}
@@ -72,6 +77,16 @@ uint32_t OatHeader::GetDexFileCount() const {
return dex_file_count_;
}
+uint32_t OatHeader::GetElfImageCount() const {
+ DCHECK(IsValid());
+ return elf_image_count_;
+}
+
+uint32_t OatHeader::GetElfImageTableOffset() const {
+ DCHECK(IsValid());
+ return elf_image_table_offset_;
+}
+
uint32_t OatHeader::GetChecksum() const {
CHECK(IsValid());
return adler32_checksum_;
@@ -116,6 +131,12 @@ std::string OatHeader::GetImageFileLocation() const {
GetImageFileLocationSize());
}
+void OatHeader::SetElfImageTableOffset(uint32_t elf_image_table_offset) {
+ DCHECK(IsValid());
+ elf_image_table_offset_ = elf_image_table_offset;
+ UpdateChecksum(&elf_image_table_offset_, sizeof(elf_image_table_offset_));
+}
+
void OatHeader::SetExecutableOffset(uint32_t executable_offset) {
DCHECK_ALIGNED(executable_offset, kPageSize);
CHECK_GT(executable_offset, sizeof(OatHeader));
diff --git a/src/oat.h b/src/oat.h
index 25a4373..a71a75b 100644
--- a/src/oat.h
+++ b/src/oat.h
@@ -30,6 +30,7 @@ class PACKED OatHeader {
OatHeader();
OatHeader(InstructionSet instruction_set,
const std::vector<const DexFile*>* dex_files,
+ uint32_t elf_image_count,
uint32_t image_file_location_checksum,
const std::string& image_file_location);
@@ -38,8 +39,11 @@ class PACKED OatHeader {
uint32_t GetChecksum() const;
void UpdateChecksum(const void* data, size_t length);
uint32_t GetDexFileCount() const;
+ uint32_t GetElfImageCount() const;
+ uint32_t GetElfImageTableOffset() const;
uint32_t GetExecutableOffset() const;
InstructionSet GetInstructionSet() const;
+ void SetElfImageTableOffset(uint32_t elf_image_offset);
void SetExecutableOffset(uint32_t executable_offset);
uint32_t GetImageFileLocationChecksum() const;
uint32_t GetImageFileLocationSize() const;
@@ -56,6 +60,8 @@ class PACKED OatHeader {
InstructionSet instruction_set_;
uint32_t dex_file_count_;
+ uint32_t elf_image_count_;
+ uint32_t elf_image_table_offset_;
uint32_t executable_offset_;
uint32_t image_file_location_checksum_;
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index 8e127de..df809d5 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -18,11 +18,14 @@
#include "class_linker.h"
#include "class_loader.h"
+#include "elf_image.h"
#include "file.h"
#include "os.h"
#include "space.h"
#include "stl_util.h"
+#include <zlib.h>
+
namespace art {
bool OatWriter::Create(File* file,
@@ -49,12 +52,15 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files,
image_file_location_checksum_ = image_file_location_checksum;
image_file_location_ = image_file_location;
dex_files_ = &dex_files;
+ elf_images_ = compiler_->GetElfImages();
oat_header_ = NULL;
executable_offset_padding_length_ = 0;
size_t offset = InitOatHeader();
offset = InitOatDexFiles(offset);
offset = InitDexFiles(offset);
+ offset = InitOatElfImages(offset);
+ offset = InitElfImages(offset);
offset = InitOatClasses(offset);
offset = InitOatCode(offset);
offset = InitOatCodeDexFiles(offset);
@@ -65,6 +71,7 @@ OatWriter::OatWriter(const std::vector<const DexFile*>& dex_files,
OatWriter::~OatWriter() {
delete oat_header_;
STLDeleteElements(&oat_dex_files_);
+ STLDeleteElements(&oat_elf_images_);
STLDeleteElements(&oat_classes_);
}
@@ -72,6 +79,7 @@ size_t OatWriter::InitOatHeader() {
// create the OatHeader
oat_header_ = new OatHeader(compiler_->GetInstructionSet(),
dex_files_,
+ elf_images_.size(),
image_file_location_checksum_,
image_file_location_);
size_t offset = sizeof(*oat_header_);
@@ -106,6 +114,29 @@ size_t OatWriter::InitDexFiles(size_t offset) {
return offset;
}
+size_t OatWriter::InitOatElfImages(size_t offset) {
+ // Offset to ELF image table should be rounded up to 4-byte aligned, so that
+ // we can read the uint32_t directly.
+ offset = RoundUp(offset, 4);
+ oat_header_->SetElfImageTableOffset(offset);
+
+ for (size_t i = 0, n = elf_images_.size(); i < n; ++i) {
+ OatElfImage* oat_elf_image = new OatElfImage(elf_images_[i]);
+ oat_elf_images_.push_back(oat_elf_image);
+ offset += oat_elf_image->SizeOf();
+ }
+ return offset;
+}
+
+size_t OatWriter::InitElfImages(size_t offset) {
+ for (size_t i = 0; i < oat_elf_images_.size(); ++i) {
+ offset = RoundUp(offset, 4);
+ oat_elf_images_[i]->SetElfOffset(offset);
+ offset += oat_elf_images_[i]->GetElfSize();
+ }
+ return offset;
+}
+
size_t OatWriter::InitOatClasses(size_t offset) {
// create the OatClasses
// calculate the offsets within OatDexFiles to OatClasses
@@ -424,6 +455,25 @@ bool OatWriter::WriteTables(File* file) {
return false;
}
}
+ for (size_t i = 0; i != oat_elf_images_.size(); ++i) {
+ if (!oat_elf_images_[i]->Write(file)) {
+ PLOG(ERROR) << "Failed to write oat elf information to " << file->name();
+ return false;
+ }
+ }
+ for (size_t i = 0; i != oat_elf_images_.size(); ++i) {
+ uint32_t expected_offset = oat_elf_images_[i]->GetElfOffset();
+ off_t actual_offset = lseek(file->Fd(), expected_offset, SEEK_SET);
+ if (static_cast<uint32_t>(actual_offset) != expected_offset) {
+ PLOG(ERROR) << "Failed to seek to dex file section."
+ << " Actual: " << actual_offset
+ << " Expected: " << expected_offset;
+ return false;
+ }
+ if (!oat_elf_images_[i]->WriteElfImage(file)) {
+ return false;
+ }
+ }
for (size_t i = 0; i != oat_classes_.size(); ++i) {
if (!oat_classes_[i]->Write(file)) {
PLOG(ERROR) << "Failed to write oat methods information to " << file->name();
@@ -772,4 +822,48 @@ bool OatWriter::OatClass::Write(File* file) const {
return true;
}
+OatWriter::OatElfImage::OatElfImage(const ElfImage& image)
+ : elf_offset_(0), elf_size_(image.size()), elf_addr_(image.begin()) {
+}
+
+size_t OatWriter::OatElfImage::SizeOf() const {
+ return (sizeof(elf_offset_) + sizeof(elf_size_));
+}
+
+uint32_t OatWriter::OatElfImage::GetElfSize() const {
+ return elf_size_;
+}
+
+uint32_t OatWriter::OatElfImage::GetElfOffset() const {
+ DCHECK_NE(elf_offset_, 0U);
+ return elf_offset_;
+}
+
+void OatWriter::OatElfImage::SetElfOffset(uint32_t offset) {
+ DCHECK_NE(offset, 0U);
+ DCHECK((offset & 0x3LU) == 0);
+ elf_offset_ = offset;
+}
+
+bool OatWriter::OatElfImage::Write(File* file) const {
+ DCHECK_NE(elf_offset_, 0U);
+ if (!file->WriteFully(&elf_offset_, sizeof(elf_offset_))) {
+ PLOG(ERROR) << "Failed to write ELF offset to " << file->name();
+ return false;
+ }
+ if (!file->WriteFully(&elf_size_, sizeof(elf_size_))) {
+ PLOG(ERROR) << "Failed to write ELF size to " << file->name();
+ return false;
+ }
+ return true;
+}
+
+bool OatWriter::OatElfImage::WriteElfImage(File* file) const {
+ if (!file->WriteFully(elf_addr_, elf_size_)) {
+ PLOG(ERROR) << "Failed to write ELF image to " << file->name();
+ return false;
+ }
+ return true;
+}
+
} // namespace art
diff --git a/src/oat_writer.h b/src/oat_writer.h
index c3a8ff6..e0d257f 100644
--- a/src/oat_writer.h
+++ b/src/oat_writer.h
@@ -48,6 +48,16 @@ namespace art {
// ...
// OatClass[C]
//
+// OatElfImage[0] one OatElfImage for each ELF image
+// OatElfImage[1] contains the size, checksum, and offset to the ELF image.
+// ...
+// OatElfImage[E]
+//
+// ELF[0]
+// ELF[1]
+// ...
+// ELF[E]
+//
// padding if necessary so that the following code will be page aligned
//
// CompiledMethod one variable sized blob with the contents of each CompiledMethod
@@ -82,6 +92,8 @@ class OatWriter {
size_t InitOatDexFiles(size_t offset);
size_t InitDexFiles(size_t offset);
size_t InitOatClasses(size_t offset);
+ size_t InitOatElfImages(size_t offset);
+ size_t InitElfImages(size_t offset);
size_t InitOatCode(size_t offset);
size_t InitOatCodeDexFiles(size_t offset);
size_t InitOatCodeDexFile(size_t offset,
@@ -143,6 +155,25 @@ class OatWriter {
DISALLOW_COPY_AND_ASSIGN(OatClass);
};
+ class OatElfImage {
+ public:
+ explicit OatElfImage(const ElfImage& elf_image);
+ size_t SizeOf() const;
+ uint32_t GetElfSize() const;
+ uint32_t GetElfOffset() const;
+ void SetElfOffset(uint32_t offset);
+ bool Write(File* file) const;
+ bool WriteElfImage(File* file) const;
+
+ private:
+ // data to write
+ uint32_t elf_offset_;
+ const uint32_t elf_size_;
+
+ const byte* const elf_addr_;
+ DISALLOW_COPY_AND_ASSIGN(OatElfImage);
+ };
+
const Compiler* compiler_;
// TODO: remove the ClassLoader when the code storage moves out of Method
@@ -151,6 +182,8 @@ class OatWriter {
// note OatFile does not take ownership of the DexFiles
const std::vector<const DexFile*>* dex_files_;
+ std::vector<ElfImage> elf_images_;
+
// dependency on the image
uint32_t image_file_location_checksum_;
std::string image_file_location_;
@@ -159,6 +192,7 @@ class OatWriter {
OatHeader* oat_header_;
std::vector<OatDexFile*> oat_dex_files_;
std::vector<OatClass*> oat_classes_;
+ std::vector<OatElfImage*> oat_elf_images_;
uint32_t executable_offset_padding_length_;
template <class T> struct MapCompare {