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