xref: /aosp_15_r20/tools/dexter/slicer/export/slicer/reader.h (revision f0dffb02cdb5c647d21204e89a92a1ffae2dad87)
1*f0dffb02SXin Li /*
2*f0dffb02SXin Li  * Copyright (C) 2017 The Android Open Source Project
3*f0dffb02SXin Li  *
4*f0dffb02SXin Li  * Licensed under the Apache License, Version 2.0 (the "License");
5*f0dffb02SXin Li  * you may not use this file except in compliance with the License.
6*f0dffb02SXin Li  * You may obtain a copy of the License at
7*f0dffb02SXin Li  *
8*f0dffb02SXin Li  *      http://www.apache.org/licenses/LICENSE-2.0
9*f0dffb02SXin Li  *
10*f0dffb02SXin Li  * Unless required by applicable law or agreed to in writing, software
11*f0dffb02SXin Li  * distributed under the License is distributed on an "AS IS" BASIS,
12*f0dffb02SXin Li  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f0dffb02SXin Li  * See the License for the specific language governing permissions and
14*f0dffb02SXin Li  * limitations under the License.
15*f0dffb02SXin Li  */
16*f0dffb02SXin Li 
17*f0dffb02SXin Li #pragma once
18*f0dffb02SXin Li 
19*f0dffb02SXin Li #include "common.h"
20*f0dffb02SXin Li #include "dex_format.h"
21*f0dffb02SXin Li #include "dex_ir.h"
22*f0dffb02SXin Li 
23*f0dffb02SXin Li #include <assert.h>
24*f0dffb02SXin Li #include <stdlib.h>
25*f0dffb02SXin Li #include <map>
26*f0dffb02SXin Li #include <memory>
27*f0dffb02SXin Li 
28*f0dffb02SXin Li namespace dex {
29*f0dffb02SXin Li 
30*f0dffb02SXin Li // Provides both a low level iteration over the .dex
31*f0dffb02SXin Li // structures and incremental .dex IR creation.
32*f0dffb02SXin Li //
33*f0dffb02SXin Li // NOTES:
34*f0dffb02SXin Li // - only little-endian .dex files and host machines are supported
35*f0dffb02SXin Li // - aggresive structure validation & minimal semantic validation
36*f0dffb02SXin Li //
37*f0dffb02SXin Li class Reader {
38*f0dffb02SXin Li  public:
39*f0dffb02SXin Li   Reader(const dex::u1* image, size_t size);
40*f0dffb02SXin Li   ~Reader() = default;
41*f0dffb02SXin Li 
42*f0dffb02SXin Li   // No copy/move semantics
43*f0dffb02SXin Li   Reader(const Reader&) = delete;
44*f0dffb02SXin Li   Reader& operator=(const Reader&) = delete;
45*f0dffb02SXin Li 
46*f0dffb02SXin Li  public:
47*f0dffb02SXin Li   // Low level dex format interface
Header()48*f0dffb02SXin Li   const dex::Header* Header() const { return header_; }
49*f0dffb02SXin Li   const char* GetStringMUTF8(dex::u4 index) const;
50*f0dffb02SXin Li   slicer::ArrayView<const dex::ClassDef> ClassDefs() const;
51*f0dffb02SXin Li   slicer::ArrayView<const dex::StringId> StringIds() const;
52*f0dffb02SXin Li   slicer::ArrayView<const dex::TypeId> TypeIds() const;
53*f0dffb02SXin Li   slicer::ArrayView<const dex::FieldId> FieldIds() const;
54*f0dffb02SXin Li   slicer::ArrayView<const dex::MethodId> MethodIds() const;
55*f0dffb02SXin Li   slicer::ArrayView<const dex::ProtoId> ProtoIds() const;
56*f0dffb02SXin Li   slicer::ArrayView<const dex::MethodHandle> MethodHandles() const;
57*f0dffb02SXin Li   const dex::MapList* DexMapList() const;
58*f0dffb02SXin Li 
59*f0dffb02SXin Li   // IR creation interface
GetIr()60*f0dffb02SXin Li   std::shared_ptr<ir::DexFile> GetIr() const { return dex_ir_; }
61*f0dffb02SXin Li   void CreateFullIr();
62*f0dffb02SXin Li   void CreateClassIr(dex::u4 index);
63*f0dffb02SXin Li   dex::u4 FindClassIndex(const char* class_descriptor) const;
64*f0dffb02SXin Li 
65*f0dffb02SXin Li  private:
66*f0dffb02SXin Li   // Internal access to IR nodes for indexed .dex structures
67*f0dffb02SXin Li   ir::Class* GetClass(dex::u4 index);
68*f0dffb02SXin Li   ir::Type* GetType(dex::u4 index);
69*f0dffb02SXin Li   ir::FieldDecl* GetFieldDecl(dex::u4 index);
70*f0dffb02SXin Li   ir::MethodDecl* GetMethodDecl(dex::u4 index);
71*f0dffb02SXin Li   ir::Proto* GetProto(dex::u4 index);
72*f0dffb02SXin Li   ir::String* GetString(dex::u4 index);
73*f0dffb02SXin Li   ir::MethodHandle* GetMethodHandle(dex::u4 index);
74*f0dffb02SXin Li 
75*f0dffb02SXin Li   // Parsing annotations
76*f0dffb02SXin Li   ir::AnnotationsDirectory* ExtractAnnotations(dex::u4 offset);
77*f0dffb02SXin Li   ir::Annotation* ExtractAnnotationItem(dex::u4 offset);
78*f0dffb02SXin Li   ir::AnnotationSet* ExtractAnnotationSet(dex::u4 offset);
79*f0dffb02SXin Li   ir::AnnotationSetRefList* ExtractAnnotationSetRefList(dex::u4 offset);
80*f0dffb02SXin Li   ir::FieldAnnotation* ParseFieldAnnotation(const dex::u1** pptr);
81*f0dffb02SXin Li   ir::MethodAnnotation* ParseMethodAnnotation(const dex::u1** pptr);
82*f0dffb02SXin Li   ir::ParamAnnotation* ParseParamAnnotation(const dex::u1** pptr);
83*f0dffb02SXin Li   ir::EncodedField* ParseEncodedField(const dex::u1** pptr, dex::u4* baseIndex);
84*f0dffb02SXin Li   ir::Annotation* ParseAnnotation(const dex::u1** pptr);
85*f0dffb02SXin Li   ir::MethodHandle* ParseMethodHandle(dex::u4 index);
86*f0dffb02SXin Li 
87*f0dffb02SXin Li   // Parse encoded values and arrays
88*f0dffb02SXin Li   ir::EncodedValue* ParseEncodedValue(const dex::u1** pptr);
89*f0dffb02SXin Li   ir::EncodedArray* ParseEncodedArray(const dex::u1** pptr);
90*f0dffb02SXin Li   ir::EncodedArray* ExtractEncodedArray(dex::u4 offset);
91*f0dffb02SXin Li 
92*f0dffb02SXin Li   // Parse root .dex structures
93*f0dffb02SXin Li   ir::Class* ParseClass(dex::u4 index);
94*f0dffb02SXin Li   ir::EncodedMethod* ParseEncodedMethod(const dex::u1** pptr, dex::u4* baseIndex);
95*f0dffb02SXin Li   ir::Type* ParseType(dex::u4 index);
96*f0dffb02SXin Li   ir::FieldDecl* ParseFieldDecl(dex::u4 index);
97*f0dffb02SXin Li   ir::MethodDecl* ParseMethodDecl(dex::u4 index);
98*f0dffb02SXin Li   ir::TypeList* ExtractTypeList(dex::u4 offset);
99*f0dffb02SXin Li   ir::Proto* ParseProto(dex::u4 index);
100*f0dffb02SXin Li   ir::String* ParseString(dex::u4 index);
101*f0dffb02SXin Li 
102*f0dffb02SXin Li   // Parse code and debug information
103*f0dffb02SXin Li   ir::DebugInfo* ExtractDebugInfo(dex::u4 offset);
104*f0dffb02SXin Li   ir::Code* ExtractCode(dex::u4 offset);
105*f0dffb02SXin Li   void ParseInstructions(slicer::ArrayView<const dex::u2> code);
106*f0dffb02SXin Li 
107*f0dffb02SXin Li   // Convert a file pointer (absolute offset) to an in-memory pointer
108*f0dffb02SXin Li   template <class T>
ptr(int offset)109*f0dffb02SXin Li   const T* ptr(int offset) const {
110*f0dffb02SXin Li     SLICER_CHECK_GE(offset, 0 && offset + sizeof(T) <= size_);
111*f0dffb02SXin Li     return reinterpret_cast<const T*>(image_ + offset);
112*f0dffb02SXin Li   }
113*f0dffb02SXin Li 
114*f0dffb02SXin Li   // Convert a data section file pointer (absolute offset) to an in-memory pointer
115*f0dffb02SXin Li   // (offset should be inside the data section)
116*f0dffb02SXin Li   template <class T>
dataPtr(int offset)117*f0dffb02SXin Li   const T* dataPtr(int offset) const {
118*f0dffb02SXin Li     SLICER_CHECK_GE(offset, header_->data_off && offset + sizeof(T) <= size_);
119*f0dffb02SXin Li     return reinterpret_cast<const T*>(image_ + offset);
120*f0dffb02SXin Li   }
121*f0dffb02SXin Li 
122*f0dffb02SXin Li   // Map an indexed section to an ArrayView<T>
123*f0dffb02SXin Li   template <class T>
section(int offset,int count)124*f0dffb02SXin Li   slicer::ArrayView<const T> section(int offset, int count) const {
125*f0dffb02SXin Li     return slicer::ArrayView<const T>(ptr<T>(offset), count);
126*f0dffb02SXin Li   }
127*f0dffb02SXin Li 
128*f0dffb02SXin Li   // Simple accessor for a MUTF8 string data
GetStringData(dex::u4 index)129*f0dffb02SXin Li   const dex::u1* GetStringData(dex::u4 index) const {
130*f0dffb02SXin Li     auto& stringId = StringIds()[index];
131*f0dffb02SXin Li     return dataPtr<dex::u1>(stringId.string_data_off);
132*f0dffb02SXin Li   }
133*f0dffb02SXin Li 
134*f0dffb02SXin Li   void ValidateHeader();
135*f0dffb02SXin Li 
136*f0dffb02SXin Li  private:
137*f0dffb02SXin Li   // the in-memory .dex image
138*f0dffb02SXin Li   const dex::u1* image_;
139*f0dffb02SXin Li   size_t size_;
140*f0dffb02SXin Li 
141*f0dffb02SXin Li   // .dex image header
142*f0dffb02SXin Li   const dex::Header* header_;
143*f0dffb02SXin Li 
144*f0dffb02SXin Li   // .dex IR associated with the reader
145*f0dffb02SXin Li   std::shared_ptr<ir::DexFile> dex_ir_;
146*f0dffb02SXin Li 
147*f0dffb02SXin Li   // maps for de-duplicating items identified by file pointers
148*f0dffb02SXin Li   std::map<dex::u4, ir::TypeList*> type_lists_;
149*f0dffb02SXin Li   std::map<dex::u4, ir::Annotation*> annotations_;
150*f0dffb02SXin Li   std::map<dex::u4, ir::AnnotationSet*> annotation_sets_;
151*f0dffb02SXin Li   std::map<dex::u4, ir::AnnotationsDirectory*> annotations_directories_;
152*f0dffb02SXin Li   std::map<dex::u4, ir::EncodedArray*> encoded_arrays_;
153*f0dffb02SXin Li };
154*f0dffb02SXin Li 
155*f0dffb02SXin Li }  // namespace dex
156