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