1 /*
2 * Copyright (C) 2008 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
17 /*
18 * Functions to deal with class definition structures in DEX files
19 */
20
21 #ifndef LIBDEX_DEXCLASS_H_
22 #define LIBDEX_DEXCLASS_H_
23
24 #include "DexFile.h"
25 #include "Leb128.h"
26
27 /* expanded form of a class_data_item header */
28 struct DexClassDataHeader {
29 u4 staticFieldsSize;
30 u4 instanceFieldsSize;
31 u4 directMethodsSize;
32 u4 virtualMethodsSize;
33 };
34
35 /* expanded form of encoded_field */
36 struct DexField {
37 u4 fieldIdx; /* index to a field_id_item */
38 u4 accessFlags;
39 };
40
41 /* expanded form of encoded_method */
42 struct DexMethod {
43 u4 methodIdx; /* index to a method_id_item */
44 u4 accessFlags;
45 u4 codeOff; /* file offset to a code_item */
46 };
47
48 /* expanded form of class_data_item. Note: If a particular item is
49 * absent (e.g., no static fields), then the corresponding pointer
50 * is set to NULL. */
51 struct DexClassData {
52 DexClassDataHeader header;
53 DexField* staticFields;
54 DexField* instanceFields;
55 DexMethod* directMethods;
56 DexMethod* virtualMethods;
57 };
58
59 /* Read and verify the header of a class_data_item. This updates the
60 * given data pointer to point past the end of the read data and
61 * returns an "okay" flag (that is, false == failure). */
62 bool dexReadAndVerifyClassDataHeader(const u1** pData, const u1* pLimit,
63 DexClassDataHeader *pHeader);
64
65 /* Read and verify an encoded_field. This updates the
66 * given data pointer to point past the end of the read data and
67 * returns an "okay" flag (that is, false == failure).
68 *
69 * The lastIndex value should be set to 0 before the first field in
70 * a list is read. It is updated as fields are read and used in the
71 * decode process.
72 *
73 * The verification done by this function is of the raw data format
74 * only; it does not verify that access flags or indices
75 * are valid. */
76 bool dexReadAndVerifyClassDataField(const u1** pData, const u1* pLimit,
77 DexField* pField, u4* lastIndex);
78
79 /* Read and verify an encoded_method. This updates the
80 * given data pointer to point past the end of the read data and
81 * returns an "okay" flag (that is, false == failure).
82 *
83 * The lastIndex value should be set to 0 before the first method in
84 * a list is read. It is updated as fields are read and used in the
85 * decode process.
86 *
87 * The verification done by this function is of the raw data format
88 * only; it does not verify that access flags, indices, or offsets
89 * are valid. */
90 bool dexReadAndVerifyClassDataMethod(const u1** pData, const u1* pLimit,
91 DexMethod* pMethod, u4* lastIndex);
92
93 /* Read, verify, and return an entire class_data_item. This updates
94 * the given data pointer to point past the end of the read data. This
95 * function allocates a single chunk of memory for the result, which
96 * must subsequently be free()d. This function returns NULL if there
97 * was trouble parsing the data. If this function is passed NULL, it
98 * returns an initialized empty DexClassData structure.
99 *
100 * The verification done by this function is of the raw data format
101 * only; it does not verify that access flags, indices, or offsets
102 * are valid. */
103 DexClassData* dexReadAndVerifyClassData(const u1** pData, const u1* pLimit);
104
105 /*
106 * Get the DexCode for a DexMethod. Returns NULL if the class is native
107 * or abstract.
108 */
dexGetCode(const DexFile * pDexFile,const DexMethod * pDexMethod)109 DEX_INLINE const DexCode* dexGetCode(const DexFile* pDexFile,
110 const DexMethod* pDexMethod)
111 {
112 if (pDexMethod->codeOff == 0)
113 return NULL;
114 return (const DexCode*) (pDexFile->baseAddr + pDexMethod->codeOff);
115 }
116
117
118 /* Read the header of a class_data_item without verification. This
119 * updates the given data pointer to point past the end of the read
120 * data. */
dexReadClassDataHeader(const u1 ** pData,DexClassDataHeader * pHeader)121 DEX_INLINE void dexReadClassDataHeader(const u1** pData,
122 DexClassDataHeader *pHeader) {
123 pHeader->staticFieldsSize = readUnsignedLeb128(pData);
124 pHeader->instanceFieldsSize = readUnsignedLeb128(pData);
125 pHeader->directMethodsSize = readUnsignedLeb128(pData);
126 pHeader->virtualMethodsSize = readUnsignedLeb128(pData);
127 }
128
129 /* Read an encoded_field without verification. This updates the
130 * given data pointer to point past the end of the read data.
131 *
132 * The lastIndex value should be set to 0 before the first field in
133 * a list is read. It is updated as fields are read and used in the
134 * decode process.
135 */
dexReadClassDataField(const u1 ** pData,DexField * pField,u4 * lastIndex)136 DEX_INLINE void dexReadClassDataField(const u1** pData, DexField* pField,
137 u4* lastIndex) {
138 u4 index = *lastIndex + readUnsignedLeb128(pData);
139
140 pField->accessFlags = readUnsignedLeb128(pData);
141 pField->fieldIdx = index;
142 *lastIndex = index;
143 }
144
145 /* Read an encoded_method without verification. This updates the
146 * given data pointer to point past the end of the read data.
147 *
148 * The lastIndex value should be set to 0 before the first method in
149 * a list is read. It is updated as fields are read and used in the
150 * decode process.
151 */
dexReadClassDataMethod(const u1 ** pData,DexMethod * pMethod,u4 * lastIndex)152 DEX_INLINE void dexReadClassDataMethod(const u1** pData, DexMethod* pMethod,
153 u4* lastIndex) {
154 u4 index = *lastIndex + readUnsignedLeb128(pData);
155
156 pMethod->accessFlags = readUnsignedLeb128(pData);
157 pMethod->codeOff = readUnsignedLeb128(pData);
158 pMethod->methodIdx = index;
159 *lastIndex = index;
160 }
161
162 #endif // LIBDEX_DEXCLASS_H_
163