blob: dce0ea92525438b44617dc692b2dbe257b12ebf0 [file] [log] [blame]
Carl Shapiro1e714bb2010-03-16 03:26:49 -07001/*
2 * Copyright (C) 2010 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#include "Dalvik.h"
18#include "alloc/HeapSource.h"
19#include "alloc/Verify.h"
Barry Hayes962adba2010-03-17 12:12:39 -070020#include "alloc/HeapBitmap.h"
Carl Shapiro1e714bb2010-03-16 03:26:49 -070021
Carl Shapiroc85ec002010-04-05 19:36:37 -070022/*
23 * Assertion that the given reference points to a valid object.
24 */
Carl Shapiro1e714bb2010-03-16 03:26:49 -070025#define VERIFY_REFERENCE(x) do { \
26 if (!verifyReference((x), &(x))) { \
27 LOGE("Verify of %p at %p failed", (x), &(x)); \
28 dvmAbort(); \
29 } \
30 } while (0)
31
32/*
33 * Verifies that a reference points to an object header.
34 */
35static bool verifyReference(const void *obj, const void *addr)
36{
37 if (obj == NULL) {
38 return true;
39 }
40 return dvmIsValidObject(obj);
41}
42
43/*
Carl Shapirod28668c2010-04-15 16:10:00 -070044 * Verifies instance fields.
45 */
46static void verifyInstanceFields(const Object *obj)
47{
48 ClassObject *clazz;
49 int i;
50
51 assert(obj != NULL);
52 assert(obj->clazz != NULL);
Carl Shapiro68733662010-05-10 19:55:50 -070053 LOGV("Entering verifyInstanceFields(obj=%p)", obj);
Carl Shapirod28668c2010-04-15 16:10:00 -070054 /* TODO(cshapiro): check reference offsets bitmap for agreement. */
55 for (clazz = obj->clazz; clazz != NULL; clazz = clazz->super) {
56 InstField *field = clazz->ifields;
57 for (i = 0; i < clazz->ifieldRefCount; ++i, ++field) {
58 void *addr = BYTE_OFFSET((Object *)obj, field->byteOffset);
59 VERIFY_REFERENCE(((JValue *)addr)->l);
60 }
61 }
Carl Shapiro68733662010-05-10 19:55:50 -070062 LOGV("Exiting verifyInstanceFields(obj=%p)", obj);
Carl Shapirod28668c2010-04-15 16:10:00 -070063}
64
65/*
66 * Verifies the header, static field references, and interface
Carl Shapiro1e714bb2010-03-16 03:26:49 -070067 * pointers of a class object.
68 */
69static void verifyClassObject(const ClassObject *obj)
70{
Carl Shapirod28668c2010-04-15 16:10:00 -070071 ClassObject *clazz;
Carl Shapiro1e714bb2010-03-16 03:26:49 -070072 int i;
Carl Shapiro1e714bb2010-03-16 03:26:49 -070073
74 LOGV("Entering verifyClassObject(obj=%p)", obj);
75 if (obj == gDvm.unlinkedJavaLangClass) {
76 assert(obj->obj.clazz == NULL);
77 goto exit;
78 }
79 VERIFY_REFERENCE(obj->obj.clazz);
80 assert(!strcmp(obj->obj.clazz->descriptor, "Ljava/lang/Class;"));
81 if (IS_CLASS_FLAG_SET(obj, CLASS_ISARRAY)) {
82 VERIFY_REFERENCE(obj->elementClass);
83 }
84 VERIFY_REFERENCE(obj->super);
85 VERIFY_REFERENCE(obj->classLoader);
86 /* Verify static field references. */
87 for (i = 0; i < obj->sfieldCount; ++i) {
Carl Shapirod28668c2010-04-15 16:10:00 -070088 char ch = obj->sfields[i].field.signature[0];
Carl Shapiro1e714bb2010-03-16 03:26:49 -070089 if (ch == '[' || ch == 'L') {
90 VERIFY_REFERENCE(obj->sfields[i].value.l);
91 }
92 }
Carl Shapirod28668c2010-04-15 16:10:00 -070093 /* Verify the instance fields. */
94 verifyInstanceFields((const Object *)obj);
Carl Shapiro1e714bb2010-03-16 03:26:49 -070095 /* Verify interface references. */
96 for (i = 0; i < obj->interfaceCount; ++i) {
97 VERIFY_REFERENCE(obj->interfaces[i]);
98 }
99exit:
100 LOGV("Exiting verifyClassObject(obj=%p)", obj);
101}
102
103/*
104 * Verifies the header of all array objects. If the array object is
105 * specialized to a reference type, verifies the array data as well.
106 */
107static void verifyArrayObject(const ArrayObject *array)
108{
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700109 size_t i;
110
Carl Shapiro68733662010-05-10 19:55:50 -0700111 LOGV("Entering verifyArrayObject(array=%p)", array);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700112 /* Verify the class object reference. */
113 assert(array->obj.clazz != NULL);
114 VERIFY_REFERENCE(array->obj.clazz);
115 if (IS_CLASS_FLAG_SET(array->obj.clazz, CLASS_ISOBJECTARRAY)) {
116 /* Verify the array contents. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700117 Object **contents = (Object **)array->contents;
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700118 for (i = 0; i < array->length; ++i) {
119 VERIFY_REFERENCE(contents[i]);
120 }
121 }
Carl Shapiro68733662010-05-10 19:55:50 -0700122 LOGV("Exiting verifyArrayObject(array=%p)", array);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700123}
124
125/*
126 * Verifies the header and field references of a data object.
127 */
128static void verifyDataObject(const DataObject *obj)
129{
130 ClassObject *clazz;
Carl Shapirod28668c2010-04-15 16:10:00 -0700131 int i;
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700132
133 LOGV("Entering verifyDataObject(obj=%p)", obj);
134 /* Verify the class object. */
135 assert(obj->obj.clazz != NULL);
136 VERIFY_REFERENCE(obj->obj.clazz);
137 /* Verify the instance fields. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700138 verifyInstanceFields((const Object *)obj);
Barry Hayes49576ae2010-03-19 10:10:59 -0700139 if (IS_CLASS_FLAG_SET(obj->obj.clazz, CLASS_ISREFERENCE)) {
Carl Shapiroc85ec002010-04-05 19:36:37 -0700140 /* Verify the hidden Reference.referent field. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700141 size_t offset = gDvm.offJavaLangRefReference_referent;
142 void *addr = BYTE_OFFSET((Object *)obj, offset);
Barry Hayes49576ae2010-03-19 10:10:59 -0700143 VERIFY_REFERENCE(((JValue *)addr)->l);
144 }
Carl Shapiro68733662010-05-10 19:55:50 -0700145 LOGV("Exiting verifyDataObject(obj=%p)", obj);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700146}
147
148/*
149 * Verifies an object reference. Determines the type of the reference
150 * and dispatches to a specialized verification routine.
151 */
152void dvmVerifyObject(const Object *obj)
153{
154 ClassObject *clazz;
155
156 LOGV("Entering dvmVerifyObject(obj=%p)", obj);
157 assert(obj != NULL);
Carl Shapirod28668c2010-04-15 16:10:00 -0700158 /* Check that the object is aligned. */
159 assert(((uintptr_t)obj & 7) == 0);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700160 clazz = obj->clazz;
Carl Shapirod28668c2010-04-15 16:10:00 -0700161 /* Check that the class object is aligned. */
162 assert(((uintptr_t)clazz & 7) == 0);
163 /* Dispatch a type-specific verification routine. */
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700164 if (clazz == gDvm.classJavaLangClass ||
165 obj == (Object *)gDvm.unlinkedJavaLangClass) {
166 verifyClassObject((ClassObject *)obj);
167 } else {
168 assert(clazz != NULL);
169 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) {
170 verifyArrayObject((ArrayObject *)obj);
171 } else {
172 verifyDataObject((DataObject *)obj);
173 }
174 }
175 LOGV("Exiting dvmVerifyObject(obj=%p)", obj);
176}
177
178/*
179 * Helper function to call dvmVerifyObject from a bitmap walker.
180 */
181static bool verifyBitmapCallback(size_t numPtrs, void **ptrs,
182 const void *finger, void *arg)
183{
184 size_t i;
185
186 for (i = 0; i < numPtrs; i++) {
187 dvmVerifyObject(*ptrs++);
188 }
189 return true;
190}
191
192/*
Barry Hayes962adba2010-03-17 12:12:39 -0700193 * Verifies the object references in a heap bitmap. Assumes the VM is
194 * suspended.
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700195 */
196void dvmVerifyBitmap(const HeapBitmap *bitmap)
197{
Barry Hayes962adba2010-03-17 12:12:39 -0700198 /* TODO: check that locks are held and the VM is suspended. */
199 dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700200}