summaryrefslogtreecommitdiff
path: root/runtime/oat_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/oat_file.cc')
-rw-r--r--runtime/oat_file.cc44
1 files changed, 43 insertions, 1 deletions
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 31eb1ccdc8..528eddc306 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -273,6 +273,36 @@ inline static bool ReadOatDexFileData(const OatFile& oat_file,
return true;
}
+static bool FindDexFileMapItem(const uint8_t* dex_begin,
+ const uint8_t* dex_end,
+ DexFile::MapItemType map_item_type,
+ const DexFile::MapItem** result_item) {
+ *result_item = nullptr;
+
+ const DexFile::Header* header =
+ BoundsCheckedCast<const DexFile::Header*>(dex_begin, dex_begin, dex_end);
+ if (nullptr == header) return false;
+
+ if (!DexFile::IsMagicValid(header->magic_)) return true; // Not a dex file, not an error.
+
+ const DexFile::MapList* map_list =
+ BoundsCheckedCast<const DexFile::MapList*>(dex_begin + header->map_off_, dex_begin, dex_end);
+ if (nullptr == map_list) return false;
+
+ const DexFile::MapItem* map_item = map_list->list_;
+ size_t count = map_list->size_;
+ while (count--) {
+ if (map_item->type_ == static_cast<uint16_t>(map_item_type)) {
+ *result_item = map_item;
+ break;
+ }
+ map_item = BoundsCheckedCast<const DexFile::MapItem*>(map_item + 1, dex_begin, dex_end);
+ if (nullptr == map_item) return false;
+ }
+
+ return true;
+}
+
bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {
if (!GetOatHeader().IsValid()) {
std::string cause = GetOatHeader().GetValidationErrorMessage();
@@ -501,7 +531,19 @@ bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {
uint8_t* current_dex_cache_arrays = nullptr;
if (dex_cache_arrays != nullptr) {
- DexCacheArraysLayout layout(pointer_size, *header);
+ // All DexCache types except for CallSite have their instance counts in the
+ // DexFile header. For CallSites, we need to read the info from the MapList.
+ const DexFile::MapItem* call_sites_item = nullptr;
+ if (!FindDexFileMapItem(DexBegin(),
+ DexEnd(),
+ DexFile::MapItemType::kDexTypeCallSiteIdItem,
+ &call_sites_item)) {
+ *error_msg = StringPrintf("In oat file '%s' could not read data from truncated DexFile map",
+ GetLocation().c_str());
+ return false;
+ }
+ size_t num_call_sites = call_sites_item == nullptr ? 0 : call_sites_item->size_;
+ DexCacheArraysLayout layout(pointer_size, *header, num_call_sites);
if (layout.Size() != 0u) {
if (static_cast<size_t>(dex_cache_arrays_end - dex_cache_arrays) < layout.Size()) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with "