Home | History | Annotate | Download | only in dexlayout
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  *
     16  * Header file of an in-memory representation of DEX files.
     17  */
     18 
     19 #include <stdint.h>
     20 #include <vector>
     21 
     22 #include "dex_ir_builder.h"
     23 
     24 namespace art {
     25 namespace dex_ir {
     26 
     27 static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections);
     28 
     29 Header* DexIrBuilder(const DexFile& dex_file) {
     30   const DexFile::Header& disk_header = dex_file.GetHeader();
     31   Header* header = new Header(disk_header.magic_,
     32                               disk_header.checksum_,
     33                               disk_header.signature_,
     34                               disk_header.endian_tag_,
     35                               disk_header.file_size_,
     36                               disk_header.header_size_,
     37                               disk_header.link_size_,
     38                               disk_header.link_off_,
     39                               disk_header.data_size_,
     40                               disk_header.data_off_);
     41   Collections& collections = header->GetCollections();
     42   // Walk the rest of the header fields.
     43   // StringId table.
     44   collections.SetStringIdsOffset(disk_header.string_ids_off_);
     45   for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) {
     46     collections.CreateStringId(dex_file, i);
     47   }
     48   // TypeId table.
     49   collections.SetTypeIdsOffset(disk_header.type_ids_off_);
     50   for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
     51     collections.CreateTypeId(dex_file, i);
     52   }
     53   // ProtoId table.
     54   collections.SetProtoIdsOffset(disk_header.proto_ids_off_);
     55   for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) {
     56     collections.CreateProtoId(dex_file, i);
     57   }
     58   // FieldId table.
     59   collections.SetFieldIdsOffset(disk_header.field_ids_off_);
     60   for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) {
     61     collections.CreateFieldId(dex_file, i);
     62   }
     63   // MethodId table.
     64   collections.SetMethodIdsOffset(disk_header.method_ids_off_);
     65   for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) {
     66     collections.CreateMethodId(dex_file, i);
     67   }
     68   // ClassDef table.
     69   collections.SetClassDefsOffset(disk_header.class_defs_off_);
     70   for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) {
     71     collections.CreateClassDef(dex_file, i);
     72   }
     73   // MapItem.
     74   collections.SetMapListOffset(disk_header.map_off_);
     75   // CallSiteIds and MethodHandleItems.
     76   collections.CreateCallSitesAndMethodHandles(dex_file);
     77 
     78   CheckAndSetRemainingOffsets(dex_file, &collections);
     79 
     80   return header;
     81 }
     82 
     83 static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections) {
     84   const DexFile::Header& disk_header = dex_file.GetHeader();
     85   // Read MapItems and validate/set remaining offsets.
     86   const DexFile::MapList* map =
     87       reinterpret_cast<const DexFile::MapList*>(dex_file.Begin() + disk_header.map_off_);
     88   const uint32_t count = map->size_;
     89   for (uint32_t i = 0; i < count; ++i) {
     90     const DexFile::MapItem* item = map->list_ + i;
     91     switch (item->type_) {
     92       case DexFile::kDexTypeHeaderItem:
     93         CHECK_EQ(item->size_, 1u);
     94         CHECK_EQ(item->offset_, 0u);
     95         break;
     96       case DexFile::kDexTypeStringIdItem:
     97         CHECK_EQ(item->size_, collections->StringIdsSize());
     98         CHECK_EQ(item->offset_, collections->StringIdsOffset());
     99         break;
    100       case DexFile::kDexTypeTypeIdItem:
    101         CHECK_EQ(item->size_, collections->TypeIdsSize());
    102         CHECK_EQ(item->offset_, collections->TypeIdsOffset());
    103         break;
    104       case DexFile::kDexTypeProtoIdItem:
    105         CHECK_EQ(item->size_, collections->ProtoIdsSize());
    106         CHECK_EQ(item->offset_, collections->ProtoIdsOffset());
    107         break;
    108       case DexFile::kDexTypeFieldIdItem:
    109         CHECK_EQ(item->size_, collections->FieldIdsSize());
    110         CHECK_EQ(item->offset_, collections->FieldIdsOffset());
    111         break;
    112       case DexFile::kDexTypeMethodIdItem:
    113         CHECK_EQ(item->size_, collections->MethodIdsSize());
    114         CHECK_EQ(item->offset_, collections->MethodIdsOffset());
    115         break;
    116       case DexFile::kDexTypeClassDefItem:
    117         CHECK_EQ(item->size_, collections->ClassDefsSize());
    118         CHECK_EQ(item->offset_, collections->ClassDefsOffset());
    119         break;
    120       case DexFile::kDexTypeCallSiteIdItem:
    121         CHECK_EQ(item->size_, collections->CallSiteIdsSize());
    122         CHECK_EQ(item->offset_, collections->CallSiteIdsOffset());
    123         break;
    124       case DexFile::kDexTypeMethodHandleItem:
    125         CHECK_EQ(item->size_, collections->MethodHandleItemsSize());
    126         CHECK_EQ(item->offset_, collections->MethodHandleItemsOffset());
    127         break;
    128       case DexFile::kDexTypeMapList:
    129         CHECK_EQ(item->size_, 1u);
    130         CHECK_EQ(item->offset_, disk_header.map_off_);
    131         break;
    132       case DexFile::kDexTypeTypeList:
    133         collections->SetTypeListsOffset(item->offset_);
    134         break;
    135       case DexFile::kDexTypeAnnotationSetRefList:
    136         collections->SetAnnotationSetRefListsOffset(item->offset_);
    137         break;
    138       case DexFile::kDexTypeAnnotationSetItem:
    139         collections->SetAnnotationSetItemsOffset(item->offset_);
    140         break;
    141       case DexFile::kDexTypeClassDataItem:
    142         collections->SetClassDatasOffset(item->offset_);
    143         break;
    144       case DexFile::kDexTypeCodeItem:
    145         collections->SetCodeItemsOffset(item->offset_);
    146         break;
    147       case DexFile::kDexTypeStringDataItem:
    148         collections->SetStringDatasOffset(item->offset_);
    149         break;
    150       case DexFile::kDexTypeDebugInfoItem:
    151         collections->SetDebugInfoItemsOffset(item->offset_);
    152         break;
    153       case DexFile::kDexTypeAnnotationItem:
    154         collections->SetAnnotationItemsOffset(item->offset_);
    155         break;
    156       case DexFile::kDexTypeEncodedArrayItem:
    157         collections->SetEncodedArrayItemsOffset(item->offset_);
    158         break;
    159       case DexFile::kDexTypeAnnotationsDirectoryItem:
    160         collections->SetAnnotationsDirectoryItemsOffset(item->offset_);
    161         break;
    162       default:
    163         LOG(ERROR) << "Unknown map list item type.";
    164     }
    165   }
    166 }
    167 
    168 }  // namespace dex_ir
    169 }  // namespace art
    170