Lines Matching +full:use +full:- +full:base +full:- +full:image
2 // Use of this source code is governed by a BSD-style license that can be
18 #include "base/bind.h"
19 #include "base/callback.h"
20 #include "base/logging.h"
21 #include "base/numerics/checked_math.h"
22 #include "base/numerics/safe_conversions.h"
23 #include "base/strings/stringprintf.h"
45 // wrecks havoc for base::checked_cast<int16_t>().
54 // - For fixed-length items (e.g., kTypeFieldIdItem) this is the exact size.
55 // - For variant-length items (e.g., kTypeCodeItem), returns a value that is
57 // - For items not handled by this function, returns 1 for sanity check.
78 return sizeof(uint32_t); // Variable-length. in GetItemBaseSize()
80 return sizeof(uint32_t); // Variable-length. in GetItemBaseSize()
82 return sizeof(uint32_t); // Variable-length. in GetItemBaseSize()
84 return sizeof(dex::CodeItem); // Variable-length. in GetItemBaseSize()
86 return sizeof(dex::AnnotationsDirectoryItem); // Variable-length. in GetItemBaseSize()
94 // A parser to extract successive code items from a DEX image whose header has
100 explicit CodeItemParser(ConstBufferView image) : image_(image) {} in CodeItemParser() argument
115 // Extracts the header of the next code item, and skips the variable-length
118 // here's a pseudo-struct of a complete code item:
121 // // 4-byte aligned here.
122 // // 16-byte header defined (dex::CodeItem).
130 // // Variable-length data follow.
135 // // 4-byte aligned here.
157 // // Padding to 4-bytes align next code_item *only if more exist*.
164 base::checked_cast<offset_t>(source_.begin() - image_.begin()); in GetNext()
170 // TODO(huangs): Fail if |code_item->insns_size == 0| (Constraint A1). in GetNext()
172 if (!source_.GetArray<uint16_t>(code_item->insns_size)) in GetNext()
175 if (code_item->tries_size > 0 && !source_.AlignOn(image_, 4U)) in GetNext()
179 // is nontrivial due to use of uleb128 / sleb128. in GetNext()
180 if (code_item->tries_size > 0) { in GetNext()
182 if (!source_.GetArray<dex::TryItem>(code_item->tries_size)) in GetNext()
213 // Success! |code_item->insns_size| is validated, but its content is still in GetNext()
219 // |image|, returns |insns| bytes as ConstBufferView.
220 static ConstBufferView GetCodeItemInsns(ConstBufferView image, in GetCodeItemInsns() argument
222 BufferSource source(BufferSource(image).Skip(code_item_offset)); in GetCodeItemInsns()
225 BufferRegion insns{0, code_item->insns_size * kInstrUnitSize}; in GetCodeItemInsns()
239 // store instructions followed by optional non-instruction "payload". Finding
250 // is unknown. An internal initialize-on-first-use table is used for fast
269 InstructionParser(ConstBufferView image, offset_t base_offset) in InstructionParser() argument
270 : image_begin_(image.begin()), in InstructionParser()
271 insns_(CodeItemParser::GetCodeItemInsns(image, base_offset)), in InstructionParser()
282 base::checked_cast<offset_t>(insns_.begin() - image_begin_); in ReadNext()
293 const int instr_length_units = instr->layout; in ReadNext()
298 // Handle instructions with variable-length data payload (31t). in ReadNext()
299 if (instr->opcode == 0x26 || // fill-array-data in ReadNext()
300 instr->opcode == 0x2B || // packed-switch in ReadNext()
301 instr->opcode == 0x2C) { // sparse-switch in ReadNext()
342 base::RepeatingCallback<offset_t(const InstructionParser::Value&)>;
345 using Mapper = base::RepeatingCallback<offset_t(offset_t)>;
347 InstructionReferenceReader(ConstBufferView image, in InstructionReferenceReader() argument
353 : image_(image), in InstructionReferenceReader()
360 // Use binary search to find the code item that contains |lo_|. in InstructionReferenceReader()
366 --cur_it_; in InstructionReferenceReader()
412 // A class to visit fixed-size item elements (determined by |item_size|) and
419 using Mapper = base::RepeatingCallback<offset_t(offset_t)>;
421 // |item_size| is the size of a fixed-size item. |rel_location| is the
423 // |rel_item_offset| is the offset to use relative to |item_offset| in cases
434 item_base_offset_(base::checked_cast<offset_t>(map_item.offset)), in ItemReferenceReader()
435 num_items_(base::checked_cast<uint32_t>(map_item.size)), in ItemReferenceReader()
436 item_size_(base::checked_cast<uint32_t>(item_size)), in ItemReferenceReader()
437 rel_location_(base::checked_cast<uint32_t>(rel_location)), in ItemReferenceReader()
439 mapper_wants_item ? 0 : base::checked_cast<uint32_t>(rel_location)), in ItemReferenceReader()
451 cur_idx_ = (lo - item_base_offset_) / item_size_; in ItemReferenceReader()
452 // Fine-tune: Advance if |lo| lies beyond the MVI. in ItemReferenceReader()
477 // - ProtoIdItem: parameters_off. in GetNext()
478 // - ClassDefItem: interfaces_off, annotations_off, class_data_off, in GetNext()
480 // - AnnotationsDirectoryItem: class_annotations_off. in GetNext()
481 // - AnnotationSetRefItem: annotations_off. in GetNext()
483 // - ClassDefItem: superclass_idx, source_file_idx. in GetNext()
484 // - MethodHandleItem: |mapper_| uses ReadMethodHandleFieldOrMethodId and in GetNext()
504 return base::checked_cast<uint32_t>(item_base_offset_ + idx * item_size_); in OffsetOfIndex()
519 // where |N| is an uint32_t representing the number of items in each sub-list,
520 // and "T" is a fixed-size item (|item_width|) of type "T". On success, stores
523 bool ParseItemOffsets(ConstBufferView image, in ParseItemOffsets() argument
527 // Sanity check: |image| should at least fit |map_item.size| copies of "N". in ParseItemOffsets()
528 if (!image.covers_array(map_item.offset, map_item.size, sizeof(uint32_t))) in ParseItemOffsets()
530 BufferSource source = std::move(BufferSource(image).Skip(map_item.offset)); in ParseItemOffsets()
531 item_offsets->clear(); in ParseItemOffsets()
533 if (!source.AlignOn(image, 4U)) in ParseItemOffsets()
539 base::checked_cast<offset_t>(source.begin() - image.begin()))); in ParseItemOffsets()
543 item_offsets->push_back( in ParseItemOffsets()
544 base::checked_cast<offset_t>(source.begin() - image.begin())); in ParseItemOffsets()
561 ConstBufferView image, in ParseAnnotationsDirectoryItems() argument
567 // Sanity check: |image| should at least fit in ParseAnnotationsDirectoryItems()
569 if (!image.covers_array(annotations_directory_map_item.offset, in ParseAnnotationsDirectoryItems()
575 BufferSource(image).Skip(annotations_directory_map_item.offset)); in ParseAnnotationsDirectoryItems()
576 annotations_directory_item_offsets->clear(); in ParseAnnotationsDirectoryItems()
577 field_annotation_offsets->clear(); in ParseAnnotationsDirectoryItems()
578 method_annotation_offsets->clear(); in ParseAnnotationsDirectoryItems()
579 parameter_annotation_offsets->clear(); in ParseAnnotationsDirectoryItems()
582 auto parse_list = [&source, image](uint32_t unsafe_size, size_t item_width, in ParseAnnotationsDirectoryItems()
585 base::checked_cast<offset_t>(source.begin() - image.begin()))); in ParseAnnotationsDirectoryItems()
588 item_offsets->reserve(item_offsets->size() + unsafe_size); in ParseAnnotationsDirectoryItems()
590 item_offsets->push_back( in ParseAnnotationsDirectoryItems()
591 base::checked_cast<offset_t>(source.begin() - image.begin())); in ParseAnnotationsDirectoryItems()
597 annotations_directory_item_offsets->reserve( in ParseAnnotationsDirectoryItems()
600 if (!source.AlignOn(image, 4U)) in ParseAnnotationsDirectoryItems()
603 annotations_directory_item_offsets->push_back( in ParseAnnotationsDirectoryItems()
604 base::checked_cast<offset_t>(source.begin() - image.begin())); in ParseAnnotationsDirectoryItems()
634 using Mapper = base::RepeatingCallback<offset_t(offset_t)>;
648 if (cur_it_ != item_offsets.begin() && *(cur_it_ - 1) + rel_location_ >= lo) in CachedItemListReferenceReader()
649 --cur_it_; in CachedItemListReferenceReader()
669 // - AnnotationsDirectoryItem: class_annotations_off in GetNext()
685 // Reads an INT index at |location| in |image| and translates the index to the
686 // offset of a fixed-size item specified by |target_map_item| and
692 static offset_t ReadTargetIndex(ConstBufferView image, in ReadTargetIndex() argument
698 const offset_t unsafe_idx = image.read<INT>(location); in ReadTargetIndex()
700 // - ClassDefItem: superclass_idx, source_file_idx. in ReadTargetIndex()
706 base::checked_cast<offset_t>(unsafe_idx * target_item_size); in ReadTargetIndex()
710 // in |image| and translates |method_handle_item.field_or_method_id| to the
711 // offset of a fixed-size item specified by |target_map_item| and
723 ConstBufferView image, in ReadMethodHandleFieldOrMethodId() argument
730 image.read<dex::MethodHandleItem>(location); in ReadMethodHandleFieldOrMethodId()
732 // Cannot use base::checked_cast as dex::MethodHandleType is an enum class so in ReadMethodHandleFieldOrMethodId()
745 // Use DexSentinelIndexAsOffset to skip the item as it isn't of the in ReadMethodHandleFieldOrMethodId()
752 image, target_map_item, target_item_size, in ReadMethodHandleFieldOrMethodId()
756 // Reads uint32_t value in |image| at (valid) |location| and checks whether it
757 // is a safe offset of a fixed-size item. Returns the target offset (possibly a
761 static offset_t ReadTargetOffset32(ConstBufferView image, offset_t location) { in ReadTargetOffset32() argument
763 static_cast<offset_t>(image.read<uint32_t>(location)); in ReadTargetOffset32()
771 if (unsafe_target >= image.size()) in ReadTargetOffset32()
778 // A ReferenceWriter that adapts a callback that performs type-specific
782 using Writer = base::RepeatingCallback<void(Reference, MutableBufferView)>;
784 ReferenceWriterAdaptor(MutableBufferView image, Writer&& writer) in ReferenceWriterAdaptor() argument
785 : image_(image), writer_(std::move(writer)) {} in ReferenceWriterAdaptor()
803 MutableBufferView image) { in WriteTargetIndex() argument
805 (ref.target - target_map_item.offset) / target_item_size; in WriteTargetIndex()
814 image.write<INT>(ref.location, base::checked_cast<INT>(unsafe_idx)); in WriteTargetIndex()
824 // Returns whether |image| points to a DEX file. If this is a possibility and
827 bool ReadDexHeader(ConstBufferView image, ReadDexHeaderResults* opt_results) { in ReadDexHeader() argument
829 BufferSource source(image); in ReadDexHeader()
833 if (header->magic[0] != 'd' || header->magic[1] != 'e' || in ReadDexHeader()
834 header->magic[2] != 'x' || header->magic[3] != '\n' || in ReadDexHeader()
835 header->magic[7] != '\0') { in ReadDexHeader()
842 if (!isdigit(header->magic[i])) in ReadDexHeader()
844 dex_version = dex_version * 10 + (header->magic[i] - '0'); in ReadDexHeader()
853 if (header->file_size > image.size() || in ReadDexHeader()
854 header->file_size < sizeof(dex::HeaderItem) || in ReadDexHeader()
855 header->map_off < sizeof(dex::HeaderItem)) { in ReadDexHeader()
873 bool DisassemblerDex::QuickDetect(ConstBufferView image) { in QuickDetect() argument
874 return ReadDexHeader(image, nullptr); in QuickDetect()
882 return base::StringPrintf("DEX (version %d)", dex_version_); in GetExeTypeString()
886 // Must follow DisassemblerDex::ReferenceType order. Initialized on first use. in MakeReferenceGroups()
1030 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadStringIdToStringData()
1039 auto mapper = base::BindRepeating( in MakeReadTypeIdToDescriptorStringId32()
1049 auto mapper = base::BindRepeating( in MakeReadProtoIdToShortyStringId32()
1059 auto mapper = base::BindRepeating( in MakeReadProtoIdToReturnTypeId32()
1070 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadProtoIdToParametersTypeList()
1079 auto mapper = base::BindRepeating( in MakeReadFieldToClassTypeId16()
1091 base::BindRepeating(ReadTargetIndex<decltype(dex::FieldIdItem::type_idx)>, in MakeReadFieldToTypeId16()
1102 base::BindRepeating(ReadTargetIndex<decltype(dex::FieldIdItem::name_idx)>, in MakeReadFieldToNameStringId32()
1111 auto mapper = base::BindRepeating( in MakeReadMethodIdToClassTypeId16()
1122 auto mapper = base::BindRepeating( in MakeReadMethodIdToProtoId16()
1132 auto mapper = base::BindRepeating( in MakeReadMethodIdToNameStringId32()
1142 auto mapper = base::BindRepeating( in MakeReadClassDefToClassTypeId32()
1153 auto mapper = base::BindRepeating( in MakeReadClassDefToSuperClassTypeId32()
1165 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadClassDefToInterfacesTypeList()
1174 auto mapper = base::BindRepeating( in MakeReadClassDefToSourceFileStringId32()
1186 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadClassDefToAnnotationDirectory()
1196 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadClassDefToClassData()
1206 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadClassDefToStaticValuesEncodedArray()
1214 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadCallSiteIdToCallSite32()
1222 auto mapper = base::BindRepeating(ReadMethodHandleFieldOrMethodId, image_, in MakeReadMethodHandleToFieldId16()
1226 // Use |mapper_wants_item == true| for ItemReferenceReader such that in MakeReadMethodHandleToFieldId16()
1238 auto mapper = base::BindRepeating(ReadMethodHandleFieldOrMethodId, image_, in MakeReadMethodHandleToMethodId16()
1242 // Use |mapper_wants_item == true| for ItemReferenceReader such that in MakeReadMethodHandleToMethodId16()
1256 base::BindRepeating(ReadTargetIndex<decltype(dex::TypeItem::type_idx)>, in MakeReadTypeListToTypeId16()
1266 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationSetToAnnotation()
1276 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationSetRefListToAnnotationSet()
1286 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationsDirectoryToClassAnnotationSet()
1295 auto mapper = base::BindRepeating( in MakeReadAnnotationsDirectoryToFieldId32()
1307 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationsDirectoryToFieldAnnotationSet()
1316 auto mapper = base::BindRepeating( in MakeReadAnnotationsDirectoryToMethodId32()
1329 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationsDirectoryToMethodAnnotationSet()
1339 auto mapper = base::BindRepeating( in MakeReadAnnotationsDirectoryToParameterMethodId32()
1353 auto mapper = base::BindRepeating(ReadTargetOffset32, image_); in MakeReadAnnotationsDirectoryToParameterAnnotationSetRef()
1360 // MakeReadCode* readers use offset relative to the instruction beginning based
1362 // See https://source.android.com/devices/tech/dalvik/instruction-formats
1367 auto filter = base::BindRepeating( in MakeReadCodeToStringId16()
1368 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToStringId16()
1369 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToStringId16()
1370 (value.instr->opcode == 0x1A)) { // const-string in MakeReadCodeToStringId16()
1371 // BBBB from e.g., const-string vAA, string@BBBB. in MakeReadCodeToStringId16()
1377 base::BindRepeating(ReadTargetIndex<uint16_t>, image_, string_map_item_, in MakeReadCodeToStringId16()
1386 auto filter = base::BindRepeating( in MakeReadCodeToStringId32()
1387 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToStringId32()
1388 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToStringId32()
1389 (value.instr->opcode == 0x1B)) { // const-string/jumbo in MakeReadCodeToStringId32()
1390 // BBBBBBBB from e.g., const-string/jumbo vAA, string@BBBBBBBB. in MakeReadCodeToStringId32()
1396 base::BindRepeating(ReadTargetIndex<uint32_t>, image_, string_map_item_, in MakeReadCodeToStringId32()
1405 auto filter = base::BindRepeating( in MakeReadCodeToTypeId16()
1406 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToTypeId16()
1407 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToTypeId16()
1408 (value.instr->opcode == 0x1C || // const-class in MakeReadCodeToTypeId16()
1409 value.instr->opcode == 0x1F || // check-cast in MakeReadCodeToTypeId16()
1410 value.instr->opcode == 0x20 || // instance-of in MakeReadCodeToTypeId16()
1411 value.instr->opcode == 0x22 || // new-instance in MakeReadCodeToTypeId16()
1412 value.instr->opcode == 0x23 || // new-array in MakeReadCodeToTypeId16()
1413 value.instr->opcode == 0x24 || // filled-new-array in MakeReadCodeToTypeId16()
1414 value.instr->opcode == 0x25)) { // filled-new-array/range in MakeReadCodeToTypeId16()
1415 // BBBB from e.g., const-class vAA, type@BBBB. in MakeReadCodeToTypeId16()
1420 auto mapper = base::BindRepeating(ReadTargetIndex<uint16_t>, image_, in MakeReadCodeToTypeId16()
1429 auto filter = base::BindRepeating( in MakeReadCodeToProtoId16()
1430 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToProtoId16()
1431 if (value.instr->format == dex::FormatId::c) { in MakeReadCodeToProtoId16()
1432 if (value.instr->opcode == 0xFA || // invoke-polymorphic in MakeReadCodeToProtoId16()
1433 value.instr->opcode == 0xFB) { // invoke-polymorphic/range in MakeReadCodeToProtoId16()
1434 // HHHH from e.g, invoke-polymorphic {vC, vD, vE, vF, vG}, in MakeReadCodeToProtoId16()
1438 if (value.instr->opcode == 0xFF) { // const-method-type in MakeReadCodeToProtoId16()
1439 // BBBB from e.g., const-method-type vAA, proto@BBBB in MakeReadCodeToProtoId16()
1445 auto mapper = base::BindRepeating(ReadTargetIndex<uint16_t>, image_, in MakeReadCodeToProtoId16()
1454 auto filter = base::BindRepeating( in MakeReadCodeToCallSiteId16()
1455 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToCallSiteId16()
1456 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToCallSiteId16()
1457 (value.instr->opcode == 0xFC || // invoke-custom in MakeReadCodeToCallSiteId16()
1458 value.instr->opcode == 0xFD)) { // invoke-custom/range in MakeReadCodeToCallSiteId16()
1459 // BBBB from e.g, invoke-custom {vC, vD, vE, vF, vG}, in MakeReadCodeToCallSiteId16()
1466 base::BindRepeating(ReadTargetIndex<uint16_t>, image_, in MakeReadCodeToCallSiteId16()
1475 auto filter = base::BindRepeating( in MakeReadCodeToMethodHandle16()
1476 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToMethodHandle16()
1477 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToMethodHandle16()
1478 value.instr->opcode == 0xFE) { // const-method-handle in MakeReadCodeToMethodHandle16()
1479 // BBBB from e.g, const-method-handle vAA, method_handle@BBBB in MakeReadCodeToMethodHandle16()
1484 auto mapper = base::BindRepeating(ReadTargetIndex<uint16_t>, image_, in MakeReadCodeToMethodHandle16()
1494 auto filter = base::BindRepeating( in MakeReadCodeToFieldId16()
1495 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToFieldId16()
1496 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToFieldId16()
1497 (value.instr->opcode == 0x52 || // iinstanceop (iget-*, iput-*) in MakeReadCodeToFieldId16()
1498 value.instr->opcode == 0x60)) { // sstaticop (sget-*, sput-*) in MakeReadCodeToFieldId16()
1504 auto mapper = base::BindRepeating(ReadTargetIndex<uint16_t>, image_, in MakeReadCodeToFieldId16()
1513 auto filter = base::BindRepeating( in MakeReadCodeToMethodId16()
1514 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToMethodId16()
1515 if (value.instr->format == dex::FormatId::c && in MakeReadCodeToMethodId16()
1516 (value.instr->opcode == 0x6E || // invoke-kind in MakeReadCodeToMethodId16()
1517 value.instr->opcode == 0x74 || // invoke-kind/range in MakeReadCodeToMethodId16()
1518 value.instr->opcode == 0xFA || // invoke-polymorphic in MakeReadCodeToMethodId16()
1519 value.instr->opcode == 0xFB)) { // invoke-polymorphic/range in MakeReadCodeToMethodId16()
1520 // BBBB from e.g., invoke-virtual {vC, vD, vE, vF, vG}, meth@BBBB. in MakeReadCodeToMethodId16()
1526 base::BindRepeating(ReadTargetIndex<uint16_t>, image_, method_map_item_, in MakeReadCodeToMethodId16()
1535 auto filter = base::BindRepeating( in MakeReadCodeToRelCode8()
1536 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToRelCode8()
1537 if (value.instr->format == dex::FormatId::t && in MakeReadCodeToRelCode8()
1538 value.instr->opcode == 0x28) { // goto in MakeReadCodeToRelCode8()
1544 auto mapper = base::BindRepeating( in MakeReadCodeToRelCode8()
1548 // int32_t so |unsafe_delta - 1| won't underflow! in MakeReadCodeToRelCode8()
1549 int32_t unsafe_delta = dis->image_.read<int8_t>(location); in MakeReadCodeToRelCode8()
1551 location + (unsafe_delta - 1) * kInstrUnitSize); in MakeReadCodeToRelCode8()
1555 base::Unretained(this)); in MakeReadCodeToRelCode8()
1563 auto filter = base::BindRepeating( in MakeReadCodeToRelCode16()
1564 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToRelCode16()
1565 if (value.instr->format == dex::FormatId::t && in MakeReadCodeToRelCode16()
1566 (value.instr->opcode == 0x29 || // goto/16 in MakeReadCodeToRelCode16()
1567 value.instr->opcode == 0x32 || // if-test in MakeReadCodeToRelCode16()
1568 value.instr->opcode == 0x38)) { // if-testz in MakeReadCodeToRelCode16()
1574 auto mapper = base::BindRepeating( in MakeReadCodeToRelCode16()
1578 // int32_t so |unsafe_delta - 1| won't underflow! in MakeReadCodeToRelCode16()
1579 int32_t unsafe_delta = dis->image_.read<int16_t>(location); in MakeReadCodeToRelCode16()
1581 location + (unsafe_delta - 1) * kInstrUnitSize); in MakeReadCodeToRelCode16()
1585 base::Unretained(this)); in MakeReadCodeToRelCode16()
1593 auto filter = base::BindRepeating( in MakeReadCodeToRelCode32()
1594 [](const InstructionParser::Value& value) -> offset_t { in MakeReadCodeToRelCode32()
1595 if (value.instr->format == dex::FormatId::t && in MakeReadCodeToRelCode32()
1596 (value.instr->opcode == 0x26 || // fill-array-data in MakeReadCodeToRelCode32()
1597 value.instr->opcode == 0x2A || // goto/32 in MakeReadCodeToRelCode32()
1598 value.instr->opcode == 0x2B || // packed-switch in MakeReadCodeToRelCode32()
1599 value.instr->opcode == 0x2C)) { // sparse-switch in MakeReadCodeToRelCode32()
1600 // +BBBBBBBB from e.g., fill-array-data vAA, +BBBBBBBB. in MakeReadCodeToRelCode32()
1606 auto mapper = base::BindRepeating( in MakeReadCodeToRelCode32()
1609 // before |location|. This needs to be subtracted out. Use int64_t to in MakeReadCodeToRelCode32()
1611 int64_t unsafe_delta = dis->image_.read<int32_t>(location); in MakeReadCodeToRelCode32()
1612 int64_t unsafe_target = location + (unsafe_delta - 1) * kInstrUnitSize; in MakeReadCodeToRelCode32()
1616 static_cast<offset_t>(base::CheckedNumeric<offset_t>(unsafe_target) in MakeReadCodeToRelCode32()
1621 base::Unretained(this)); in MakeReadCodeToRelCode32()
1627 MutableBufferView image) { in MakeWriteStringId16() argument
1628 auto writer = base::BindRepeating( in MakeWriteStringId16()
1630 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteStringId16()
1634 MutableBufferView image) { in MakeWriteStringId32() argument
1635 auto writer = base::BindRepeating( in MakeWriteStringId32()
1637 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteStringId32()
1641 MutableBufferView image) { in MakeWriteTypeId16() argument
1642 auto writer = base::BindRepeating(WriteTargetIndex<uint16_t>, type_map_item_, in MakeWriteTypeId16()
1644 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteTypeId16()
1648 MutableBufferView image) { in MakeWriteTypeId32() argument
1649 auto writer = base::BindRepeating(WriteTargetIndex<uint32_t>, type_map_item_, in MakeWriteTypeId32()
1651 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteTypeId32()
1655 MutableBufferView image) { in MakeWriteProtoId16() argument
1656 auto writer = base::BindRepeating(WriteTargetIndex<uint16_t>, proto_map_item_, in MakeWriteProtoId16()
1658 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteProtoId16()
1662 MutableBufferView image) { in MakeWriteFieldId16() argument
1663 auto writer = base::BindRepeating(WriteTargetIndex<uint16_t>, field_map_item_, in MakeWriteFieldId16()
1665 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteFieldId16()
1669 MutableBufferView image) { in MakeWriteFieldId32() argument
1670 auto writer = base::BindRepeating(WriteTargetIndex<uint32_t>, field_map_item_, in MakeWriteFieldId32()
1672 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteFieldId32()
1676 MutableBufferView image) { in MakeWriteMethodId16() argument
1677 auto writer = base::BindRepeating( in MakeWriteMethodId16()
1679 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteMethodId16()
1683 MutableBufferView image) { in MakeWriteMethodId32() argument
1684 auto writer = base::BindRepeating( in MakeWriteMethodId32()
1686 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteMethodId32()
1690 MutableBufferView image) { in MakeWriteCallSiteId16() argument
1692 base::BindRepeating(WriteTargetIndex<uint16_t>, call_site_map_item_, in MakeWriteCallSiteId16()
1694 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteCallSiteId16()
1698 MutableBufferView image) { in MakeWriteMethodHandle16() argument
1700 base::BindRepeating(WriteTargetIndex<uint16_t>, method_handle_map_item_, in MakeWriteMethodHandle16()
1702 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteMethodHandle16()
1706 MutableBufferView image) { in MakeWriteRelCode8() argument
1707 auto writer = base::BindRepeating([](Reference ref, MutableBufferView image) { in MakeWriteRelCode8() argument
1709 static_cast<ptrdiff_t>(ref.target) - ref.location; in MakeWriteRelCode8()
1713 base::CheckedNumeric<int8_t> delta((unsafe_byte_diff / kInstrUnitSize) + 1); in MakeWriteRelCode8()
1718 image.write<int8_t>(ref.location, delta.ValueOrDie()); in MakeWriteRelCode8()
1720 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteRelCode8()
1724 MutableBufferView image) { in MakeWriteRelCode16() argument
1725 auto writer = base::BindRepeating([](Reference ref, MutableBufferView image) { in MakeWriteRelCode16() argument
1727 static_cast<ptrdiff_t>(ref.target) - ref.location; in MakeWriteRelCode16()
1731 base::CheckedNumeric<int16_t> delta((unsafe_byte_diff / kInstrUnitSize) + in MakeWriteRelCode16()
1737 image.write<int16_t>(ref.location, delta.ValueOrDie()); in MakeWriteRelCode16()
1739 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteRelCode16()
1743 MutableBufferView image) { in MakeWriteRelCode32() argument
1744 auto writer = base::BindRepeating([](Reference ref, MutableBufferView image) { in MakeWriteRelCode32() argument
1746 static_cast<ptrdiff_t>(ref.target) - ref.location; in MakeWriteRelCode32()
1750 base::CheckedNumeric<int32_t> delta((unsafe_byte_diff / kInstrUnitSize) + in MakeWriteRelCode32()
1756 image.write<int32_t>(ref.location, delta.ValueOrDie()); in MakeWriteRelCode32()
1758 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteRelCode32()
1762 MutableBufferView image) { in MakeWriteAbs32() argument
1763 auto writer = base::BindRepeating([](Reference ref, MutableBufferView image) { in MakeWriteAbs32() argument
1764 image.write<uint32_t>(ref.location, ref.target); in MakeWriteAbs32()
1766 return std::make_unique<ReferenceWriterAdaptor>(image, std::move(writer)); in MakeWriteAbs32()
1769 bool DisassemblerDex::Parse(ConstBufferView image) { in Parse() argument
1770 image_ = image; in Parse()
1783 // DEX header contains file size, so use it to resize |image_| right away. in ParseHeader()
1784 image_.shrink(header_->file_size); in ParseHeader()
1786 // Read map list. This is not a fixed-size array, so instead of reading in ParseHeader()
1792 source = std::move(BufferSource(image_).Skip(header_->map_off)); in ParseHeader()
1804 // Reject unreasonably large |item->size|. in ParseHeader()
1805 size_t item_size = GetItemBaseSize(item->type); in ParseHeader()
1806 // Confusing name: |item->size| is actually the number of items. in ParseHeader()
1807 if (!image_.covers_array(item->offset, item->size, item_size)) in ParseHeader()
1809 if (!map_item_map_.insert(std::make_pair(item->type, item)).second) in ParseHeader()