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