2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Functions to deal with class definition structures in DEX files
26 /* Helper for verification which reads and verifies a given number
27 * of uleb128 values. */
28 static bool verifyUlebs(const u1* pData, const u1* pLimit, u4 count) {
32 while (okay && (count-- != 0)) {
33 readAndVerifyUnsignedLeb128(&pData, pLimit, &okay);
39 /* Read and verify the header of a class_data_item. This updates the
40 * given data pointer to point past the end of the read data and
41 * returns an "okay" flag (that is, false == failure). */
42 bool dexReadAndVerifyClassDataHeader(const u1** pData, const u1* pLimit,
43 DexClassDataHeader *pHeader) {
44 if (! verifyUlebs(*pData, pLimit, 4)) {
48 dexReadClassDataHeader(pData, pHeader);
52 /* Read and verify an encoded_field. This updates the
53 * given data pointer to point past the end of the read data and
54 * returns an "okay" flag (that is, false == failure).
56 * The lastIndex value should be set to 0 before the first field in
57 * a list is read. It is updated as fields are read and used in the
60 * The verification done by this function is of the raw data format
61 * only; it does not verify that access flags or indices
63 bool dexReadAndVerifyClassDataField(const u1** pData, const u1* pLimit,
64 DexField* pField, u4* lastIndex) {
65 if (! verifyUlebs(*pData, pLimit, 2)) {
69 dexReadClassDataField(pData, pField, lastIndex);
73 /* Read and verify an encoded_method. This updates the
74 * given data pointer to point past the end of the read data and
75 * returns an "okay" flag (that is, false == failure).
77 * The lastIndex value should be set to 0 before the first method in
78 * a list is read. It is updated as fields are read and used in the
81 * The verification done by this function is of the raw data format
82 * only; it does not verify that access flags, indices, or offsets
84 bool dexReadAndVerifyClassDataMethod(const u1** pData, const u1* pLimit,
85 DexMethod* pMethod, u4* lastIndex) {
86 if (! verifyUlebs(*pData, pLimit, 3)) {
90 dexReadClassDataMethod(pData, pMethod, lastIndex);
94 /* Read, verify, and return an entire class_data_item. This updates
95 * the given data pointer to point past the end of the read data. This
96 * function allocates a single chunk of memory for the result, which
97 * must subsequently be free()d. This function returns NULL if there
98 * was trouble parsing the data. If this function is passed NULL, it
99 * returns an initialized empty DexClassData structure.
101 * The verification done by this function is of the raw data format
102 * only; it does not verify that access flags, indices, or offsets
104 DexClassData* dexReadAndVerifyClassData(const u1** pData, const u1* pLimit) {
105 DexClassDataHeader header;
108 if (*pData == NULL) {
109 DexClassData* result = (DexClassData*) malloc(sizeof(DexClassData));
110 memset(result, 0, sizeof(*result));
114 if (! dexReadAndVerifyClassDataHeader(pData, pLimit, &header)) {
118 size_t resultSize = sizeof(DexClassData) +
119 (header.staticFieldsSize * sizeof(DexField)) +
120 (header.instanceFieldsSize * sizeof(DexField)) +
121 (header.directMethodsSize * sizeof(DexMethod)) +
122 (header.virtualMethodsSize * sizeof(DexMethod));
124 DexClassData* result = (DexClassData*) malloc(resultSize);
125 u1* ptr = ((u1*) result) + sizeof(DexClassData);
129 if (result == NULL) {
133 result->header = header;
135 if (header.staticFieldsSize != 0) {
136 result->staticFields = (DexField*) ptr;
137 ptr += header.staticFieldsSize * sizeof(DexField);
139 result->staticFields = NULL;
142 if (header.instanceFieldsSize != 0) {
143 result->instanceFields = (DexField*) ptr;
144 ptr += header.instanceFieldsSize * sizeof(DexField);
146 result->instanceFields = NULL;
149 if (header.directMethodsSize != 0) {
150 result->directMethods = (DexMethod*) ptr;
151 ptr += header.directMethodsSize * sizeof(DexMethod);
153 result->directMethods = NULL;
156 if (header.virtualMethodsSize != 0) {
157 result->virtualMethods = (DexMethod*) ptr;
159 result->virtualMethods = NULL;
163 for (i = 0; okay && (i < header.staticFieldsSize); i++) {
164 okay = dexReadAndVerifyClassDataField(pData, pLimit,
165 &result->staticFields[i], &lastIndex);
169 for (i = 0; okay && (i < header.instanceFieldsSize); i++) {
170 okay = dexReadAndVerifyClassDataField(pData, pLimit,
171 &result->instanceFields[i], &lastIndex);
175 for (i = 0; okay && (i < header.directMethodsSize); i++) {
176 okay = dexReadAndVerifyClassDataMethod(pData, pLimit,
177 &result->directMethods[i], &lastIndex);
181 for (i = 0; okay && (i < header.virtualMethodsSize); i++) {
182 okay = dexReadAndVerifyClassDataMethod(pData, pLimit,
183 &result->virtualMethods[i], &lastIndex);