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 */ 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. */ 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 */ 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 */ 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