Debugger.cpp revision 884cd427f504a6e105059199c3eeadd51a8b9c6e
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 * (This is a HashForeachFunc callback.)
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int markRef(void* data, void* arg)
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(arg);
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //LOGI("dbg mark %p\n", data);
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmMarkObjectNonNull(data);
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Mark all of the registered debugger references so the
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * GC doesn't collect them.
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmGcMarkDebuggerRefs()
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* dvmDebuggerStartup() may not have been called before the first GC.
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.dbgRegistry != NULL) {
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashTableLock(gDvm.dbgRegistry);
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashForeach(gDvm.dbgRegistry, markRef, NULL);
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashTableUnlock(gDvm.dbgRegistry);
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that an object has been registered.  If it hasn't, the debugger
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is asking for something we didn't send it, which means something
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * somewhere is broken.
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If speed is an issue we can encode the registry index in the high
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * four bytes.  We could also just hard-wire this to "true".
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note this actually takes both ObjectId and RefTypeId.
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
276b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#ifndef NDEBUG
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool objectIsRegistered(ObjectId id, RegistryType type)
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(type);
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (id == 0)        // null reference?
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.dbgRegistry);
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = lookupId(id);
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.dbgRegistry);
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
289b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro#endif
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a RefTypeId.
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These are rarely NULL, but can be (e.g. java/lang/Object's superclass).
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeId(ClassObject* clazz)
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, true);
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
300e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#if 0
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic RefTypeId classObjectToRefTypeIdNoReg(ClassObject* clazz)
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (RefTypeId) registerObject((Object*) clazz, kRefTypeId, false);
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
305e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9Carl Shapiro#endif
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ClassObject* refTypeIdToClassObject(RefTypeId id)
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(objectIsRegistered(id, kRefTypeId) || !gDvm.debuggerConnected);
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (ClassObject*)(u4) id;
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from an ObjectId.
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectId(const Object* obj)
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return registerObject(obj, kObjectId, true);
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ObjectId objectToObjectIdNoReg(const Object* obj)
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return registerObject(obj, kObjectId, false);
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* objectIdToObject(ObjectId id)
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(objectIsRegistered(id, kObjectId) || !gDvm.debuggerConnected);
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Object*)(u4) id;
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
330c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Register an object ID that might not have been registered previously.
331c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden *
332c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * Normally this wouldn't happen -- the conversion to an ObjectId would
333c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * have added the object to the registry -- but in some cases (e.g.
334c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * throwing exceptions) we really want to do the registration late.
335c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden */
336c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFaddenvoid dvmDbgRegisterObjectId(ObjectId id)
337c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden{
338c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    Object* obj = (Object*)(u4) id;
339c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    LOGV("+++ registering %p (%s)\n", obj, obj->clazz->descriptor);
340c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    registerObject(obj, kObjectId, true);
341c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden}
342c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden
343c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden/*
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a MethodId.
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index.  For now we just use the Method*.
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic MethodId methodToMethodId(const Method* meth)
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (MethodId)(u4) meth;
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Method* methodIdToMethod(RefTypeId refTypeId, MethodId id)
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? verify "id" is actually a method in "refTypeId"
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Method*)(u4) id;
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FieldId.
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These IDs are only guaranteed unique within a class, so they could be
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an enumeration index.  For now we just use the Field*.
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FieldId fieldToFieldId(const Field* field)
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (FieldId)(u4) field;
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Field* fieldIdToField(RefTypeId refTypeId, FieldId id)
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? verify "id" is actually a field in "refTypeId"
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (Field*)(u4) id;
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert to/from a FrameId.
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We just return a pointer to the stack frame.
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic FrameId frameToFrameId(const void* frame)
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (FrameId)(u4) frame;
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* frameIdToFrame(FrameId id)
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (void*)(u4) id;
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the invocation request state.
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDebugInvokeReq* dvmDbgGetInvokeReq(void)
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return &dvmThreadSelf()->invokeReq;
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable the object registry, but don't enable debugging features yet.
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgConnected(void)
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!gDvm.debuggerConnected);
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("JDWP has attached\n");
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmHashTableNumEntries(gDvm.dbgRegistry) == 0);
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerConnected = true;
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enable all debugging features, including scans for breakpoints.
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a no-op if we're already active.
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgActive(void)
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.debuggerActive)
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGI("Debugger is active\n");
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmInitBreakpoints();
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerActive = true;
42706bb83906737fec543c86ab36f450cc62066b58aBill Buzbee#if defined(WITH_JIT)
42806bb83906737fec543c86ab36f450cc62066b58aBill Buzbee    dvmCompilerStateRefresh();
42906bb83906737fec543c86ab36f450cc62066b58aBill Buzbee#endif
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Disable debugging features.
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "debuggerConnected" to false, which disables use of the object
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registry.
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only called from the JDWP handler thread.
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDisconnected(void)
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(gDvm.debuggerConnected);
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerActive = false;
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.dbgRegistry);
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.debuggerConnected = false;
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4492fbe6d15ed8d266ed55fb76e97f866dbd07d5fa6Andy McFadden    LOGD("Debugger has detached; object registry had %d entries\n",
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashTableNumEntries(gDvm.dbgRegistry));
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //int i;
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //for (i = 0; i < gDvm.dbgRegistryNext; i++)
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //    LOGVV("%4d: 0x%llx\n", i, gDvm.dbgRegistryTable[i]);
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableClear(gDvm.dbgRegistry);
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.dbgRegistry);
45706bb83906737fec543c86ab36f450cc62066b58aBill Buzbee#if defined(WITH_JIT)
45806bb83906737fec543c86ab36f450cc62066b58aBill Buzbee    dvmCompilerStateRefresh();
45906bb83906737fec543c86ab36f450cc62066b58aBill Buzbee#endif
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if a debugger is connected.
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not return "true" if it's just a DDM server.
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsDebuggerConnected(void)
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return gDvm.debuggerActive;
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get time since last debugger activity.  Used when figuring out if the
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger has finished configuring us.
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projects8 dvmDbgLastDebuggerActivity(void)
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmJdwpLastDebuggerActivity(gDvm.jdwpState);
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is running, don't allow GC.
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadRunning(void)
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, THREAD_RUNNING);
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP thread is idle, allow GC.
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadWaiting(void)
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, THREAD_VMWAIT);
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Restore state returned by Running/Waiting calls.
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgThreadContinuing(int status)
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmChangeStatus(NULL, status);
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The debugger wants us to exit.
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExit(int status)
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO? invoke System.exit() to perform exit processing; ends up
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // in System.exitInternal(), which can call JNI exit hook
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef WITH_PROFILER
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGI("GC lifetime allocation: %d bytes\n", gDvm.allocProf.allocCount);
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (CALC_CACHE_STATS) {
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpAtomicCacheStats(gDvm.instanceofCache);
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpBootClassPath();
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef PROFILE_FIELD_ACCESS
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDumpFieldAccessCounts();
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    exit(status);
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Class, Object, Array
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the class's type descriptor from a reference type ID.
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetClassDescriptor(RefTypeId id)
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(id);
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->descriptor;
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
5456ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden * Convert a RefTypeId to an ObjectId.
5466ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden */
5476ff3c8fde9623dadad726dbd5e1658585c321751Andy McFaddenObjectId dvmDbgGetClassObject(RefTypeId id)
5486ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden{
5496ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden    ClassObject* clazz = refTypeIdToClassObject(id);
5506ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden    return objectToObjectId((Object*) clazz);
5516ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden}
5526ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden
5536ff3c8fde9623dadad726dbd5e1658585c321751Andy McFadden/*
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the superclass of a class (will be NULL for java/lang/Object).
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetSuperclass(RefTypeId id)
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return classObjectToRefTypeId(clazz->super);
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's defining class loader.
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRefTypeId dvmDbgGetClassLoader(RefTypeId id)
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(clazz->classLoader);
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a class's access flags.
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetAccessFlags(RefTypeId id)
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->accessFlags & JAVA_FLAGS_MASK;
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Is this class an interface?
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsInterface(RefTypeId id)
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(id);
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmIsInterfaceClass(clazz);
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmHashForeach callback
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int copyRefType(void* vclazz, void* varg)
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId** pRefType = (RefTypeId**)varg;
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    **pRefType = classObjectToRefTypeId((ClassObject*) vclazz);
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    (*pRefType)++;
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the complete list of reference classes (i.e. all classes except
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the primitive types).
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values.
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassList(u4* pNumClasses, RefTypeId** pClassRefBuf)
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId* pRefType;
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.loadedClasses);
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pNumClasses = dvmHashTableNumEntries(gDvm.loadedClasses);
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pRefType = *pClassRefBuf = malloc(sizeof(RefTypeId) * *pNumClasses);
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmHashForeach(gDvm.loadedClasses, copyRefType, &pRefType) != 0) {
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Warning: problem getting class list\n");
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* not really expecting this to happen */
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(pRefType - *pClassRefBuf == (int) *pNumClasses);
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.loadedClasses);
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of reference classes "visible" to the specified class
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * loader.  A class is visible to a class loader if the ClassLoader object
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is the defining loader or is listed as an initiating loader.
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated buffer full of RefTypeId values.
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetVisibleClassList(ObjectId classLoaderId, u4* pNumClasses,
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId** pClassRefBuf)
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* classLoader;
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numClasses = 0, maxClasses;
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    classLoader = objectIdToObject(classLoaderId);
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // I don't think classLoader can be NULL, but the spec doesn't say
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("GetVisibleList: comparing to %p\n", classLoader);
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableLock(gDvm.loadedClasses);
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* over-allocate the return buffer */
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    maxClasses = dvmHashTableNumEntries(gDvm.loadedClasses);
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pClassRefBuf = malloc(sizeof(RefTypeId) * maxClasses);
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Run through the list, looking for matches.
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HashIter iter;
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (dvmHashIterBegin(gDvm.loadedClasses, &iter); !dvmHashIterDone(&iter);
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmHashIterNext(&iter))
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* clazz = (ClassObject*) dvmHashIterData(&iter);
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (clazz->classLoader == classLoader ||
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmLoaderInInitiatingList(clazz, classLoader))
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("  match '%s'\n", clazz->descriptor);
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (*pClassRefBuf)[numClasses++] = classObjectToRefTypeId(clazz);
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pNumClasses = numClasses;
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmHashTableUnlock(gDvm.loadedClasses);
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate the "JNI signature" for a class, e.g. "Ljava/lang/String;".
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Our class descriptors are in the correct format, so we just copy that.
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: figure out if we can avoid the copy now that we're using
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptors instead of unadorned class names.
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* generateJNISignature(ClassObject* clazz)
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return strdup(clazz->descriptor);
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get information about a class.
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If "pSignature" is not NULL, *pSignature gets the "JNI signature" of
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class.
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetClassInfo(RefTypeId classId, u1* pTypeTag, u4* pStatus,
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char** pSignature)
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(classId);
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz->descriptor[0] == '[') {
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* generated array class */
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pStatus = CS_VERIFIED | CS_PREPARED;
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pTypeTag = TT_ARRAY;
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (clazz->status == CLASS_ERROR)
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pStatus = CS_ERROR;
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pStatus = CS_VERIFIED | CS_PREPARED | CS_INITIALIZED;
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsInterfaceClass(clazz))
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pTypeTag = TT_INTERFACE;
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pTypeTag = TT_CLASS;
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pSignature != NULL)
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pSignature = generateJNISignature(clazz);
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Search the list of loaded classes for a match.
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgFindLoadedClassBySignature(const char* classDescriptor,
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RefTypeId* pRefTypeId)
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = dvmFindLoadedClass(classDescriptor);
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz != NULL) {
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeId = classObjectToRefTypeId(clazz);
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get an object's class and "type tag".
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetObjectType(ObjectId objectId, u1* pRefTypeTag,
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId* pRefTypeId)
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsArrayClass(obj->clazz))
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_ARRAY;
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (dvmIsInterfaceClass(obj->clazz))
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_INTERFACE;
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pRefTypeTag = TT_CLASS;
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pRefTypeId = classObjectToRefTypeId(obj->clazz);
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class object's "type tag".
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu1 dvmDbgGetClassObjectType(RefTypeId refTypeId)
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(refTypeId);
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsArrayClass(clazz))
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_ARRAY;
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (dvmIsInterfaceClass(clazz))
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_INTERFACE;
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return TT_CLASS;
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a class' signature.
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetSignature(RefTypeId refTypeId)
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return generateJNISignature(clazz);
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get class' source file.
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetSourceFile(RefTypeId refTypeId)
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return clazz->sourceFile;
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get an object's type name.  Converted to a "JNI signature".
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetObjectTypeName(ObjectId objectId)
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(obj != NULL);
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return generateJNISignature(obj->clazz);
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given a type signature (e.g. "Ljava/lang/String;"), return the JDWP
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "type tag".
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In many cases this is necessary but not sufficient.  For example, if
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we have a NULL String object, we want to return JT_STRING.  If we have
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a java/lang/Object that holds a String reference, we also want to
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return JT_STRING.  See dvmDbgGetObjectTag().
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetSignatureTag(const char* type)
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * We're not checking the class loader here (to guarantee that JT_STRING
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is truly the one and only String), but it probably doesn't matter
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for our purposes.
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (strcmp(type, "Ljava/lang/String;") == 0)
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_STRING;
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (strcmp(type, "Ljava/lang/Class;") == 0)
824de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        return JT_CLASS_OBJECT;
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (strcmp(type, "Ljava/lang/Thread;") == 0)
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD;
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (strcmp(type, "Ljava/lang/ThreadGroup;") == 0)
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD_GROUP;
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (strcmp(type, "Ljava/lang/ClassLoader;") == 0)
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_CLASS_LOADER;
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (type[0]) {
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case '[':       return JT_ARRAY;
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'B':       return JT_BYTE;
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'C':       return JT_CHAR;
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'L':       return JT_OBJECT;
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'F':       return JT_FLOAT;
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'D':       return JT_DOUBLE;
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'I':       return JT_INT;
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'J':       return JT_LONG;
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'S':       return JT_SHORT;
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'V':       return JT_VOID;
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 'Z':       return JT_BOOLEAN;
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled type '%s'\n", type);
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Methods declared to return Object might actually be returning one
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the "refined types".  We need to check the object explicitly.
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u1 resultTagFromObject(Object* obj)
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL)
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_OBJECT;
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = obj->clazz;
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Comparing against the known classes is faster than string
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * comparisons.  It ensures that we only find the classes in the
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * bootstrap class loader, which may or may not be what we want.
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz == gDvm.classJavaLangString)
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_STRING;
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (clazz == gDvm.classJavaLangClass)
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_CLASS_OBJECT;
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (clazz == gDvm.classJavaLangThread)
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD;
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (clazz == gDvm.classJavaLangThreadGroup)
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_THREAD_GROUP;
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (strcmp(clazz->descriptor, "Ljava/lang/ClassLoader;") == 0)
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_CLASS_LOADER;
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (clazz->descriptor[0] == '[')
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_ARRAY;
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return JT_OBJECT;
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine the tag for an object with a known type.
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetObjectTag(ObjectId objectId, const char* type)
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag;
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    tag = dvmDbgGetSignatureTag(type);
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (tag == JT_OBJECT && objectId != 0)
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tag = resultTagFromObject(objectIdToObject(objectId));
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return tag;
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the widths of the specified JDWP.Tag value.
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetTagWidth(int tag)
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_VOID:
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 0;
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 1;
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 2;
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 4;
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_STRING:
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD:
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD_GROUP:
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_LOADER:
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_OBJECT:
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sizeof(ObjectId);
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 8;
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a tag represents a primitive type.
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool isTagPrimitive(u1 tag)
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_VOID:
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_STRING:
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_OBJECT:
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD:
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD_GROUP:
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_LOADER:
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the length of the specified array.
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetArrayLength(ObjectId arrayId)
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return arrayObj->length;
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a tag indicating the general type of elements in the array.
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetArrayElementTag(ObjectId arrayId)
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDbgGetSignatureTag(arrayObj->obj.clazz->descriptor + 1);
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a series of values with the specified width, changing the byte
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ordering to big-endian.
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesToBE(u1* out, const u1* in, int count, int width)
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (width) {
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 1:
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memcpy(out, in, count);
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 2:
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u2*) out)+i) = get2BE(in + i*2);
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 4:
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u4*) out)+i) = get4BE(in + i*4);
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 8:
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *(((u8*) out)+i) = get8BE(in + i*8);
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a series of values with the specified with, changing the
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte order from big-endian.
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void copyValuesFromBE(u1* out, const u1* in, int count, int width)
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (width) {
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 1:
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memcpy(out, in, count);
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 2:
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set2BE(out + i*2, *((u2*)in + i));
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 4:
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set4BE(out + i*4, *((u4*)in + i));
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 8:
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++)
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            set8BE(out + i*8, *((u8*)in + i));
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output a piece of an array to the reply buffer.
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if something looks fishy.
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgOutputArray(ObjectId arrayId, int firstIndex, int count,
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* data = (const u1*)arrayObj->contents;
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag;
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (firstIndex + count > (int)arrayObj->length) {
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Request for index=%d + count=%d excceds length=%d\n",
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstIndex, count, arrayObj->length);
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    tag = dvmDbgGetSignatureTag(arrayObj->obj.clazz->descriptor + 1);
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(tag)) {
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int width = dvmDbgGetTagWidth(tag);
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u1* outBuf;
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        outBuf = expandBufAddSpace(pReply, count * width);
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyValuesToBE(outBuf, data + firstIndex*width, count, width);
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object** pObjects;
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects = (Object**) data;
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects += firstIndex;
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> copying %d object IDs\n", count);
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //assert(tag == JT_OBJECT);     // could be object or "refined" type
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++, pObjects++) {
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u1 thisTag;
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (*pObjects != NULL)
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                thisTag = resultTagFromObject(*pObjects);
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            else
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                thisTag = tag;
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAdd1(pReply, thisTag);
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddObjectId(pReply, objectToObjectId(*pObjects));
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set a range of elements in an array from the data in "buf".
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgSetArrayElements(ObjectId arrayId, int firstIndex, int count,
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* buf)
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* arrayObj = (ArrayObject*) objectIdToObject(arrayId);
1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* data = (u1*)arrayObj->contents;
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag;
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArray(arrayObj));
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (firstIndex + count > (int)arrayObj->length) {
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Attempt to set index=%d + count=%d excceds length=%d\n",
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstIndex, count, arrayObj->length);
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    tag = dvmDbgGetSignatureTag(arrayObj->obj.clazz->descriptor + 1);
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(tag)) {
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int width = dvmDbgGetTagWidth(tag);
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> setting %d '%c' width=%d\n", count, tag, width);
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyValuesFromBE(data + firstIndex*width, buf, count, width);
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object** pObjects;
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects = (Object**) data;
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pObjects += firstIndex;
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("    --> setting %d objects", count);
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* should do array type check here */
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = 0; i < count; i++) {
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ObjectId id = dvmReadObjectId(&buf);
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *pObjects++ = objectIdToObject(id);
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new string.
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The only place the reference will be held in the VM is in our registry.
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgCreateString(const char* str)
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* strObj;
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115381f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes    strObj = dvmCreateStringFromCstr(str);
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmReleaseTrackedAlloc((Object*) strObj, NULL);
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId((Object*) strObj);
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1159f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Allocate a new object of the specified type.
1160f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden *
1161f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden * Add it to the registry to prevent it from being GCed.
1162f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden */
1163f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFaddenObjectId dvmDbgCreateObject(RefTypeId classId)
1164f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden{
1165f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    ClassObject* clazz = refTypeIdToClassObject(classId);
1166f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    Object* newObj = dvmAllocObject(clazz, ALLOC_DEFAULT);
1167f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    dvmReleaseTrackedAlloc(newObj, NULL);
1168f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    return objectToObjectId(newObj);
1169f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden}
1170f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden
1171f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden/*
1172884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Allocate a new array object of the specified type and length.  The
1173884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * type is the array type, not the element type.
1174884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden *
1175884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden * Add it to the registry to prevent it from being GCed.
1176884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden */
1177884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFaddenObjectId dvmDbgCreateArrayObject(RefTypeId arrayTypeId, u4 length)
1178884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden{
1179884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    ClassObject* clazz = refTypeIdToClassObject(arrayTypeId);
1180884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    Object* newObj = (Object*) dvmAllocArrayByClass(clazz, length, ALLOC_DEFAULT);
1181884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    dvmReleaseTrackedAlloc(newObj, NULL);
1182884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden    return objectToObjectId(newObj);
1183884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden}
1184884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden
1185884cd427f504a6e105059199c3eeadd51a8b9c6eAndy McFadden/*
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if "instClassId" is an instance of "classId".
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgMatchType(RefTypeId instClassId, RefTypeId classId)
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* instClazz = refTypeIdToClassObject(instClassId);
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz = refTypeIdToClassObject(classId);
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmInstanceof(instClazz, clazz);
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Method and Field
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the method name from a MethodId.
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst char* dvmDbgGetMethodName(RefTypeId refTypeId, MethodId id)
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* meth;
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    meth = methodIdToMethod(refTypeId, id);
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return meth->name;
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Fields and ReferenceType.FieldsWithGeneric:
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output all fields declared by the class.  Inerhited fields are
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included.
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllFields(RefTypeId refTypeId, bool withGeneric,
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const u1 genericSignature[1] = "";
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field;
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 declared;
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    declared = clazz->sfieldCount + clazz->ifieldCount;
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, declared);
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->sfieldCount; i++) {
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        field = (Field*) &clazz->sfields[i];
1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddFieldId(pReply, fieldToFieldId(field));
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->name);
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->signature);
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAdd4BE(pReply, field->accessFlags);
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->ifieldCount; i++) {
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        field = (Field*) &clazz->ifields[i];
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddFieldId(pReply, fieldToFieldId(field));
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->name);
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) field->signature);
1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAdd4BE(pReply, field->accessFlags);
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For ReferenceType.Methods and ReferenceType.MethodsWithGeneric:
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output all methods declared by the class.  Inherited methods are
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not included.
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllMethods(RefTypeId refTypeId, bool withGeneric,
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DexStringCache stringCache;
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const u1 genericSignature[1] = "";
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* meth;
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 declared;
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexStringCacheInit(&stringCache);
1272de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    declared = clazz->directMethodCount + clazz->virtualMethodCount;
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, declared);
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->directMethodCount; i++) {
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = &clazz->directMethods[i];
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddMethodId(pReply, methodToMethodId(meth));
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) meth->name);
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply,
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (const u1*) dexProtoGetMethodDescriptor(&meth->prototype,
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    &stringCache));
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAdd4BE(pReply, meth->accessFlags);
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->virtualMethodCount; i++) {
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = &clazz->virtualMethods[i];
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddMethodId(pReply, methodToMethodId(meth));
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply, (const u1*) meth->name);
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pReply,
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (const u1*) dexProtoGetMethodDescriptor(&meth->prototype,
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    &stringCache));
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (withGeneric)
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            expandBufAddUtf8String(pReply, genericSignature);
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAdd4BE(pReply, meth->accessFlags);
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexStringCacheRelease(&stringCache);
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Output all interfaces directly implemented by the class.
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputAllInterfaces(RefTypeId refTypeId, ExpandBuf* pReply)
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ClassObject* clazz;
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i, start, count;
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clazz = refTypeIdToClassObject(refTypeId);
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(clazz != NULL);
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz->super == NULL)
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = 0;
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = clazz->super->iftableCount;
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = clazz->iftableCount - start;
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, count);
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = start; i < clazz->iftableCount; i++) {
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* iface = clazz->iftable[i].clazz;
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddRefTypeId(pReply, classObjectToRefTypeId(iface));
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DebugCallbackContext {
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int numItems;
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply;
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // used by locals table
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool withGeneric;
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DebugCallbackContext;
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1342de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirostatic int lineTablePositionsCb(void *cnxt, u4 address, u4 lineNum)
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt;
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pContext->pReply, address);
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, lineNum);
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pContext->numItems++;
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.LineTable: output the line table.
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we operate in Dalvik's 16-bit units rather than bytes.
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputLineTable(RefTypeId refTypeId, MethodId methodId,
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ExpandBuf* pReply)
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method;
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 start, end;
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext context;
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset (&context, 0, sizeof(DebugCallbackContext));
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    method = methodIdToMethod(refTypeId, methodId);
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsNativeMethod(method)) {
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = (u8) -1;
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        end = (u8) -1;
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        start = 0;
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        end = dvmGetMethodInsnsSize(method);
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pReply, start);
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pReply, end);
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Add numLines later
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t numLinesOffset = expandBufGetLength(pReply);
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, 0);
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pReply = pReply;
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile,
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmGetMethodCode(method),
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lineTablePositionsCb, NULL, &context);
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Eclipse appears to expect that the "this" reference is in slot zero.
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If it's not, the "variables" display will show two copies of "this",
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possibly because it gets "this" from SF.ThisObject and then displays
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all locals with nonzero slot numbers.
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * So, we remap the item in slot 0 to 1000, and remap "this" to zero.  On
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SF.GetValues / SF.SetValues we map them back.
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int tweakSlot(int slot, const char* name)
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newSlot = slot;
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (strcmp(name, "this") == 0)      // only remap "this" ptr
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = 0;
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else if (slot == 0)                 // always remap slot 0
1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = kSlot0Sub;
1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("untweak: %d to %d\n", slot, newSlot);
1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newSlot;
1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reverse Eclipse hack.
1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int untweakSlot(int slot, const void* framePtr)
1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newSlot = slot;
1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (slot == kSlot0Sub) {
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = 0;
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (slot == 0) {
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const Method* method = saveArea->method;
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSlot = method->registersSize - method->insSize;
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("untweak: %d to %d\n", slot, newSlot);
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newSlot;
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void variableTableCb (void *cnxt, u2 reg, u4 startAddress,
1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 endAddress, const char *name, const char *descriptor,
1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const char *signature)
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext *pContext = (DebugCallbackContext *)cnxt;
1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    reg = (u2) tweakSlot(reg, name);
1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    %2d: %d(%d) '%s' '%s' slot=%d\n",
1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pContext->numItems, startAddress, endAddress - startAddress,
1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        name, descriptor, reg);
1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd8BE(pContext->pReply, startAddress);
1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAddUtf8String(pContext->pReply, (const u1*)name);
1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAddUtf8String(pContext->pReply, (const u1*)descriptor);
1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pContext->withGeneric) {
1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        expandBufAddUtf8String(pContext->pReply, (const u1*) signature);
1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, endAddress - startAddress);
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pContext->pReply, reg);
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pContext->numItems++;
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For Method.VariableTable[WithGeneric]: output information about local
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * variables for the specified method.
1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgOutputVariableTable(RefTypeId refTypeId, MethodId methodId,
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool withGeneric, ExpandBuf* pReply)
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method;
1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DebugCallbackContext context;
1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset (&context, 0, sizeof(DebugCallbackContext));
1471de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    method = methodIdToMethod(refTypeId, methodId);
1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, method->insSize);
1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Add numLocals later
1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t numLocalsOffset = expandBufGetLength(pReply);
1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    expandBufAdd4BE(pReply, 0);
1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pReply = pReply;
1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.withGeneric = withGeneric;
1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(method->clazz->pDvmDex->pDexFile,
1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmGetMethodCode(method),
1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        NULL, variableTableCb, &context);
1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set4BE(expandBufGetBuffer(pReply) + numLocalsOffset, context.numItems);
1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type tag for the field's type.
1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetFieldTag(ObjectId objId, FieldId fieldId)
1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objId);
1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field = fieldIdToField(classId, fieldId);
1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDbgGetSignatureTag(field->signature);
1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the type tag for the static field's type.
1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetStaticFieldTag(RefTypeId refTypeId, FieldId fieldId)
1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field = fieldIdToField(refTypeId, fieldId);
1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDbgGetSignatureTag(field->signature);
1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the value of a field into the specified buffer.
1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetFieldValue(ObjectId objectId, FieldId fieldId, u1* buf,
1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int expectedLen)
1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* field = (InstField*) fieldIdToField(classId, fieldId);
1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 intVal;
1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 longVal;
1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (field->field.signature[0]) {
1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = dvmGetFieldBoolean(obj, field->byteOffset);
1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf, intVal != 0);
1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = dvmGetFieldInt(obj, field->byteOffset);
1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf, intVal);
1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 2);
1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = dvmGetFieldInt(obj, field->byteOffset);
1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set2BE(buf, intVal);
1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 4);
1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = dvmGetFieldInt(obj, field->byteOffset);
1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set4BE(buf, intVal);
1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == sizeof(ObjectId));
1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objVal = dvmGetFieldObject(obj, field->byteOffset);
1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetObjectId(buf, objectToObjectId(objVal));
1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        longVal = dvmGetFieldLong(obj, field->byteOffset);
1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set8BE(buf, longVal);
1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", field->field.signature);
1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of the specified field.
1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetFieldValue(ObjectId objectId, FieldId fieldId, u8 value,
1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int width)
1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* obj = objectIdToObject(objectId);
1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId = classObjectToRefTypeId(obj->clazz);
1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* field = (InstField*) fieldIdToField(classId, fieldId);
1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (field->field.signature[0]) {
1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldBoolean(obj, field->byteOffset, value != 0);
1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldInt(obj, field->byteOffset, value);
1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldObject(obj, field->byteOffset, objectIdToObject(value));
1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetFieldLong(obj, field->byteOffset, value);
1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", field->field.signature);
1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the value of a static field into the specified buffer.
1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId, u1* buf,
1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int expectedLen)
1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId);
1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue value;
1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (sfield->field.signature[0]) {
1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf, dvmGetStaticFieldBoolean(sfield));
1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf, dvmGetStaticFieldByte(sfield));
1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 2);
1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set2BE(buf, dvmGetStaticFieldShort(sfield));
1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 2);
1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set2BE(buf, dvmGetStaticFieldChar(sfield));
1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 4);
1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set4BE(buf, dvmGetStaticFieldInt(sfield));
1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 4);
1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        value.f = dvmGetStaticFieldFloat(sfield);
1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set4BE(buf, value.i);
1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == sizeof(ObjectId));
1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objVal = dvmGetStaticFieldObject(sfield);
1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetObjectId(buf, objectToObjectId(objVal));
1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set8BE(buf, dvmGetStaticFieldLong(sfield));
1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        value.d = dvmGetStaticFieldDouble(sfield);
1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set8BE(buf, value.j);
1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", sfield->field.signature);
1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the value of a static field.
1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetStaticFieldValue(RefTypeId refTypeId, FieldId fieldId,
1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 rawValue, int width)
1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StaticField* sfield = (StaticField*) fieldIdToField(refTypeId, fieldId);
1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue value;
1681de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    value.j = rawValue;
1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (sfield->field.signature[0]) {
1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldBoolean(sfield, value.z);
1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldByte(sfield, value.b);
1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldShort(sfield, value.s);
1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldChar(sfield, value.c);
1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldInt(sfield, value.i);
1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldFloat(sfield, value.f);
1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objVal = objectIdToObject(rawValue);
1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldObject(sfield, objVal);
1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldLong(sfield, value.j);
1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticFieldDouble(sfield, value.d);
1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled class type '%s'\n", sfield->field.signature);
1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a string object to a UTF-8 string.
1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgStringToUtf8(ObjectId strId)
1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* strObj = (StringObject*) objectIdToObject(strId);
1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmCreateCstrFromString(strObj);
1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Thread and ThreadGroup
1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Convert a thread object to a Thread ptr.
1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This currently requires running through the list of threads and finding
1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a match.
1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * IMPORTANT: grab gDvm.threadListLock before calling here.
1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Thread* threadObjToThread(Object* threadObj)
1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->threadObj == threadObj)
1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            break;
1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return thread;
1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the status and suspend state of a thread.
1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadStatus(ObjectId threadId, u4* pThreadStatus,
1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4* pSuspendStatus)
1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
1778de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (thread->status) {
1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_ZOMBIE:         *pThreadStatus = TS_ZOMBIE;     break;
1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_RUNNING:        *pThreadStatus = TS_RUNNING;    break;
1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_TIMED_WAIT:     *pThreadStatus = TS_SLEEPING;   break;
1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_MONITOR:        *pThreadStatus = TS_MONITOR;    break;
1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_WAIT:           *pThreadStatus = TS_WAIT;       break;
1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_INITIALIZING:   *pThreadStatus = TS_ZOMBIE;     break;
1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_STARTING:       *pThreadStatus = TS_ZOMBIE;     break;
1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_NATIVE:         *pThreadStatus = TS_RUNNING;    break;
1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case THREAD_VMWAIT:         *pThreadStatus = TS_WAIT;       break;
1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pThreadStatus = THREAD_ZOMBIE;
1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsSuspended(thread))
1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pSuspendStatus = SUSPEND_STATUS_SUSPENDED;
1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pSuspendStatus = 0;
1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = true;
1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the thread's suspend count.
1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmDbgGetThreadSuspendCount(ObjectId threadId)
1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 result = 0;
1825de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = thread->suspendCount;
1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread exists in the VM's thread list.
1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if the thread exists.
1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgThreadExists(ObjectId threadId)
1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result;
1853de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = false;
1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = true;
1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not a thread is suspended.
1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "false" if the thread is running or doesn't exist.
1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgIsSuspended(ObjectId threadId)
1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
1880de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = dvmIsSuspended(thread);
1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Wait until a thread suspends.
1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We stray from the usual pattern here, and release the thread list lock
1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * before we use the Thread.  This is necessary and should be safe in this
1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * circumstance; see comments in dvmWaitForSuspend().
1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgWaitForSuspend(ObjectId threadId)
1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
1910de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != NULL)
1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmWaitForSuspend(thread);
1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the ObjectId for the "system" thread group.
1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetSystemThreadGroupId(void)
1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* groupObj = dvmGetSystemThreadGroup();
1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(groupObj);
1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the ObjectId for the "system" thread group.
1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetMainThreadGroupId(void)
1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* groupObj = dvmGetMainThreadGroup();
1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(groupObj);
1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread.
1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadName(ObjectId threadId)
1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* nameStr;
1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* str;
1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* result;
1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                gDvm.offJavaLangThread_name);
1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    str = dvmCreateCstrFromString(nameStr);
1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = (char*) malloc(strlen(str) + 20);
1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* lock the thread list, so the thread doesn't vanish while we work */
1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread = threadObjToThread(threadObj);
1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != NULL)
1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sprintf(result, "<%d> %s", thread->threadId, str);
1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sprintf(result, "%s", str);
1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(str);
1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a thread's group.
1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroup(ObjectId threadId)
1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* group;
1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    group = dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_group);
1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(group);
1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the name of a thread group.
1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar* dvmDbgGetThreadGroupName(ObjectId threadGroupId)
1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadGroup;
1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* nameField;
2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* nameStr;
2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadGroup = objectIdToObject(threadGroupId);
2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadGroup != NULL);
2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameField = dvmFindInstanceField(gDvm.classJavaLangThreadGroup,
2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "name", "Ljava/lang/String;");
2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (nameField == NULL) {
2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("unable to find name field in ThreadGroup\n");
2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    nameStr = (StringObject*) dvmGetFieldObject(threadGroup,
2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                nameField->byteOffset);
2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmCreateCstrFromString(nameStr);
2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the parent of a thread group.
2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a newly-allocated string.
2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadGroupParent(ObjectId threadGroupId)
2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadGroup;
2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* parentField;
2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* parent;
2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadGroup = objectIdToObject(threadGroupId);
2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadGroup != NULL);
2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    parentField = dvmFindInstanceField(gDvm.classJavaLangThreadGroup,
2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "parent", "Ljava/lang/ThreadGroup;");
2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (parentField == NULL) {
2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("unable to find parent field in ThreadGroup\n");
2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parent = NULL;
2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parent = dvmGetFieldObject(threadGroup, parentField->byteOffset);
2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(parent);
2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the list of threads in the thread group.
2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We do this by running through the full list of threads and returning
2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ones that have the ThreadGroup object as their owner.
2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If threadGroupId is set to "kAllThreads", we ignore the group field and
2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return all threads.
2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds".
2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetThreadGroupThreads(ObjectId threadGroupId,
2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ObjectId** ppThreadIds, u4* pThreadCount)
2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* targetThreadGroup = NULL;
2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InstField* groupField = NULL;
2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (threadGroupId != THREAD_GROUP_ALL) {
2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        targetThreadGroup = objectIdToObject(threadGroupId);
2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(targetThreadGroup != NULL);
2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    groupField = dvmFindInstanceField(gDvm.classJavaLangThread,
2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "group", "Ljava/lang/ThreadGroup;");
2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = gDvm.threadList;
2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = 0;
2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* group;
2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Skip over the JDWP support thread.  Some debuggers
2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * get bent out of shape when they can't suspend and
2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * query all threads, so it's easier if we just don't
2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * tell them about us.
2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* This thread is currently being created, and isn't ready
2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * to be seen by the debugger yet.
2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->threadObj == NULL)
2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        group = dvmGetFieldObject(thread->threadObj, groupField->byteOffset);
2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup)
2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pThreadCount = count;
2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (count == 0) {
2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *ppThreadIds = NULL;
2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ObjectId* ptr;
2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ptr = *ppThreadIds = (ObjectId*) malloc(sizeof(ObjectId) * count);
2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Object* group;
2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Skip over the JDWP support thread.  Some debuggers
2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * get bent out of shape when they can't suspend and
2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * query all threads, so it's easier if we just don't
2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * tell them about us.
2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* This thread is currently being created, and isn't ready
2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to be seen by the debugger yet.
2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (thread->threadObj == NULL)
2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            group = dvmGetFieldObject(thread->threadObj,groupField->byteOffset);
2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (threadGroupId == THREAD_GROUP_ALL || group == targetThreadGroup)
2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *ptr++ = objectToObjectId(thread->threadObj);
2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count--;
2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(count == 0);
2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get all threads.
2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must free "*ppThreadIds".
2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetAllThreads(ObjectId** ppThreadIds, u4* pThreadCount)
2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDbgGetThreadGroupThreads(THREAD_GROUP_ALL, ppThreadIds, pThreadCount);
2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count up the #of frames on the thread's stack.
2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns -1 on failure;
2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmDbgGetThreadFrameCount(ObjectId threadId)
2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* framePtr;
2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 count = 0;
2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    framePtr = thread->curFrame;
2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (framePtr != NULL) {
2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!dvmIsBreakFrame(framePtr))
2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr = SAVEAREA_FROM_FP(framePtr)->prevFrame;
2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return count;
2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get info for frame N from the specified thread's stack.
2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThreadFrame(ObjectId threadId, int num, FrameId* pFrameId,
2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation* pLoc)
2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* framePtr;
2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL)
2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    framePtr = thread->curFrame;
2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = 0;
2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (framePtr != NULL) {
2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const Method* method = saveArea->method;
2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!dvmIsBreakFrame(framePtr)) {
2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count == num) {
2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                *pFrameId = frameToFrameId(framePtr);
2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (dvmIsInterfaceClass(method->clazz))
2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->typeTag = TT_INTERFACE;
2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else
2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->typeTag = TT_CLASS;
2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pLoc->classId = classObjectToRefTypeId(method->clazz);
2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pLoc->methodId = methodToMethodId(method);
2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (dvmIsNativeMethod(method))
2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->idx = (u8)-1;
2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else
2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pLoc->idx = saveArea->xtra.currentPc - method->insns;
2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmUnlockThreadList();
2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr = saveArea->prevFrame;
2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return false;
2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the ThreadId for the current thread.
2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectObjectId dvmDbgGetThreadSelfId(void)
2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return objectToObjectId(self->threadObj);
2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend the VM.
2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendVM(bool isEvent)
2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmSuspendAllThreads(isEvent ? SUSPEND_FOR_DEBUG_EVENT : SUSPEND_FOR_DEBUG);
2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume the VM.
2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeVM()
2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmResumeAllThreads(SUSPEND_FOR_DEBUG);
2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend one thread (not ourselves).
2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendThread(ObjectId threadId)
2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* can happen if our ThreadDeath notify crosses in the mail */
2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj);
2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSuspendThread(thread);
2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resume one thread (not ourselves).
2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgResumeThread(ObjectId threadId)
2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("WARNING: threadid=%llx obj=%p no match\n", threadId, threadObj);
2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(thread);
2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suspend ourselves after sending an event to the debugger.
2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSuspendSelf(void)
2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmSuspendSelf(true);
2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the "this" object for the specified frame.
2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Object* getThisObject(const u4* framePtr)
2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const StackSaveArea* saveArea = SAVEAREA_FROM_FP(framePtr);
2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* method = saveArea->method;
2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int argOffset = method->registersSize - method->insSize;
2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisObj;
2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (method == NULL) {
2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* this is a "break" frame? */
2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("  Pulling this object for frame at %p\n", framePtr);
2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("    Method='%s' native=%d static=%d this=%p\n",
2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->name, dvmIsNativeMethod(method),
2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmIsStaticMethod(method), (Object*) framePtr[argOffset]);
2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * No "this" pointer for statics.  No args on the interp stack for
2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * native methods invoked directly from the VM.
2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsNativeMethod(method) || dvmIsStaticMethod(method))
2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = NULL;
2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = (Object*) framePtr[argOffset];
2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thisObj != NULL && !dvmIsValidObject(thisObj)) {
2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Debugger: invalid 'this' pointer %p in %s.%s; returning NULL\n",
2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            framePtr, method->clazz->descriptor, method->name);
2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisObj = NULL;
2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return thisObj;
2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the "this" object for the specified frame.  The thread must be
2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suspended.
2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgGetThisObject(ObjectId threadId, FrameId frameId, ObjectId* pThisId)
2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u4* framePtr = frameIdToFrame(frameId);
2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisObj;
2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thisObj = getThisObject(framePtr);
2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pThisId = objectToObjectId(thisObj);
2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the value of a method argument or local variable into the
2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified buffer.  The value will be preceeded with the tag.
2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgGetLocalValue(ObjectId threadId, FrameId frameId, int slot,
2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1 tag, u1* buf, int expectedLen)
2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u4* framePtr = frameIdToFrame(frameId);
2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* objVal;
2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 intVal;
2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 longVal;
2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    slot = untweakSlot(slot, framePtr);     // Eclipse workaround
2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf+1, intVal != 0);
2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 1);
2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set1(buf+1, intVal);
2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 2);
2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set2BE(buf+1, intVal);
2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 4);
2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intVal = framePtr[slot];
2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set4BE(buf+1, intVal);
2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* convert to "ObjectId" */
2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objVal = (Object*)framePtr[slot];
2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (objVal != NULL && !dvmIsValidObject(objVal)) {
2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JDWP: slot %d expected to hold array, %p invalid\n",
2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    slot, objVal);
2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmAbort();         // DEBUG: make it obvious
2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                objVal = NULL;
2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tag = JT_OBJECT;    // JT_ARRAY not expected for NULL ref
2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetObjectId(buf+1, objectToObjectId(objVal));
2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* convert to "ObjectId" */
2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objVal = (Object*)framePtr[slot];
2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //char* name;
2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (objVal != NULL) {
2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (!dvmIsValidObject(objVal)) {
2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGW("JDWP: slot %d expected to hold object, %p invalid\n",
2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        slot, objVal);
2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    dvmAbort();         // DEBUG: make it obvious
2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    objVal = NULL;
2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //name = generateJNISignature(objVal->clazz);
2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tag = resultTagFromObject(objVal);
2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //free(name);
2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tag = JT_OBJECT;
2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetObjectId(buf+1, objectToObjectId(objVal));
2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(expectedLen == 8);
2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        longVal = *(u8*)(&framePtr[slot]);
2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set8BE(buf+1, longVal);
2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    set1(buf, tag);
2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy a new value into an argument or local variable.
2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgSetLocalValue(ObjectId threadId, FrameId frameId, int slot, u1 tag,
2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u8 value, int width)
2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4* framePtr = frameIdToFrame(frameId);
2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    slot = untweakSlot(slot, framePtr);     // Eclipse workaround
2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (tag) {
2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BOOLEAN:
2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_BYTE:
2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 1);
2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_SHORT:
2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CHAR:
2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 2);
2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_INT:
2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_FLOAT:
2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 4);
2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4)value;
2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_STRING:
2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* The debugger calls VirtualMachine.CreateString to create a new
2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * string, then uses this to set the object reference, when you
2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * edit a String object */
2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_ARRAY:
2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_OBJECT:
2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == sizeof(ObjectId));
2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        framePtr[slot] = (u4) objectIdToObject(value);
2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_DOUBLE:
2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_LONG:
2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(width == 8);
2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(u8*)(&framePtr[slot]) = value;
2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_VOID:
2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_OBJECT:
2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD:
2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_THREAD_GROUP:
2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JT_CLASS_LOADER:
2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("ERROR: unhandled tag '%c'\n", tag);
2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Debugger notification
2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a breakpoint address has been reached.
2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "pcOffset" will be -1 for native methods.
2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "thisPtr" will be NULL for static methods.
2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostLocationEvent(const Method* method, int pcOffset,
2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisPtr, int eventFlags)
2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation loc;
2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(method->clazz))
2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        loc.typeTag = TT_INTERFACE;
2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        loc.typeTag = TT_CLASS;
2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.classId = classObjectToRefTypeId(method->clazz);
2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.methodId = methodToMethodId(method);
2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    loc.idx = pcOffset;
2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Note we use "NoReg" so we don't keep track of references that are
2538c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * never actually sent to the debugger.  The "thisPtr" is only used to
2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * compare against registered events.
2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmJdwpPostLocationEvent(gDvm.jdwpState, &loc,
2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectIdNoReg(thisPtr), eventFlags))
2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classObjectToRefTypeId(method->clazz);
2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objectToObjectId(thisPtr);
2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that an exception has occurred.
2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostException(void* throwFp, int throwRelPc, void* catchFp,
2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int catchRelPc, Object* exception)
2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpLocation throwLoc, catchLoc;
2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* throwMeth;
2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* catchMeth;
2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwMeth = SAVEAREA_FROM_FP(throwFp)->method;
2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(throwMeth->clazz))
2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwLoc.typeTag = TT_INTERFACE;
2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwLoc.typeTag = TT_CLASS;
2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.classId = classObjectToRefTypeId(throwMeth->clazz);
2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.methodId = methodToMethodId(throwMeth);
2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    throwLoc.idx = throwRelPc;
2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (catchRelPc < 0) {
2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        memset(&catchLoc, 0, sizeof(catchLoc));
2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchMeth = SAVEAREA_FROM_FP(catchFp)->method;
2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsInterfaceClass(catchMeth->clazz))
2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchLoc.typeTag = TT_INTERFACE;
2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchLoc.typeTag = TT_CLASS;
2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.classId = classObjectToRefTypeId(catchMeth->clazz);
2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.methodId = methodToMethodId(catchMeth);
2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchLoc.idx = catchRelPc;
2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* need this for InstanceOnly filters */
2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* thisObj = getThisObject(throwFp);
2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2585c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    /*
2586c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * Hand the event to the JDWP exception handler.  Note we're using the
2587c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * "NoReg" objectID on the exception, which is not strictly correct --
2588c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * the exception object WILL be passed up to the debugger if the
2589c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * debugger is interested in the event.  We do this because the current
2590c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * implementation of the debugger object registry never throws anything
2591c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * away, and some people were experiencing a fatal build up of exception
2592c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     * objects when dealing with certain libraries.
2593c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden     */
2594c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden    dvmJdwpPostException(gDvm.jdwpState, &throwLoc,
2595c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden        objectToObjectIdNoReg(exception),
2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classObjectToRefTypeId(exception->clazz), &catchLoc,
2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        objectToObjectId(thisObj));
2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has started.
2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadStart(Thread* thread)
2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.debuggerActive) {
2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmJdwpPostThreadChange(gDvm.jdwpState,
2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectId(thread->threadObj), true);
2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.ddmThreadNotification)
2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDdmSendThreadNotification(thread, true);
2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP and/or DDMS that a thread has gone away.
2615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostThreadDeath(Thread* thread)
2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.debuggerActive) {
2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmJdwpPostThreadChange(gDvm.jdwpState,
2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objectToObjectId(thread->threadObj), false);
2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.ddmThreadNotification)
2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDdmSendThreadNotification(thread, false);
2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell JDWP that a new class has been prepared.
2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgPostClassPrepare(ClassObject* clazz)
2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int tag;
2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* signature;
2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(clazz))
2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tag = TT_INTERFACE;
2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tag = TT_CLASS;
2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO - we currently always send both "verified" and "prepared" since
2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // debuggers seem to like that.  There might be some advantage to honesty,
2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // since the class may not yet be verified.
2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    signature = generateJNISignature(clazz);
2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmJdwpPostClassPrepare(gDvm.jdwpState, tag, classObjectToRefTypeId(clazz),
2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        signature, CS_VERIFIED | CS_PREPARED);
2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(signature);
2646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered an event with a LocationOnly
2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mod.  Tell the interpreter to call us if we hit the specified
2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * address.
2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgWatchLocation(const JdwpLocation* pLoc)
2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId);
2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!dvmIsNativeMethod(method));
2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmAddBreakAddr(method, pLoc->idx);
2658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;        /* assume success */
2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An event with a LocationOnly mod has been removed.
2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnwatchLocation(const JdwpLocation* pLoc)
2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Method* method = methodIdToMethod(pLoc->classId, pLoc->methodId);
2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!dvmIsNativeMethod(method));
2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmClearBreakAddr(method, pLoc->idx);
2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP event mechanism has registered a single-step event.  Tell
2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interpreter about it.
2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgConfigureStep(ObjectId threadId, enum JdwpStepSize size,
2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    enum JdwpStepDepth depth)
2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj;
2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool result = false;
2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadObj = objectIdToObject(threadId);
2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(threadObj != NULL);
2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get a pointer to the Thread struct for this ID.  The pointer will
2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * be used strictly for comparisons against the current thread pointer
2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * after the setup is complete, so we can safely release the lock.
2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    thread = threadObjToThread(threadObj);
2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Thread for single-step not found\n");
2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmIsSuspended(thread)) {
2698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("Thread for single-step not suspended\n");
2699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!"non-susp step");      // I want to know if this can happen
2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsSuspended(thread));
2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmAddSingleStep(thread, size, depth))
2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = true;
2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A single-step event has been removed.
2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgUnconfigureStep(ObjectId threadId)
2718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(threadId);
2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* right now it's global, so don't need to find Thread */
2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmClearSingleStep(NULL);
2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Invoke a method in a thread that has been stopped on a breakpoint or
2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * other debugger event.  (This function is called from the JDWP thread.)
2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that access control is not enforced, per spec.
2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJdwpError dvmDbgInvokeMethod(ObjectId threadId, ObjectId objectId,
2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RefTypeId classId, MethodId methodId, u4 numArgs, ObjectId* argArray,
2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 options, u1* pResultTag, u8* pResultValue, ObjectId* pExceptObj)
2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* threadObj = objectIdToObject(threadId);
2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* targetThread;
2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JdwpError err = ERR_NONE;
2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(NULL);
2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread = threadObjToThread(threadObj);
2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (targetThread == NULL) {
2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        err = ERR_INVALID_THREAD;       /* thread does not exist */
2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmUnlockThreadList();
2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!targetThread->invokeReq.ready) {
2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        err = ERR_INVALID_THREAD;       /* thread not stopped by event */
2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmUnlockThreadList();
2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
27540d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * We currently have a bug where we don't successfully resume the
27550d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * target thread if the suspend count is too deep.  We're expected to
27560d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * require one "resume" for each "suspend", but when asked to execute
27570d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * a method we have to resume fully and then re-suspend it back to the
27580d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * same level.  (The easiest way to cause this is to type "suspend"
27590d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * multiple times in jdb.)
27600d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     *
27610d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * It's unclear what this means when the event specifies "resume all"
27620d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * and some threads are suspended more deeply than others.  This is
27630d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * a rare problem, so for now we just prevent it from hanging forever
27640d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * by rejecting the method invocation request.  Without this, we will
27650d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     * be stuck waiting on a suspended thread.
27660d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden     */
27670d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden    if (targetThread->suspendCount > 1) {
27680d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        LOGW("threadid=%d: suspend count on threadid=%d is %d, too deep "
27690d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden             "for method exec\n",
27700d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden            dvmThreadSelf()->threadId, targetThread->threadId,
27710d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden            targetThread->suspendCount);
27720d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        err = ERR_THREAD_SUSPENDED;     /* probably not expected here */
27730d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        dvmUnlockThreadList();
27740d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden        goto bail;
27750d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden    }
27760d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden
27770d6fff2da41e53c3ee790f352a40e84ad782d286Andy McFadden    /*
2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: ought to screen the various IDs, and verify that the argument
2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list is valid.
2780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.obj = objectIdToObject(objectId);
2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.thread = threadObj;
2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.clazz = refTypeIdToClassObject(classId);
2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.method = methodIdToMethod(classId, methodId);
2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.numArgs = numArgs;
2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.argArray = argArray;
2788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.options = options;
2789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    targetThread->invokeReq.invokeNeeded = true;
2790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is a bit risky -- if the thread goes away we're sitting high
2793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and dry -- but we must release this before the dvmResumeAllThreads
2794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call, and it's unwise to hold it during dvmWaitForSuspend.
2795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
2797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
279999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * We change our (JDWP thread) status, which should be THREAD_RUNNING,
280099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * so the VM can suspend for a GC if the invoke request causes us to
280199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * run out of memory.  It's also a good idea to change it before locking
280299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * the invokeReq mutex, although that should never be held for long.
2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
2806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    Transferring control to event thread\n");
2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockMutex(&targetThread->invokeReq.lock);
2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((options & INVOKE_SINGLE_THREADED) == 0) {
2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming all threads\n");
2812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeAllThreads(SUSPEND_FOR_DEBUG_EVENT);
2813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming event thread only\n");
2815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(targetThread);
2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Wait for the request to finish executing.
2820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (targetThread->invokeReq.invokeNeeded) {
2822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pthread_cond_wait(&targetThread->invokeReq.cv,
2823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          &targetThread->invokeReq.lock);
2824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockMutex(&targetThread->invokeReq.lock);
2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGV("    Control has returned from event thread\n");
2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* wait for thread to re-suspend itself */
2829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmWaitForSuspend(targetThread);
2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Done waiting, switch back to RUNNING.
2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmChangeStatus(self, oldStatus);
2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Suspend the threads.  We waited for the target thread to suspend
2838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * itself, so all we need to do is suspend the others.
2839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
2840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The suspendAllThreads() call will double-suspend the event thread,
2841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * so we want to resume the target thread once to keep the books straight.
2842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((options & INVOKE_SINGLE_THREADED) == 0) {
2844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Suspending all threads\n");
2845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSuspendAllThreads(SUSPEND_FOR_DEBUG_EVENT);
2846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("      Resuming event thread to balance the count\n");
2847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(targetThread);
2848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set up the result.
2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pResultTag = targetThread->invokeReq.resultTag;
2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isTagPrimitive(targetThread->invokeReq.resultTag))
2855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pResultValue = targetThread->invokeReq.resultValue.j;
2856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else
2857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pResultValue = objectToObjectId(targetThread->invokeReq.resultValue.l);
2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *pExceptObj = targetThread->invokeReq.exceptObj;
2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    err = targetThread->invokeReq.err;
2860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return err;
2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine the tag type for the return value for this method.
2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic u1 resultTagFromSignature(const Method* method)
2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* descriptor = dexProtoGetReturnType(&method->prototype);
2871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDbgGetSignatureTag(descriptor);
2872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Execute the method described by "*pReq".
287699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
287799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * We're currently in VMWAIT, because we're stopped on a breakpoint.  We
287899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * want to switch to RUNNING while we execute.
2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgExecuteMethod(DebugInvokeReq* pReq)
2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* meth;
2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Object* oldExcept;
288599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    int oldStatus;
2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * We can be called while an exception is pending in the VM.  We need
2889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to preserve that across the method invocation.
2890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    oldExcept = dvmGetException(self);
289299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    dvmClearException(self);
289399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
289499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    oldStatus = dvmChangeStatus(self, THREAD_RUNNING);
2895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
2897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Translate the method through the vtable, unless we're calling a
2898f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden     * direct method or the debugger wants to suppress it.
2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
2900f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    if ((pReq->options & INVOKE_NONVIRTUAL) != 0 || pReq->obj == NULL ||
2901f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        dvmIsDirectMethod(pReq->method))
2902f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden    {
2903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = pReq->method;
2904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
2905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth = dvmGetVirtualizedMethod(pReq->clazz, pReq->method);
2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(meth != NULL);
2908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(sizeof(jvalue) == sizeof(u8));
2910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    IF_LOGV() {
2912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
2913f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        LOGV("JDWP invoking method %p/%p %s.%s:%s\n",
2914f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden            pReq->method, meth, meth->clazz->descriptor, meth->name, desc);
2915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        free(desc);
2916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2918d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    dvmCallMethodA(self, meth, pReq->obj, false, &pReq->resultValue,
2919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (jvalue*)pReq->argArray);
2920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pReq->exceptObj = objectToObjectId(dvmGetException(self));
2921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pReq->resultTag = resultTagFromSignature(meth);
2922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pReq->exceptObj != 0) {
2923f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        Object* exc = dvmGetException(self);
2924f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        LOGD("  JDWP invocation returning with exceptObj=%p (%s)\n",
2925f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden            exc, exc->clazz->descriptor);
2926f50c6d57afb09f8ed9da179a8bc8b409279ef8a6Andy McFadden        //dvmLogExceptionStackTrace();
2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmClearException(self);
2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
2929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Nothing should try to use this, but it looks like something is.
2930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Make it null to be safe.
2931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pReq->resultValue.j = 0; /*0xadadadad;*/
2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (pReq->resultTag == JT_OBJECT) {
2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* if no exception thrown, examine object result more closely */
2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u1 newTag = resultTagFromObject(pReq->resultValue.l);
2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newTag != pReq->resultTag) {
2937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("  JDWP promoted result from %d to %d\n",
2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pReq->resultTag, newTag);
2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pReq->resultTag = newTag;
2940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (oldExcept != NULL)
2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetException(self, oldExcept);
294599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    dvmChangeStatus(self, oldStatus);
2946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine
2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct AddressSetContext {
2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool lastAddressValid;
2951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 lastAddress;
2952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 lineNum;
2953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSet *pSet;
2954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} AddressSetContext;
2955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for dvmAddressSetForLine
2957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int addressSetCb (void *cnxt, u4 address, u4 lineNum)
2958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSetContext *pContext = (AddressSetContext *)cnxt;
2960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (lineNum == pContext->lineNum) {
2962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!pContext->lastAddressValid) {
2963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Everything from this address until the next line change is ours
2964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pContext->lastAddress = address;
2965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pContext->lastAddressValid = true;
2966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // else, If we're already in a valid range for this lineNum,
2968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // just keep going (shouldn't really happen)
2969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (pContext->lastAddressValid) { // and the line number is new
2970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 i;
2971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Add everything from the last entry up until here to the set
2972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = pContext->lastAddress; i < address; i++) {
2973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAddressSetSet(pContext->pSet, i);
2974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pContext->lastAddressValid = false;
2977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // there may be multiple entries for a line
2980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
2981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Build up a set of bytecode addresses associated with a line number
2984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst AddressSet *dvmAddressSetForLine(const Method* method, int line)
2986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSet *result;
2988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const DexFile *pDexFile = method->clazz->pDvmDex->pDexFile;
2989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 insnsSize = dvmGetMethodInsnsSize(method);
2990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AddressSetContext context;
2991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = calloc(1, sizeof(AddressSet) + (insnsSize/8) + 1);
2993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result->setSize = insnsSize;
2994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(&context, 0, sizeof(context));
2996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.pSet = result;
2997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.lineNum = line;
2998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    context.lastAddressValid = false;
2999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(pDexFile, dvmGetMethodCode(method),
3001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->clazz->descriptor,
3002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->prototype.protoIdx,
3003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        method->accessFlags,
3004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        addressSetCb, NULL, &context);
3005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // If the line number was the last in the position table...
3007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (context.lastAddressValid) {
3008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 i;
3009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (i = context.lastAddress; i < insnsSize; i++) {
3010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAddressSetSet(result, i);
3011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
3012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
3013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
3015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
3020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Dalvik Debug Monitor support
3021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
3022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We have received a DDM packet over JDWP.  Hand it off to the VM.
3026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmDbgDdmHandlePacket(const u1* buf, int dataLen, u1** pReplyBuf,
3028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int* pReplyLen)
3029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return dvmDdmHandlePacket(buf, dataLen, pReplyBuf, pReplyLen);
3031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * First DDM packet has arrived over JDWP.  Notify the press.
3035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDdmConnected(void)
3037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDdmConnected();
3039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP connection has dropped.
3043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDbgDdmDisconnected(void)
3045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDdmDisconnected();
3047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send up a JDWP event packet with a DDM chunk in it.
3051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
30520171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunk(int type, size_t len, const u1* buf)
30530171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden{
30540171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    assert(buf != NULL);
30550171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    struct iovec vec[1] = { {(void*)buf, len} };
30560171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    dvmDbgDdmSendChunkV(type, vec, 1);
30570171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden}
30580171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden
30590171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden/*
30600171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * Send up a JDWP event packet with a DDM chunk in it.  The chunk is
30610171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * concatenated from multiple source buffers.
30620171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden */
30630171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt)
3064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.jdwpState == NULL) {
3066dced79474902ffa57fbd48121eb794aad7d24ddcAndy McFadden        LOGV("Debugger thread not active, ignoring DDM send (t=0x%08x l=%d)\n",
3067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            type, len);
3068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
3069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
3070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30710171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    dvmJdwpDdmSendChunkV(gDvm.jdwpState, type, iov, iovcnt);
3072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
3073