diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -476,8 +476,10 @@ static const dt_ident_t _dtrace_globals[ #if defined(sun) { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_regs, NULL }, +#if defined(sun) { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH, diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -73,6 +73,12 @@ CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/ut CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel .endif +.if ${MACHINE_ARCH} == "i386" +DSRCS+= regs_i386.d +.elif ${MACHINE_ARCH} == "amd64" +DSRCS+= regs_amd64.d +.endif + LFLAGS+=-l YFLAGS+=-d diff --git a/cddl/lib/libdtrace/regs_amd64.d b/cddl/lib/libdtrace/regs_amd64.d new file mode 100644 --- /dev/null +++ b/cddl/lib/libdtrace/regs_amd64.d @@ -0,0 +1,121 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Portions Copyright 2009 Stacey Son sson@FreeBSD.org + * + * $FreeBSD: $ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI" + +inline int R_GS = 0; +#pragma D binding "1.0" R_GS +inline int R_FS = 1; +#pragma D binding "1.0" R_FS +inline int R_ES = 2; +#pragma D binding "1.0" R_ES +inline int R_DS = 3; +#pragma D binding "1.0" R_DS + +inline int R_EDI = 4; +#pragma D binding "1.0" R_EDI +inline int R_ESI = 5; +#pragma D binding "1.0" R_ESI +inline int R_EBP = 6; +#pragma D binding "1.0" R_EBP +inline int R_ESP = 7; +#pragma D binding "1.0" R_ESP +inline int R_EBX = 8; +#pragma D binding "1.0" R_EBX +inline int R_EDX = 9; +#pragma D binding "1.0" R_EDX +inline int R_ECX = 10; +#pragma D binding "1.0" R_ECX +inline int R_EAX = 11; +#pragma D binding "1.0" R_EAX + +inline int R_TRAPNO = 12; +#pragma D binding "1.0" R_TRAPNO +inline int R_ERR = 13; +#pragma D binding "1.0" R_ERR +inline int R_EIP = 14; +#pragma D binding "1.0" R_EIP +inline int R_CS = 15; +#pragma D binding "1.0" R_CS +inline int R_EFL = 16; +#pragma D binding "1.0" R_EFL +inline int R_UESP = 17; +#pragma D binding "1.0" R_UESP +inline int R_SS = 18; +#pragma D binding "1.0" R_SS + +inline int R_PC = R_EIP; +#pragma D binding "1.0" R_PC +inline int R_SP = R_UESP; +#pragma D binding "1.0" R_SP +inline int R_PS = R_EFL; +#pragma D binding "1.0" R_PS +inline int R_R0 = R_EAX; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_EBX; +#pragma D binding "1.0" R_R1 + +inline int R_RSP = 18 + 1 + 20; +#pragma D binding "1.0" R_RSP +inline int R_RFL = 18 + 1 + 19; +#pragma D binding "1.0" R_RFL +inline int R_RIP = 18 + 1 + 17; +#pragma D binding "1.0" R_RIP +inline int R_RAX = 18 + 1 + 14; +#pragma D binding "1.0" R_RAX +inline int R_RCX = 18 + 1 + 13; +#pragma D binding "1.0" R_RCX +inline int R_RDX = 18 + 1 + 12; +#pragma D binding "1.0" R_RDX +inline int R_RBX = 18 + 1 + 11; +#pragma D binding "1.0" R_RBX +inline int R_RBP = 18 + 1 + 10; +#pragma D binding "1.0" R_RBP +inline int R_RSI = 18 + 1 + 9; +#pragma D binding "1.0" R_RSI +inline int R_RDI = 18 + 1 + 8; +#pragma D binding "1.0" R_RDI +inline int R_R8 = 18 + 1 + 7; +#pragma D binding "1.0" R_R8 +inline int R_R9 = 18 + 1 + 6; +#pragma D binding "1.0" R_R9 +inline int R_R10 = 18 + 1 + 5; +#pragma D binding "1.0" R_R10 +inline int R_R11 = 18 + 1 + 4; +#pragma D binding "1.0" R_R11 +inline int R_R12 = 18 + 1 + 3; +#pragma D binding "1.0" R_R12 +inline int R_R13 = 18 + 1 + 2; +#pragma D binding "1.0" R_R13 +inline int R_R14 = 18 + 1 + 1; +#pragma D binding "1.0" R_R14 +inline int R_R15 = 18 + 1 + 0; +#pragma D binding "1.0" R_R15 + diff --git a/cddl/lib/libdtrace/regs_i386.d b/cddl/lib/libdtrace/regs_i386.d new file mode 100644 --- /dev/null +++ b/cddl/lib/libdtrace/regs_i386.d @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Portions Copyright 2009 Stacey Son sson@FreeBSD.org + * + * $FreeBSD: $ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI" + +inline int R_GS = 0; +#pragma D binding "1.0" R_GS +inline int R_FS = 1; +#pragma D binding "1.0" R_FS +inline int R_ES = 2; +#pragma D binding "1.0" R_ES +inline int R_DS = 3; +#pragma D binding "1.0" R_DS + +inline int R_EDI = 4; +#pragma D binding "1.0" R_EDI +inline int R_ESI = 5; +#pragma D binding "1.0" R_ESI +inline int R_EBP = 6; +#pragma D binding "1.0" R_EBP +inline int R_ESP = 7; +#pragma D binding "1.0" R_ESP +inline int R_EBX = 8; +#pragma D binding "1.0" R_EBX +inline int R_EDX = 9; +#pragma D binding "1.0" R_EDX +inline int R_ECX = 10; +#pragma D binding "1.0" R_ECX +inline int R_EAX = 11; +#pragma D binding "1.0" R_EAX + +inline int R_TRAPNO = 12; +#pragma D binding "1.0" R_TRAPNO +inline int R_ERR = 13; +#pragma D binding "1.0" R_ERR +inline int R_EIP = 14; +#pragma D binding "1.0" R_EIP +inline int R_CS = 15; +#pragma D binding "1.0" R_CS +inline int R_EFL = 16; +#pragma D binding "1.0" R_EFL +inline int R_UESP = 17; +#pragma D binding "1.0" R_UESP +inline int R_SS = 18; +#pragma D binding "1.0" R_SS + +inline int R_PC = R_EIP; +#pragma D binding "1.0" R_PC +inline int R_SP = R_UESP; +#pragma D binding "1.0" R_SP +inline int R_PS = R_EFL; +#pragma D binding "1.0" R_PS +inline int R_R0 = R_EAX; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_EBX; +#pragma D binding "1.0" R_R1 diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -2784,6 +2784,21 @@ dtrace_dif_variable(dtrace_mstate_t *mst return (dtrace_getreg(lwp->lwp_regs, ndx)); return (0); } +#else + case DIF_VAR_UREGS: { + struct trapframe *tframe; + + if (!dtrace_priv_proc(state)) + return (0); + + if ((tframe = curthread->td_frame) == NULL) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[curcpu].cpuc_dtrace_illval = 0; + return (0); + } + + return (dtrace_getreg(tframe, ndx)); + } #endif case DIF_VAR_CURTHREAD: diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h @@ -1268,7 +1268,7 @@ extern void dtrace_copyout(uintptr_t, ui extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t, volatile uint16_t *); extern void dtrace_getpcstack(pc_t *, int, int, uint32_t *); -extern ulong_t dtrace_getreg(struct regs *, uint_t); +extern ulong_t dtrace_getreg(struct trapframe *, uint_t); extern int dtrace_getstackdepth(int); extern void dtrace_getupcstack(uint64_t *, int); extern void dtrace_getufpstack(uint64_t *, uint64_t *, int); diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -42,6 +42,7 @@ #include #include +#include "regset.h" uint8_t dtrace_fuword8_nocheck(void *); uint16_t dtrace_fuword16_nocheck(void *); @@ -412,31 +413,30 @@ dtrace_getstackdepth(int aframes) return depth - aframes; } -#ifdef notyet ulong_t -dtrace_getreg(struct regs *rp, uint_t reg) +dtrace_getreg(struct trapframe *rp, uint_t reg) { -#if defined(__amd64) + /* This table is dependent on reg.d. */ int regmap[] = { - REG_GS, /* GS */ - REG_FS, /* FS */ - REG_ES, /* ES */ - REG_DS, /* DS */ - REG_RDI, /* EDI */ - REG_RSI, /* ESI */ - REG_RBP, /* EBP */ - REG_RSP, /* ESP */ - REG_RBX, /* EBX */ - REG_RDX, /* EDX */ - REG_RCX, /* ECX */ - REG_RAX, /* EAX */ - REG_TRAPNO, /* TRAPNO */ - REG_ERR, /* ERR */ - REG_RIP, /* EIP */ - REG_CS, /* CS */ - REG_RFL, /* EFL */ - REG_RSP, /* UESP */ - REG_SS /* SS */ + REG_GS, /* 0 GS */ + REG_FS, /* 1 FS */ + REG_ES, /* 2 ES */ + REG_DS, /* 3 DS */ + REG_RDI, /* 4 EDI */ + REG_RSI, /* 5 ESI */ + REG_RBP, /* 6 EBP, REG_FP */ + REG_RSP, /* 7 ESP */ + REG_RBX, /* 8 EBX, REG_R1 */ + REG_RDX, /* 9 EDX */ + REG_RCX, /* 10 ECX */ + REG_RAX, /* 11 EAX, REG_R0 */ + REG_TRAPNO, /* 12 TRAPNO */ + REG_ERR, /* 13 ERR */ + REG_RIP, /* 14 EIP, REG_PC */ + REG_CS, /* 15 CS */ + REG_RFL, /* 16 EFL, REG_PS */ + REG_RSP, /* 17 UESP, REG_SP */ + REG_SS /* 18 SS */ }; if (reg <= SS) { @@ -447,77 +447,68 @@ dtrace_getreg(struct regs *rp, uint_t re reg = regmap[reg]; } else { + /* This is dependent on reg.d. */ reg -= SS + 1; } switch (reg) { case REG_RDI: - return (rp->r_rdi); + return (rp->tf_rdi); case REG_RSI: - return (rp->r_rsi); + return (rp->tf_rsi); case REG_RDX: - return (rp->r_rdx); + return (rp->tf_rdx); case REG_RCX: - return (rp->r_rcx); + return (rp->tf_rcx); case REG_R8: - return (rp->r_r8); + return (rp->tf_r8); case REG_R9: - return (rp->r_r9); + return (rp->tf_r9); case REG_RAX: - return (rp->r_rax); + return (rp->tf_rax); case REG_RBX: - return (rp->r_rbx); + return (rp->tf_rbx); case REG_RBP: - return (rp->r_rbp); + return (rp->tf_rbp); case REG_R10: - return (rp->r_r10); + return (rp->tf_r10); case REG_R11: - return (rp->r_r11); + return (rp->tf_r11); case REG_R12: - return (rp->r_r12); + return (rp->tf_r12); case REG_R13: - return (rp->r_r13); + return (rp->tf_r13); case REG_R14: - return (rp->r_r14); + return (rp->tf_r14); case REG_R15: - return (rp->r_r15); + return (rp->tf_r15); case REG_DS: - return (rp->r_ds); + return (rp->tf_ds); case REG_ES: - return (rp->r_es); + return (rp->tf_es); case REG_FS: - return (rp->r_fs); + return (rp->tf_fs); case REG_GS: - return (rp->r_gs); + return (rp->tf_gs); case REG_TRAPNO: - return (rp->r_trapno); + return (rp->tf_trapno); case REG_ERR: - return (rp->r_err); + return (rp->tf_err); case REG_RIP: - return (rp->r_rip); + return (rp->tf_rip); case REG_CS: - return (rp->r_cs); + return (rp->tf_cs); case REG_SS: - return (rp->r_ss); + return (rp->tf_ss); case REG_RFL: - return (rp->r_rfl); + return (rp->tf_rflags); case REG_RSP: - return (rp->r_rsp); + return (rp->tf_rsp); default: DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); return (0); } - -#else - if (reg > SS) { - DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); - return (0); - } - - return ((&rp->r_gs)[reg]); -#endif } -#endif static int dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) diff --git a/sys/cddl/dev/dtrace/amd64/regset.h b/sys/cddl/dev/dtrace/amd64/regset.h new file mode 100644 --- /dev/null +++ b/sys/cddl/dev/dtrace/amd64/regset.h @@ -0,0 +1,127 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD: $ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#ifndef _REGSET_H +#define _REGSET_H + +/* + * #pragma ident "@(#)regset.h 1.11 05/06/08 SMI" + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The names and offsets defined here should be specified by the + * AMD64 ABI suppl. + * + * We make fsbase and gsbase part of the lwp context (since they're + * the only way to access the full 64-bit address range via the segment + * registers) and thus belong here too. However we treat them as + * read-only; if %fs or %gs are updated, the results of the descriptor + * table lookup that those updates implicitly cause will be reflected + * in the corresponding fsbase and/or gsbase values the next time the + * context can be inspected. However it is NOT possible to override + * the fsbase/gsbase settings via this interface. + * + * Direct modification of the base registers (thus overriding the + * descriptor table base address) can be achieved with _lwp_setprivate. + */ + +#define REG_GSBASE 27 +#define REG_FSBASE 26 +#define REG_DS 25 +#define REG_ES 24 + +#define REG_GS 23 +#define REG_FS 22 +#define REG_SS 21 +#define REG_RSP 20 +#define REG_RFL 19 +#define REG_CS 18 +#define REG_RIP 17 +#define REG_ERR 16 +#define REG_TRAPNO 15 +#define REG_RAX 14 +#define REG_RCX 13 +#define REG_RDX 12 +#define REG_RBX 11 +#define REG_RBP 10 +#define REG_RSI 9 +#define REG_RDI 8 +#define REG_R8 7 +#define REG_R9 6 +#define REG_R10 5 +#define REG_R11 4 +#define REG_R12 3 +#define REG_R13 2 +#define REG_R14 1 +#define REG_R15 0 + +/* + * The names and offsets defined here are specified by i386 ABI suppl. + */ + +#define SS 18 /* only stored on a privilege transition */ +#define UESP 17 /* only stored on a privilege transition */ +#define EFL 16 +#define CS 15 +#define EIP 14 +#define ERR 13 +#define TRAPNO 12 +#define EAX 11 +#define ECX 10 +#define EDX 9 +#define EBX 8 +#define ESP 7 +#define EBP 6 +#define ESI 5 +#define EDI 4 +#define DS 3 +#define ES 2 +#define FS 1 +#define GS 0 + +#define REG_PC EIP +#define REG_FP EBP +#define REG_SP UESP +#define REG_PS EFL +#define REG_R0 EAX +#define REG_R1 EDX + +#ifdef __cplusplus +} +#endif + +#endif /* _REGSET_H */ diff --git a/sys/cddl/dev/dtrace/i386/dtrace_isa.c b/sys/cddl/dev/dtrace/i386/dtrace_isa.c --- a/sys/cddl/dev/dtrace/i386/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_isa.c @@ -33,13 +33,17 @@ #include #include +#include #include +#include #include #include #include #include +#include "regset.h" + extern uintptr_t kernbase; uintptr_t kernelbase = (uintptr_t) &kernbase; @@ -424,112 +428,92 @@ dtrace_getstackdepth(int aframes) return depth - aframes; } -#ifdef notyet ulong_t -dtrace_getreg(struct regs *rp, uint_t reg) +dtrace_getreg(struct trapframe *rp, uint_t reg) { -#if defined(__amd64) - int regmap[] = { - REG_GS, /* GS */ - REG_FS, /* FS */ - REG_ES, /* ES */ - REG_DS, /* DS */ - REG_RDI, /* EDI */ - REG_RSI, /* ESI */ - REG_RBP, /* EBP */ - REG_RSP, /* ESP */ - REG_RBX, /* EBX */ - REG_RDX, /* EDX */ - REG_RCX, /* ECX */ - REG_RAX, /* EAX */ - REG_TRAPNO, /* TRAPNO */ - REG_ERR, /* ERR */ - REG_RIP, /* EIP */ - REG_CS, /* CS */ - REG_RFL, /* EFL */ - REG_RSP, /* UESP */ - REG_SS /* SS */ + struct pcb *pcb; + int regmap[] = { /* Order is dependent on reg.d */ + REG_GS, /* 0 GS */ + REG_FS, /* 1 FS */ + REG_ES, /* 2 ES */ + REG_DS, /* 3 DS */ + REG_RDI, /* 4 EDI */ + REG_RSI, /* 5 ESI */ + REG_RBP, /* 6 EBP, REG_FP */ + REG_RSP, /* 7 ESP */ + REG_RBX, /* 8 EBX */ + REG_RDX, /* 9 EDX, REG_R1 */ + REG_RCX, /* 10 ECX */ + REG_RAX, /* 11 EAX, REG_R0 */ + REG_TRAPNO, /* 12 TRAPNO */ + REG_ERR, /* 13 ERR */ + REG_RIP, /* 14 EIP, REG_PC */ + REG_CS, /* 15 CS */ + REG_RFL, /* 16 EFL, REG_PS */ + REG_RSP, /* 17 UESP, REG_SP */ + REG_SS /* 18 SS */ }; - if (reg <= SS) { - if (reg >= sizeof (regmap) / sizeof (int)) { - DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); - return (0); - } - - reg = regmap[reg]; - } else { - reg -= SS + 1; - } - - switch (reg) { - case REG_RDI: - return (rp->r_rdi); - case REG_RSI: - return (rp->r_rsi); - case REG_RDX: - return (rp->r_rdx); - case REG_RCX: - return (rp->r_rcx); - case REG_R8: - return (rp->r_r8); - case REG_R9: - return (rp->r_r9); - case REG_RAX: - return (rp->r_rax); - case REG_RBX: - return (rp->r_rbx); - case REG_RBP: - return (rp->r_rbp); - case REG_R10: - return (rp->r_r10); - case REG_R11: - return (rp->r_r11); - case REG_R12: - return (rp->r_r12); - case REG_R13: - return (rp->r_r13); - case REG_R14: - return (rp->r_r14); - case REG_R15: - return (rp->r_r15); - case REG_DS: - return (rp->r_ds); - case REG_ES: - return (rp->r_es); - case REG_FS: - return (rp->r_fs); - case REG_GS: - return (rp->r_gs); - case REG_TRAPNO: - return (rp->r_trapno); - case REG_ERR: - return (rp->r_err); - case REG_RIP: - return (rp->r_rip); - case REG_CS: - return (rp->r_cs); - case REG_SS: - return (rp->r_ss); - case REG_RFL: - return (rp->r_rfl); - case REG_RSP: - return (rp->r_rsp); - default: - DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); - return (0); - } - -#else if (reg > SS) { DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); return (0); } - return ((&rp->r_gs)[reg]); + if (reg >= sizeof (regmap) / sizeof (int)) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); + return (0); + } + + reg = regmap[reg]; + + switch(reg) { + case REG_GS: + if ((pcb = curthread->td_pcb) == NULL) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); + return (0); + } + return (pcb->pcb_gs); + case REG_FS: + return (rp->tf_fs); + case REG_ES: + return (rp->tf_es); + case REG_DS: + return (rp->tf_ds); + case REG_RDI: + return (rp->tf_edi); + case REG_RSI: + return (rp->tf_esi); + case REG_RBP: + return (rp->tf_ebp); + case REG_RSP: + return (rp->tf_isp); + case REG_RBX: + return (rp->tf_ebx); + case REG_RCX: + return (rp->tf_ecx); + case REG_RAX: + return (rp->tf_eax); + case REG_TRAPNO: + return (rp->tf_trapno); + case REG_ERR: + return (rp->tf_err); + case REG_RIP: + return (rp->tf_eip); + case REG_CS: + return (rp->tf_cs); + case REG_RFL: + return (rp->tf_eflags); +#if 0 + case REG_RSP: + return (rp->tf_esp); #endif + case REG_SS: + return (rp->tf_ss); + default: + DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); + return (0); + } } -#endif static int dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) diff --git a/sys/cddl/dev/dtrace/i386/regset.h b/sys/cddl/dev/dtrace/i386/regset.h new file mode 100644 --- /dev/null +++ b/sys/cddl/dev/dtrace/i386/regset.h @@ -0,0 +1,127 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD: $ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#ifndef _REGSET_H +#define _REGSET_H + +/* + * #pragma ident "@(#)regset.h 1.11 05/06/08 SMI" + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The names and offsets defined here should be specified by the + * AMD64 ABI suppl. + * + * We make fsbase and gsbase part of the lwp context (since they're + * the only way to access the full 64-bit address range via the segment + * registers) and thus belong here too. However we treat them as + * read-only; if %fs or %gs are updated, the results of the descriptor + * table lookup that those updates implicitly cause will be reflected + * in the corresponding fsbase and/or gsbase values the next time the + * context can be inspected. However it is NOT possible to override + * the fsbase/gsbase settings via this interface. + * + * Direct modification of the base registers (thus overriding the + * descriptor table base address) can be achieved with _lwp_setprivate. + */ + +#define REG_GSBASE 27 +#define REG_FSBASE 26 +#define REG_DS 25 +#define REG_ES 24 + +#define REG_GS 23 +#define REG_FS 22 +#define REG_SS 21 +#define REG_RSP 20 +#define REG_RFL 19 +#define REG_CS 18 +#define REG_RIP 17 +#define REG_ERR 16 +#define REG_TRAPNO 15 +#define REG_RAX 14 +#define REG_RCX 13 +#define REG_RDX 12 +#define REG_RBX 11 +#define REG_RBP 10 +#define REG_RSI 9 +#define REG_RDI 8 +#define REG_R8 7 +#define REG_R9 6 +#define REG_R10 5 +#define REG_R11 4 +#define REG_R12 3 +#define REG_R13 2 +#define REG_R14 1 +#define REG_R15 0 + +/* + * The names and offsets defined here are specified by i386 ABI suppl. + */ + +#define SS 18 /* only stored on a privilege transition */ +#define UESP 17 /* only stored on a privilege transition */ +#define EFL 16 +#define CS 15 +#define EIP 14 +#define ERR 13 +#define TRAPNO 12 +#define EAX 11 +#define ECX 10 +#define EDX 9 +#define EBX 8 +#define ESP 7 +#define EBP 6 +#define ESI 5 +#define EDI 4 +#define DS 3 +#define ES 2 +#define FS 1 +#define GS 0 + +#define REG_PC EIP +#define REG_FP EBP +#define REG_SP UESP +#define REG_PS EFL +#define REG_R0 EAX +#define REG_R1 EDX + +#ifdef __cplusplus +} +#endif + +#endif /* _REGSET_H */