|
56 | 56 |
|
57 | 57 | // put OS-includes here
|
58 | 58 | # include <dlfcn.h>
|
59 |
| -# include <fpu_control.h> |
60 | 59 | # include <errno.h>
|
| 60 | +# include <fpu_control.h> |
| 61 | +# include <linux/ptrace.h> |
61 | 62 | # include <pthread.h>
|
62 | 63 | # include <signal.h>
|
63 | 64 | # include <stdio.h>
|
@@ -350,6 +351,72 @@ void os::print_context(outputStream *st, const void *context) {
|
350 | 351 | st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]);
|
351 | 352 | }
|
352 | 353 | st->cr();
|
| 354 | + const struct __riscv_mc_d_ext_state * const f_ext_state = &(uc->uc_mcontext.__fpregs.__d); |
| 355 | + st->print_cr("Floating point state:"); |
| 356 | + st->print_cr("fcsr=" UINT32_FORMAT, f_ext_state->__fcsr); |
| 357 | + st->print_cr("Floating point registers:"); |
| 358 | + for (int r = 0; r < 32; r++) { |
| 359 | + st->print_cr("f%d=" INTPTR_FORMAT, r, (intptr_t)f_ext_state->__f[r]); |
| 360 | + } |
| 361 | + st->cr(); |
| 362 | + |
| 363 | +#ifdef NO_RVV_SIGCONTEXT |
| 364 | + st->print_cr("Vector state: JVM compiled without vector sigcontext support"); |
| 365 | +#else // ifndef NO_RVV_SIGCONTEXT |
| 366 | +// This magic number is not in any user-space header. |
| 367 | +// No other choice but to define it (arch/riscv/include/uapi/asm/sigcontext.h). |
| 368 | +#ifndef RISCV_V_MAGIC |
| 369 | +#define RISCV_V_MAGIC 0x53465457 |
| 370 | +#endif |
| 371 | + |
| 372 | + // Find the vector context |
| 373 | + struct __riscv_extra_ext_header *ext = (struct __riscv_extra_ext_header *)(&uc->uc_mcontext.__fpregs); |
| 374 | + if (ext->hdr.magic != RISCV_V_MAGIC) { |
| 375 | + st->print_cr("Vector state: not found"); |
| 376 | + return; |
| 377 | + } |
| 378 | + |
| 379 | + // The size passed to user-space is calculated accordingly: |
| 380 | + // size = sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state) + riscv_v_vsize; |
| 381 | + uint32_t ext_size = ext->hdr.size; |
| 382 | + |
| 383 | + if (ext_size < (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state))) { |
| 384 | + st->print_cr("Vector state: not found, invalid size"); |
| 385 | + return; |
| 386 | + } |
| 387 | + |
| 388 | + struct __riscv_v_ext_state *v_ext_state = (struct __riscv_v_ext_state *)((char *)(ext) + sizeof(struct __riscv_extra_ext_header)); |
| 389 | + |
| 390 | + st->print_cr("Vector state:"); |
| 391 | + st->print_cr("vstart=" INTPTR_FORMAT, v_ext_state->vstart); |
| 392 | + st->print_cr("vl =" INTPTR_FORMAT, v_ext_state->vl); |
| 393 | + st->print_cr("vtype =" INTPTR_FORMAT, v_ext_state->vtype); |
| 394 | + st->print_cr("vcsr =" INTPTR_FORMAT, v_ext_state->vcsr); |
| 395 | + st->print_cr("vlenb =" INTPTR_FORMAT, v_ext_state->vlenb); |
| 396 | + st->print_cr("Vector registers:"); |
| 397 | + |
| 398 | + uint64_t vr_size = v_ext_state->vlenb; |
| 399 | + |
| 400 | + // Registers are after the v extensions header. |
| 401 | + ext_size -= (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state)); |
| 402 | + |
| 403 | + if (ext_size != (32 * vr_size)) { |
| 404 | + st->print_cr("Vector registers: not found, invalid size"); |
| 405 | + return; |
| 406 | + } |
| 407 | + |
| 408 | + // datap format is undocumented, but is generated by kernel function riscv_v_vstate_save(). |
| 409 | + uint8_t *regp = (uint8_t *)v_ext_state->datap; |
| 410 | + for (int r = 0; r < 32; r++) { |
| 411 | + st->print("v%d=0x", r); |
| 412 | + for (int i = vr_size; i > 0; i--) { |
| 413 | + st->print("%02" PRIx8, regp[i-1]); |
| 414 | + } |
| 415 | + st->print_cr(""); |
| 416 | + regp += vr_size; |
| 417 | + } |
| 418 | + st->cr(); |
| 419 | +#endif // #ifndef NO_RVV_SIGCONTEXT |
353 | 420 | }
|
354 | 421 |
|
355 | 422 | void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
|
0 commit comments