blob: 11b3b0eeef27c8ccc4c4097fd6adcb00c38da218 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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
Carl Shapiro375fb112011-06-14 20:31:24 -070021#ifndef LIBDEX_DEXCLASS_H_
22#define LIBDEX_DEXCLASS_H_
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080023
24#include "DexFile.h"
25#include "Leb128.h"
26
27/* expanded form of a class_data_item header */
Carl Shapirobfc97992011-04-27 14:16:08 -070028struct DexClassDataHeader {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080029 u4 staticFieldsSize;
30 u4 instanceFieldsSize;
31 u4 directMethodsSize;
32 u4 virtualMethodsSize;
Carl Shapirobfc97992011-04-27 14:16:08 -070033};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080034
35/* expanded form of encoded_field */
Carl Shapirobfc97992011-04-27 14:16:08 -070036struct DexField {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037 u4 fieldIdx; /* index to a field_id_item */
38 u4 accessFlags;
Carl Shapirobfc97992011-04-27 14:16:08 -070039};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080040
41/* expanded form of encoded_method */
Carl Shapirobfc97992011-04-27 14:16:08 -070042struct DexMethod {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080043 u4 methodIdx; /* index to a method_id_item */
44 u4 accessFlags;
45 u4 codeOff; /* file offset to a code_item */
Carl Shapirobfc97992011-04-27 14:16:08 -070046};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080047
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. */
Carl Shapirobfc97992011-04-27 14:16:08 -070051struct DexClassData {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080052 DexClassDataHeader header;
53 DexField* staticFields;
54 DexField* instanceFields;
55 DexMethod* directMethods;
56 DexMethod* virtualMethods;
Carl Shapirobfc97992011-04-27 14:16:08 -070057};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080058
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). */
62bool 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).
Carl Shapirode750892010-06-08 16:37:12 -070068 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080069 * 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.
Carl Shapirode750892010-06-08 16:37:12 -070072 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080073 * 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. */
76bool 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).
Carl Shapirode750892010-06-08 16:37:12 -070082 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080083 * 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. */
90bool 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.
Carl Shapirode750892010-06-08 16:37:12 -070099 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800100 * 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. */
103DexClassData* 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 */
109DEX_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. */
121DEX_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
Carl Shapirode750892010-06-08 16:37:12 -0700130 * given data pointer to point past the end of the read data.
131 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800132 * 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 */
136DEX_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
Carl Shapirode750892010-06-08 16:37:12 -0700146 * given data pointer to point past the end of the read data.
147 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800148 * 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 */
152DEX_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
Carl Shapiro375fb112011-06-14 20:31:24 -0700162#endif // LIBDEX_DEXCLASS_H_