Debugger.cpp revision 9a3147c7412f4794434b4c2604aa2ba784867774
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Link between JDWP and the VM.  The code here only runs as a result of
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * requests from the debugger, so speed is not essential.  Maintaining
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * isolation of the JDWP code should make it easier to maintain and reuse.
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Collecting all debugger-related pieces here will also allow us to #ifdef
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the JDWP code out of release builds.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNotes on garbage collection and object registration
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJDWP does not allow the debugger to assume that objects passed to it
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectwill not be garbage collected.  It specifies explicit commands (e.g.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectReference.DisableCollection) to allow the debugger to manage
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject lifetime.  It does, however, require that the VM not re-use an
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject ID unless an explicit "dispose" call has been made, and if the
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectVM asks for a now-collected object we must return INVALID_OBJECT.
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJDWP also requires that, while the VM is suspended, no garbage collection
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectoccur.  The JDWP docs suggest that this is obvious, because no threads
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectcan be running.  Unfortunately it's not entirely clear how to deal
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectwith situations where the debugger itself allocates strings or executes
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectcode as part of displaying variables.  The easiest way to enforce this,
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectshort of disabling GC whenever the debugger is connected, is to ensure
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectthat the debugger thread can't cause a GC: it has to expand the heap or
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail to allocate.  (Might want to make that "is debugger thread AND all
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectother threads are suspended" to avoid unnecessary heap expansion by a
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpoorly-timed JDWP request.)
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe use an "object registry" so that we can separate our internal
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectrepresentation from what we show the debugger.  This allows us to
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectreturn a registry table index instead of a pointer or handle.
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThere are various approaches we can take to achieve correct behavior:
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(1) Disable garbage collection entirely while the debugger is attached.
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThis is very easy, but doesn't allow extended debugging sessions on
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsmall devices.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(2) Keep a list of all object references requested by or sent to the
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdebugger, and include the list in the GC root set.  This ensures that
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobjects the debugger might care about don't go away.  This is straightforward,
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbut it can cause us to hold on to large objects and prevent finalizers from
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbeing executed.
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project(3) Keep a list of what amount to weak object references.  This way we
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdon't interfere with the GC, and can support JDWP requests like
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"ObjectReference.IsCollected".
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe current implementation is #2.  The set should be reasonably small and
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectperformance isn't critical, so a simple expanding array can be used.
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNotes on threads:
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe VM has a Thread struct associated with every active thread.  The
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThreadId we pass to the debugger is the ObjectId for the java/lang/Thread
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectobject, so to retrieve the VM's Thread struct we have to scan through the
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlist looking for a match.
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWhen a thread goes away, we lock the list and free the struct.  To
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectavoid having the thread list updated or Thread structs freed out from
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunder us, we want to acquire and hold the thread list lock while we're
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectperforming operations on Threads.  Exceptions to this rule are noted in
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecta couple of places.
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe can speed this up a bit by adding a Thread struct pointer to the
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectjava/lang/Thread object, and ensuring that both are discarded at the
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectsame time.
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define THREAD_GROUP_ALL ((ObjectId) 0x12345)   // magic, internal-only value
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kSlot0Sub   1000    // Eclipse workaround
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System init.  We don't allocate the registry until first use.
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure we do this before initializing JDWP.
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDebuggerStartup(void)
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
10096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden    if (!dvmBreakpointStartup())
10196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden        return false;
10296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.dbgRegistry = dvmHashTableCreate(1000, NULL);
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (gDvm.dbgRegistry != NULL);
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free registry storage.
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDebuggerShutdown(void)
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableFree(gDvm.dbgRegistry);
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.dbgRegistry = NULL;
11496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden    dvmBreakpointShutdown();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pass these through to the VM functions.  Allows extended checking
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (e.g. "errorcheck" mutexes).  If nothing else we can assert() success.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgInitMutex(pthread_mutex_t* pMutex)
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmInitMutex(pMutex);
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgLockMutex(pthread_mutex_t* pMutex)
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockMutex(pMutex);
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnlockMutex(pthread_mutex_t* pMutex)
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockMutex(pMutex);
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgInitCond(pthread_cond_t* pCond)
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pthread_cond_init(pCond, NULL);
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondWait(pthread_cond_t* pCond, pthread_mutex_t* pMutex)
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
140b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro    int cc __attribute__ ((__unused__)) = pthread_cond_wait(pCond, pMutex);
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(cc == 0);
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondSignal(pthread_cond_t* pCond)
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
145b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro    int cc __attribute__ ((__unused__)) = pthread_cond_signal(pCond);
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(cc == 0);
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgCondBroadcast(pthread_cond_t* pCond)
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
150b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro    int cc __attribute__ ((__unused__)) = pthread_cond_broadcast(pCond);
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(cc == 0);
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* keep track of type, in case we need to distinguish them someday */
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegistryType {
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    kObjectId = 0xc1, kRefTypeId
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegistryType;
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Hash function for object IDs.  Since objects are at least 8 bytes, and
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * could someday be allocated on 16-byte boundaries, we don't want to use
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the low 4 bits in our hash.
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline u4 registryHash(u4 val)
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return val >> 4;
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This is a dvmHashTableLookup() callback.)
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int registryCompare(const void* obj1, const void* obj2)
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (int) obj1 - (int) obj2;
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if an id is already in the list.
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the list doesn't yet exist, this creates it.
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Lock the registry before calling here.
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
186b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#ifndef NDEBUG
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool lookupId(ObjectId id)
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* found;
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    found = dvmHashTableLookup(gDvm.dbgRegistry, registryHash((u4) id),
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (void*)(u4) id, registryCompare, false);
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (found == NULL)
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(found == (void*)(u4) id);
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
198b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#endif
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Register an object, if it hasn't already been.
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is used for both ObjectId and RefTypeId.  In theory we don't have
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to register RefTypeIds unless we're worried about classes unloading.
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Null references must be represented as zero, or the debugger will get
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * very confused.
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId registerObject(const Object* obj, RegistryType type, bool reg)
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ObjectId id;
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL)
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 0;
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert((u4) obj != 0xcccccccc);
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert((u4) obj > 0x100);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    id = (ObjectId)(u4)obj | ((u8) type) << 32;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!reg)
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return id;
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.dbgRegistry);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!gDvm.debuggerConnected) {
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* debugger has detached while we were doing stuff? */
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGI("ignoring registerObject request in thread=%d\n",
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmThreadSelf()->threadId);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //dvmAbort();
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    (void) dvmHashTableLookup(gDvm.dbgRegistry, registryHash((u4) id),
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (void*)(u4) id, registryCompare, true);
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.dbgRegistry);
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return id;
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that an object has been registered.  If it hasn't, the debugger
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is asking for something we didn't send it, which means something
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * somewhere is broken.
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If speed is an issue we can encode the registry index in the high
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * four bytes.  We could also just hard-wire this to "true".
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note this actually takes both ObjectId and RefTypeId.
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
250b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#ifndef NDEBUG
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool objectIsRegistered(ObjectId id, RegistryType type)
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(type);
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (id == 0)        // null reference?
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.dbgRegistry);
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = lookupId(id);
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.dbgRegistry);
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
263b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#endif
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a RefTypeId.
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These are rarely NULL, but can be (e.g. java/lang/Object's superclass).
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeId(ClassObject* clazz)
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, true);
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
274e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#if 0
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeIdNoReg(ClassObject* clazz)
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, false);
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
279e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#endif
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* refTypeIdToClassObject(RefTypeId id)
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(objectIsRegistered(id, kRefTypeId) || !gDvm.debuggerConnected);
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (ClassObject*)(u4) id;
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from an ObjectId.
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectId(const Object* obj)
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return registerObject(obj, kObjectId, true);
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectIdNoReg(const Object* obj)
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return registerObject(obj, kObjectId, false);
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* objectIdToObject(ObjectId id)
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(objectIsRegistered(id, kObjectId) || !gDvm.debuggerConnected);
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Object*)(u4) id;
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
304c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Register an object ID that might not have been registered previously.
305c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden *
306c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Normally this wouldn't happen -- the conversion to an ObjectId would
307c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * have added the object to the registry -- but in some cases (e.g.
308c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * throwing exceptions) we really want to do the registration late.
309c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden */
310c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFaddenvoid dvmDbgRegisterObjectId(ObjectId id)
311c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden{
312c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    Object* obj = (Object*)(u4) id;
313c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    LOGV("+++ registering %p (%s)\n", obj, obj->clazz->descriptor);
314c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    registerObject(obj, kObjectId, true);
315c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden}
316c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden
317c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden/*
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a MethodId.
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index.  For now we just use the Method*.
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic MethodId methodToMethodId(const Method* meth)
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (MethodId)(u4) meth;
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* methodIdToMethod(RefTypeId refTypeId, MethodId id)
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? verify "id" is actually a method in "refTypeId"
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Method*)(u4) id;
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FieldId.
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index.  For now we just use the Field*.
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FieldId fieldToFieldId(const Field* field)
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (FieldId)(u4) field;
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Field* fieldIdToField(RefTypeId refTypeId, FieldId id)
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? verify "id" is actually a field in "refTypeId"
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Field*)(u4) id;
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FrameId.
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We just return a pointer to the stack frame.
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FrameId frameToFrameId(const void* frame)
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (FrameId)(u4) frame;
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
358fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapirostatic u4* frameIdToFrame(FrameId id)
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
360fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    return (u4*)(u4) id;
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the invocation request state.
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDebugInvokeReq* dvmDbgGetInvokeReq(void)
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return &dvmThreadSelf()->invokeReq;
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable the object registry, but don't enable debugging features yet.
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgConnected(void)
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!gDvm.debuggerConnected);
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("JDWP has attached\n");
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmHashTableNumEntries(gDvm.dbgRegistry) == 0);
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerConnected = true;
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable all debugging features, including scans for breakpoints.
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a no-op if we're already active.
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgActive(void)
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3959a3147c7412f4794434b4c2604aa2ba784867774buzbee    if (gDvm.debuggerActive)
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGI("Debugger is active\n");
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmInitBreakpoints();
4009a3147c7412f4794434b4c2604aa2ba784867774buzbee    gDvm.debuggerActive = true;
4019a3147c7412f4794434b4c2604aa2ba784867774buzbee    dvmUpdateAllInterpBreak(kInterpDebugBreak, kSubModeDebuggerActive, true);
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Disable debugging features.
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "debuggerConnected" to false, which disables use of the object
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registry.
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDisconnected(void)
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(gDvm.debuggerConnected);
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4169a3147c7412f4794434b4c2604aa2ba784867774buzbee    gDvm.debuggerActive = false;
4179a3147c7412f4794434b4c2604aa2ba784867774buzbee    dvmUpdateAllInterpBreak(kInterpDebugBreak, kSubModeDebuggerActive, false);
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.dbgRegistry);
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerConnected = false;
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4222fbe6d15ed8d266ed55fb76e97f866dbd07d5fa6Andy McFadden    LOGD("Debugger has detached; object registry had %d entries\n",
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashTableNumEntries(gDvm.dbgRegistry));
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //int i;
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //for (i = 0; i < gDvm.dbgRegistryNext; i++)
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //    LOGVV("%4d: 0x%llx\n", i, gDvm.dbgRegistryTable[i]);
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableClear(gDvm.dbgRegistry);
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.dbgRegistry);
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if a debugger is connected.
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not return "true" if it's just a DDM server.
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsDebuggerConnected(void)
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
4399a3147c7412f4794434b4c2604aa2ba784867774buzbee    return gDvm.debuggerActive;
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get time since last debugger activity.  Used when figuring out if the
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger has finished configuring us.
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projects8 dvmDbgLastDebuggerActivity(void)
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmJdwpLastDebuggerActivity(gDvm.jdwpState);
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is running, don't allow GC.
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadRunning(void)
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, THREAD_RUNNING);
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is idle, allow GC.
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadWaiting(void)
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, THREAD_VMWAIT);
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Restore state returned by Running/Waiting calls.
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadContinuing(int status)
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, status);
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The debugger wants us to exit.
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExit(int status)
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? invoke System.exit() to perform exit processing; ends up
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // in System.exitInternal(), which can call JNI exit hook
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGI("GC lifetime allocation: %d bytes\n", gDvm.allocProf.allocCount);
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (CALC_CACHE_STATS) {
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpAtomicCacheStats(gDvm.instanceofCache);
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpBootClassPath();
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef PROFILE_FIELD_ACCESS
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDumpFieldAccessCounts();
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    exit(status);
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Class, Object, Array
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class's type descriptor from a reference type ID.
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetClassDescriptor(RefTypeId id)
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(id);
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->descriptor;
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
5136ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden * Convert a RefTypeId to an ObjectId.
5146ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden */
5156ff3c8fde9623dadad726dbd5e1658585c321751Andy McFaddenObjectId dvmDbgGetClassObject(RefTypeId id)
5166ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden{
5176ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden    ClassObject* clazz = refTypeIdToClassObject(id);
5186ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden    return objectToObjectId((Object*) clazz);
5196ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden}
5206ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden
5216ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden/*
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the superclass of a class (will be NULL for java/lang/Object).
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetSuperclass(RefTypeId id)
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return classObjectToRefTypeId(clazz->super);
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's defining class loader.
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetClassLoader(RefTypeId id)
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(clazz->classLoader);
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's access flags.
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetAccessFlags(RefTypeId id)
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->accessFlags & JAVA_FLAGS_MASK;
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this class an interface?
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsInterface(RefTypeId id)
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmIsInterfaceClass(clazz);
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmHashForeach callback
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int copyRefType(void* vclazz, void* varg)
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId** pRefType = (RefTypeId**)varg;
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    **pRefType = classObjectToRefTypeId((ClassObject*) vclazz);
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    (*pRefType)++;
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the complete list of reference classes (i.e. all classes except
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the primitive types).
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values.
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf)
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId* pRefType;
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.loadedClasses);
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pNumClasses = dvmHashTableNumEntries(gDvm.loadedClasses);
580fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    pRefType = *pClassRefBuf =
581fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        (RefTypeId*)malloc(sizeof(RefTypeId) * *pNumClasses);
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmHashForeach(gDvm.loadedClasses, copyRefType, &pRefType) != 0) {
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Warning: problem getting class list\n");
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* not really expecting this to happen */
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(pRefType - *pClassRefBuf == (int) *pNumClasses);
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.loadedClasses);
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of reference classes "visible" to the specified class
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loader.  A class is visible to a class loader if the ClassLoader object
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is the defining loader or is listed as an initiating loader.
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values.
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId** pClassRefBuf)
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* classLoader;
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numClasses = 0, maxClasses;
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    classLoader = objectIdToObject(classLoaderId);
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // I don't think classLoader can be NULL, but the spec doesn't say
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("GetVisibleList: comparing to %p\n", classLoader);
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.loadedClasses);
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* over-allocate the return buffer */
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    maxClasses = dvmHashTableNumEntries(gDvm.loadedClasses);
615fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    *pClassRefBuf = (RefTypeId*)malloc(sizeof(RefTypeId) * maxClasses);
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Run through the list, looking for matches.
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HashIter iter;
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (dvmHashIterBegin(gDvm.loadedClasses, &iter); !dvmHashIterDone(&iter);
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashIterNext(&iter))
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* clazz = (ClassObject*) dvmHashIterData(&iter);
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (clazz->classLoader == classLoader ||
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmLoaderInInitiatingList(clazz, classLoader))
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("  match '%s'\n", clazz->descriptor);
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (*pClassRefBuf)[numClasses++] = classObjectToRefTypeId(clazz);
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pNumClasses = numClasses;
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.loadedClasses);
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
6390970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the "JNI signature" for a class, e.g. "Ljava/lang/String;".
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
6410970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Our class descriptors are in the correct format, so we just return that.
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
6430970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic const char* jniSignature(ClassObject* clazz)
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
6450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return clazz->descriptor;
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get information about a class.
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "pSignature" is not NULL, *pSignature gets the "JNI signature" of
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class.
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
6550970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    const char** pSignature)
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(classId);
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz->descriptor[0] == '[') {
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* generated array class */
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pStatus = CS_VERIFIED | CS_PREPARED;
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pTypeTag = TT_ARRAY;
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (clazz->status == CLASS_ERROR)
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pStatus = CS_ERROR;
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pStatus = CS_VERIFIED | CS_PREPARED | CS_INITIALIZED;
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsInterfaceClass(clazz))
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pTypeTag = TT_INTERFACE;
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pTypeTag = TT_CLASS;
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pSignature != NULL)
6740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        *pSignature = jniSignature(clazz);
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search the list of loaded classes for a match.
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RefTypeId* pRefTypeId)
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = dvmFindLoadedClass(classDescriptor);
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz != NULL) {
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeId = classObjectToRefTypeId(clazz);
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get an object's class and "type tag".
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId* pRefTypeId)
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsArrayClass(obj->clazz))
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_ARRAY;
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (dvmIsInterfaceClass(obj->clazz))
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_INTERFACE;
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_CLASS;
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pRefTypeId = classObjectToRefTypeId(obj->clazz);
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class object's "type tag".
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu1 dvmDbgGetClassObjectType(RefTypeId refTypeId)
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(refTypeId);
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsArrayClass(clazz))
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_ARRAY;
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (dvmIsInterfaceClass(clazz))
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_INTERFACE;
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_CLASS;
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class' signature.
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
7290970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenconst char* dvmDbgGetSignature(RefTypeId refTypeId)
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7360970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return jniSignature(clazz);
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get class' source file.
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetSourceFile(RefTypeId refTypeId)
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->sourceFile;
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
7550970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get an object's type name.  (For log message display only.)
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
7570970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenconst char* dvmDbgGetObjectTypeName(ObjectId objectId)
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
7590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (objectId == 0)
7600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return "(null)";
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    Object* obj = objectIdToObject(objectId);
7630970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return jniSignature(obj->clazz);
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
7670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine whether or not a tag represents a primitive type.
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
7690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic bool isTagPrimitive(u1 tag)
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
7710970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    switch (tag) {
7720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_BYTE:
7730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_CHAR:
7740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_FLOAT:
7750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_DOUBLE:
7760970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_INT:
7770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_LONG:
7780970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_SHORT:
7790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_VOID:
7800970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_BOOLEAN:
7810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return true;
7820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_ARRAY:
7830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_OBJECT:
7840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_STRING:
7850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_CLASS_OBJECT:
7860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_THREAD:
7870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_THREAD_GROUP:
7880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    case JT_CLASS_LOADER:
7890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return false;
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
7910970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        LOGE("ERROR: unhandled tag '%c'\n", tag);
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
7930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return false;
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
7980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine the best tag type given an object's class.
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
8000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 tagFromClass(ClassObject* clazz)
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
8020970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (dvmIsArrayClass(clazz))
8030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return JT_ARRAY;
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8050970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (clazz == gDvm.classJavaLangString) {
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_STRING;
8070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else if (clazz == gDvm.classJavaLangClass) {
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_CLASS_OBJECT;
8090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else if (dvmInstanceof(clazz, gDvm.classJavaLangThread)) {
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD;
8110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else if (dvmInstanceof(clazz, gDvm.classJavaLangThreadGroup)) {
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD_GROUP;
8130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else if (dvmInstanceof(clazz, gDvm.classJavaLangClassLoader)) {
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_CLASS_LOADER;
8150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else {
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_OBJECT;
8170970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    }
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
8210970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Return a basic tag value based solely on a type descriptor.
8220970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden *
8230970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * The ASCII value maps directly to the JDWP tag constants, so we don't
8240970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * need to do much here.  This does not return the fancier tags like
8250970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * JT_THREAD.
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
8270970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 basicTagFromDescriptor(const char* descriptor)
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
8290970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return descriptor[0];
8300970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden}
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8320970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/*
8330970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Objects declared to hold Object might actually hold a more specific
8340970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * type.  The debugger may take a special interest in these (e.g. it
8350970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * wants to display the contents of Strings), so we want to return an
8360970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * appropriate tag.
8370970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden *
8380970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Null objects are tagged JT_OBJECT.
8390970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */
8400970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 tagFromObject(const Object* obj)
8410970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{
8420970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (obj == NULL)
8430970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return JT_OBJECT;
8440970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return tagFromClass(obj->clazz);
8450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden}
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8470970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/*
8480970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Determine the tag for an object.
8490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden *
8500970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * "objectId" may be 0 (i.e. NULL reference).
8510970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */
8520970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetObjectTag(ObjectId objectId)
8530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{
8540970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return tagFromObject(objectIdToObject(objectId));
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the widths of the specified JDWP.Tag value.
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetTagWidth(int tag)
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_VOID:
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 0;
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 1;
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 2;
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 4;
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_STRING:
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD:
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD_GROUP:
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_LOADER:
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_OBJECT:
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sizeof(ObjectId);
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 8;
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the length of the specified array.
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetArrayLength(ObjectId arrayId)
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return arrayObj->length;
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a tag indicating the general type of elements in the array.
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
9060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetArrayElementTag(ObjectId arrayId)
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    ClassObject* arrayClass = arrayObj->obj.clazz;
9110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    u1 tag = basicTagFromDescriptor(arrayClass->descriptor + 1);
9120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (!isTagPrimitive(tag)) {
9130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        /* try to refine it */
9140970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        tag = tagFromClass(arrayClass->elementClass);
9150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    }
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9170970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return tag;
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a series of values with the specified width, changing the byte
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ordering to big-endian.
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesToBE(u1* out, const u1* in, int count, int width)
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (width) {
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 1:
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memcpy(out, in, count);
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 2:
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u2*) out)+i) = get2BE(in + i*2);
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 4:
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u4*) out)+i) = get4BE(in + i*4);
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 8:
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u8*) out)+i) = get8BE(in + i*8);
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
9500970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy a series of values with the specified width, changing the
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte order from big-endian.
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesFromBE(u1* out, const u1* in, int count, int width)
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (width) {
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 1:
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memcpy(out, in, count);
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 2:
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set2BE(out + i*2, *((u2*)in + i));
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 4:
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set4BE(out + i*4, *((u4*)in + i));
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 8:
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set8BE(out + i*8, *((u8*)in + i));
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output a piece of an array to the reply buffer.
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if something looks fishy.
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* data = (const u1*)arrayObj->contents;
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag;
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (firstIndex + count > (int)arrayObj->length) {
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Request for index=%d + count=%d excceds length=%d\n",
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstIndex, count, arrayObj->length);
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    tag = basicTagFromDescriptor(arrayObj->obj.clazz->descriptor + 1);
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(tag)) {
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int width = dvmDbgGetTagWidth(tag);
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u1* outBuf;
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        outBuf = expandBufAddSpace(pReply, count * width);
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyValuesToBE(outBuf, data + firstIndex*width, count, width);
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object** pObjects;
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects = (Object**) data;
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects += firstIndex;
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> copying %d object IDs\n", count);
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //assert(tag == JT_OBJECT);     // could be object or "refined" type
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++, pObjects++) {
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u1 thisTag;
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (*pObjects != NULL)
10200970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden                thisTag = tagFromObject(*pObjects);
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            else
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                thisTag = tag;
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAdd1(pReply, thisTag);
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddObjectId(pReply, objectToObjectId(*pObjects));
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set a range of elements in an array from the data in "buf".
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* buf)
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* data = (u1*)arrayObj->contents;
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag;
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (firstIndex + count > (int)arrayObj->length) {
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Attempt to set index=%d + count=%d excceds length=%d\n",
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstIndex, count, arrayObj->length);
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
10490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    tag = basicTagFromDescriptor(arrayObj->obj.clazz->descriptor + 1);
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(tag)) {
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int width = dvmDbgGetTagWidth(tag);
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> setting %d '%c' width=%d\n", count, tag, width);
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyValuesFromBE(data + firstIndex*width, buf, count, width);
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object** pObjects;
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects = (Object**) data;
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects += firstIndex;
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> setting %d objects", count);
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* should do array type check here */
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++) {
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ObjectId id = dvmReadObjectId(&buf);
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pObjects++ = objectIdToObject(id);
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new string.
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only place the reference will be held in the VM is in our registry.
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgCreateString(const char* str)
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* strObj;
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108581f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes    strObj = dvmCreateStringFromCstr(str);
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmReleaseTrackedAlloc((Object*) strObj, NULL);
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId((Object*) strObj);
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1091f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Allocate a new object of the specified type.
1092f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden *
1093f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Add it to the registry to prevent it from being GCed.
1094f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden */
1095f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFaddenObjectId dvmDbgCreateObject(RefTypeId classId)
1096f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden{
1097f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    ClassObject* clazz = refTypeIdToClassObject(classId);
1098f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    Object* newObj = dvmAllocObject(clazz, ALLOC_DEFAULT);
1099f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    dvmReleaseTrackedAlloc(newObj, NULL);
1100f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    return objectToObjectId(newObj);
1101f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden}
1102f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden
1103f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden/*
1104884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Allocate a new array object of the specified type and length.  The
1105884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * type is the array type, not the element type.
1106884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden *
1107884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Add it to the registry to prevent it from being GCed.
1108884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden */
1109884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFaddenObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length)
1110884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden{
1111884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    ClassObject* clazz = refTypeIdToClassObject(arrayTypeId);
1112884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    Object* newObj = (Object*) dvmAllocArrayByClass(clazz, length, ALLOC_DEFAULT);
1113884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    dvmReleaseTrackedAlloc(newObj, NULL);
1114884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    return objectToObjectId(newObj);
1115884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden}
1116884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden
1117884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden/*
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if "instClassId" is an instance of "classId".
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId)
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* instClazz = refTypeIdToClassObject(instClassId);
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(classId);
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmInstanceof(instClazz, clazz);
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Method and Field
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the method name from a MethodId.
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id)
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* meth;
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    meth = methodIdToMethod(refTypeId, id);
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return meth->name;
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
11470970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Augment the access flags for synthetic methods and fields by setting
11480970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * the (as described by the spec) "0xf0000000 bit".
11490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */
11500970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u4 augmentedAccessFlags(u4 accessFlags)
11510970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{
11520970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if ((accessFlags & ACC_SYNTHETIC) != 0) {
11530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return accessFlags | 0xf0000000;
11540970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else {
11550970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        return accessFlags;
11560970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    }
11570970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden}
11580970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
11590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/*
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Fields and ReferenceType.FieldsWithGeneric:
11610970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * output all fields declared by the class.  Inherited fields are
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included.
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const u1 genericSignature[1] = "";
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field;
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 declared;
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    declared = clazz->sfieldCount + clazz->ifieldCount;
1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, declared);
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->sfieldCount; i++) {
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        field = (Field*) &clazz->sfields[i];
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddFieldId(pReply, fieldToFieldId(field));
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->name);
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->signature);
1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
11870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd4BE(pReply, augmentedAccessFlags(field->accessFlags));
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->ifieldCount; i++) {
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        field = (Field*) &clazz->ifields[i];
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddFieldId(pReply, fieldToFieldId(field));
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->name);
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->signature);
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
11970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd4BE(pReply, augmentedAccessFlags(field->accessFlags));
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Methods and ReferenceType.MethodsWithGeneric:
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output all methods declared by the class.  Inherited methods are
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included.
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DexStringCache stringCache;
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const u1 genericSignature[1] = "";
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* meth;
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 declared;
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexStringCacheInit(&stringCache);
1217de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    declared = clazz->directMethodCount + clazz->virtualMethodCount;
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, declared);
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->directMethodCount; i++) {
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = &clazz->directMethods[i];
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddMethodId(pReply, methodToMethodId(meth));
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) meth->name);
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply,
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (const u1*) dexProtoGetMethodDescriptor(&meth->prototype,
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    &stringCache));
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
12360970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd4BE(pReply, augmentedAccessFlags(meth->accessFlags));
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->virtualMethodCount; i++) {
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = &clazz->virtualMethods[i];
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddMethodId(pReply, methodToMethodId(meth));
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) meth->name);
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply,
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (const u1*) dexProtoGetMethodDescriptor(&meth->prototype,
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    &stringCache));
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
12500970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd4BE(pReply, augmentedAccessFlags(meth->accessFlags));
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexStringCacheRelease(&stringCache);
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output all interfaces directly implemented by the class.
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply)
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i, start, count;
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz->super == NULL)
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = 0;
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = clazz->super->iftableCount;
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = clazz->iftableCount - start;
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, count);
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = start; i < clazz->iftableCount; i++) {
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* iface = clazz->iftable[i].clazz;
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddRefTypeId(pReply, classObjectToRefTypeId(iface));
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DebugCallbackContext {
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numItems;
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply;
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // used by locals table
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool withGeneric;
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DebugCallbackContext;
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1287de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirostatic int lineTablePositionsCb(void *cnxt, u4 address, u4 lineNum)
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt;
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pContext->pReply, address);
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, lineNum);
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pContext->numItems++;
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.LineTable: output the line table.
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we operate in Dalvik's 16-bit units rather than bytes.
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method;
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 start, end;
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext context;
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset (&context, 0, sizeof(DebugCallbackContext));
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    method = methodIdToMethod(refTypeId, methodId);
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsNativeMethod(method)) {
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = (u8) -1;
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        end = (u8) -1;
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = 0;
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        end = dvmGetMethodInsnsSize(method);
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pReply, start);
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pReply, end);
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Add numLines later
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t numLinesOffset = expandBufGetLength(pReply);
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, 0);
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pReply = pReply;
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile,
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmGetMethodCode(method),
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lineTablePositionsCb, NULL, &context);
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Eclipse appears to expect that the "this" reference is in slot zero.
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it's not, the "variables" display will show two copies of "this",
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possibly because it gets "this" from SF.ThisObject and then displays
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all locals with nonzero slot numbers.
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * So, we remap the item in slot 0 to 1000, and remap "this" to zero.  On
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SF.GetValues / SF.SetValues we map them back.
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int tweakSlot(int slot, const char* name)
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newSlot = slot;
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (strcmp(name, "this") == 0)      // only remap "this" ptr
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = 0;
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (slot == 0)                 // always remap slot 0
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = kSlot0Sub;
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("untweak: %d to %d\n", slot, newSlot);
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newSlot;
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reverse Eclipse hack.
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int untweakSlot(int slot, const void* framePtr)
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newSlot = slot;
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (slot == kSlot0Sub) {
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = 0;
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (slot == 0) {
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const Method* method = saveArea->method;
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = method->registersSize - method->insSize;
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("untweak: %d to %d\n", slot, newSlot);
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newSlot;
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void variableTableCb (void *cnxt, u2 reg, u4 startAddress,
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 endAddress, const char *name, const char *descriptor,
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const char *signature)
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt;
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    reg = (u2) tweakSlot(reg, name);
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    %2d: %d(%d) '%s' '%s' slot=%d\n",
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pContext->numItems, startAddress, endAddress - startAddress,
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        name, descriptor, reg);
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pContext->pReply, startAddress);
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAddUtf8String(pContext->pReply, (const u1*)name);
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAddUtf8String(pContext->pReply, (const u1*)descriptor);
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pContext->withGeneric) {
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pContext->pReply, (const u1*) signature);
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, endAddress - startAddress);
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, reg);
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pContext->numItems++;
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.VariableTable[WithGeneric]: output information about local
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * variables for the specified method.
1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId methodId,
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool withGeneric, ExpandBuf* pReply)
1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method;
1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext context;
1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset (&context, 0, sizeof(DebugCallbackContext));
1416de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    method = methodIdToMethod(refTypeId, methodId);
1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, method->insSize);
1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Add numLocals later
1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t numLocalsOffset = expandBufGetLength(pReply);
1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, 0);
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pReply = pReply;
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.withGeneric = withGeneric;
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile,
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmGetMethodCode(method),
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        NULL, variableTableCb, &context);
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set4BE(expandBufGetBuffer(pReply) + numLocalsOffset, context.numItems);
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
14380970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the basic tag for an instance field.
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
14400970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetFieldBasicTag(ObjectId objId, FieldId fieldId)
1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objId);
1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
14440970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    const Field* field = fieldIdToField(classId, fieldId);
14450970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return basicTagFromDescriptor(field->signature);
1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
14490970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Get the basic tag for a static field.
1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
14510970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenu1 dvmDbgGetStaticFieldBasicTag(RefTypeId refTypeId, FieldId fieldId)
1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
14530970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    const Field* field = fieldIdToField(refTypeId, fieldId);
14540970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return basicTagFromDescriptor(field->signature);
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14570970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
14590970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy the value of a static field into the output buffer, preceded
14600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * by an appropriate tag.  The tag is based on the value held by the
14610970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * field, not the field's type.
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
14630970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenvoid dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, ExpandBuf* pReply)
1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
14670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    InstField* ifield = (InstField*) fieldIdToField(classId, fieldId);
14680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    u1 tag = basicTagFromDescriptor(ifield->field.signature);
14690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
14700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (tag == JT_ARRAY || tag == JT_OBJECT) {
14710970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        Object* objVal = dvmGetFieldObject(obj, ifield->byteOffset);
14720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        tag = tagFromObject(objVal);
14730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd1(pReply, tag);
14740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAddObjectId(pReply, objectToObjectId(objVal));
14750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        LOGV("    --> ifieldId %x --> tag '%c' %p\n", fieldId, tag, objVal);
14760970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else {
14770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        JValue value;
1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        LOGV("    --> ifieldId %x --> tag '%c'\n", fieldId, tag);
14800970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd1(pReply, tag);
14810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
14820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        switch (tag) {
14830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_BOOLEAN:
14840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd1(pReply, dvmGetFieldBoolean(obj, ifield->byteOffset));
14850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
14860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_BYTE:
14870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd1(pReply, dvmGetFieldByte(obj, ifield->byteOffset));
14880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
14890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_SHORT:
14900970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd2BE(pReply, dvmGetFieldShort(obj, ifield->byteOffset));
14910970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
14920970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_CHAR:
14930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd2BE(pReply, dvmGetFieldChar(obj, ifield->byteOffset));
14940970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
14950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_INT:
14960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd4BE(pReply, dvmGetFieldInt(obj, ifield->byteOffset));
14970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
14980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_FLOAT:
14990970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            value.f = dvmGetFieldInt(obj, ifield->byteOffset);
15000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd4BE(pReply, value.i);
15010970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15020970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_LONG:
15030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd8BE(pReply, dvmGetFieldLong(obj, ifield->byteOffset));
15040970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15050970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_DOUBLE:
15060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            value.d = dvmGetFieldInt(obj, ifield->byteOffset);
15070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd8BE(pReply, value.j);
15080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        default:
15100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            LOGE("ERROR: unhandled field type '%s'\n", ifield->field.signature);
15110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            assert(false);
15120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        }
1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of the specified field.
1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int width)
1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* field = (InstField*) fieldIdToField(classId, fieldId);
1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (field->field.signature[0]) {
1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldBoolean(obj, field->byteOffset, value != 0);
1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldObject(obj, field->byteOffset, objectIdToObject(value));
1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldLong(obj, field->byteOffset, value);
1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", field->field.signature);
1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
15640970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Copy the value of a static field into the output buffer, preceded
15650970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * by an appropriate tag.  The tag is based on the value held by the
15660970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * field, not the field's type.
1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
15680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenvoid dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
15690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    ExpandBuf* pReply)
1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId);
15720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    u1 tag = basicTagFromDescriptor(sfield->field.signature);
15730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
15740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    if (tag == JT_ARRAY || tag == JT_OBJECT) {
15750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        Object* objVal = dvmGetStaticFieldObject(sfield);
15760970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        tag = tagFromObject(objVal);
15770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd1(pReply, tag);
15780970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAddObjectId(pReply, objectToObjectId(objVal));
15790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        LOGV("    --> sfieldId %x --> tag '%c' %p\n", fieldId, tag, objVal);
15800970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    } else {
15810970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        JValue value;
1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
15830970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        LOGV("    --> sfieldId %x --> tag '%c'\n", fieldId, tag);
15840970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        expandBufAdd1(pReply, tag);
15850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
15860970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        switch (tag) {
15870970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_BOOLEAN:
15880970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd1(pReply, dvmGetStaticFieldBoolean(sfield));
15890970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15900970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_BYTE:
15910970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd1(pReply, dvmGetStaticFieldByte(sfield));
15920970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15930970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_SHORT:
15940970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd2BE(pReply, dvmGetStaticFieldShort(sfield));
15950970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_CHAR:
15970970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd2BE(pReply, dvmGetStaticFieldChar(sfield));
15980970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
15990970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_INT:
16000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd4BE(pReply, dvmGetStaticFieldInt(sfield));
16010970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
16020970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_FLOAT:
16030970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            value.f = dvmGetStaticFieldFloat(sfield);
16040970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd4BE(pReply, value.i);
16050970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
16060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_LONG:
16070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd8BE(pReply, dvmGetStaticFieldLong(sfield));
16080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
16090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        case JT_DOUBLE:
16100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            value.d = dvmGetStaticFieldDouble(sfield);
16110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            expandBufAdd8BE(pReply, value.j);
16120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
16130970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        default:
16140970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            LOGE("ERROR: unhandled field type '%s'\n", sfield->field.signature);
16150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            assert(false);
16160970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            break;
16170970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        }
1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of a static field.
1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 rawValue, int width)
1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId);
1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue value;
1630de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    value.j = rawValue;
1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (sfield->field.signature[0]) {
1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldBoolean(sfield, value.z);
1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldByte(sfield, value.b);
1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldShort(sfield, value.s);
1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldChar(sfield, value.c);
1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldInt(sfield, value.i);
1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldFloat(sfield, value.f);
1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objVal = objectIdToObject(rawValue);
1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldObject(sfield, objVal);
1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldLong(sfield, value.j);
1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldDouble(sfield, value.d);
1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", sfield->field.signature);
1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a string object to a UTF-8 string.
1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgStringToUtf8(ObjectId strId)
1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* strObj = (StringObject*) objectIdToObject(strId);
1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmCreateCstrFromString(strObj);
1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Thread and ThreadGroup
1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a thread object to a Thread ptr.
1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This currently requires running through the list of threads and finding
1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a match.
1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * IMPORTANT: grab gDvm.threadListLock before calling here.
1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Thread* threadObjToThread(Object* threadObj)
1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->threadObj == threadObj)
1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            break;
1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return thread;
1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the status and suspend state of a thread.
1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadStatus(ObjectId threadId, u4* pThreadStatus,
1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4* pSuspendStatus)
1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
1727de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (thread->status) {
1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_ZOMBIE:         *pThreadStatus = TS_ZOMBIE;     break;
1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_RUNNING:        *pThreadStatus = TS_RUNNING;    break;
1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_TIMED_WAIT:     *pThreadStatus = TS_SLEEPING;   break;
1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_MONITOR:        *pThreadStatus = TS_MONITOR;    break;
1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_WAIT:           *pThreadStatus = TS_WAIT;       break;
1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_INITIALIZING:   *pThreadStatus = TS_ZOMBIE;     break;
1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_STARTING:       *pThreadStatus = TS_ZOMBIE;     break;
1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_NATIVE:         *pThreadStatus = TS_RUNNING;    break;
1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_VMWAIT:         *pThreadStatus = TS_WAIT;       break;
1748b5f3c0b8222efea953adb94b97a2c70ba58e26e3Andy McFadden    case THREAD_SUSPENDED:      *pThreadStatus = TS_RUNNING;    break;
1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pThreadStatus = THREAD_ZOMBIE;
1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsSuspended(thread))
1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pSuspendStatus = SUSPEND_STATUS_SUSPENDED;
1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pSuspendStatus = 0;
1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = true;
1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the thread's suspend count.
1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetThreadSuspendCount(ObjectId threadId)
1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 result = 0;
1775de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17869a3147c7412f4794434b4c2604aa2ba784867774buzbee    result = thread->interpBreak.ctl.suspendCount;
1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread exists in the VM's thread list.
1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if the thread exists.
1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgThreadExists(ObjectId threadId)
1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result;
1803de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = false;
1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = true;
1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread is suspended.
1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if the thread is running or doesn't exist.
1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsSuspended(ObjectId threadId)
1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
1830de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = dvmIsSuspended(thread);
1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Wait until a thread suspends.
1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We stray from the usual pattern here, and release the thread list lock
1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * before we use the Thread.  This is necessary and should be safe in this
1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * circumstance; see comments in dvmWaitForSuspend().
1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgWaitForSuspend(ObjectId threadId)
1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1860de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != NULL)
1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmWaitForSuspend(thread);
1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the ObjectId for the "system" thread group.
1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetSystemThreadGroupId(void)
1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* groupObj = dvmGetSystemThreadGroup();
1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(groupObj);
1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the ObjectId for the "system" thread group.
1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetMainThreadGroupId(void)
1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* groupObj = dvmGetMainThreadGroup();
1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(groupObj);
1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread.
1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadName(ObjectId threadId)
1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* nameStr;
1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* str;
1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* result;
1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                gDvm.offJavaLangThread_name);
1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    str = dvmCreateCstrFromString(nameStr);
1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = (char*) malloc(strlen(str) + 20);
1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread = threadObjToThread(threadObj);
1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != NULL)
1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sprintf(result, "<%d> %s", thread->threadId, str);
1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sprintf(result, "%s", str);
1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(str);
1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a thread's group.
1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroup(ObjectId threadId)
1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* group;
1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    group = dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_group);
1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(group);
1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread group.
1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadGroupName(ObjectId threadGroupId)
1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadGroup;
1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* nameField;
1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* nameStr;
1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadGroup = objectIdToObject(threadGroupId);
1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadGroup != NULL);
1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameField = dvmFindInstanceField(gDvm.classJavaLangThreadGroup,
1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "name", "Ljava/lang/String;");
1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (nameField == NULL) {
1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("unable to find name field in ThreadGroup\n");
1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameStr = (StringObject*) dvmGetFieldObject(threadGroup,
1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                nameField->byteOffset);
1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmCreateCstrFromString(nameStr);
1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the parent of a thread group.
1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId)
1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadGroup;
1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* parentField;
1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* parent;
1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadGroup = objectIdToObject(threadGroupId);
1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadGroup != NULL);
1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    parentField = dvmFindInstanceField(gDvm.classJavaLangThreadGroup,
1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "parent", "Ljava/lang/ThreadGroup;");
1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (parentField == NULL) {
1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("unable to find parent field in ThreadGroup\n");
1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parent = NULL;
1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parent = dvmGetFieldObject(threadGroup, parentField->byteOffset);
1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(parent);
1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of threads in the thread group.
1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We do this by running through the full list of threads and returning
1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ones that have the ThreadGroup object as their owner.
1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If threadGroupId is set to "kAllThreads", we ignore the group field and
1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return all threads.
2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds".
2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ObjectId** ppThreadIds, u4* pThreadCount)
2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* targetThreadGroup = NULL;
2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* groupField = NULL;
2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (threadGroupId != THREAD_GROUP_ALL) {
2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        targetThreadGroup = objectIdToObject(threadGroupId);
2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(targetThreadGroup != NULL);
2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    groupField = dvmFindInstanceField(gDvm.classJavaLangThread,
2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "group", "Ljava/lang/ThreadGroup;");
2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = gDvm.threadList;
2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = 0;
2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* group;
2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Skip over the JDWP support thread.  Some debuggers
2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * get bent out of shape when they can't suspend and
2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * query all threads, so it's easier if we just don't
2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * tell them about us.
2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* This thread is currently being created, and isn't ready
2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * to be seen by the debugger yet.
2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->threadObj == NULL)
2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        group = dvmGetFieldObject(thread->threadObj, groupField->byteOffset);
2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup)
2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pThreadCount = count;
2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (count == 0) {
2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *ppThreadIds = NULL;
2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ObjectId* ptr;
2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ptr = *ppThreadIds = (ObjectId*) malloc(sizeof(ObjectId) * count);
2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Object* group;
2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Skip over the JDWP support thread.  Some debuggers
2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * get bent out of shape when they can't suspend and
2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * query all threads, so it's easier if we just don't
2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * tell them about us.
2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* This thread is currently being created, and isn't ready
2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to be seen by the debugger yet.
2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (thread->threadObj == NULL)
2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            group = dvmGetFieldObject(thread->threadObj,groupField->byteOffset);
2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup)
2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *ptr++ = objectToObjectId(thread->threadObj);
2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count--;
2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(count == 0);
2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get all threads.
2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds".
2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount)
2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDbgGetThreadGroupThreads(THREAD_GROUP_ALL, ppThreadIds, pThreadCount);
2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count up the #of frames on the thread's stack.
2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns -1 on failure;
2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetThreadFrameCount(ObjectId threadId)
2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* framePtr;
2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 count = 0;
2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    framePtr = thread->curFrame;
2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (framePtr != NULL) {
2117fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        if (!dvmIsBreakFrame((u4*)framePtr))
2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr = SAVEAREA_FROM_FP(framePtr)->prevFrame;
2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return count;
2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get info for frame N from the specified thread's stack.
2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation* pLoc)
2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* framePtr;
2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    framePtr = thread->curFrame;
2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = 0;
2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (framePtr != NULL) {
2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const Method* method = saveArea->method;
2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2153fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        if (!dvmIsBreakFrame((u4*)framePtr)) {
2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count == num) {
2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *pFrameId = frameToFrameId(framePtr);
2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (dvmIsInterfaceClass(method->clazz))
2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->typeTag = TT_INTERFACE;
2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else
2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->typeTag = TT_CLASS;
2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pLoc->classId = classObjectToRefTypeId(method->clazz);
2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pLoc->methodId = methodToMethodId(method);
2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (dvmIsNativeMethod(method))
2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->idx = (u8)-1;
2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else
2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->idx = saveArea->xtra.currentPc - method->insns;
2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmUnlockThreadList();
2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr = saveArea->prevFrame;
2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return false;
2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the ThreadId for the current thread.
2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadSelfId(void)
2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(self->threadObj);
2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend the VM.
2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendVM(bool isEvent)
2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmSuspendAllThreads(isEvent ? SUSPEND_FOR_DEBUG_EVENT : SUSPEND_FOR_DEBUG);
2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume the VM.
2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeVM()
2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmResumeAllThreads(SUSPEND_FOR_DEBUG);
2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend one thread (not ourselves).
2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendThread(ObjectId threadId)
2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* can happen if our ThreadDeath notify crosses in the mail */
2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj);
2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSuspendThread(thread);
2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume one thread (not ourselves).
2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeThread(ObjectId threadId)
2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj);
2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(thread);
2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend ourselves after sending an event to the debugger.
2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendSelf(void)
2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmSuspendSelf(true);
2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the "this" object for the specified frame.
2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* getThisObject(const u4* framePtr)
2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* method = saveArea->method;
2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int argOffset = method->registersSize - method->insSize;
2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisObj;
2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (method == NULL) {
2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* this is a "break" frame? */
2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("  Pulling this object for frame at %p\n", framePtr);
2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("    Method='%s' native=%d static=%d this=%p\n",
2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->name, dvmIsNativeMethod(method),
2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmIsStaticMethod(method), (Object*) framePtr[argOffset]);
2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * No "this" pointer for statics.  No args on the interp stack for
2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * native methods invoked directly from the VM.
2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsNativeMethod(method) || dvmIsStaticMethod(method))
2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = NULL;
2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = (Object*) framePtr[argOffset];
2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thisObj != NULL && !dvmIsValidObject(thisObj)) {
2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Debugger: invalid 'this' pointer %p in %s.%s; returning NULL\n",
2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            framePtr, method->clazz->descriptor, method->name);
2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = NULL;
2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return thisObj;
2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the "this" object for the specified frame.  The thread must be
2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suspended.
2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId)
2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u4* framePtr = frameIdToFrame(frameId);
2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisObj;
2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thisObj = getThisObject(framePtr);
2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pThisId = objectToObjectId(thisObj);
2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the value of a method argument or local variable into the
2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified buffer.  The value will be preceeded with the tag.
2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag, u1* buf, int expectedLen)
2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u4* framePtr = frameIdToFrame(frameId);
2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 intVal;
2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 longVal;
2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    slot = untweakSlot(slot, framePtr);     // Eclipse workaround
2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf+1, intVal != 0);
2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf+1, intVal);
2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 2);
2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set2BE(buf+1, intVal);
2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 4);
2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set4BE(buf+1, intVal);
2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* convert to "ObjectId" */
2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objVal = (Object*)framePtr[slot];
2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (objVal != NULL && !dvmIsValidObject(objVal)) {
2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JDWP: slot %d expected to hold array, %p invalid\n",
2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    slot, objVal);
2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmAbort();         // DEBUG: make it obvious
2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                objVal = NULL;
2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tag = JT_OBJECT;    // JT_ARRAY not expected for NULL ref
2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetObjectId(buf+1, objectToObjectId(objVal));
2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* convert to "ObjectId" */
2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objVal = (Object*)framePtr[slot];
23700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden
23710970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            if (objVal != NULL && !dvmIsValidObject(objVal)) {
23720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden                LOGW("JDWP: slot %d expected to hold object, %p invalid\n",
23730970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden                    slot, objVal);
23740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden                dvmAbort();         // DEBUG: make it obvious
23750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden                objVal = NULL;
2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
23770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden            tag = tagFromObject(objVal);
2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetObjectId(buf+1, objectToObjectId(objVal));
2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        longVal = *(u8*)(&framePtr[slot]);
2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set8BE(buf+1, longVal);
2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set1(buf, tag);
2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a new value into an argument or local variable.
2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot, u1 tag,
2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 value, int width)
2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4* framePtr = frameIdToFrame(frameId);
2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    slot = untweakSlot(slot, framePtr);     // Eclipse workaround
2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_STRING:
2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* The debugger calls VirtualMachine.CreateString to create a new
2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * string, then uses this to set the object reference, when you
2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * edit a String object */
2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4) objectIdToObject(value);
2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(u8*)(&framePtr[slot]) = value;
2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_VOID:
2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_OBJECT:
2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD:
2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD_GROUP:
2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_LOADER:
2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Debugger notification
2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a breakpoint address has been reached.
2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "pcOffset" will be -1 for native methods.
2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "thisPtr" will be NULL for static methods.
2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostLocationEvent(const Method* method, int pcOffset,
2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisPtr, int eventFlags)
2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation loc;
2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(method->clazz))
2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        loc.typeTag = TT_INTERFACE;
2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        loc.typeTag = TT_CLASS;
2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.classId = classObjectToRefTypeId(method->clazz);
2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.methodId = methodToMethodId(method);
2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.idx = pcOffset;
2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Note we use "NoReg" so we don't keep track of references that are
2481c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * never actually sent to the debugger.  The "thisPtr" is only used to
2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * compare against registered events.
2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmJdwpPostLocationEvent(gDvm.jdwpState, &loc,
2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectIdNoReg(thisPtr), eventFlags))
2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classObjectToRefTypeId(method->clazz);
2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objectToObjectId(thisPtr);
2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that an exception has occurred.
2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int catchRelPc, Object* exception)
2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation throwLoc, catchLoc;
2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* throwMeth;
2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* catchMeth;
2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwMeth = SAVEAREA_FROM_FP(throwFp)->method;
2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(throwMeth->clazz))
2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwLoc.typeTag = TT_INTERFACE;
2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwLoc.typeTag = TT_CLASS;
2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.classId = classObjectToRefTypeId(throwMeth->clazz);
2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.methodId = methodToMethodId(throwMeth);
2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.idx = throwRelPc;
2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (catchRelPc < 0) {
2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memset(&catchLoc, 0, sizeof(catchLoc));
2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchMeth = SAVEAREA_FROM_FP(catchFp)->method;
2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsInterfaceClass(catchMeth->clazz))
2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchLoc.typeTag = TT_INTERFACE;
2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchLoc.typeTag = TT_CLASS;
2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.classId = classObjectToRefTypeId(catchMeth->clazz);
2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.methodId = methodToMethodId(catchMeth);
2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.idx = catchRelPc;
2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* need this for InstanceOnly filters */
2526fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    Object* thisObj = getThisObject((u4*)throwFp);
2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2528c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    /*
2529c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * Hand the event to the JDWP exception handler.  Note we're using the
2530c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * "NoReg" objectID on the exception, which is not strictly correct --
2531c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * the exception object WILL be passed up to the debugger if the
2532c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * debugger is interested in the event.  We do this because the current
2533c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * implementation of the debugger object registry never throws anything
2534c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * away, and some people were experiencing a fatal build up of exception
2535c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * objects when dealing with certain libraries.
2536c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     */
2537c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    dvmJdwpPostException(gDvm.jdwpState, &throwLoc,
2538c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden        objectToObjectIdNoReg(exception),
2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classObjectToRefTypeId(exception->clazz), &catchLoc,
2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objectToObjectId(thisObj));
2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has started.
2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadStart(Thread* thread)
2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
25489a3147c7412f4794434b4c2604aa2ba784867774buzbee    if (gDvm.debuggerActive) {
2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmJdwpPostThreadChange(gDvm.jdwpState,
2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectId(thread->threadObj), true);
2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.ddmThreadNotification)
2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDdmSendThreadNotification(thread, true);
2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has gone away.
2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadDeath(Thread* thread)
2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
25619a3147c7412f4794434b4c2604aa2ba784867774buzbee    if (gDvm.debuggerActive) {
2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmJdwpPostThreadChange(gDvm.jdwpState,
2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectId(thread->threadObj), false);
2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.ddmThreadNotification)
2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDdmSendThreadNotification(thread, false);
2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a new class has been prepared.
2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostClassPrepare(ClassObject* clazz)
2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
25740970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    const char* signature;
2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int tag;
2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(clazz))
2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tag = TT_INTERFACE;
2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tag = TT_CLASS;
2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO - we currently always send both "verified" and "prepared" since
2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // debuggers seem to like that.  There might be some advantage to honesty,
2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // since the class may not yet be verified.
25850970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    signature = jniSignature(clazz);
2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmJdwpPostClassPrepare(gDvm.jdwpState, tag, classObjectToRefTypeId(clazz),
2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        signature, CS_VERIFIED | CS_PREPARED);
2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered an event with a LocationOnly
2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mod.  Tell the interpreter to call us if we hit the specified
2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * address.
2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgWatchLocation(const JdwpLocation* pLoc)
2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId);
2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!dvmIsNativeMethod(method));
2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmAddBreakAddr(method, pLoc->idx);
2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;        /* assume success */
2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An event with a LocationOnly mod has been removed.
2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnwatchLocation(const JdwpLocation* pLoc)
2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId);
2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!dvmIsNativeMethod(method));
2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmClearBreakAddr(method, pLoc->idx);
2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered a single-step event.  Tell
2615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interpreter about it.
2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    enum JdwpStepDepth depth)
2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get a pointer to the Thread struct for this ID.  The pointer will
2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * be used strictly for comparisons against the current thread pointer
2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * after the setup is complete, so we can safely release the lock.
2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Thread for single-step not found\n");
2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmIsSuspended(thread)) {
2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Thread for single-step not suspended\n");
2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!"non-susp step");      // I want to know if this can happen
2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsSuspended(thread));
2646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmAddSingleStep(thread, size, depth))
2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = true;
2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A single-step event has been removed.
2658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnconfigureStep(ObjectId threadId)
2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* right now it's global, so don't need to find Thread */
2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmClearSingleStep(NULL);
2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Invoke a method in a thread that has been stopped on a breakpoint or
2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * other debugger event.  (This function is called from the JDWP thread.)
2670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that access control is not enforced, per spec.
2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId, MethodId methodId, u4 numArgs, ObjectId* argArray,
2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj)
2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* targetThread;
2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpError err = ERR_NONE;
2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread = threadObjToThread(threadObj);
2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (targetThread == NULL) {
2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        err = ERR_INVALID_THREAD;       /* thread does not exist */
2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmUnlockThreadList();
2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!targetThread->invokeReq.ready) {
2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        err = ERR_INVALID_THREAD;       /* thread not stopped by event */
2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmUnlockThreadList();
2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
26960d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * We currently have a bug where we don't successfully resume the
26970d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * target thread if the suspend count is too deep.  We're expected to
26980d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * require one "resume" for each "suspend", but when asked to execute
26990d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * a method we have to resume fully and then re-suspend it back to the
27000d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * same level.  (The easiest way to cause this is to type "suspend"
27010d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * multiple times in jdb.)
27020d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     *
27030d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * It's unclear what this means when the event specifies "resume all"
27040d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * and some threads are suspended more deeply than others.  This is
27050d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * a rare problem, so for now we just prevent it from hanging forever
27060d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * by rejecting the method invocation request.  Without this, we will
27070d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * be stuck waiting on a suspended thread.
27080d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     */
27099a3147c7412f4794434b4c2604aa2ba784867774buzbee    if (targetThread->interpBreak.ctl.suspendCount > 1) {
27100d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        LOGW("threadid=%d: suspend count on threadid=%d is %d, too deep "
27110d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden             "for method exec\n",
27120d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden            dvmThreadSelf()->threadId, targetThread->threadId,
27139a3147c7412f4794434b4c2604aa2ba784867774buzbee            targetThread->interpBreak.ctl.suspendCount);
27140d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        err = ERR_THREAD_SUSPENDED;     /* probably not expected here */
27150d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        dvmUnlockThreadList();
27160d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        goto bail;
27170d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden    }
27180d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden
27190d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden    /*
2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: ought to screen the various IDs, and verify that the argument
2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list is valid.
2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.obj = objectIdToObject(objectId);
2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.thread = threadObj;
2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.clazz = refTypeIdToClassObject(classId);
2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.method = methodIdToMethod(classId, methodId);
2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.numArgs = numArgs;
2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.argArray = argArray;
2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.options = options;
2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.invokeNeeded = true;
2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is a bit risky -- if the thread goes away we're sitting high
2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and dry -- but we must release this before the dvmResumeAllThreads
2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call, and it's unwise to hold it during dvmWaitForSuspend.
2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
274199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * We change our (JDWP thread) status, which should be THREAD_RUNNING,
274299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * so the VM can suspend for a GC if the invoke request causes us to
274399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * run out of memory.  It's also a good idea to change it before locking
274499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * the invokeReq mutex, although that should never be held for long.
2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    Transferring control to event thread\n");
2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockMutex(&targetThread->invokeReq.lock);
2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((options & INVOKE_SINGLE_THREADED) == 0) {
2753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming all threads\n");
2754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeAllThreads(SUSPEND_FOR_DEBUG_EVENT);
2755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming event thread only\n");
2757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(targetThread);
2758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Wait for the request to finish executing.
2762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (targetThread->invokeReq.invokeNeeded) {
2764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pthread_cond_wait(&targetThread->invokeReq.cv,
2765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          &targetThread->invokeReq.lock);
2766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockMutex(&targetThread->invokeReq.lock);
2768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    Control has returned from event thread\n");
2769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* wait for thread to re-suspend itself */
2771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmWaitForSuspend(targetThread);
2772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Done waiting, switch back to RUNNING.
2775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmChangeStatus(self, oldStatus);
2777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Suspend the threads.  We waited for the target thread to suspend
2780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * itself, so all we need to do is suspend the others.
2781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
2782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The suspendAllThreads() call will double-suspend the event thread,
2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * so we want to resume the target thread once to keep the books straight.
2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((options & INVOKE_SINGLE_THREADED) == 0) {
2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Suspending all threads\n");
2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSuspendAllThreads(SUSPEND_FOR_DEBUG_EVENT);
2788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming event thread to balance the count\n");
2789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(targetThread);
2790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set up the result.
2794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pResultTag = targetThread->invokeReq.resultTag;
2796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(targetThread->invokeReq.resultTag))
2797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pResultValue = targetThread->invokeReq.resultValue.j;
2798fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    else {
2799fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        Object* tmpObj = (Object*)targetThread->invokeReq.resultValue.l;
2800fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        *pResultValue = objectToObjectId(tmpObj);
2801fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    }
2802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pExceptObj = targetThread->invokeReq.exceptObj;
2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    err = targetThread->invokeReq.err;
2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return err;
2807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
28100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Return a basic tag value for the return type.
2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
28120970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic u1 getReturnTypeBasicTag(const Method* method)
2813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* descriptor = dexProtoGetReturnType(&method->prototype);
28150970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    return basicTagFromDescriptor(descriptor);
2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Execute the method described by "*pReq".
282099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
282199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * We're currently in VMWAIT, because we're stopped on a breakpoint.  We
282299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * want to switch to RUNNING while we execute.
2823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExecuteMethod(DebugInvokeReq* pReq)
2825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* meth;
2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* oldExcept;
282999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    int oldStatus;
2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * We can be called while an exception is pending in the VM.  We need
2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to preserve that across the method invocation.
2834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    oldExcept = dvmGetException(self);
28367dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden    if (oldExcept != NULL) {
28377dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden        dvmAddTrackedAlloc(oldExcept, self);
28387dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden        dvmClearException(self);
28397dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden    }
284099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
284199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    oldStatus = dvmChangeStatus(self, THREAD_RUNNING);
2842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Translate the method through the vtable, unless we're calling a
2845f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden     * direct method or the debugger wants to suppress it.
2846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2847f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    if ((pReq->options & INVOKE_NONVIRTUAL) != 0 || pReq->obj == NULL ||
2848f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        dvmIsDirectMethod(pReq->method))
2849f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    {
2850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = pReq->method;
2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = dvmGetVirtualizedMethod(pReq->clazz, pReq->method);
2853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(meth != NULL);
2855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(sizeof(jvalue) == sizeof(u8));
2857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    IF_LOGV() {
2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
2860f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        LOGV("JDWP invoking method %p/%p %s.%s:%s\n",
2861f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden            pReq->method, meth, meth->clazz->descriptor, meth->name, desc);
2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        free(desc);
2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2865d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    dvmCallMethodA(self, meth, pReq->obj, false, &pReq->resultValue,
2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (jvalue*)pReq->argArray);
2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pReq->exceptObj = objectToObjectId(dvmGetException(self));
28680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden    pReq->resultTag = getReturnTypeBasicTag(meth);
2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pReq->exceptObj != 0) {
2870f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        Object* exc = dvmGetException(self);
2871f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        LOGD("  JDWP invocation returning with exceptObj=%p (%s)\n",
2872f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden            exc, exc->clazz->descriptor);
2873f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        //dvmLogExceptionStackTrace();
2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmClearException(self);
2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
2876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Nothing should try to use this, but it looks like something is.
2877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Make it null to be safe.
2878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pReq->resultValue.j = 0; /*0xadadadad;*/
2880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (pReq->resultTag == JT_OBJECT) {
2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* if no exception thrown, examine object result more closely */
28820970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden        u1 newTag = tagFromObject((Object*)pReq->resultValue.l);
2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newTag != pReq->resultTag) {
2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("  JDWP promoted result from %d to %d\n",
2885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pReq->resultTag, newTag);
2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pReq->resultTag = newTag;
2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
28887dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden
28897dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden        /*
28907dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * Register the object.  We don't actually need an ObjectId yet,
28917dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * but we do need to be sure that the GC won't move or discard the
28927dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * object when we switch out of RUNNING.  The ObjectId conversion
28937dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * will add the object to the "do not touch" list.
28947dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         *
28957dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * We can't use the "tracked allocation" mechanism here because
28967dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         * the object is going to be handed off to a different thread.
28977dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden         */
2898fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        (void) objectToObjectId((Object*)pReq->resultValue.l);
2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29017dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden    if (oldExcept != NULL) {
2902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetException(self, oldExcept);
29037dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden        dvmReleaseTrackedAlloc(oldExcept, self);
29047dd7bf1870169f31ca81d22b8cc38b955184f414Andy McFadden    }
290599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    dvmChangeStatus(self, oldStatus);
2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine
2909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct AddressSetContext {
2910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool lastAddressValid;
2911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 lastAddress;
2912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 lineNum;
2913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSet *pSet;
2914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} AddressSetContext;
2915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine
2917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int addressSetCb (void *cnxt, u4 address, u4 lineNum)
2918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSetContext *pContext = (AddressSetContext *)cnxt;
2920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (lineNum == pContext->lineNum) {
2922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!pContext->lastAddressValid) {
2923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Everything from this address until the next line change is ours
2924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pContext->lastAddress = address;
2925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pContext->lastAddressValid = true;
2926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // else, If we're already in a valid range for this lineNum,
2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // just keep going (shouldn't really happen)
2929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (pContext->lastAddressValid) { // and the line number is new
2930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 i;
2931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Add everything from the last entry up until here to the set
2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = pContext->lastAddress; i < address; i++) {
2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAddressSetSet(pContext->pSet, i);
2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pContext->lastAddressValid = false;
2937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // there may be multiple entries for a line
2940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
2941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Build up a set of bytecode addresses associated with a line number
2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst AddressSet *dvmAddressSetForLine(const Method* method, int line)
2946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSet *result;
2948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const DexFile *pDexFile = method->clazz->pDvmDex->pDexFile;
2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 insnsSize = dvmGetMethodInsnsSize(method);
2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSetContext context;
2951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2952fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro    result = (AddressSet*)calloc(1, sizeof(AddressSet) + (insnsSize/8) + 1);
2953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result->setSize = insnsSize;
2954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(&context, 0, sizeof(context));
2956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pSet = result;
2957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.lineNum = line;
2958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.lastAddressValid = false;
2959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(pDexFile, dvmGetMethodCode(method),
2961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
2962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
2963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
2964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        addressSetCb, NULL, &context);
2965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // If the line number was the last in the position table...
2967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (context.lastAddressValid) {
2968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 i;
2969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = context.lastAddress; i < insnsSize; i++) {
2970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAddressSetSet(result, i);
2971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Dalvik Debug Monitor support
2981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have received a DDM packet over JDWP.  Hand it off to the VM.
2986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
2988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int* pReplyLen)
2989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDdmHandlePacket(buf, dataLen, pReplyBuf, pReplyLen);
2991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * First DDM packet has arrived over JDWP.  Notify the press.
2995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDdmConnected(void)
2997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDdmConnected();
2999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP connection has dropped.
3003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDdmDisconnected(void)
3005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDdmDisconnected();
3007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send up a JDWP event packet with a DDM chunk in it.
3011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
30120171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunk(int type, size_t len, const u1* buf)
30130171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden{
30140171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    assert(buf != NULL);
30150171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    struct iovec vec[1] = { {(void*)buf, len} };
30160171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    dvmDbgDdmSendChunkV(type, vec, 1);
30170171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden}
30180171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden
30190171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden/*
30200171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * Send up a JDWP event packet with a DDM chunk in it.  The chunk is
30210171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * concatenated from multiple source buffers.
30220171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden */
30230171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt)
3024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.jdwpState == NULL) {
3026a6ef944d938832ea2768e0b165d9cf325c0f65aeRobert CH Chou        LOGV("Debugger thread not active, ignoring DDM send (t=0x%08x)\n",
3027a6ef944d938832ea2768e0b165d9cf325c0f65aeRobert CH Chou            type);
3028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
3029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
3030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30310171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    dvmJdwpDdmSendChunkV(gDvm.jdwpState, type, iov, iovcnt);
3032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3033