Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
    usr/src/uts/common/fs/proc/prcontrol.c
    usr/src/uts/intel/os/archdep.c
    usr/src/uts/intel/sys/ucontext.h
    usr/src/uts/intel/syscall/getcontext.c

*** 24,37 **** * Use is subject to license terms. */ /* * Copyright (c) 2018, Joyent, Inc. * Copyright 2019 Doma Gergő Mihály <doma.gergo.mihaly@gmail.com> */ /* ! * User Process Target Intel 32-bit component * * This file provides the ISA-dependent portion of the user process target. * For more details on the implementation refer to mdb_proc.c. */ --- 24,38 ---- * Use is subject to license terms. */ /* * Copyright (c) 2018, Joyent, Inc. * Copyright 2019 Doma Gergő Mihály <doma.gergo.mihaly@gmail.com> + * Copyright 2023 Oxide Computer Company */ /* ! * User Process Target Intel 64-bit component * * This file provides the ISA-dependent portion of the user process target. * For more details on the implementation refer to mdb_proc.c. */
*** 38,54 **** --- 39,57 ---- #include <mdb/mdb_proc.h> #include <mdb/mdb_kreg.h> #include <mdb/mdb_err.h> #include <mdb/mdb_isautil.h> #include <mdb/mdb_amd64util.h> + #include <mdb/proc_x86util.h> #include <mdb/mdb.h> #include <sys/ucontext.h> #include <sys/frame.h> #include <libproc.h> #include <sys/fp.h> #include <ieeefp.h> + #include <sys/sysmacros.h> #include <stddef.h> const mdb_tgt_regdesc_t pt_regdesc[] = { { "r15", REG_R15, MDB_TGT_R_EXPORT },
*** 277,522 **** mdb_printf(" %%err = 0x%x\n", grs[REG_ERR]); return (set_errno(ENOTSUP)); } - static const char * - fpcw2str(uint32_t cw, char *buf, size_t nbytes) - { - char *end = buf + nbytes; - char *p = buf; - - buf[0] = '\0'; - - /* - * Decode all exception masks in the x87 FPU Control Word. - * - * See here: - * Intel® 64 and IA-32 Architectures Software Developer’s Manual, - * Volume 1: Basic Architecture, 8.1.5 x87 FPU Control Word - */ - if (cw & FPIM) /* Invalid operation mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|IM"); - if (cw & FPDM) /* Denormalized operand mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|DM"); - if (cw & FPZM) /* Zero divide mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|ZM"); - if (cw & FPOM) /* Overflow mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|OM"); - if (cw & FPUM) /* Underflow mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|UM"); - if (cw & FPPM) /* Precision mask. */ - p += mdb_snprintf(p, (size_t)(end - p), "|PM"); - - /* - * Decode precision control options. - */ - switch (cw & FPPC) { - case FPSIG24: - /* 24-bit significand, single precision. */ - p += mdb_snprintf(p, (size_t)(end - p), "|SIG24"); - break; - case FPSIG53: - /* 53-bit significand, double precision. */ - p += mdb_snprintf(p, (size_t)(end - p), "|SIG53"); - break; - case FPSIG64: - /* 64-bit significand, double extended precision. */ - p += mdb_snprintf(p, (size_t)(end - p), "|SIG64"); - break; - default: - /* - * Should never happen. - * Value 0x00000100 is 'Reserved'. - */ - break; - } - - /* - * Decode rounding control options. - */ - switch (cw & FPRC) { - case FPRTN: - /* Round to nearest, or to even if equidistant. */ - p += mdb_snprintf(p, (size_t)(end - p), "|RTN"); - break; - case FPRD: - /* Round down. */ - p += mdb_snprintf(p, (size_t)(end - p), "|RD"); - break; - case FPRU: - /* Round up. */ - p += mdb_snprintf(p, (size_t)(end - p), "|RU"); - break; - case FPCHOP: - /* Truncate. */ - p += mdb_snprintf(p, (size_t)(end - p), "|RTZ"); - break; - default: - /* - * This is a two-bit field. - * No other options left. - */ - break; - } - - /* - * Decode infinity control options. - * - * This field has been retained for compatibility with - * the 287 and earlier co-processors. - * In the more modern FPUs, this bit is disregarded and - * both -infinity and +infinity are respected. - * Comment source: SIMPLY FPU by Raymond Filiatreault - */ - switch (cw & FPIC) { - case FPP: - /* - * Projective infinity. - * Both -infinity and +infinity are treated as - * unsigned infinity. - */ - p += mdb_snprintf(p, (size_t)(end - p), "|P"); - break; - case FPA: - /* - * Affine infinity. - * Respects both -infinity and +infinity. - */ - p += mdb_snprintf(p, (size_t)(end - p), "|A"); - break; - default: - /* - * This is a one-bit field. - * No other options left. - */ - break; - } - - if (cw & WFPB17) - p += mdb_snprintf(p, (size_t)(end - p), "|WFPB17"); - if (cw & WFPB24) - p += mdb_snprintf(p, (size_t)(end - p), "|WFPB24"); - - if (buf[0] == '|') - return (buf + 1); - - return ("0"); - } - - static const char * - fpsw2str(uint32_t cw, char *buf, size_t nbytes) - { - char *end = buf + nbytes; - char *p = buf; - - buf[0] = '\0'; - - /* - * Decode all masks in the 80387 status word. - */ - if (cw & FPS_IE) - p += mdb_snprintf(p, (size_t)(end - p), "|IE"); - if (cw & FPS_DE) - p += mdb_snprintf(p, (size_t)(end - p), "|DE"); - if (cw & FPS_ZE) - p += mdb_snprintf(p, (size_t)(end - p), "|ZE"); - if (cw & FPS_OE) - p += mdb_snprintf(p, (size_t)(end - p), "|OE"); - if (cw & FPS_UE) - p += mdb_snprintf(p, (size_t)(end - p), "|UE"); - if (cw & FPS_PE) - p += mdb_snprintf(p, (size_t)(end - p), "|PE"); - if (cw & FPS_SF) - p += mdb_snprintf(p, (size_t)(end - p), "|SF"); - if (cw & FPS_ES) - p += mdb_snprintf(p, (size_t)(end - p), "|ES"); - if (cw & FPS_C0) - p += mdb_snprintf(p, (size_t)(end - p), "|C0"); - if (cw & FPS_C1) - p += mdb_snprintf(p, (size_t)(end - p), "|C1"); - if (cw & FPS_C2) - p += mdb_snprintf(p, (size_t)(end - p), "|C2"); - if (cw & FPS_C3) - p += mdb_snprintf(p, (size_t)(end - p), "|C3"); - if (cw & FPS_B) - p += mdb_snprintf(p, (size_t)(end - p), "|B"); - - if (buf[0] == '|') - return (buf + 1); - - return ("0"); - } - - static const char * - fpmxcsr2str(uint32_t mxcsr, char *buf, size_t nbytes) - { - char *end = buf + nbytes; - char *p = buf; - - buf[0] = '\0'; - - /* - * Decode the MXCSR word - */ - if (mxcsr & SSE_IE) - p += mdb_snprintf(p, (size_t)(end - p), "|IE"); - if (mxcsr & SSE_DE) - p += mdb_snprintf(p, (size_t)(end - p), "|DE"); - if (mxcsr & SSE_ZE) - p += mdb_snprintf(p, (size_t)(end - p), "|ZE"); - if (mxcsr & SSE_OE) - p += mdb_snprintf(p, (size_t)(end - p), "|OE"); - if (mxcsr & SSE_UE) - p += mdb_snprintf(p, (size_t)(end - p), "|UE"); - if (mxcsr & SSE_PE) - p += mdb_snprintf(p, (size_t)(end - p), "|PE"); - - if (mxcsr & SSE_DAZ) - p += mdb_snprintf(p, (size_t)(end - p), "|DAZ"); - - if (mxcsr & SSE_IM) - p += mdb_snprintf(p, (size_t)(end - p), "|IM"); - if (mxcsr & SSE_DM) - p += mdb_snprintf(p, (size_t)(end - p), "|DM"); - if (mxcsr & SSE_ZM) - p += mdb_snprintf(p, (size_t)(end - p), "|ZM"); - if (mxcsr & SSE_OM) - p += mdb_snprintf(p, (size_t)(end - p), "|OM"); - if (mxcsr & SSE_UM) - p += mdb_snprintf(p, (size_t)(end - p), "|UM"); - if (mxcsr & SSE_PM) - p += mdb_snprintf(p, (size_t)(end - p), "|PM"); - - if ((mxcsr & SSE_RC) == (SSE_RD|SSE_RU)) - p += mdb_snprintf(p, (size_t)(end - p), "|RTZ"); - else if (mxcsr & SSE_RD) - p += mdb_snprintf(p, (size_t)(end - p), "|RD"); - else if (mxcsr & SSE_RU) - p += mdb_snprintf(p, (size_t)(end - p), "|RU"); - else - p += mdb_snprintf(p, (size_t)(end - p), "|RTN"); - - if (mxcsr & SSE_FZ) - p += mdb_snprintf(p, (size_t)(end - p), "|FZ"); - - if (buf[0] == '|') - return (buf + 1); - return ("0"); - } - - /*ARGSUSED*/ int pt_fpregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { ! mdb_tgt_t *t = mdb.m_target; ! mdb_tgt_tid_t tid; prfpregset_t fprs; struct _fpchip_state fps; char buf[256]; uint_t top; ! int i; /* * Union for overlaying _fpreg structure on to quad-precision * floating-point value (long double). */ --- 280,298 ---- mdb_printf(" %%err = 0x%x\n", grs[REG_ERR]); return (set_errno(ENOTSUP)); } int pt_fpregs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { ! int ret; prfpregset_t fprs; struct _fpchip_state fps; char buf[256]; uint_t top; ! size_t i; /* * Union for overlaying _fpreg structure on to quad-precision * floating-point value (long double). */
*** 524,564 **** struct _fpreg reg; long double ld; } fpru; /* ! * Array of strings corresponding to FPU tag word values (see ! * section 7.3.6 of the Intel Programmer's Reference Manual). */ ! const char *tag_strings[] = { "valid", "zero", "special", "empty" }; - if (argc != 0) - return (DCMD_USAGE); - - if (t->t_pshandle == NULL || Pstate(t->t_pshandle) == PS_UNDEAD) { - mdb_warn("no process active\n"); - return (DCMD_ERR); - } - - if (Pstate(t->t_pshandle) == PS_LOST) { - mdb_warn("debugger has lost control of process\n"); - return (DCMD_ERR); - } - - if (flags & DCMD_ADDRSPEC) - tid = (mdb_tgt_tid_t)addr; - else - tid = PTL_TID(t); - - mdb_printf("AMD64 (80486 chip with SSE)\n"); - - if (PTL_GETFPREGS(t, tid, &fprs) != 0) { - mdb_warn("failed to get floating point registers"); - return (DCMD_ERR); - } - bcopy(&fprs.fp_reg_set.fpchip_state, &fps, sizeof (fps)); fps.status &= 0xffff; /* saved status word is really 16 bits */ mdb_printf("cw 0x%04x (%s)\n", fps.cw, fpcw2str(fps.cw, buf, sizeof (buf))); --- 300,319 ---- struct _fpreg reg; long double ld; } fpru; /* ! * We use common code between 32-bit and 64-bit x86 to capture and print ! * the extended vector state. The remaining classic 387 state is ! * finicky and different enough that it is left to be dealt with on its ! * own. */ ! if ((ret = x86_pt_fpregs_common(addr, flags, argc, &fprs)) != DCMD_OK) ! return (ret); bcopy(&fprs.fp_reg_set.fpchip_state, &fps, sizeof (fps)); + mdb_printf("387 and FP Control State\n"); fps.status &= 0xffff; /* saved status word is really 16 bits */ mdb_printf("cw 0x%04x (%s)\n", fps.cw, fpcw2str(fps.cw, buf, sizeof (buf)));
*** 572,582 **** mdb_printf("fop 0x%x\n", fps.fop); mdb_printf("rip 0x%x\n", fps.rip); mdb_printf("rdp 0x%x\n\n", fps.rdp); ! for (i = 0; i < 8; i++) { /* * Recall that we need to use the current TOP-of-stack value to * associate the _st[] index back to a physical register number, * since tag word indices are physical register numbers. Then * to get the tag value, we shift over two bits for each tag --- 327,337 ---- mdb_printf("fop 0x%x\n", fps.fop); mdb_printf("rip 0x%x\n", fps.rip); mdb_printf("rdp 0x%x\n\n", fps.rdp); ! for (i = 0; i < ARRAY_SIZE(fps.st); i++) { /* * Recall that we need to use the current TOP-of-stack value to * associate the _st[] index back to a physical register number, * since tag word indices are physical register numbers. Then * to get the tag value, we shift over two bits for each tag
*** 617,639 **** mdb_printf("%%st%d 0x%04x.%04x%04x%04x%04x = %lg %s\n", i, fpru.reg.exponent, fpru.reg.significand[3], fpru.reg.significand[2], fpru.reg.significand[1], fpru.reg.significand[0], ! fpru.ld, tag_strings[tag_value]); } ! mdb_printf("\nmxcsr 0x%04x (%s)\n", fps.mxcsr, ! fpmxcsr2str(fps.mxcsr, buf, sizeof (buf))); ! mdb_printf("xcp 0x%04x (%s)\n\n", fps.xstatus, ! fpmxcsr2str(fps.xstatus, buf, sizeof (buf))); - for (i = 0; i < 8; i++) - mdb_printf("%%xmm%d 0x%08x%08x%08x%08x\n", i, - fps.xmm[i]._l[3], fps.xmm[i]._l[2], - fps.xmm[i]._l[1], fps.xmm[i]._l[0]); - return (DCMD_OK); } /*ARGSUSED*/ int --- 372,386 ---- mdb_printf("%%st%d 0x%04x.%04x%04x%04x%04x = %lg %s\n", i, fpru.reg.exponent, fpru.reg.significand[3], fpru.reg.significand[2], fpru.reg.significand[1], fpru.reg.significand[0], ! fpru.ld, fptag2str(tag_value)); } ! x86_pt_fpregs_sse_ctl(fps.mxcsr, fps.xstatus, buf, sizeof (buf)); return (DCMD_OK); } /*ARGSUSED*/ int