summaryrefslogtreecommitdiff
path: root/usr.bin/pmdb/arch
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/pmdb/arch')
-rw-r--r--usr.bin/pmdb/arch/alpha/Makefile.inc1
-rw-r--r--usr.bin/pmdb/arch/alpha/alpha.c70
-rw-r--r--usr.bin/pmdb/arch/alpha/alpha_instruction.h750
-rw-r--r--usr.bin/pmdb/arch/alpha/alpha_trace.c343
-rw-r--r--usr.bin/pmdb/arch/alpha/pmdb_machdep.h3
-rw-r--r--usr.bin/pmdb/arch/i386/Makefile.inc3
-rw-r--r--usr.bin/pmdb/arch/i386/i386.c91
-rw-r--r--usr.bin/pmdb/arch/i386/pmdb_machdep.h3
-rw-r--r--usr.bin/pmdb/arch/sparc/Makefile.inc1
-rw-r--r--usr.bin/pmdb/arch/sparc/pmdb_machdep.h3
-rw-r--r--usr.bin/pmdb/arch/sparc/sparc.c107
-rw-r--r--usr.bin/pmdb/arch/sparc64/Makefile.inc1
-rw-r--r--usr.bin/pmdb/arch/sparc64/pmdb_machdep.h3
-rw-r--r--usr.bin/pmdb/arch/sparc64/sparc64.c122
14 files changed, 1501 insertions, 0 deletions
diff --git a/usr.bin/pmdb/arch/alpha/Makefile.inc b/usr.bin/pmdb/arch/alpha/Makefile.inc
new file mode 100644
index 00000000000..90bf092b2e2
--- /dev/null
+++ b/usr.bin/pmdb/arch/alpha/Makefile.inc
@@ -0,0 +1 @@
+SRCS+=alpha.c alpha_trace.c
diff --git a/usr.bin/pmdb/arch/alpha/alpha.c b/usr.bin/pmdb/arch/alpha/alpha.c
new file mode 100644
index 00000000000..a09f59f036e
--- /dev/null
+++ b/usr.bin/pmdb/arch/alpha/alpha.c
@@ -0,0 +1,70 @@
+/* $PMDB: alpha.c,v 1.4 2002/02/21 02:20:51 art Exp $ */
+/*
+ * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#include <string.h>
+
+#include "pmdb.h"
+
+/*
+ * This happens to be the same order as in struct reg.
+ */
+
+static const char *md_reg_names[] = {
+ "v0",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6",
+ "a0", "a1", "a2", "a3", "a4", "a5",
+ "t8", "t9", "t10", "t11",
+ "ra",
+ "t12",
+ "at", "gp", "sp", "zero"
+};
+
+struct md_def md_def = { md_reg_names, 32, 31 };
+
+void
+md_def_init(void)
+{
+ /* nothing */
+}
+
+int
+md_getregs(struct pstate *ps, reg *regs)
+{
+ struct reg r;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return -1;
+
+ memcpy(regs, &r, sizeof(r));
+
+ return 0;
+} \ No newline at end of file
diff --git a/usr.bin/pmdb/arch/alpha/alpha_instruction.h b/usr.bin/pmdb/arch/alpha/alpha_instruction.h
new file mode 100644
index 00000000000..631aad909ea
--- /dev/null
+++ b/usr.bin/pmdb/arch/alpha/alpha_instruction.h
@@ -0,0 +1,750 @@
+/* $PMDB: alpha_instruction.h,v 1.3 2002/01/30 23:14:34 art Exp $ */
+/*
+ * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1993,1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * File: alpha_instruction.h
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 11/91
+ *
+ * Alpha Instruction set definition
+ *
+ * Reference: "Alpha System Reference Manual", V4.0, April 1991
+ *
+ */
+
+#ifndef _ALPHA_INSTRUCTION_H_
+#define _ALPHA_INSTRUCTION_H_ 1
+
+#if !defined(ASSEMBLER)
+
+/*
+ * All instructions are in one of five formats:
+ * Memory, Branch, Operate, Floating-point Operate, PAL
+ *
+ * The original Mach sources attempted to use 'smarter' names
+ * for registers, which reflected source and destination. These
+ * definitions use the names from the Architecture Reference Manual,
+ * both for clarity and because you can't differentiate between
+ * 'source' and 'destinations' for some types of instructions (loads
+ * and stores; they'd be correct for one, but swapped for the other).
+ */
+
+
+typedef union {
+ /*
+ * All instructions are 32 bits wide
+ */
+ unsigned int bits;
+
+ /*
+ * Generic instruction pseudo format; look at
+ * opcode to see how to interpret the rest.
+ */
+ struct {
+ unsigned bits:26,
+ opcode:6;
+ } generic_format;
+
+ /*
+ * Memory instructions contain a 16 bit
+ * signed immediate value and two register
+ * specifiers
+ */
+ struct {
+ signed short displacement;
+ unsigned rb : 5,
+ ra : 5,
+ opcode : 6;
+ } mem_format;
+
+ /*
+ * Branch instruction contain a 21 bit offset,
+ * which is sign-extended, shifted and combined
+ * with the PC to form a 64 bit destination address.
+ *
+ * In computed jump instructions the opcode is further
+ * specified in the offset field, the rest of it is
+ * used as branch target hint. The destination of the
+ * jump is the source register.
+ */
+ struct {
+ signed int displacement : 21;
+ unsigned ra : 5,
+ opcode : 6;
+ } branch_format;
+
+ struct {
+ signed int hint : 14;
+ unsigned action : 2,
+ rb : 5,
+ ra : 5,
+ opcode : 6;
+ } jump_format;
+
+
+ /*
+ * Operate instructions are of two types, with
+ * a second source register or with a literal
+ * specifier. Bit 12 sez which is which.
+ */
+ struct {
+ unsigned rc : 5,
+ function : 7,
+ is_lit : 1,
+ sbz_or_litlo : 3,
+ rb_or_lithi : 5,
+ ra : 5,
+ opcode : 6;
+ } operate_generic_format;
+
+ struct {
+ unsigned rc : 5,
+ function : 7,
+ zero : 1,
+ sbz : 3,
+ rb : 5,
+ ra : 5,
+ opcode : 6;
+ } operate_reg_format;
+
+ struct {
+ unsigned rc : 5,
+ function : 7,
+ one : 1,
+ literal : 8,
+ ra : 5,
+ opcode : 6;
+ } operate_lit_format;
+
+
+ /*
+ * Floating point operate instruction are quite
+ * uniform in the encoding. As for the semantics..
+ */
+ struct {
+ unsigned fc : 5,
+ function : 11,
+ fb : 5,
+ fa : 5,
+ opcode : 6;
+ } float_format;
+
+
+ /*
+ * PAL instructions just define the major opcode
+ */
+
+ struct {
+ unsigned function : 26,
+ opcode : 6;
+ } pal_format;
+
+} alpha_instruction;
+
+#endif /* !defined(ASSEMBLER) */
+
+/*
+ *
+ * Encoding of regular instructions (Appendix C op cit)
+ *
+ */
+
+ /* OPCODE, bits 26..31 */
+
+#define op_pal 0x00 /* see PAL sub-table */
+ /* 1..7 reserved */
+#define op_lda 0x08
+#define op_ldah 0x09
+#define op_ldbu 0x0a
+#define op_ldq_u 0x0b
+#define op_ldwu 0x0c
+#define op_stw 0x0d
+#define op_stb 0x0e
+#define op_stq_u 0x0f
+
+#define op_arit 0x10 /* see ARIT sub-table */
+#define op_logical 0x11 /* see LOGICAL sub-table */
+#define op_bit 0x12 /* see BIT sub-table */
+#define op_mul 0x13 /* see MUL sub-table */
+ /* reserved */
+#define op_vax_float 0x15 /* see FLOAT sub-table */
+#define op_ieee_float 0x16 /* see FLOAT sub-table */
+#define op_any_float 0x17 /* see FLOAT sub-table */
+
+#define op_special 0x18 /* see SPECIAL sub-table */
+#define op_pal19 0x19 /* reserved for pal code */
+#define op_j 0x1a /* see JUMP sub-table */
+#define op_pal1b 0x1b /* reserved for pal code */
+#define op_intmisc 0x1c /* see INTMISC sub-table */
+#define op_pal1d 0x1d /* reserved for pal code */
+#define op_pal1e 0x1e /* reserved for pal code */
+#define op_pal1f 0x1f /* reserved for pal code */
+
+#define op_ldf 0x20
+#define op_ldg 0x21
+#define op_lds 0x22
+#define op_ldt 0x23
+#define op_stf 0x24
+#define op_stg 0x25
+#define op_sts 0x26
+#define op_stt 0x27
+#define op_ldl 0x28
+#define op_ldq 0x29
+#define op_ldl_l 0x2a
+#define op_ldq_l 0x2b
+#define op_stl 0x2c
+#define op_stq 0x2d
+#define op_stl_c 0x2e
+#define op_stq_c 0x2f
+#define op_br 0x30
+#define op_fbeq 0x31
+#define op_fblt 0x32
+#define op_fble 0x33
+#define op_bsr 0x34
+#define op_fbne 0x35
+#define op_fbge 0x36
+#define op_fbgt 0x37
+#define op_blbc 0x38
+#define op_beq 0x39
+#define op_blt 0x3a
+#define op_ble 0x3b
+#define op_blbs 0x3c
+#define op_bne 0x3d
+#define op_bge 0x3e
+#define op_bgt 0x3f
+
+
+ /* PAL, "function" opcodes (bits 0..25) */
+/*
+ * What we will implement is TBD. These are the unprivileged ones
+ * that we probably have to support for compat reasons.
+ */
+
+/* See <machine/pal.h> */
+
+ /* ARIT, "function" opcodes (bits 5..11) */
+
+#define op_addl 0x00
+#define op_s4addl 0x02
+#define op_subl 0x09
+#define op_s4subl 0x0b
+#define op_cmpbge 0x0f
+#define op_s8addl 0x12
+#define op_s8subl 0x1b
+#define op_cmpult 0x1d
+#define op_addq 0x20
+#define op_s4addq 0x22
+#define op_subq 0x29
+#define op_s4subq 0x2b
+#define op_cmpeq 0x2d
+#define op_s8addq 0x32
+#define op_s8subq 0x3b
+#define op_cmpule 0x3d
+#define op_addl_v 0x40
+#define op_subl_v 0x49
+#define op_cmplt 0x4d
+#define op_addq_v 0x60
+#define op_subq_v 0x69
+#define op_cmple 0x6d
+
+
+ /* LOGICAL, "function" opcodes (bits 5..11) */
+
+#define op_and 0x00
+#define op_andnot 0x08 /* bic */
+#define op_cmovlbs 0x14
+#define op_cmovlbc 0x16
+#define op_or 0x20 /* bis */
+#define op_cmoveq 0x24
+#define op_cmovne 0x26
+#define op_ornot 0x28
+#define op_xor 0x40
+#define op_cmovlt 0x44
+#define op_cmovge 0x46
+#define op_xornot 0x48 /* eqv */
+#define op_amask 0x61
+#define op_cmovle 0x64
+#define op_cmovgt 0x66
+#define op_implver 0x6c
+
+ /* BIT, "function" opcodes (bits 5..11) */
+
+#define op_mskbl 0x02
+#define op_extbl 0x06
+#define op_insbl 0x0b
+#define op_mskwl 0x12
+#define op_extwl 0x16
+#define op_inswl 0x1b
+#define op_mskll 0x22
+#define op_extll 0x26
+#define op_insll 0x2b
+#define op_zap 0x30
+#define op_zapnot 0x31
+#define op_mskql 0x32
+#define op_srl 0x34
+#define op_extql 0x36
+#define op_sll 0x39
+#define op_insql 0x3b
+#define op_sra 0x3c
+#define op_mskwh 0x52
+#define op_inswh 0x57
+#define op_extwh 0x5a
+#define op_msklh 0x62
+#define op_inslh 0x67
+#define op_extlh 0x6a
+#define op_extqh 0x7a
+#define op_insqh 0x77
+#define op_mskqh 0x72
+
+ /* MUL, "function" opcodes (bits 5..11) */
+
+#define op_mull 0x00
+#define op_mulq_v 0x60
+#define op_mull_v 0x40
+#define op_umulh 0x30
+#define op_mulq 0x20
+
+
+ /* SPECIAL, "displacement" opcodes (bits 0..15) */
+
+#define op_trapb 0x0000
+#define op_excb 0x0400
+#define op_mb 0x4000
+#define op_wmb 0x4400
+#define op_fetch 0x8000
+#define op_fetch_m 0xa000
+#define op_rpcc 0xc000
+#define op_rc 0xe000
+#define op_ecb 0xe800
+#define op_rs 0xf000
+#define op_wh64 0xf800
+
+ /* JUMP, "action" opcodes (bits 14..15) */
+
+#define op_jmp 0x0
+#define op_jsr 0x1
+#define op_ret 0x2
+#define op_jcr 0x3
+
+ /* INTMISC, "function" opcodes (operate format) */
+
+#define op_sextb 0x00
+#define op_sextw 0x01
+#define op_ctpop 0x30
+#define op_perr 0x31
+#define op_ctlz 0x32
+#define op_cttz 0x33
+#define op_unpkbw 0x34
+#define op_unpkbl 0x35
+#define op_pkwb 0x36
+#define op_pklb 0x37
+#define op_minsb8 0x38
+#define op_minsw4 0x39
+#define op_minub8 0x3a
+#define op_minuw4 0x3b
+#define op_maxub8 0x3c
+#define op_maxuw4 0x3d
+#define op_maxsb8 0x3e
+#define op_maxsw4 0x3f
+#define op_ftoit 0x70
+#define op_ftois 0x78
+
+/*
+ *
+ * Encoding of floating point instructions (pagg. C-5..6 op cit)
+ *
+ * Load and store operations use opcodes op_ldf..op_stt
+ */
+
+ /* any FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_cvtlq 0x010
+#define op_cpys 0x020
+#define op_cpysn 0x021
+#define op_cpyse 0x022
+#define op_mt_fpcr 0x024
+#define op_mf_fpcr 0x025
+#define op_fcmoveq 0x02a
+#define op_fcmovne 0x02b
+#define op_fcmovlt 0x02c
+#define op_fcmovge 0x02d
+#define op_fcmovle 0x02e
+#define op_fcmovgt 0x02f
+#define op_cvtql 0x030
+#define op_cvtql_v 0x130
+#define op_cvtql_sv 0x330
+
+
+ /* ieee FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_adds_c 0x000
+#define op_subs_c 0x001
+#define op_muls_c 0x002
+#define op_divs_c 0x003
+#define op_addt_c 0x020
+#define op_subt_c 0x021
+#define op_mult_c 0x022
+#define op_divt_c 0x023
+#define op_cvtts_c 0x02c
+#define op_cvttq_c 0x02f
+#define op_cvtqs_c 0x03c
+#define op_cvtqt_c 0x03e
+#define op_adds_m 0x040
+#define op_subs_m 0x041
+#define op_muls_m 0x042
+#define op_divs_m 0x043
+#define op_addt_m 0x060
+#define op_subt_m 0x061
+#define op_mult_m 0x062
+#define op_divt_m 0x063
+#define op_cvtts_m 0x06c
+#define op_cvtqs_m 0x07c
+#define op_cvtqt_m 0x07e
+#define op_adds 0x080
+#define op_subs 0x081
+#define op_muls 0x082
+#define op_divs 0x083
+#define op_addt 0x0a0
+#define op_subt 0x0a1
+#define op_mult 0x0a2
+#define op_divt 0x0a3
+#define op_cmptun 0x0a4
+#define op_cmpteq 0x0a5
+#define op_cmptlt 0x0a6
+#define op_cmptle 0x0a7
+#define op_cvtts 0x0ac
+#define op_cvttq 0x0af
+#define op_cvtqs 0x0bc
+#define op_cvtqt 0x0be
+#define op_adds_d 0x0c0
+#define op_subs_d 0x0c1
+#define op_muls_d 0x0c2
+#define op_divs_d 0x0c3
+#define op_addt_d 0x0e0
+#define op_subt_d 0x0e1
+#define op_mult_d 0x0e2
+#define op_divt_d 0x0e3
+#define op_cvtts_d 0x0ec
+#define op_cvtqs_d 0x0fc
+#define op_cvtqt_d 0x0fe
+#define op_adds_uc 0x100
+#define op_subs_uc 0x101
+#define op_muls_uc 0x102
+#define op_divs_uc 0x103
+#define op_addt_uc 0x120
+#define op_subt_uc 0x121
+#define op_mult_uc 0x122
+#define op_divt_uc 0x123
+#define op_cvtts_uc 0x12c
+#define op_cvttq_vc 0x12f
+#define op_adds_um 0x140
+#define op_subs_um 0x141
+#define op_muls_um 0x142
+#define op_divs_um 0x143
+#define op_addt_um 0x160
+#define op_subt_um 0x161
+#define op_mult_um 0x162
+#define op_divt_um 0x163
+#define op_cvtts_um 0x16c
+#define op_adds_u 0x180
+#define op_subs_u 0x181
+#define op_muls_u 0x182
+#define op_divs_u 0x183
+#define op_addt_u 0x1a0
+#define op_subt_u 0x1a1
+#define op_mult_u 0x1a2
+#define op_divt_u 0x1a3
+#define op_cvtts_u 0x1ac
+#define op_cvttq_v 0x1af
+#define op_adds_ud 0x1c0
+#define op_subs_ud 0x1c1
+#define op_muls_ud 0x1c2
+#define op_divs_ud 0x1c3
+#define op_addt_ud 0x1e0
+#define op_subt_ud 0x1e1
+#define op_mult_ud 0x1e2
+#define op_divt_ud 0x1e3
+#define op_cvtts_ud 0x1ec
+#define op_adds_suc 0x500
+#define op_subs_suc 0x501
+#define op_muls_suc 0x502
+#define op_divs_suc 0x503
+#define op_addt_suc 0x520
+#define op_subt_suc 0x521
+#define op_mult_suc 0x522
+#define op_divt_suc 0x523
+#define op_cvtts_suc 0x52c
+#define op_cvttq_svc 0x52f
+#define op_adds_sum 0x540
+#define op_subs_sum 0x541
+#define op_muls_sum 0x542
+#define op_divs_sum 0x543
+#define op_addt_sum 0x560
+#define op_subt_sum 0x561
+#define op_mult_sum 0x562
+#define op_divt_sum 0x563
+#define op_cvtts_sum 0x56c
+#define op_adds_su 0x580
+#define op_subs_su 0x581
+#define op_muls_su 0x582
+#define op_divs_su 0x583
+#define op_addt_su 0x5a0
+#define op_subt_su 0x5a1
+#define op_mult_su 0x5a2
+#define op_divt_su 0x5a3
+#define op_cmptun_su 0x5a4
+#define op_cmpteq_su 0x5a5
+#define op_cmptlt_su 0x5a6
+#define op_cmptle_su 0x5a7
+#define op_cvtts_su 0x5ac
+#define op_cvttq_sv 0x5af
+#define op_adds_sud 0x5c0
+#define op_subs_sud 0x5c1
+#define op_muls_sud 0x5c2
+#define op_divs_sud 0x5c3
+#define op_addt_sud 0x5e0
+#define op_subt_sud 0x5e1
+#define op_mult_sud 0x5e2
+#define op_divt_sud 0x5e3
+#define op_cvtts_sud 0x5ec
+#define op_adds_suic 0x700
+#define op_subs_suic 0x701
+#define op_muls_suic 0x702
+#define op_divs_suic 0x703
+#define op_addt_suic 0x720
+#define op_subt_suic 0x721
+#define op_mult_suic 0x722
+#define op_divt_suic 0x723
+#define op_cvtts_suic 0x72c
+#define op_cvttq_svic 0x72f
+#define op_cvtqs_suic 0x73c
+#define op_cvtqt_suic 0x73e
+#define op_adds_suim 0x740
+#define op_subs_suim 0x741
+#define op_muls_suim 0x742
+#define op_divs_suim 0x743
+#define op_addt_suim 0x760
+#define op_subt_suim 0x761
+#define op_mult_suim 0x762
+#define op_divt_suim 0x763
+#define op_cvtts_suim 0x76c
+#define op_cvtqs_suim 0x77c
+#define op_cvtqt_suim 0x77e
+#define op_adds_sui 0x780
+#define op_subs_sui 0x781
+#define op_muls_sui 0x782
+#define op_divs_sui 0x783
+#define op_addt_sui 0x7a0
+#define op_subt_sui 0x7a1
+#define op_mult_sui 0x7a2
+#define op_divt_sui 0x7a3
+#define op_cvtts_sui 0x7ac
+#define op_cvttq_svi 0x7af
+#define op_cvtqs_sui 0x7bc
+#define op_cvtqt_sui 0x7be
+#define op_adds_suid 0x7c0
+#define op_subs_suid 0x7c1
+#define op_muls_suid 0x7c2
+#define op_divs_suid 0x7c3
+#define op_addt_suid 0x7e0
+#define op_subt_suid 0x7e1
+#define op_mult_suid 0x7e2
+#define op_divt_suid 0x7e3
+#define op_cvtts_suid 0x7ec
+#define op_cvtqs_suid 0x7fc
+#define op_cvtqt_suid 0x7fe
+
+
+ /* vax FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_addf_c 0x000
+#define op_subf_c 0x001
+#define op_mulf_c 0x002
+#define op_divf_c 0x003
+#define op_cvtdg_c 0x01e
+#define op_addg_c 0x020
+#define op_subg_c 0x021
+#define op_mulg_c 0x022
+#define op_divg_c 0x023
+#define op_cvtgf_c 0x02c
+#define op_cvtgd_c 0x02d
+#define op_cvtgqg_c 0x02f
+#define op_cvtqf_c 0x03c
+#define op_cvtqg_c 0x03e
+#define op_addf 0x080
+#define op_subf 0x081
+#define op_mulf 0x082
+#define op_divf 0x083
+#define op_cvtdg 0x09e
+#define op_addg 0x0a0
+#define op_subg 0x0a1
+#define op_mulg 0x0a2
+#define op_divg 0x0a3
+#define op_cmpgeq 0x0a5
+#define op_cmpglt 0x0a6
+#define op_cmpgle 0x0a7
+#define op_cvtgf 0x0ac
+#define op_cvtgd 0x0ad
+#define op_cvtgq 0x0af
+#define op_cvtqf 0x0bc
+#define op_cvtqg 0x0be
+#define op_addf_uc 0x100
+#define op_subf_uc 0x101
+#define op_mulf_uc 0x102
+#define op_divf_uc 0x103
+#define op_cvtdg_uc 0x11e
+#define op_addg_uc 0x120
+#define op_subg_uc 0x121
+#define op_mulg_uc 0x122
+#define op_divg_uc 0x123
+#define op_cvtgf_uc 0x12c
+#define op_cvtgd_uc 0x12d
+#define op_cvtgqg_vc 0x12f
+#define op_addf_u 0x180
+#define op_subf_u 0x181
+#define op_mulf_u 0x182
+#define op_divf_u 0x183
+#define op_cvtdg_u 0x19e
+#define op_addg_u 0x1a0
+#define op_subg_u 0x1a1
+#define op_mulg_u 0x1a2
+#define op_divg_u 0x1a3
+#define op_cvtgf_u 0x1ac
+#define op_cvtgd_u 0x1ad
+#define op_cvtgqg_v 0x1af
+#define op_addf_sc 0x400
+#define op_subf_sc 0x401
+#define op_mulf_sc 0x402
+#define op_divf_sc 0x403
+#define op_cvtdg_sc 0x41e
+#define op_addg_sc 0x420
+#define op_subg_sc 0x421
+#define op_mulg_sc 0x422
+#define op_divg_sc 0x423
+#define op_cvtgf_sc 0x42c
+#define op_cvtgd_sc 0x42d
+#define op_cvtgqg_sc 0x42f
+#define op_cvtqf_sc 0x43c
+#define op_cvtqg_sc 0x43e
+#define op_addf_s 0x480
+#define op_subf_s 0x481
+#define op_mulf_s 0x482
+#define op_divf_s 0x483
+#define op_cvtdg_s 0x49e
+#define op_addg_s 0x4a0
+#define op_subg_s 0x4a1
+#define op_mulg_s 0x4a2
+#define op_divg_s 0x4a3
+#define op_cmpgeq_s 0x4a5
+#define op_cmpglt_s 0x4a6
+#define op_cmpgle_s 0x4a7
+#define op_cvtgf_s 0x4ac
+#define op_cvtgd_s 0x4ad
+#define op_cvtgqg_s 0x4af
+#define op_cvtqf_s 0x4bc
+#define op_cvtqg_s 0x4be
+#define op_addf_suc 0x500
+#define op_subf_suc 0x501
+#define op_mulf_suc 0x502
+#define op_divf_suc 0x503
+#define op_cvtdg_suc 0x51e
+#define op_addg_suc 0x520
+#define op_subg_suc 0x521
+#define op_mulg_suc 0x522
+#define op_divg_suc 0x523
+#define op_cvtgf_suc 0x52c
+#define op_cvtgd_suc 0x52d
+#define op_cvtgqg_svc 0x52f
+#define op_addf_su 0x580
+#define op_subf_su 0x581
+#define op_mulf_su 0x582
+#define op_divf_su 0x583
+#define op_cvtdg_su 0x59e
+#define op_addg_su 0x5a0
+#define op_subg_su 0x5a1
+#define op_mulg_su 0x5a2
+#define op_divg_su 0x5a3
+#define op_cvtgf_su 0x5ac
+#define op_cvtgd_su 0x5ad
+#define op_cvtgqg_sv 0x5af
+
+#endif /* _ALPHA_INSTRUCTION_H_ */
diff --git a/usr.bin/pmdb/arch/alpha/alpha_trace.c b/usr.bin/pmdb/arch/alpha/alpha_trace.c
new file mode 100644
index 00000000000..a0c4f6c73bd
--- /dev/null
+++ b/usr.bin/pmdb/arch/alpha/alpha_trace.c
@@ -0,0 +1,343 @@
+/* $PMDB: alpha_trace.c,v 1.5 2002/03/10 10:52:16 art Exp $ */
+/*
+ * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Niklas Hallqvist. All rights reserverd.
+ * Copyright (c) 1997 Theo de Raadt. All rights reserverd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niklas Hallqvist and
+ * Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pmdb.h"
+#include "alpha_instruction.h"
+#include "symbol.h"
+
+struct opcode {
+ enum opc_fmt { OPC_PAL, OPC_RES, OPC_MEM, OPC_OP, OPC_BR } opc_fmt;
+ char *opc_name;
+ int opc_print;
+};
+
+#define inst_return(ins) (((ins) & 0xfc000000) == 0x68000000)
+
+const struct opcode opcode[] = {
+ { OPC_PAL, "call_pal", 0 }, /* 00 */
+ { OPC_RES, "opc01", 0 }, /* 01 */
+ { OPC_RES, "opc02", 0 }, /* 02 */
+ { OPC_RES, "opc03", 0 }, /* 03 */
+ { OPC_RES, "opc04", 0 }, /* 04 */
+ { OPC_RES, "opc05", 0 }, /* 05 */
+ { OPC_RES, "opc06", 0 }, /* 06 */
+ { OPC_RES, "opc07", 0 }, /* 07 */
+ { OPC_MEM, "lda", 1 }, /* 08 */
+ { OPC_MEM, "ldah", 1 }, /* 09 */
+ { OPC_RES, "opc0a", 0 }, /* 0A */
+ { OPC_MEM, "ldq_u", 1 }, /* 0B */
+ { OPC_RES, "opc0c", 0 }, /* 0C */
+ { OPC_RES, "opc0d", 0 }, /* 0D */
+ { OPC_RES, "opc0e", 0 }, /* 0E */
+ { OPC_MEM, "stq_u", 1 }, /* 0F */
+ { OPC_OP, "inta", 0 }, /* 10 */
+ { OPC_OP, "intl", 0 }, /* 11 */
+ { OPC_OP, "ints", 0 }, /* 12 */
+ { OPC_OP, "intm", 0 }, /* 13 */
+ { OPC_RES, "opc14", 0 }, /* 14 */
+ { OPC_OP, "fltv", 1 }, /* 15 */
+ { OPC_OP, "flti", 1 }, /* 16 */
+ { OPC_OP, "fltl", 1 }, /* 17 */
+ { OPC_MEM, "misc", 0 }, /* 18 */
+ { OPC_PAL, "pal19", 0 }, /* 19 */
+ { OPC_MEM, "jsr", 0 }, /* 1A */
+ { OPC_PAL, "pal1b", 0 }, /* 1B */
+ { OPC_RES, "opc1c", 0 }, /* 1C */
+ { OPC_PAL, "pal1d", 0 }, /* 1D */
+ { OPC_PAL, "pal1e", 0 }, /* 1E */
+ { OPC_PAL, "pal1f", 0 }, /* 1F */
+ { OPC_MEM, "ldf", 1 }, /* 20 */
+ { OPC_MEM, "ldg", 1 }, /* 21 */
+ { OPC_MEM, "lds", 1 }, /* 22 */
+ { OPC_MEM, "ldt", 1 }, /* 23 */
+ { OPC_MEM, "stf", 1 }, /* 24 */
+ { OPC_MEM, "stg", 1 }, /* 25 */
+ { OPC_MEM, "sts", 1 }, /* 26 */
+ { OPC_MEM, "stt", 1 }, /* 27 */
+ { OPC_MEM, "ldl", 1 }, /* 28 */
+ { OPC_MEM, "ldq", 1 }, /* 29 */
+ { OPC_MEM, "ldl_l", 1 }, /* 2A */
+ { OPC_MEM, "ldq_l", 1 }, /* 2B */
+ { OPC_MEM, "stl", 1 }, /* 2C */
+ { OPC_MEM, "stq", 1 }, /* 2D */
+ { OPC_MEM, "stl_c", 1 }, /* 2E */
+ { OPC_MEM, "stq_c", 1 }, /* 2F */
+ { OPC_BR, "br", 1 }, /* 30 */
+ { OPC_BR, "fbeq", 1 }, /* 31 */
+ { OPC_BR, "fblt", 1 }, /* 32 */
+ { OPC_BR, "fble", 1 }, /* 33 */
+ { OPC_BR, "bsr", 1 }, /* 34 */
+ { OPC_BR, "fbne", 1 }, /* 35 */
+ { OPC_BR, "fbge", 1 }, /* 36 */
+ { OPC_BR, "fbgt", 1 }, /* 37 */
+ { OPC_BR, "blbc", 1 }, /* 38 */
+ { OPC_BR, "beq", 1 }, /* 39 */
+ { OPC_BR, "blt", 1 }, /* 3A */
+ { OPC_BR, "ble", 1 }, /* 3B */
+ { OPC_BR, "blbs", 1 }, /* 3C */
+ { OPC_BR, "bne", 1 }, /* 3D */
+ { OPC_BR, "bge", 1 }, /* 3E */
+ { OPC_BR, "bgt", 1 }, /* 3F */
+};
+
+int
+inst_load(int ins)
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+
+ /* Loads. */
+ if (insn.mem_format.opcode == op_ldbu ||
+ insn.mem_format.opcode == op_ldq_u ||
+ insn.mem_format.opcode == op_ldwu)
+ return (1);
+ if ((insn.mem_format.opcode >= op_ldf) &&
+ (insn.mem_format.opcode <= op_ldt))
+ return (1);
+ if ((insn.mem_format.opcode >= op_ldl) &&
+ (insn.mem_format.opcode <= op_ldq_l))
+ return (1);
+
+ /* Prefetches. */
+ if (insn.mem_format.opcode == op_special) {
+ /* Note: MB is treated as a store. */
+ if ((insn.mem_format.displacement == (short)op_fetch) ||
+ (insn.mem_format.displacement == (short)op_fetch_m))
+ return (1);
+ }
+
+ return (0);
+}
+
+static __inline int sext __P((u_int));
+static __inline int rega __P((u_int));
+static __inline int regb __P((u_int));
+static __inline int regc __P((u_int));
+static __inline int disp __P((u_int));
+
+static __inline int
+sext(x)
+ u_int x;
+{
+ return ((x & 0x8000) ? -(-x & 0xffff) : (x & 0xffff));
+}
+
+static __inline int
+rega(x)
+ u_int x;
+{
+ return ((x >> 21) & 0x1f);
+}
+
+static __inline int
+regb(x)
+ u_int x;
+{
+ return ((x >> 16) & 0x1f);
+}
+
+static __inline int
+regc(x)
+ u_int x;
+{
+ return (x & 0x1f);
+}
+
+static __inline int
+disp(x)
+ u_int x;
+{
+ return (sext(x & 0xffff));
+}
+
+/*
+ * XXX There are a couple of problems with this code:
+ *
+ * The argument list printout code is likely to get confused.
+ *
+ * It relies on the conventions of gcc code generation.
+ *
+ * It uses heuristics to calculate the framesize, and might get it wrong.
+ *
+ * It doesn't yet use the framepointer if available.
+ *
+ * The address argument can only be used for pointing at trapframes
+ * since a frame pointer of its own serves no good on the alpha,
+ * you need a pc value too.
+ *
+ * The heuristics used for tracing through a trap relies on having
+ * symbols available.
+ */
+int
+md_getframe(struct pstate *ps, int framec, struct md_frame *fram)
+{
+ reg frame;
+ int i, framesize;
+ reg pc, ra;
+ u_int inst;
+ char *name;
+ char namebuf[1024];
+ reg offset;
+ reg slot[32];
+ struct reg regs;
+ int count;
+
+ bzero(slot, sizeof(slot));
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&regs, 0) != 0)
+ return -1;
+
+ for (i = 0; i < 32; i++)
+ slot[i] = -1;
+
+ frame = regs.r_regs[R_SP];
+ pc = regs.r_regs[R_ZERO]; /* Ieeek. on drugs. */
+ ra = regs.r_regs[R_RA];
+
+ for (count = 0; count < framec + 1; count++) {
+ /* XXX - better out of bounds check needed. */
+ if (pc < 0x1000 || pc == 0xffffffffffffffff) {
+ return -1;
+ }
+
+ name = sym_name_and_offset(ps, pc, namebuf,
+ sizeof(namebuf), &offset);
+ if (!name) {
+ /* Limit the search for procedure start */
+ offset = 65536;
+ }
+
+ framesize = 0;
+ for (i = sizeof (int); i <= offset; i += sizeof (int)) {
+ if (read_from_pid(ps->ps_pid, pc - i, &inst, sizeof(inst)) < 0)
+ return -1;
+
+ /*
+ * If by chance we don't have any symbols we have to
+ * get out somehow anyway. Check for the preceding
+ * procedure return in that case.
+ */
+ if (name == NULL && inst_return(inst))
+ break;
+
+ /*
+ * Disassemble to get the needed info for the frame.
+ */
+ if ((inst & 0xffff0000) == 0x23de0000) {
+ /* lda sp,n(sp) */
+ framesize -= disp(inst) / sizeof (u_long);
+ } else if ((inst & 0xfc1f0000) == 0xb41e0000) {
+ /* stq X,n(sp) */
+ slot[rega(inst)] = frame + disp(inst);
+ } else if ((inst & 0xfc000fe0) == 0x44000400 &&
+ rega(inst) == regb(inst)) {
+ /* bis X,X,Y (aka mov X,Y) */
+ /* zero is hardwired */
+ if (rega(inst) != 31)
+ slot[rega(inst)] = slot[regc(inst)];
+ slot[regc(inst)] = 0;
+ /*
+ * XXX In here we might special case a frame
+ * pointer setup, i.e. mov sp, fp.
+ */
+ } else if (inst_load(inst)) {
+ /* clobbers a register */
+ slot[rega(inst)] = 0;
+ } else if (opcode[inst >> 26].opc_fmt == OPC_OP) {
+ /* clobbers a register */
+ slot[regc(inst)] = 0;
+ }
+ /*
+ * XXX Recognize more reg clobbering instructions and
+ * set slot[reg] = 0 then too.
+ */
+ }
+
+ fram->pc = pc;
+ fram->fp = frame;
+
+ /* Look for the return address if recorded. */
+ if (slot[R_RA]) {
+ if (slot[R_RA] == -1)
+ ra = regs.r_regs[R_RA];
+ else
+ if (read_from_pid(ps->ps_pid, (off_t)slot[R_RA],
+ &ra, sizeof(ra)) < 0)
+ return -1;
+ } else {
+ break;
+ }
+
+ /* Advance to the next frame. */
+ frame += framesize * sizeof(u_long);
+ if (pc == ra) {
+ break;
+ }
+ pc = ra;
+ }
+
+ return count == framec + 1 ? 0 : -1;
+}
diff --git a/usr.bin/pmdb/arch/alpha/pmdb_machdep.h b/usr.bin/pmdb/arch/alpha/pmdb_machdep.h
new file mode 100644
index 00000000000..6ff260d09d0
--- /dev/null
+++ b/usr.bin/pmdb/arch/alpha/pmdb_machdep.h
@@ -0,0 +1,3 @@
+#define BREAKPOINT { 0x80, 0, 0, 0 }
+#define BREAKPOINT_LEN 4
+#define BREAKPOINT_DECR_PC 4
diff --git a/usr.bin/pmdb/arch/i386/Makefile.inc b/usr.bin/pmdb/arch/i386/Makefile.inc
new file mode 100644
index 00000000000..7226cf7cbb4
--- /dev/null
+++ b/usr.bin/pmdb/arch/i386/Makefile.inc
@@ -0,0 +1,3 @@
+# $PMDB: Makefile.inc,v 1.2 2002/01/30 23:20:13 fgs Exp $
+
+SRCS+= i386.c
diff --git a/usr.bin/pmdb/arch/i386/i386.c b/usr.bin/pmdb/arch/i386/i386.c
new file mode 100644
index 00000000000..2612ef63568
--- /dev/null
+++ b/usr.bin/pmdb/arch/i386/i386.c
@@ -0,0 +1,91 @@
+/* $PMDB: i386.c,v 1.5 2002/02/21 01:54:44 art Exp $ */
+/*
+ * Copyright (c) 2002 Federico Schwindt <fgsch@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "pmdb.h"
+
+/*
+ * No frame for x86?
+ */
+struct frame {
+ int fp;
+ int pc;
+};
+
+static const char *md_reg_names[] = {
+ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", "%eip",
+ "%eflags", "%cs", "%ss", "%ds", "%es", "%fs", "%gs"
+};
+
+struct md_def md_def = { md_reg_names, 16, 8 };
+
+void
+md_def_init(void)
+{
+ /* no need to do anything */
+}
+
+int
+md_getframe(struct pstate *ps, int frame, struct md_frame *fram)
+{
+ struct frame fr;
+ struct reg r;
+ int count;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return (-1);
+
+ fr.fp = r.r_ebp;
+ fr.pc = r.r_eip;
+ for (count = 0; count < frame; count++) {
+ if (read_from_pid(ps->ps_pid, fr.fp, &fr, sizeof(fr)) < 0)
+ return (-1);
+
+ if (fr.pc < 0x1000)
+ return (-1);
+ }
+
+ fram->pc = fr.pc;
+ fram->fp = fr.fp;
+
+ return 0;
+}
+
+int
+md_getregs(struct pstate *ps, reg *regs)
+{
+ struct reg r;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return -1;
+
+ memcpy(regs, &r, sizeof(r));
+
+ return 0;
+}
diff --git a/usr.bin/pmdb/arch/i386/pmdb_machdep.h b/usr.bin/pmdb/arch/i386/pmdb_machdep.h
new file mode 100644
index 00000000000..9c25e38ee6f
--- /dev/null
+++ b/usr.bin/pmdb/arch/i386/pmdb_machdep.h
@@ -0,0 +1,3 @@
+#define BREAKPOINT { 0xcc }
+#define BREAKPOINT_LEN 1
+#define BREAKPOINT_DECR_PC 1
diff --git a/usr.bin/pmdb/arch/sparc/Makefile.inc b/usr.bin/pmdb/arch/sparc/Makefile.inc
new file mode 100644
index 00000000000..7e104c0feee
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc/Makefile.inc
@@ -0,0 +1 @@
+SRCS+=sparc.c
diff --git a/usr.bin/pmdb/arch/sparc/pmdb_machdep.h b/usr.bin/pmdb/arch/sparc/pmdb_machdep.h
new file mode 100644
index 00000000000..d47a3b78c47
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc/pmdb_machdep.h
@@ -0,0 +1,3 @@
+#define BREAKPOINT { 0x91, 0xd0, 0x20, 0x01 }
+#define BREAKPOINT_LEN 4
+#define BREAKPOINT_DECR_PC 0
diff --git a/usr.bin/pmdb/arch/sparc/sparc.c b/usr.bin/pmdb/arch/sparc/sparc.c
new file mode 100644
index 00000000000..70aeb7687b8
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc/sparc.c
@@ -0,0 +1,107 @@
+/* $PMDB: sparc.c,v 1.4 2002/03/05 12:04:26 art Exp $ */
+/*
+ * Copyright (c) 2002 Federico Schwindt <fgsch@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "pmdb.h"
+
+static const char *md_reg_names[] = {
+ "%pc", "%npc", /* %y */
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%o7",
+ "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+};
+
+struct md_def md_def = { md_reg_names, 18, 0 };
+
+#define next_frame(f) ((struct frame*)(f->fr_fp))
+
+void
+md_def_init(void)
+{
+ /* no need to do anything */
+}
+
+int
+md_getframe(struct pstate *ps, int frame, struct md_frame *fram)
+{
+ struct frame fr;
+ struct reg r;
+ reg fp, pc;
+ int i;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return -1;
+
+ if (frame == 0) {
+ fram->pc = r.r_pc;
+ fram->fp = r.r_out[6];
+ return 0;
+ }
+
+ fp = r.r_out[6];
+ pc = r.r_out[7];
+
+ for (i = 1; i < frame; i++) {
+ if (fp < 8192 || (fp & 7) != 0)
+ return -1;
+
+ if (read_from_pid(ps->ps_pid, fp, &fr, sizeof(fr)) < 0)
+ return -1;
+ fp = (unsigned long)next_frame((&fr));
+ pc = fr.fr_pc;
+ }
+ fram->pc = pc;
+ fram->fp = fp;
+
+ fram->nargs = 6; /* XXX - don't know the real number */
+ for (i = 0; i < 6; i++) {
+ fram->args[i] = fr.fr_arg[i];
+ }
+
+ return 0;
+}
+
+int
+md_getregs(struct pstate *ps, reg *regs)
+{
+ struct reg r;
+ int i;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return -1;
+ regs[0] = r.r_pc;
+ regs[1] = r.r_npc;
+ for (i = 0; i < 8; i++) {
+ regs[2 + i] = r.r_out[i];
+ }
+ for (i = 0; i < 8; i++) {
+ regs[10 + i] = r.r_global[i];
+ }
+
+ return 0;
+}
diff --git a/usr.bin/pmdb/arch/sparc64/Makefile.inc b/usr.bin/pmdb/arch/sparc64/Makefile.inc
new file mode 100644
index 00000000000..3257538c715
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc64/Makefile.inc
@@ -0,0 +1 @@
+SRCS+=sparc64.c
diff --git a/usr.bin/pmdb/arch/sparc64/pmdb_machdep.h b/usr.bin/pmdb/arch/sparc64/pmdb_machdep.h
new file mode 100644
index 00000000000..d47a3b78c47
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc64/pmdb_machdep.h
@@ -0,0 +1,3 @@
+#define BREAKPOINT { 0x91, 0xd0, 0x20, 0x01 }
+#define BREAKPOINT_LEN 4
+#define BREAKPOINT_DECR_PC 0
diff --git a/usr.bin/pmdb/arch/sparc64/sparc64.c b/usr.bin/pmdb/arch/sparc64/sparc64.c
new file mode 100644
index 00000000000..d4f44a56402
--- /dev/null
+++ b/usr.bin/pmdb/arch/sparc64/sparc64.c
@@ -0,0 +1,122 @@
+/* $PMDB: sparc64.c,v 1.6 2002/03/07 01:10:52 art Exp $ */
+/*
+ * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include "pmdb.h"
+
+static const char *md_reg_names[] = {
+ "%pc", "%npc", /* %y */
+ "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%o7",
+ "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+};
+
+struct md_def md_def = { md_reg_names, 18, 0 };
+
+void
+md_def_init(void)
+{
+ /* no need to do anything */
+}
+
+int
+md_getframe(struct pstate *ps, int frame, struct md_frame *fram)
+{
+ struct frame64 fr;
+ struct reg r;
+ reg fp, pc;
+ reg *outs;
+ int i;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return (-1);
+
+ if (frame == 0) {
+ pc = r.r_pc;
+ fp = r.r_out[6] + BIAS;
+ /*
+ * XXX - we need some kind of heuristics here to decide
+ * if the function has done a save or not and then pick
+ * the in registers. the problem is just that there are
+ * no in registers in PT_GETREGS.
+ */
+ outs = (reg *)&r.r_out;
+ goto out;
+ }
+
+ fp = r.r_out[6] + BIAS;
+ pc = r.r_out[7];
+
+ for (i = 1; i < frame; i++) {
+ /* Too low or unaligned frame pointer? */
+ if (fp < 8192 || (fp & 7) != 0)
+ return (-1);
+
+ if (read_from_pid(ps->ps_pid, fp, &fr, sizeof(fr)) < 0)
+ return -1;
+ fp = (unsigned long)v9next_frame((&fr));
+ pc = fr.fr_pc;
+
+ /* Too low or unaligned pc ? */
+ if ((pc < 8192) || (pc & 3) != 0)
+ return (-1);
+
+ outs = (reg *)&fr.fr_arg;
+ }
+
+out:
+ fram->pc = pc;
+ fram->fp = fp;
+
+ fram->nargs = 6; /* XXX - don't know the real number */
+ for (i = 0; i < 6; i++) {
+ fram->args[i] = fr.fr_arg[i];
+ }
+
+ return 0;
+}
+
+int
+md_getregs(struct pstate *ps, reg *regs)
+{
+ struct reg r;
+ int i;
+
+ if (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)&r, 0) != 0)
+ return -1;
+ regs[0] = r.r_pc;
+ regs[1] = r.r_npc;
+ for (i = 0; i < 8; i++) {
+ regs[2 + i] = r.r_out[i];
+ }
+ for (i = 0; i < 8; i++) {
+ regs[10 + i] = r.r_global[i];
+ }
+
+ return 0;
+} \ No newline at end of file