blob: d0c5bf964eb3f0fbb3690791fe898a5241ae2cc9 [file] [log] [blame]
David Sehr853a8e12016-09-01 13:03:50 -07001/*
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
24namespace art {
25namespace dex_ir {
26
David Sehrcdcfde72016-09-26 07:44:04 -070027static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections);
28
David Sehr853a8e12016-09-01 13:03:50 -070029Header* 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_);
Jeff Hao3ab96b42016-09-09 18:35:01 -070041 Collections& collections = header->GetCollections();
David Sehr853a8e12016-09-01 13:03:50 -070042 // Walk the rest of the header fields.
43 // StringId table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070044 collections.SetStringIdsOffset(disk_header.string_ids_off_);
David Sehr853a8e12016-09-01 13:03:50 -070045 for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070046 collections.CreateStringId(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070047 }
48 // TypeId table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070049 collections.SetTypeIdsOffset(disk_header.type_ids_off_);
David Sehr853a8e12016-09-01 13:03:50 -070050 for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070051 collections.CreateTypeId(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070052 }
53 // ProtoId table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070054 collections.SetProtoIdsOffset(disk_header.proto_ids_off_);
David Sehr853a8e12016-09-01 13:03:50 -070055 for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070056 collections.CreateProtoId(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070057 }
58 // FieldId table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070059 collections.SetFieldIdsOffset(disk_header.field_ids_off_);
David Sehr853a8e12016-09-01 13:03:50 -070060 for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070061 collections.CreateFieldId(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070062 }
63 // MethodId table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070064 collections.SetMethodIdsOffset(disk_header.method_ids_off_);
David Sehr853a8e12016-09-01 13:03:50 -070065 for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070066 collections.CreateMethodId(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070067 }
68 // ClassDef table.
Jeff Hao3ab96b42016-09-09 18:35:01 -070069 collections.SetClassDefsOffset(disk_header.class_defs_off_);
David Sehr853a8e12016-09-01 13:03:50 -070070 for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) {
Jeff Hao3ab96b42016-09-09 18:35:01 -070071 collections.CreateClassDef(dex_file, i);
David Sehr853a8e12016-09-01 13:03:50 -070072 }
Jeff Haoa8621002016-10-04 18:13:44 +000073 // MapItem.
Jeff Haoea7c6292016-11-14 18:10:16 -080074 collections.SetMapListOffset(disk_header.map_off_);
David Sehr853a8e12016-09-01 13:03:50 -070075
David Sehrcdcfde72016-09-26 07:44:04 -070076 CheckAndSetRemainingOffsets(dex_file, &collections);
77
David Sehr853a8e12016-09-01 13:03:50 -070078 return header;
79}
80
David Sehrcdcfde72016-09-26 07:44:04 -070081static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections) {
82 const DexFile::Header& disk_header = dex_file.GetHeader();
83 // Read MapItems and validate/set remaining offsets.
84 const DexFile::MapList* map =
85 reinterpret_cast<const DexFile::MapList*>(dex_file.Begin() + disk_header.map_off_);
86 const uint32_t count = map->size_;
87 for (uint32_t i = 0; i < count; ++i) {
88 const DexFile::MapItem* item = map->list_ + i;
89 switch (item->type_) {
90 case DexFile::kDexTypeHeaderItem:
91 CHECK_EQ(item->size_, 1u);
92 CHECK_EQ(item->offset_, 0u);
93 break;
94 case DexFile::kDexTypeStringIdItem:
95 CHECK_EQ(item->size_, collections->StringIdsSize());
96 CHECK_EQ(item->offset_, collections->StringIdsOffset());
97 break;
98 case DexFile::kDexTypeTypeIdItem:
99 CHECK_EQ(item->size_, collections->TypeIdsSize());
100 CHECK_EQ(item->offset_, collections->TypeIdsOffset());
101 break;
102 case DexFile::kDexTypeProtoIdItem:
103 CHECK_EQ(item->size_, collections->ProtoIdsSize());
104 CHECK_EQ(item->offset_, collections->ProtoIdsOffset());
105 break;
106 case DexFile::kDexTypeFieldIdItem:
107 CHECK_EQ(item->size_, collections->FieldIdsSize());
108 CHECK_EQ(item->offset_, collections->FieldIdsOffset());
109 break;
110 case DexFile::kDexTypeMethodIdItem:
111 CHECK_EQ(item->size_, collections->MethodIdsSize());
112 CHECK_EQ(item->offset_, collections->MethodIdsOffset());
113 break;
114 case DexFile::kDexTypeClassDefItem:
115 CHECK_EQ(item->size_, collections->ClassDefsSize());
116 CHECK_EQ(item->offset_, collections->ClassDefsOffset());
117 break;
118 case DexFile::kDexTypeMapList:
119 CHECK_EQ(item->size_, 1u);
120 CHECK_EQ(item->offset_, disk_header.map_off_);
121 break;
122 case DexFile::kDexTypeTypeList:
123 collections->SetTypeListsOffset(item->offset_);
124 break;
125 case DexFile::kDexTypeAnnotationSetRefList:
126 collections->SetAnnotationSetRefListsOffset(item->offset_);
127 break;
128 case DexFile::kDexTypeAnnotationSetItem:
Jeff Haoa8621002016-10-04 18:13:44 +0000129 collections->SetAnnotationSetItemsOffset(item->offset_);
David Sehrcdcfde72016-09-26 07:44:04 -0700130 break;
131 case DexFile::kDexTypeClassDataItem:
132 collections->SetClassDatasOffset(item->offset_);
133 break;
134 case DexFile::kDexTypeCodeItem:
135 collections->SetCodeItemsOffset(item->offset_);
136 break;
137 case DexFile::kDexTypeStringDataItem:
138 collections->SetStringDatasOffset(item->offset_);
139 break;
140 case DexFile::kDexTypeDebugInfoItem:
Jeff Haoa8621002016-10-04 18:13:44 +0000141 collections->SetDebugInfoItemsOffset(item->offset_);
David Sehrcdcfde72016-09-26 07:44:04 -0700142 break;
143 case DexFile::kDexTypeAnnotationItem:
Jeff Haoa8621002016-10-04 18:13:44 +0000144 collections->SetAnnotationItemsOffset(item->offset_);
David Sehrcdcfde72016-09-26 07:44:04 -0700145 break;
146 case DexFile::kDexTypeEncodedArrayItem:
Jeff Haoa8621002016-10-04 18:13:44 +0000147 collections->SetEncodedArrayItemsOffset(item->offset_);
David Sehrcdcfde72016-09-26 07:44:04 -0700148 break;
149 case DexFile::kDexTypeAnnotationsDirectoryItem:
Jeff Haoa8621002016-10-04 18:13:44 +0000150 collections->SetAnnotationsDirectoryItemsOffset(item->offset_);
David Sehrcdcfde72016-09-26 07:44:04 -0700151 break;
152 default:
153 LOG(ERROR) << "Unknown map list item type.";
154 }
155 }
156}
157
David Sehr853a8e12016-09-01 13:03:50 -0700158} // namespace dex_ir
159} // namespace art