blob: 30f57d95a4bfdefa0109c62eb45d031471e6a0a4 [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
27namespace {
28
29static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_extend) {
30 uint64_t value = 0;
31 for (uint32_t i = 0; i <= length; i++) {
32 value |= static_cast<uint64_t>(*(*data)++) << (i * 8);
33 }
34 if (sign_extend) {
35 int shift = (7 - length) * 8;
36 return (static_cast<int64_t>(value) << shift) >> shift;
37 }
38 return value;
39}
40
41// Prototype to break cyclic dependency.
David Sehr72359222016-09-07 13:04:01 -070042void ReadArrayItemVariant(Header& header,
43 const uint8_t** data,
44 uint8_t type,
45 uint8_t length,
46 ArrayItem::ArrayItemVariant* item);
David Sehr853a8e12016-09-01 13:03:50 -070047
48ArrayItem* ReadArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length) {
49 ArrayItem* item = new ArrayItem(type);
David Sehr72359222016-09-07 13:04:01 -070050 ReadArrayItemVariant(header, data, type, length, item->GetArrayItemVariant());
David Sehr853a8e12016-09-01 13:03:50 -070051 return item;
52}
53
54ArrayItem* ReadArrayItem(Header& header, const uint8_t** data) {
55 const uint8_t encoded_value = *(*data)++;
56 const uint8_t type = encoded_value & 0x1f;
57 ArrayItem* item = new ArrayItem(type);
David Sehr72359222016-09-07 13:04:01 -070058 ReadArrayItemVariant(header, data, type, encoded_value >> 5, item->GetArrayItemVariant());
David Sehr853a8e12016-09-01 13:03:50 -070059 return item;
60}
61
David Sehr72359222016-09-07 13:04:01 -070062void ReadArrayItemVariant(Header& header,
63 const uint8_t** data,
64 uint8_t type,
65 uint8_t length,
66 ArrayItem::ArrayItemVariant* item) {
David Sehr853a8e12016-09-01 13:03:50 -070067 switch (type) {
68 case DexFile::kDexAnnotationByte:
David Sehr72359222016-09-07 13:04:01 -070069 item->u_.byte_val_ = static_cast<int8_t>(ReadVarWidth(data, length, false));
David Sehr853a8e12016-09-01 13:03:50 -070070 break;
71 case DexFile::kDexAnnotationShort:
David Sehr72359222016-09-07 13:04:01 -070072 item->u_.short_val_ = static_cast<int16_t>(ReadVarWidth(data, length, true));
David Sehr853a8e12016-09-01 13:03:50 -070073 break;
74 case DexFile::kDexAnnotationChar:
David Sehr72359222016-09-07 13:04:01 -070075 item->u_.char_val_ = static_cast<uint16_t>(ReadVarWidth(data, length, false));
David Sehr853a8e12016-09-01 13:03:50 -070076 break;
77 case DexFile::kDexAnnotationInt:
David Sehr72359222016-09-07 13:04:01 -070078 item->u_.int_val_ = static_cast<int32_t>(ReadVarWidth(data, length, true));
David Sehr853a8e12016-09-01 13:03:50 -070079 break;
80 case DexFile::kDexAnnotationLong:
David Sehr72359222016-09-07 13:04:01 -070081 item->u_.long_val_ = static_cast<int64_t>(ReadVarWidth(data, length, true));
David Sehr853a8e12016-09-01 13:03:50 -070082 break;
83 case DexFile::kDexAnnotationFloat: {
84 // Fill on right.
85 union {
86 float f;
87 uint32_t data;
88 } conv;
89 conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8;
David Sehr72359222016-09-07 13:04:01 -070090 item->u_.float_val_ = conv.f;
David Sehr853a8e12016-09-01 13:03:50 -070091 break;
92 }
93 case DexFile::kDexAnnotationDouble: {
94 // Fill on right.
95 union {
96 double d;
97 uint64_t data;
98 } conv;
99 conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8;
David Sehr72359222016-09-07 13:04:01 -0700100 item->u_.double_val_ = conv.d;
David Sehr853a8e12016-09-01 13:03:50 -0700101 break;
102 }
103 case DexFile::kDexAnnotationString: {
104 const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
David Sehr72359222016-09-07 13:04:01 -0700105 item->u_.string_val_ = header.StringIds()[string_index].get();
David Sehr853a8e12016-09-01 13:03:50 -0700106 break;
107 }
108 case DexFile::kDexAnnotationType: {
109 const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
David Sehr72359222016-09-07 13:04:01 -0700110 item->u_.string_val_ = header.TypeIds()[string_index]->GetStringId();
David Sehr853a8e12016-09-01 13:03:50 -0700111 break;
112 }
113 case DexFile::kDexAnnotationField:
114 case DexFile::kDexAnnotationEnum: {
115 const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
David Sehr72359222016-09-07 13:04:01 -0700116 item->u_.field_val_ = header.FieldIds()[field_index].get();
David Sehr853a8e12016-09-01 13:03:50 -0700117 break;
118 }
119 case DexFile::kDexAnnotationMethod: {
120 const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
David Sehr72359222016-09-07 13:04:01 -0700121 item->u_.method_val_ = header.MethodIds()[method_index].get();
David Sehr853a8e12016-09-01 13:03:50 -0700122 break;
123 }
124 case DexFile::kDexAnnotationArray: {
David Sehr72359222016-09-07 13:04:01 -0700125 item->annotation_array_val_.reset(new ArrayItemVector());
David Sehr853a8e12016-09-01 13:03:50 -0700126 // Decode all elements.
127 const uint32_t size = DecodeUnsignedLeb128(data);
128 for (uint32_t i = 0; i < size; i++) {
129 item->annotation_array_val_->push_back(
130 std::unique_ptr<ArrayItem>(ReadArrayItem(header, data)));
131 }
132 break;
133 }
134 case DexFile::kDexAnnotationAnnotation: {
135 const uint32_t type_idx = DecodeUnsignedLeb128(data);
136 item->annotation_annotation_val_.string_ = header.TypeIds()[type_idx]->GetStringId();
David Sehr72359222016-09-07 13:04:01 -0700137 item->annotation_annotation_val_.array_.reset(
138 new std::vector<std::unique_ptr<ArrayItem::NameValuePair>>());
David Sehr853a8e12016-09-01 13:03:50 -0700139 // Decode all name=value pairs.
140 const uint32_t size = DecodeUnsignedLeb128(data);
141 for (uint32_t i = 0; i < size; i++) {
142 const uint32_t name_index = DecodeUnsignedLeb128(data);
143 item->annotation_annotation_val_.array_->push_back(
144 std::unique_ptr<ArrayItem::NameValuePair>(
145 new ArrayItem::NameValuePair(header.StringIds()[name_index].get(),
146 ReadArrayItem(header, data))));
147 }
148 break;
149 }
150 case DexFile::kDexAnnotationNull:
151 break;
152 case DexFile::kDexAnnotationBoolean:
David Sehr72359222016-09-07 13:04:01 -0700153 item->u_.bool_val_ = (length != 0);
David Sehr853a8e12016-09-01 13:03:50 -0700154 break;
155 default:
156 break;
157 }
158}
159
160static bool GetPositionsCb(void* context, const DexFile::PositionInfo& entry) {
161 DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
162 PositionInfoVector& positions = debug_info->GetPositionInfo();
163 positions.push_back(std::unique_ptr<PositionInfo>(new PositionInfo(entry.address_, entry.line_)));
164 return false;
165}
166
167static void GetLocalsCb(void* context, const DexFile::LocalInfo& entry) {
168 DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
169 LocalInfoVector& locals = debug_info->GetLocalInfo();
170 const char* name = entry.name_ != nullptr ? entry.name_ : "(null)";
171 const char* signature = entry.signature_ != nullptr ? entry.signature_ : "";
172 locals.push_back(std::unique_ptr<LocalInfo>(
173 new LocalInfo(name, entry.descriptor_, signature, entry.start_address_,
174 entry.end_address_, entry.reg_)));
175}
176
177CodeItem* ReadCodeItem(const DexFile& dex_file,
178 const DexFile::CodeItem& disk_code_item,
179 Header& header) {
180 uint16_t registers_size = disk_code_item.registers_size_;
181 uint16_t ins_size = disk_code_item.ins_size_;
182 uint16_t outs_size = disk_code_item.outs_size_;
183 uint32_t tries_size = disk_code_item.tries_size_;
184
185 const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(&disk_code_item);
186 DebugInfoItem* debug_info = nullptr;
187 if (debug_info_stream != nullptr) {
188 debug_info = new DebugInfoItem();
189 }
190
191 uint32_t insns_size = disk_code_item.insns_size_in_code_units_;
192 uint16_t* insns = new uint16_t[insns_size];
193 memcpy(insns, disk_code_item.insns_, insns_size * sizeof(uint16_t));
194
195 TryItemVector* tries = nullptr;
196 if (tries_size > 0) {
197 tries = new TryItemVector();
198 for (uint32_t i = 0; i < tries_size; ++i) {
199 const DexFile::TryItem* disk_try_item = dex_file.GetTryItems(disk_code_item, i);
200 uint32_t start_addr = disk_try_item->start_addr_;
201 uint16_t insn_count = disk_try_item->insn_count_;
202 CatchHandlerVector* handlers = new CatchHandlerVector();
203 for (CatchHandlerIterator it(disk_code_item, *disk_try_item); it.HasNext(); it.Next()) {
204 const uint16_t type_index = it.GetHandlerTypeIndex();
205 const TypeId* type_id = header.GetTypeIdOrNullPtr(type_index);
206 handlers->push_back(std::unique_ptr<const CatchHandler>(
207 new CatchHandler(type_id, it.GetHandlerAddress())));
208 }
209 TryItem* try_item = new TryItem(start_addr, insn_count, handlers);
210 tries->push_back(std::unique_ptr<const TryItem>(try_item));
211 }
212 }
213 return new CodeItem(registers_size, ins_size, outs_size, debug_info, insns_size, insns, tries);
214}
215
216MethodItem* GenerateMethodItem(const DexFile& dex_file,
217 dex_ir::Header& header,
218 ClassDataItemIterator& cdii) {
219 MethodId* method_item = header.MethodIds()[cdii.GetMemberIndex()].get();
220 uint32_t access_flags = cdii.GetRawMemberAccessFlags();
221 const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
222 CodeItem* code_item = nullptr;
223 DebugInfoItem* debug_info = nullptr;
224 if (disk_code_item != nullptr) {
225 code_item = ReadCodeItem(dex_file, *disk_code_item, header);
226 code_item->SetOffset(cdii.GetMethodCodeItemOffset());
227 debug_info = code_item->DebugInfo();
228 }
229 if (debug_info != nullptr) {
230 bool is_static = (access_flags & kAccStatic) != 0;
231 dex_file.DecodeDebugLocalInfo(
232 disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info);
233 dex_file.DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info);
234 }
235 return new MethodItem(access_flags, method_item, code_item);
236}
237
238AnnotationSetItem* ReadAnnotationSetItem(const DexFile& dex_file,
239 const DexFile::AnnotationSetItem& disk_annotations_item,
240 Header& header) {
241 if (disk_annotations_item.size_ == 0) {
242 return nullptr;
243 }
244 AnnotationItemVector* items = new AnnotationItemVector();
245 for (uint32_t i = 0; i < disk_annotations_item.size_; ++i) {
246 const DexFile::AnnotationItem* annotation =
247 dex_file.GetAnnotationItem(&disk_annotations_item, i);
248 if (annotation == nullptr) {
249 continue;
250 }
251 uint8_t visibility = annotation->visibility_;
252 const uint8_t* annotation_data = annotation->annotation_;
253 ArrayItem* array_item =
254 ReadArrayItem(header, &annotation_data, DexFile::kDexAnnotationAnnotation, 0);
255 items->push_back(std::unique_ptr<AnnotationItem>(new AnnotationItem(visibility, array_item)));
256 }
257 return new AnnotationSetItem(items);
258}
259
260ParameterAnnotation* ReadParameterAnnotation(
261 const DexFile& dex_file,
262 MethodId* method_id,
263 const DexFile::AnnotationSetRefList* annotation_set_ref_list,
264 Header& header) {
265 AnnotationSetItemVector* annotations = new AnnotationSetItemVector();
266 for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) {
267 const DexFile::AnnotationSetItem* annotation_set_item =
268 dex_file.GetSetRefItemItem(&annotation_set_ref_list->list_[i]);
269 annotations->push_back(std::unique_ptr<AnnotationSetItem>(
270 ReadAnnotationSetItem(dex_file, *annotation_set_item, header)));
271 }
272 return new ParameterAnnotation(method_id, annotations);
273}
274
275AnnotationsDirectoryItem* ReadAnnotationsDirectoryItem(
276 const DexFile& dex_file,
277 const DexFile::AnnotationsDirectoryItem* disk_annotations_item,
278 Header& header) {
279 const DexFile::AnnotationSetItem* class_set_item =
280 dex_file.GetClassAnnotationSet(disk_annotations_item);
281 AnnotationSetItem* class_annotation = nullptr;
282 if (class_set_item != nullptr) {
283 class_annotation = ReadAnnotationSetItem(dex_file, *class_set_item, header);
284 }
285 const DexFile::FieldAnnotationsItem* fields =
286 dex_file.GetFieldAnnotations(disk_annotations_item);
287 FieldAnnotationVector* field_annotations = nullptr;
288 if (fields != nullptr) {
289 field_annotations = new FieldAnnotationVector();
290 for (uint32_t i = 0; i < disk_annotations_item->fields_size_; ++i) {
291 FieldId* field_id = header.FieldIds()[fields[i].field_idx_].get();
292 const DexFile::AnnotationSetItem* field_set_item =
293 dex_file.GetFieldAnnotationSetItem(fields[i]);
294 AnnotationSetItem* annotation_set_item =
295 ReadAnnotationSetItem(dex_file, *field_set_item, header);
296 field_annotations->push_back(std::unique_ptr<FieldAnnotation>(
297 new FieldAnnotation(field_id, annotation_set_item)));
298 }
299 }
300 const DexFile::MethodAnnotationsItem* methods =
301 dex_file.GetMethodAnnotations(disk_annotations_item);
302 MethodAnnotationVector* method_annotations = nullptr;
303 if (methods != nullptr) {
304 method_annotations = new MethodAnnotationVector();
305 for (uint32_t i = 0; i < disk_annotations_item->methods_size_; ++i) {
306 MethodId* method_id = header.MethodIds()[methods[i].method_idx_].get();
307 const DexFile::AnnotationSetItem* method_set_item =
308 dex_file.GetMethodAnnotationSetItem(methods[i]);
309 AnnotationSetItem* annotation_set_item =
310 ReadAnnotationSetItem(dex_file, *method_set_item, header);
311 method_annotations->push_back(std::unique_ptr<MethodAnnotation>(
312 new MethodAnnotation(method_id, annotation_set_item)));
313 }
314 }
315 const DexFile::ParameterAnnotationsItem* parameters =
316 dex_file.GetParameterAnnotations(disk_annotations_item);
317 ParameterAnnotationVector* parameter_annotations = nullptr;
318 if (parameters != nullptr) {
319 parameter_annotations = new ParameterAnnotationVector();
320 for (uint32_t i = 0; i < disk_annotations_item->parameters_size_; ++i) {
321 MethodId* method_id = header.MethodIds()[parameters[i].method_idx_].get();
322 const DexFile::AnnotationSetRefList* list =
323 dex_file.GetParameterAnnotationSetRefList(&parameters[i]);
324 parameter_annotations->push_back(std::unique_ptr<ParameterAnnotation>(
325 ReadParameterAnnotation(dex_file, method_id, list, header)));
326 }
327 }
328
329 return new AnnotationsDirectoryItem(class_annotation,
330 field_annotations,
331 method_annotations,
332 parameter_annotations);
333}
334
335ClassDef* ReadClassDef(const DexFile& dex_file,
336 const DexFile::ClassDef& disk_class_def,
337 Header& header) {
338 const TypeId* class_type = header.TypeIds()[disk_class_def.class_idx_].get();
339 uint32_t access_flags = disk_class_def.access_flags_;
340 const TypeId* superclass = header.GetTypeIdOrNullPtr(disk_class_def.superclass_idx_);
341
342 TypeIdVector* interfaces = nullptr;
343 const DexFile::TypeList* type_list = dex_file.GetInterfacesList(disk_class_def);
344 uint32_t interfaces_offset = disk_class_def.interfaces_off_;
345 if (type_list != nullptr) {
346 interfaces = new TypeIdVector();
347 for (uint32_t index = 0; index < type_list->Size(); ++index) {
348 interfaces->push_back(header.TypeIds()[type_list->GetTypeItem(index).type_idx_].get());
349 }
350 }
351 const StringId* source_file = header.GetStringIdOrNullPtr(disk_class_def.source_file_idx_);
352 // Annotations.
353 AnnotationsDirectoryItem* annotations = nullptr;
354 const DexFile::AnnotationsDirectoryItem* disk_annotations_directory_item =
355 dex_file.GetAnnotationsDirectory(disk_class_def);
356 if (disk_annotations_directory_item != nullptr) {
357 annotations = ReadAnnotationsDirectoryItem(dex_file, disk_annotations_directory_item, header);
358 annotations->SetOffset(disk_class_def.annotations_off_);
359 }
360 // Static field initializers.
361 ArrayItemVector* static_values = nullptr;
362 const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def);
363 if (static_data != nullptr) {
364 uint32_t static_value_count = static_data == nullptr ? 0 : DecodeUnsignedLeb128(&static_data);
365 if (static_value_count > 0) {
366 static_values = new ArrayItemVector();
367 for (uint32_t i = 0; i < static_value_count; ++i) {
368 static_values->push_back(std::unique_ptr<ArrayItem>(ReadArrayItem(header, &static_data)));
369 }
370 }
371 }
372 // Read the fields and methods defined by the class, resolving the circular reference from those
373 // to classes by setting class at the same time.
374 const uint8_t* encoded_data = dex_file.GetClassData(disk_class_def);
375 ClassData* class_data = nullptr;
376 if (encoded_data != nullptr) {
377 uint32_t offset = disk_class_def.class_data_off_;
378 ClassDataItemIterator cdii(dex_file, encoded_data);
379 // Static fields.
380 FieldItemVector* static_fields = new FieldItemVector();
381 for (uint32_t i = 0; cdii.HasNextStaticField(); i++, cdii.Next()) {
382 FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
383 uint32_t access_flags = cdii.GetRawMemberAccessFlags();
384 static_fields->push_back(std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
385 }
386 // Instance fields.
387 FieldItemVector* instance_fields = new FieldItemVector();
388 for (uint32_t i = 0; cdii.HasNextInstanceField(); i++, cdii.Next()) {
389 FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
390 uint32_t access_flags = cdii.GetRawMemberAccessFlags();
391 instance_fields->push_back(
392 std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
393 }
394 // Direct methods.
395 MethodItemVector* direct_methods = new MethodItemVector();
396 for (uint32_t i = 0; cdii.HasNextDirectMethod(); i++, cdii.Next()) {
397 direct_methods->push_back(
398 std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, header, cdii)));
399 }
400 // Virtual methods.
401 MethodItemVector* virtual_methods = new MethodItemVector();
402 for (uint32_t i = 0; cdii.HasNextVirtualMethod(); i++, cdii.Next()) {
403 virtual_methods->push_back(
404 std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, header, cdii)));
405 }
406 class_data = new ClassData(static_fields, instance_fields, direct_methods, virtual_methods);
407 class_data->SetOffset(offset);
408 }
409 return new ClassDef(class_type,
410 access_flags,
411 superclass,
412 interfaces,
413 interfaces_offset,
414 source_file,
415 annotations,
416 static_values,
417 class_data);
418}
419
420} // namespace
421
422Header* DexIrBuilder(const DexFile& dex_file) {
423 const DexFile::Header& disk_header = dex_file.GetHeader();
424 Header* header = new Header(disk_header.magic_,
425 disk_header.checksum_,
426 disk_header.signature_,
427 disk_header.endian_tag_,
428 disk_header.file_size_,
429 disk_header.header_size_,
430 disk_header.link_size_,
431 disk_header.link_off_,
432 disk_header.data_size_,
433 disk_header.data_off_);
434 // Walk the rest of the header fields.
435 // StringId table.
436 std::vector<std::unique_ptr<StringId>>& string_ids = header->StringIds();
437 header->SetStringIdsOffset(disk_header.string_ids_off_);
438 for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) {
439 const DexFile::StringId& disk_string_id = dex_file.GetStringId(i);
440 StringId* string_id = new StringId(dex_file.GetStringData(disk_string_id));
441 string_id->SetOffset(i);
442 string_ids.push_back(std::unique_ptr<StringId>(string_id));
443 }
444 // TypeId table.
445 std::vector<std::unique_ptr<TypeId>>& type_ids = header->TypeIds();
446 header->SetTypeIdsOffset(disk_header.type_ids_off_);
447 for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
448 const DexFile::TypeId& disk_type_id = dex_file.GetTypeId(i);
449 TypeId* type_id = new TypeId(header->StringIds()[disk_type_id.descriptor_idx_].get());
450 type_id->SetOffset(i);
451 type_ids.push_back(std::unique_ptr<TypeId>(type_id));
452 }
453 // ProtoId table.
454 std::vector<std::unique_ptr<ProtoId>>& proto_ids = header->ProtoIds();
455 header->SetProtoIdsOffset(disk_header.proto_ids_off_);
456 for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) {
457 const DexFile::ProtoId& disk_proto_id = dex_file.GetProtoId(i);
458 // Build the parameter type vector.
459 TypeIdVector* parameters = new TypeIdVector();
460 DexFileParameterIterator dfpi(dex_file, disk_proto_id);
461 while (dfpi.HasNext()) {
462 parameters->push_back(header->TypeIds()[dfpi.GetTypeIdx()].get());
463 dfpi.Next();
464 }
465 ProtoId* proto_id = new ProtoId(header->StringIds()[disk_proto_id.shorty_idx_].get(),
466 header->TypeIds()[disk_proto_id.return_type_idx_].get(),
467 parameters);
468 proto_id->SetOffset(i);
469 proto_ids.push_back(std::unique_ptr<ProtoId>(proto_id));
470 }
471 // FieldId table.
472 std::vector<std::unique_ptr<FieldId>>& field_ids = header->FieldIds();
473 header->SetFieldIdsOffset(disk_header.field_ids_off_);
474 for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) {
475 const DexFile::FieldId& disk_field_id = dex_file.GetFieldId(i);
476 FieldId* field_id = new FieldId(header->TypeIds()[disk_field_id.class_idx_].get(),
477 header->TypeIds()[disk_field_id.type_idx_].get(),
478 header->StringIds()[disk_field_id.name_idx_].get());
479 field_id->SetOffset(i);
480 field_ids.push_back(std::unique_ptr<FieldId>(field_id));
481 }
482 // MethodId table.
483 std::vector<std::unique_ptr<MethodId>>& method_ids = header->MethodIds();
484 header->SetMethodIdsOffset(disk_header.method_ids_off_);
485 for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) {
486 const DexFile::MethodId& disk_method_id = dex_file.GetMethodId(i);
487 MethodId* method_id = new MethodId(header->TypeIds()[disk_method_id.class_idx_].get(),
488 header->ProtoIds()[disk_method_id.proto_idx_].get(),
489 header->StringIds()[disk_method_id.name_idx_].get());
490 method_id->SetOffset(i);
491 method_ids.push_back(std::unique_ptr<MethodId>(method_id));
492 }
493 // ClassDef table.
494 std::vector<std::unique_ptr<ClassDef>>& class_defs = header->ClassDefs();
495 header->SetClassDefsOffset(disk_header.class_defs_off_);
496 for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) {
497 const DexFile::ClassDef& disk_class_def = dex_file.GetClassDef(i);
498 ClassDef* class_def = ReadClassDef(dex_file, disk_class_def, *header);
499 class_def->SetOffset(i);
500 class_defs.push_back(std::unique_ptr<ClassDef>(class_def));
501 }
502
503 return header;
504}
505
506} // namespace dex_ir
507} // namespace art