Home | History | Annotate | Download | only in libdex
      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