blob: 9ea99020be4f0ae2cda82217eef82bfe4fc992aa [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);
53 /* TODO(cshapiro): check reference offsets bitmap for agreement. */
54 for (clazz = obj->clazz; clazz != NULL; clazz = clazz->super) {
55 InstField *field = clazz->ifields;
56 for (i = 0; i < clazz->ifieldRefCount; ++i, ++field) {
57 void *addr = BYTE_OFFSET((Object *)obj, field->byteOffset);
58 VERIFY_REFERENCE(((JValue *)addr)->l);
59 }
60 }
61}
62
63/*
64 * Verifies the header, static field references, and interface
Carl Shapiro1e714bb2010-03-16 03:26:49 -070065 * pointers of a class object.
66 */
67static void verifyClassObject(const ClassObject *obj)
68{
Carl Shapirod28668c2010-04-15 16:10:00 -070069 ClassObject *clazz;
Carl Shapiro1e714bb2010-03-16 03:26:49 -070070 int i;
Carl Shapiro1e714bb2010-03-16 03:26:49 -070071
72 LOGV("Entering verifyClassObject(obj=%p)", obj);
73 if (obj == gDvm.unlinkedJavaLangClass) {
74 assert(obj->obj.clazz == NULL);
75 goto exit;
76 }
77 VERIFY_REFERENCE(obj->obj.clazz);
78 assert(!strcmp(obj->obj.clazz->descriptor, "Ljava/lang/Class;"));
79 if (IS_CLASS_FLAG_SET(obj, CLASS_ISARRAY)) {
80 VERIFY_REFERENCE(obj->elementClass);
81 }
82 VERIFY_REFERENCE(obj->super);
83 VERIFY_REFERENCE(obj->classLoader);
84 /* Verify static field references. */
85 for (i = 0; i < obj->sfieldCount; ++i) {
Carl Shapirod28668c2010-04-15 16:10:00 -070086 char ch = obj->sfields[i].field.signature[0];
Carl Shapiro1e714bb2010-03-16 03:26:49 -070087 if (ch == '[' || ch == 'L') {
88 VERIFY_REFERENCE(obj->sfields[i].value.l);
89 }
90 }
Carl Shapirod28668c2010-04-15 16:10:00 -070091 /* Verify the instance fields. */
92 verifyInstanceFields((const Object *)obj);
Carl Shapiro1e714bb2010-03-16 03:26:49 -070093 /* Verify interface references. */
94 for (i = 0; i < obj->interfaceCount; ++i) {
95 VERIFY_REFERENCE(obj->interfaces[i]);
96 }
97exit:
98 LOGV("Exiting verifyClassObject(obj=%p)", obj);
99}
100
101/*
102 * Verifies the header of all array objects. If the array object is
103 * specialized to a reference type, verifies the array data as well.
104 */
105static void verifyArrayObject(const ArrayObject *array)
106{
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700107 size_t i;
108
109 LOGV("Entering verifyArrayObject(obj=%p)", obj);
110 /* Verify the class object reference. */
111 assert(array->obj.clazz != NULL);
112 VERIFY_REFERENCE(array->obj.clazz);
113 if (IS_CLASS_FLAG_SET(array->obj.clazz, CLASS_ISOBJECTARRAY)) {
114 /* Verify the array contents. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700115 Object **contents = (Object **)array->contents;
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700116 for (i = 0; i < array->length; ++i) {
117 VERIFY_REFERENCE(contents[i]);
118 }
119 }
120 LOGV("Exiting verifyArrayObject(obj=%p)", obj);
121}
122
123/*
124 * Verifies the header and field references of a data object.
125 */
126static void verifyDataObject(const DataObject *obj)
127{
128 ClassObject *clazz;
Carl Shapirod28668c2010-04-15 16:10:00 -0700129 int i;
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700130
131 LOGV("Entering verifyDataObject(obj=%p)", obj);
132 /* Verify the class object. */
133 assert(obj->obj.clazz != NULL);
134 VERIFY_REFERENCE(obj->obj.clazz);
135 /* Verify the instance fields. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700136 verifyInstanceFields((const Object *)obj);
Barry Hayes49576ae2010-03-19 10:10:59 -0700137 if (IS_CLASS_FLAG_SET(obj->obj.clazz, CLASS_ISREFERENCE)) {
Carl Shapiroc85ec002010-04-05 19:36:37 -0700138 /* Verify the hidden Reference.referent field. */
Carl Shapirod28668c2010-04-15 16:10:00 -0700139 size_t offset = gDvm.offJavaLangRefReference_referent;
140 void *addr = BYTE_OFFSET((Object *)obj, offset);
Barry Hayes49576ae2010-03-19 10:10:59 -0700141 VERIFY_REFERENCE(((JValue *)addr)->l);
142 }
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700143 LOGV("Exiting verifyDataObject(obj=%p) %zx", obj, length);
144}
145
146/*
147 * Verifies an object reference. Determines the type of the reference
148 * and dispatches to a specialized verification routine.
149 */
150void dvmVerifyObject(const Object *obj)
151{
152 ClassObject *clazz;
153
154 LOGV("Entering dvmVerifyObject(obj=%p)", obj);
155 assert(obj != NULL);
Carl Shapirod28668c2010-04-15 16:10:00 -0700156 /* Check that the object is aligned. */
157 assert(((uintptr_t)obj & 7) == 0);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700158 clazz = obj->clazz;
Carl Shapirod28668c2010-04-15 16:10:00 -0700159 /* Check that the class object is aligned. */
160 assert(((uintptr_t)clazz & 7) == 0);
161 /* Dispatch a type-specific verification routine. */
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700162 if (clazz == gDvm.classJavaLangClass ||
163 obj == (Object *)gDvm.unlinkedJavaLangClass) {
164 verifyClassObject((ClassObject *)obj);
165 } else {
166 assert(clazz != NULL);
167 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) {
168 verifyArrayObject((ArrayObject *)obj);
169 } else {
170 verifyDataObject((DataObject *)obj);
171 }
172 }
173 LOGV("Exiting dvmVerifyObject(obj=%p)", obj);
174}
175
176/*
177 * Helper function to call dvmVerifyObject from a bitmap walker.
178 */
179static bool verifyBitmapCallback(size_t numPtrs, void **ptrs,
180 const void *finger, void *arg)
181{
182 size_t i;
183
184 for (i = 0; i < numPtrs; i++) {
185 dvmVerifyObject(*ptrs++);
186 }
187 return true;
188}
189
190/*
Barry Hayes962adba2010-03-17 12:12:39 -0700191 * Verifies the object references in a heap bitmap. Assumes the VM is
192 * suspended.
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700193 */
194void dvmVerifyBitmap(const HeapBitmap *bitmap)
195{
Barry Hayes962adba2010-03-17 12:12:39 -0700196 /* TODO: check that locks are held and the VM is suspended. */
197 dvmHeapBitmapWalk(bitmap, verifyBitmapCallback, NULL);
Carl Shapiro1e714bb2010-03-16 03:26:49 -0700198}