diff options
author | Calder Kitagawa <ckitagawa@chromium.org> | 2018-06-11 13:54:24 +0000 |
---|---|---|
committer | Edward Lesmes <ehmaldonado@google.com> | 2021-07-23 22:50:32 +0000 |
commit | 6b80ac7f4fbd9558e55a335340c23d5d43bbec41 (patch) | |
tree | 56fee58946d1525648432cc29df3636d7844d8fe /disassembler_dex.h | |
parent | 18379914c9b6ce649f1ce2fbfc76c7bf71d1df9a (diff) | |
download | zucchini-6b80ac7f4fbd9558e55a335340c23d5d43bbec41.tar.gz |
[Zucchini]: Support reference lists in DEX
Adds support for types which contain variable length lists of references
in DEX. These lists take the form: |NTTTTT|NTT|N|NTT|... where N is the
header containing the length and T is a reference body. There are three
types which utilize this format. AnnotationsDirectoryItem also uses a
variant of this format with multiple lists per item (to be added in a
separate CL).
Method:
We pre-cache the offsets of each T within the list using the parser and
iterate over it in the ReferenceReader. This is faster than implicitly
parsing each list and avoids having to handle all the accounting for
the number of lists, items per list, map size, etc. in the
ReferenceReader. The tradeoff is memory which varies by number of types
and annotations but could exceed 1 MB in a very large DEX file. This is
an acceptable cost for the time and simplicity gained. Explicitly
parsing beforehand is also safer as it delegates the validation of DEX
structure to the parser early before any references are read. This is
also inkeeping with the style of the other ReferenceReaders in the file.
Bug: 847571
Change-Id: I853905b10ab7003e87895cc50c5ebf6b9fb4a424
Reviewed-on: https://chromium-review.googlesource.com/1087409
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Reviewed-by: agrieve <agrieve@chromium.org>
Reviewed-by: Greg Thompson <grt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565989}
NOKEYCHECK=True
GitOrigin-RevId: 55a60dd9ab731cb569e49ae3600bc42c716d4756
Diffstat (limited to 'disassembler_dex.h')
-rw-r--r-- | disassembler_dex.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/disassembler_dex.h b/disassembler_dex.h index 5d0d069..8c6f691 100644 --- a/disassembler_dex.h +++ b/disassembler_dex.h @@ -67,7 +67,7 @@ class DisassemblerDex : public Disassembler { kMethodIdToClassTypeId, kClassDefToClassTypeId, kClassDefToSuperClassTypeId, - // kTypeListToTypeId, // Unused + kTypeListToTypeId, kCodeToTypeId, kMethodIdToProtoId, // kProtoId @@ -84,7 +84,7 @@ class DisassemblerDex : public Disassembler { // kAnnotationsDirectoryToParameterAnnotationSetRef, // kAnnotationSetRef, - // kAnnotationSetRefListToAnnotationSet, // kAnnotationSet, + kAnnotationSetRefListToAnnotationSet, // kAnnotationSet, // kAnnotationsDirectoryToClassAnnotationSet, // kAnnotationsDirectoryToFieldAnnotationSet, // kAnnotationsDirectoryToMethodAnnotationSet, @@ -97,7 +97,7 @@ class DisassemblerDex : public Disassembler { kStringIdToStringData, // kStringData - // kAnnotationSetToAnnotation, // kAnnotation + kAnnotationSetToAnnotation, // kAnnotation kClassDefToStaticValuesEncodedArray, // kEncodedArrayItem @@ -171,6 +171,14 @@ class DisassemblerDex : public Disassembler { std::unique_ptr<ReferenceReader> MakeReadClassDefToStaticValuesEncodedArray( offset_t lo, offset_t hi); + std::unique_ptr<ReferenceReader> MakeReadTypeListToTypeId16(offset_t lo, + offset_t hi); + std::unique_ptr<ReferenceReader> MakeReadAnnotationSetToAnnotation( + offset_t lo, + offset_t hi); + std::unique_ptr<ReferenceReader> MakeReadAnnotationSetRefListToAnnotationSet( + offset_t lo, + offset_t hi); std::unique_ptr<ReferenceReader> MakeReadCodeToStringId16(offset_t lo, offset_t hi); std::unique_ptr<ReferenceReader> MakeReadCodeToStringId32(offset_t lo, @@ -222,10 +230,18 @@ class DisassemblerDex : public Disassembler { dex::MapItem field_map_item_ = {}; dex::MapItem method_map_item_ = {}; dex::MapItem class_def_map_item_ = {}; + dex::MapItem type_list_map_item_ = {}; dex::MapItem code_map_item_ = {}; - // Sorted list of offsets of code items in |image_|. + // Optionally supported (not all DEX files have these). + dex::MapItem annotation_set_ref_list_map_item_ = {}; + dex::MapItem annotation_set_map_item_ = {}; + + // Sorted list of offsets of parsed items in |image_|. std::vector<offset_t> code_item_offsets_; + std::vector<offset_t> type_list_offsets_; + std::vector<offset_t> annotation_set_ref_list_offsets_; + std::vector<offset_t> annotation_set_offsets_; DISALLOW_COPY_AND_ASSIGN(DisassemblerDex); }; |