1 /*
2 * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include <jni.h>
26 #include "libproc.h"
27
28 #include <elf.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <limits.h>
35
36 #if defined(x86_64) && !defined(amd64)
37 #define amd64 1
38 #endif
39
40 #ifdef i386
41 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
42 #endif
43
44 #ifdef amd64
45 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
46 #endif
47
48 #if defined(sparc) || defined(sparcv9)
49 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
50 #endif
51
52 #if defined(ppc64) || defined(ppc64le)
53 #include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
54 #endif
55
56 #ifdef aarch64
57 #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
58 #endif
59
60 static jfieldID p_ps_prochandle_ID = 0;
61 static jfieldID threadList_ID = 0;
62 static jfieldID loadObjectList_ID = 0;
63
64 static jmethodID createClosestSymbol_ID = 0;
65 static jmethodID createLoadObject_ID = 0;
66 static jmethodID getThreadForThreadId_ID = 0;
67 static jmethodID listAdd_ID = 0;
68
69 /*
70 * SA_ALTROOT environment variable.
71 * This memory holds env string for putenv(3).
72 */
73 static char *saaltroot = NULL;
74
75 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
76 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
77 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
78 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
79
throw_new_debugger_exception(JNIEnv * env,const char * errMsg)80 void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
81 jclass clazz;
82 clazz = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
83 CHECK_EXCEPTION;
84 (*env)->ThrowNew(env, clazz, errMsg);
85 }
86
get_proc_handle(JNIEnv * env,jobject this_obj)87 struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
88 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
89 return (struct ps_prochandle*)(intptr_t)ptr;
90 }
91
92 /*
93 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
94 * Method: init0
95 * Signature: ()V
96 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0(JNIEnv * env,jclass cls)97 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0
98 (JNIEnv *env, jclass cls) {
99 jclass listClass;
100
101 if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
102 THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
103 }
104
105 // fields we use
106 p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
107 CHECK_EXCEPTION;
108 threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
109 CHECK_EXCEPTION;
110 loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
111 CHECK_EXCEPTION;
112
113 // methods we use
114 createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
115 "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
116 CHECK_EXCEPTION;
117 createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
118 "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
119 CHECK_EXCEPTION;
120 getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
121 "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
122 CHECK_EXCEPTION;
123 // java.util.List method we call
124 listClass = (*env)->FindClass(env, "java/util/List");
125 CHECK_EXCEPTION;
126 listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
127 CHECK_EXCEPTION;
128 }
129
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize(JNIEnv * env,jclass cls)130 JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize
131 (JNIEnv *env, jclass cls)
132 {
133 #ifdef _LP64
134 return 8;
135 #else
136 return 4;
137 #endif
138
139 }
140
141
fillThreadsAndLoadObjects(JNIEnv * env,jobject this_obj,struct ps_prochandle * ph)142 static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
143 int n = 0, i = 0;
144
145 // add threads
146 n = get_num_threads(ph);
147 for (i = 0; i < n; i++) {
148 jobject thread;
149 jobject threadList;
150 lwpid_t lwpid;
151
152 lwpid = get_lwp_id(ph, i);
153 thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
154 (jlong)lwpid);
155 CHECK_EXCEPTION;
156 threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
157 CHECK_EXCEPTION;
158 (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
159 CHECK_EXCEPTION;
160 }
161
162 // add load objects
163 n = get_num_libs(ph);
164 for (i = 0; i < n; i++) {
165 uintptr_t base;
166 const char* name;
167 jobject loadObject;
168 jobject loadObjectList;
169 jstring str;
170
171 base = get_lib_base(ph, i);
172 name = get_lib_name(ph, i);
173
174 str = (*env)->NewStringUTF(env, name);
175 CHECK_EXCEPTION;
176 loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, str, (jlong)0, (jlong)base);
177 CHECK_EXCEPTION;
178 loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
179 CHECK_EXCEPTION;
180 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
181 CHECK_EXCEPTION;
182 }
183 }
184
185
186 /*
187 * Verify that a named ELF binary file (core or executable) has the same
188 * bitness as ourselves.
189 * Throw an exception if there is a mismatch or other problem.
190 *
191 * If we proceed using a mismatched debugger/debuggee, the best to hope
192 * for is a missing symbol, the worst is a crash searching for debug symbols.
193 */
verifyBitness(JNIEnv * env,const char * binaryName)194 void verifyBitness(JNIEnv *env, const char *binaryName) {
195 int fd = open(binaryName, O_RDONLY);
196 if (fd < 0) {
197 THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");
198 }
199 unsigned char elf_ident[EI_NIDENT];
200 int i = read(fd, &elf_ident, sizeof(elf_ident));
201 close(fd);
202
203 if (i < 0) {
204 THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
205 }
206 #ifndef _LP64
207 if (elf_ident[EI_CLASS] == ELFCLASS64) {
208 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
209 }
210 #else
211 if (elf_ident[EI_CLASS] != ELFCLASS64) {
212 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
213 }
214 #endif
215 }
216
217
218 /*
219 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
220 * Method: setSAAltRoot0
221 * Signature: (Ljava/lang/String;)V
222 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_setSAAltRoot0(JNIEnv * env,jobject this_obj,jstring altroot)223 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_setSAAltRoot0
224 (JNIEnv *env, jobject this_obj, jstring altroot) {
225 if (saaltroot != NULL) {
226 free(saaltroot);
227 }
228 const char *path = (*env)->GetStringUTFChars(env, altroot, JNI_FALSE);
229 /*
230 * `saaltroot` is used for putenv().
231 * So we need to keep this memory.
232 */
233 static const char *PREFIX = "SA_ALTROOT=";
234 size_t len = strlen(PREFIX) + strlen(path) + 1;
235 saaltroot = (char *)malloc(len);
236 snprintf(saaltroot, len, "%s%s", PREFIX, path);
237 putenv(saaltroot);
238 (*env)->ReleaseStringUTFChars(env, altroot, path);
239 }
240
241 /*
242 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
243 * Method: attach0
244 * Signature: (IZ)V
245 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__IZ(JNIEnv * env,jobject this_obj,jint jpid,jboolean is_in_container)246 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__IZ
247 (JNIEnv *env, jobject this_obj, jint jpid, jboolean is_in_container) {
248
249 // For bitness checking, locate binary at /proc/jpid/exe
250 char buf[PATH_MAX];
251 snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
252 verifyBitness(env, (char *) &buf);
253 CHECK_EXCEPTION;
254
255 char err_buf[200];
256 struct ps_prochandle* ph;
257 if ((ph = Pgrab(jpid, err_buf, sizeof(err_buf), is_in_container)) == NULL) {
258 char msg[230];
259 snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);
260 THROW_NEW_DEBUGGER_EXCEPTION(msg);
261 }
262 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
263 fillThreadsAndLoadObjects(env, this_obj, ph);
264 }
265
266 /*
267 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
268 * Method: attach0
269 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
270 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2(JNIEnv * env,jobject this_obj,jstring execName,jstring coreName)271 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
272 (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
273 const char *execName_cstr;
274 const char *coreName_cstr;
275 jboolean isCopy;
276 struct ps_prochandle* ph;
277
278 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
279 CHECK_EXCEPTION;
280 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
281 CHECK_EXCEPTION;
282
283 verifyBitness(env, execName_cstr);
284 CHECK_EXCEPTION;
285
286 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
287 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
288 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
289 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
290 }
291 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
292 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
293 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
294 fillThreadsAndLoadObjects(env, this_obj, ph);
295 }
296
297 /*
298 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
299 * Method: detach0
300 * Signature: ()V
301 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0(JNIEnv * env,jobject this_obj)302 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0
303 (JNIEnv *env, jobject this_obj) {
304 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
305 if (ph != NULL) {
306 Prelease(ph);
307 }
308 if (saaltroot != NULL) {
309 free(saaltroot);
310 saaltroot = NULL;
311 }
312 }
313
314 /*
315 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
316 * Method: lookupByName0
317 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
318 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0(JNIEnv * env,jobject this_obj,jstring objectName,jstring symbolName)319 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0
320 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
321 const char *objectName_cstr, *symbolName_cstr;
322 jlong addr;
323 jboolean isCopy;
324 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
325
326 objectName_cstr = NULL;
327 if (objectName != NULL) {
328 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
329 CHECK_EXCEPTION_(0);
330 }
331 symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
332 CHECK_EXCEPTION_(0);
333
334 addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
335
336 if (objectName_cstr != NULL) {
337 (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
338 }
339 (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
340 return addr;
341 }
342
343 /*
344 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
345 * Method: lookupByAddress0
346 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
347 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0(JNIEnv * env,jobject this_obj,jlong addr)348 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0
349 (JNIEnv *env, jobject this_obj, jlong addr) {
350 uintptr_t offset;
351 jobject obj;
352 jstring str;
353 const char* sym = NULL;
354
355 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
356 sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
357 if (sym == NULL) return 0;
358 str = (*env)->NewStringUTF(env, sym);
359 CHECK_EXCEPTION_(NULL);
360 obj = (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, str, (jlong)offset);
361 CHECK_EXCEPTION_(NULL);
362 return obj;
363 }
364
365 /*
366 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
367 * Method: readBytesFromProcess0
368 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
369 */
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0(JNIEnv * env,jobject this_obj,jlong addr,jlong numBytes)370 JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0
371 (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
372
373 jboolean isCopy;
374 jbyteArray array;
375 jbyte *bufPtr;
376 ps_err_e err;
377
378 array = (*env)->NewByteArray(env, numBytes);
379 CHECK_EXCEPTION_(0);
380 bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
381 CHECK_EXCEPTION_(0);
382
383 err = ps_pdread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
384 (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
385 return (err == PS_OK)? array : 0;
386 }
387
388 #if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64)
Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0(JNIEnv * env,jobject this_obj,jint lwp_id)389 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
390 (JNIEnv *env, jobject this_obj, jint lwp_id) {
391
392 struct user_regs_struct gregs;
393 jboolean isCopy;
394 jlongArray array;
395 jlong *regs;
396 int i;
397
398 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
399 if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
400 THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
401 }
402
403 #undef NPRGREG
404 #ifdef i386
405 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
406 #endif
407 #ifdef amd64
408 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
409 #endif
410 #ifdef aarch64
411 #define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG
412 #endif
413 #if defined(sparc) || defined(sparcv9)
414 #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
415 #endif
416 #if defined(ppc64) || defined(ppc64le)
417 #define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG
418 #endif
419
420
421 array = (*env)->NewLongArray(env, NPRGREG);
422 CHECK_EXCEPTION_(0);
423 regs = (*env)->GetLongArrayElements(env, array, &isCopy);
424
425 #undef REG_INDEX
426
427 #ifdef i386
428 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
429
430 regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs;
431 regs[REG_INDEX(FS)] = (uintptr_t) gregs.xfs;
432 regs[REG_INDEX(ES)] = (uintptr_t) gregs.xes;
433 regs[REG_INDEX(DS)] = (uintptr_t) gregs.xds;
434 regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi;
435 regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi;
436 regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp;
437 regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp;
438 regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx;
439 regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx;
440 regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx;
441 regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax;
442 regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip;
443 regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs;
444 regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss;
445
446 #endif /* i386 */
447
448 #ifdef amd64
449 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
450
451 regs[REG_INDEX(R15)] = gregs.r15;
452 regs[REG_INDEX(R14)] = gregs.r14;
453 regs[REG_INDEX(R13)] = gregs.r13;
454 regs[REG_INDEX(R12)] = gregs.r12;
455 regs[REG_INDEX(RBP)] = gregs.rbp;
456 regs[REG_INDEX(RBX)] = gregs.rbx;
457 regs[REG_INDEX(R11)] = gregs.r11;
458 regs[REG_INDEX(R10)] = gregs.r10;
459 regs[REG_INDEX(R9)] = gregs.r9;
460 regs[REG_INDEX(R8)] = gregs.r8;
461 regs[REG_INDEX(RAX)] = gregs.rax;
462 regs[REG_INDEX(RCX)] = gregs.rcx;
463 regs[REG_INDEX(RDX)] = gregs.rdx;
464 regs[REG_INDEX(RSI)] = gregs.rsi;
465 regs[REG_INDEX(RDI)] = gregs.rdi;
466 regs[REG_INDEX(RIP)] = gregs.rip;
467 regs[REG_INDEX(CS)] = gregs.cs;
468 regs[REG_INDEX(RSP)] = gregs.rsp;
469 regs[REG_INDEX(SS)] = gregs.ss;
470 regs[REG_INDEX(FSBASE)] = gregs.fs_base;
471 regs[REG_INDEX(GSBASE)] = gregs.gs_base;
472 regs[REG_INDEX(DS)] = gregs.ds;
473 regs[REG_INDEX(ES)] = gregs.es;
474 regs[REG_INDEX(FS)] = gregs.fs;
475 regs[REG_INDEX(GS)] = gregs.gs;
476
477 #endif /* amd64 */
478
479 #if defined(sparc) || defined(sparcv9)
480
481 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
482
483 #ifdef _LP64
484 regs[REG_INDEX(R_PSR)] = gregs.tstate;
485 regs[REG_INDEX(R_PC)] = gregs.tpc;
486 regs[REG_INDEX(R_nPC)] = gregs.tnpc;
487 regs[REG_INDEX(R_Y)] = gregs.y;
488 #else
489 regs[REG_INDEX(R_PSR)] = gregs.psr;
490 regs[REG_INDEX(R_PC)] = gregs.pc;
491 regs[REG_INDEX(R_nPC)] = gregs.npc;
492 regs[REG_INDEX(R_Y)] = gregs.y;
493 #endif
494 regs[REG_INDEX(R_G0)] = 0 ;
495 regs[REG_INDEX(R_G1)] = gregs.u_regs[0];
496 regs[REG_INDEX(R_G2)] = gregs.u_regs[1];
497 regs[REG_INDEX(R_G3)] = gregs.u_regs[2];
498 regs[REG_INDEX(R_G4)] = gregs.u_regs[3];
499 regs[REG_INDEX(R_G5)] = gregs.u_regs[4];
500 regs[REG_INDEX(R_G6)] = gregs.u_regs[5];
501 regs[REG_INDEX(R_G7)] = gregs.u_regs[6];
502 regs[REG_INDEX(R_O0)] = gregs.u_regs[7];
503 regs[REG_INDEX(R_O1)] = gregs.u_regs[8];
504 regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];
505 regs[REG_INDEX(R_O3)] = gregs.u_regs[10];
506 regs[REG_INDEX(R_O4)] = gregs.u_regs[11];
507 regs[REG_INDEX(R_O5)] = gregs.u_regs[12];
508 regs[REG_INDEX(R_O6)] = gregs.u_regs[13];
509 regs[REG_INDEX(R_O7)] = gregs.u_regs[14];
510 #endif /* sparc */
511
512 #if defined(aarch64)
513
514 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
515
516 {
517 int i;
518 for (i = 0; i < 31; i++)
519 regs[i] = gregs.regs[i];
520 regs[REG_INDEX(SP)] = gregs.sp;
521 regs[REG_INDEX(PC)] = gregs.pc;
522 }
523 #endif /* aarch64 */
524
525 #if defined(ppc64) || defined(ppc64le)
526 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg
527
528 regs[REG_INDEX(LR)] = gregs.link;
529 regs[REG_INDEX(NIP)] = gregs.nip;
530 regs[REG_INDEX(R0)] = gregs.gpr[0];
531 regs[REG_INDEX(R1)] = gregs.gpr[1];
532 regs[REG_INDEX(R2)] = gregs.gpr[2];
533 regs[REG_INDEX(R3)] = gregs.gpr[3];
534 regs[REG_INDEX(R4)] = gregs.gpr[4];
535 regs[REG_INDEX(R5)] = gregs.gpr[5];
536 regs[REG_INDEX(R6)] = gregs.gpr[6];
537 regs[REG_INDEX(R7)] = gregs.gpr[7];
538 regs[REG_INDEX(R8)] = gregs.gpr[8];
539 regs[REG_INDEX(R9)] = gregs.gpr[9];
540 regs[REG_INDEX(R10)] = gregs.gpr[10];
541 regs[REG_INDEX(R11)] = gregs.gpr[11];
542 regs[REG_INDEX(R12)] = gregs.gpr[12];
543 regs[REG_INDEX(R13)] = gregs.gpr[13];
544 regs[REG_INDEX(R14)] = gregs.gpr[14];
545 regs[REG_INDEX(R15)] = gregs.gpr[15];
546 regs[REG_INDEX(R16)] = gregs.gpr[16];
547 regs[REG_INDEX(R17)] = gregs.gpr[17];
548 regs[REG_INDEX(R18)] = gregs.gpr[18];
549 regs[REG_INDEX(R19)] = gregs.gpr[19];
550 regs[REG_INDEX(R20)] = gregs.gpr[20];
551 regs[REG_INDEX(R21)] = gregs.gpr[21];
552 regs[REG_INDEX(R22)] = gregs.gpr[22];
553 regs[REG_INDEX(R23)] = gregs.gpr[23];
554 regs[REG_INDEX(R24)] = gregs.gpr[24];
555 regs[REG_INDEX(R25)] = gregs.gpr[25];
556 regs[REG_INDEX(R26)] = gregs.gpr[26];
557 regs[REG_INDEX(R27)] = gregs.gpr[27];
558 regs[REG_INDEX(R28)] = gregs.gpr[28];
559 regs[REG_INDEX(R29)] = gregs.gpr[29];
560 regs[REG_INDEX(R30)] = gregs.gpr[30];
561 regs[REG_INDEX(R31)] = gregs.gpr[31];
562
563 #endif
564
565 (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
566 return array;
567 }
568 #endif
569