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 * The VM wraps some additional data structures around the DexFile. These
19 * are defined here.
20 */
21 #ifndef _DALVIK_DVMDEX
22 #define _DALVIK_DVMDEX
23
24 #include "libdex/DexFile.h"
25
26 /* extern */
27 struct ClassObject;
28 struct HashTable;
29 struct InstField;
30 struct Method;
31 struct StringObject;
32
33
34 /*
35 * Some additional VM data structures that are associated with the DEX file.
36 */
37 typedef struct DvmDex {
38 /* pointer to the DexFile we're associated with */
39 DexFile* pDexFile;
40
41 /* clone of pDexFile->pHeader (it's used frequently enough) */
42 const DexHeader* pHeader;
43
44 /* interned strings; parallel to "stringIds" */
45 struct StringObject** pResStrings;
46
47 /* resolved classes; parallel to "typeIds" */
48 struct ClassObject** pResClasses;
49
50 /* resolved methods; parallel to "methodIds" */
51 struct Method** pResMethods;
52
53 /* resolved instance fields; parallel to "fieldIds" */
54 /* (this holds both InstField and StaticField) */
55 struct Field** pResFields;
56
57 /* interface method lookup cache */
58 struct AtomicCache* pInterfaceCache;
59
60 /* shared memory region with file contents */
61 MemMapping memMap;
62
63 /* lock ensuring mutual exclusion during updates */
64 pthread_mutex_t modLock;
65 } DvmDex;
66
67
68 /*
69 * Given a file descriptor for an open "optimized" DEX file, map it into
70 * memory and parse the contents.
71 *
72 * On success, returns 0 and sets "*ppDvmDex" to a newly-allocated DvmDex.
73 * On failure, returns a meaningful error code [currently just -1].
74 */
75 int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex);
76
77 /*
78 * Open a partial DEX file. Only useful as part of the optimization process.
79 */
80 int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);
81
82 /*
83 * Free a DvmDex structure, along with any associated structures.
84 */
85 void dvmDexFileFree(DvmDex* pDvmDex);
86
87
88 /*
89 * Change the 1- or 2-byte value at the specified address to a new value. If
90 * the location already has the new value, do nothing.
91 *
92 * This does not make any synchronization guarantees. The caller must
93 * ensure exclusivity vs. other callers.
94 *
95 * For the 2-byte call, the pointer should have 16-bit alignment.
96 *
97 * Returns "true" on success.
98 */
99 bool dvmDexChangeDex1(DvmDex* pDvmDex, u1* addr, u1 newVal);
100 bool dvmDexChangeDex2(DvmDex* pDvmDex, u2* addr, u2 newVal);
101
102
103 /*
104 * Return the requested item if it has been resolved, or NULL if it hasn't.
105 */
dvmDexGetResolvedString(const DvmDex * pDvmDex,u4 stringIdx)106 INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
107 u4 stringIdx)
108 {
109 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
110 return pDvmDex->pResStrings[stringIdx];
111 }
dvmDexGetResolvedClass(const DvmDex * pDvmDex,u4 classIdx)112 INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
113 u4 classIdx)
114 {
115 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
116 return pDvmDex->pResClasses[classIdx];
117 }
dvmDexGetResolvedMethod(const DvmDex * pDvmDex,u4 methodIdx)118 INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
119 u4 methodIdx)
120 {
121 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
122 return pDvmDex->pResMethods[methodIdx];
123 }
dvmDexGetResolvedField(const DvmDex * pDvmDex,u4 fieldIdx)124 INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
125 u4 fieldIdx)
126 {
127 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
128 return pDvmDex->pResFields[fieldIdx];
129 }
130
131 /*
132 * Update the resolved item table. Resolution always produces the same
133 * result, so we're not worried about atomicity here.
134 */
dvmDexSetResolvedString(DvmDex * pDvmDex,u4 stringIdx,struct StringObject * str)135 INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
136 struct StringObject* str)
137 {
138 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
139 pDvmDex->pResStrings[stringIdx] = str;
140 }
dvmDexSetResolvedClass(DvmDex * pDvmDex,u4 classIdx,struct ClassObject * clazz)141 INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
142 struct ClassObject* clazz)
143 {
144 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
145 pDvmDex->pResClasses[classIdx] = clazz;
146 }
dvmDexSetResolvedMethod(DvmDex * pDvmDex,u4 methodIdx,struct Method * method)147 INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
148 struct Method* method)
149 {
150 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
151 pDvmDex->pResMethods[methodIdx] = method;
152 }
dvmDexSetResolvedField(DvmDex * pDvmDex,u4 fieldIdx,struct Field * field)153 INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
154 struct Field* field)
155 {
156 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
157 pDvmDex->pResFields[fieldIdx] = field;
158 }
159
160 #endif /*_DALVIK_DVMDEX*/
161