Merge art-cache dex files into oat files

Change-Id: I5a327a4e0b678bd9dabb12de4e21ef05e3fefd0b
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 472a20c..c37c7a6 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -54,12 +54,13 @@
     return false;
   }
 
-  UniquePtr<MemMap> map(MemMap::Map(requested_base,
-                                    file->Length(),
-                                    PROT_READ,
-                                    MAP_PRIVATE | ((requested_base != NULL) ? MAP_FIXED : 0),
-                                    file->Fd(),
-                                    0));
+  int flags = MAP_PRIVATE | ((requested_base != NULL) ? MAP_FIXED : 0);
+  UniquePtr<MemMap> map(MemMap::MapFileAtAddress(requested_base,
+                                                 file->Length(),
+                                                 PROT_READ,
+                                                 flags,
+                                                 file->Fd(),
+                                                 0));
   if (map.get() == NULL) {
     LOG(WARNING) << "Failed to map oat file " << filename;
     return false;
@@ -67,7 +68,7 @@
   CHECK(requested_base == 0 || requested_base == map->GetAddress()) << map->GetAddress();
   DCHECK_EQ(0, memcmp(&oat_header, map->GetAddress(), sizeof(OatHeader)));
 
-  off_t code_offset = oat_header.GetExecutableOffset();
+  off64_t code_offset = oat_header.GetExecutableOffset();
   if (code_offset < file->Length()) {
     byte* code_address = map->GetAddress() + code_offset;
     size_t code_length = file->Length() - code_offset;
@@ -98,6 +99,14 @@
     oat += sizeof(dex_file_checksum);
     CHECK_LT(oat, map->GetLimit());
 
+    uint32_t dex_file_offset = *reinterpret_cast<const uint32_t*>(oat);
+    CHECK_GT(dex_file_offset, 0U);
+    CHECK_LT(dex_file_offset, static_cast<uint32_t>(file->Length()));
+    oat += sizeof(dex_file_offset);
+    CHECK_LT(oat, map->GetLimit());
+
+    uint8_t* dex_file_pointer = map->GetAddress() + dex_file_offset;
+
     uint32_t classes_offset = *reinterpret_cast<const uint32_t*>(oat);
     CHECK_GT(classes_offset, 0U);
     CHECK_LT(classes_offset, static_cast<uint32_t>(file->Length()));
@@ -109,6 +118,7 @@
     oat_dex_files_[dex_file_location] = new OatDexFile(this,
                                                        dex_file_location,
                                                        dex_file_checksum,
+                                                       dex_file_pointer,
                                                        classes_pointer);
   }
 
@@ -153,14 +163,21 @@
 OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
                                 std::string dex_file_location,
                                 uint32_t dex_file_checksum,
+                                byte* dex_file_pointer,
                                 uint32_t* classes_pointer)
     : oat_file_(oat_file),
       dex_file_location_(dex_file_location),
       dex_file_checksum_(dex_file_checksum),
+      dex_file_pointer_(dex_file_pointer),
       classes_pointer_(classes_pointer) {}
 
 OatFile::OatDexFile::~OatDexFile() {}
 
+const DexFile* OatFile::OatDexFile::OpenDexFile() const {
+  size_t length = reinterpret_cast<const DexFile::Header*>(dex_file_pointer_)->file_size_;
+  return DexFile::Open(dex_file_pointer_, length, dex_file_location_);
+}
+
 const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
   uint32_t methods_offset = classes_pointer_[class_def_index];
   const byte* methods_pointer = oat_file_->GetBase() + methods_offset;