Sun May 23 23:22:55 2021 UTC ()
Improve ddb disassembly for mips (and riscv, cribbed from mips).

- use db_read_bytes to get instructions
- move the address check logic previously attached only to fetching
  instructions for disassembly to db_read_bytes (and db_write_bytes)

Motivated by related x86 changes this afternoon.

Note that the address check logic is not as sophisticated as what the
x86 code does, but it's what we had before. (Except that riscv will
now also try to fetch usermode instructions instead of just failing.)


(dholland)
diff -r1.42 -r1.43 src/sys/arch/mips/mips/db_disasm.c
diff -r1.93 -r1.94 src/sys/arch/mips/mips/db_interface.c
diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/db_disasm.c
diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/db_machdep.c

cvs diff -r1.42 -r1.43 src/sys/arch/mips/mips/db_disasm.c (expand / switch to unified diff)

--- src/sys/arch/mips/mips/db_disasm.c 2021/04/12 11:35:22 1.42
+++ src/sys/arch/mips/mips/db_disasm.c 2021/05/23 23:22:55 1.43
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: db_disasm.c,v 1.42 2021/04/12 11:35:22 simonb Exp $ */ 1/* $NetBSD: db_disasm.c,v 1.43 2021/05/23 23:22:55 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1991, 1993 4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Ralph Campbell. 8 * Ralph Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -25,38 +25,39 @@ @@ -25,38 +25,39 @@
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93 34 * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.42 2021/04/12 11:35:22 simonb Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.43 2021/05/23 23:22:55 dholland Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/cpu.h> 41#include <sys/cpu.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43 43
44#include <mips/locore.h> 44#include <mips/locore.h>
45#include <mips/mips_opcode.h> 45#include <mips/mips_opcode.h>
46#include <mips/reg.h> 46#include <mips/reg.h>
47 47
48#include <machine/db_machdep.h> 48#include <machine/db_machdep.h>
49 49
 50#include <ddb/db_access.h>
50#include <ddb/db_user.h> 51#include <ddb/db_user.h>
51#include <ddb/db_interface.h> 52#include <ddb/db_interface.h>
52#include <ddb/db_output.h> 53#include <ddb/db_output.h>
53#include <ddb/db_extern.h> 54#include <ddb/db_extern.h>
54#include <ddb/db_sym.h> 55#include <ddb/db_sym.h>
55 56
56static const char * const op_name[64] = { 57static const char * const op_name[64] = {
57/* 0 */ "spec", "regimm","j", "jal", "beq", "bne", "blez", "bgtz", 58/* 0 */ "spec", "regimm","j", "jal", "beq", "bne", "blez", "bgtz",
58/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", 59/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
59/*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl", 60/*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
60/*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37", 61/*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
61/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu", 62/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
62/*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache", 63/*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
@@ -208,53 +209,43 @@ static const char * const c0_reg[32] = { @@ -208,53 +209,43 @@ static const char * const c0_reg[32] = {
208}; 209};
209 210
210static void print_addr(db_addr_t); 211static void print_addr(db_addr_t);
211 212
212/* 213/*
213 * Disassemble instruction at 'loc'. 'altfmt' specifies an 214 * Disassemble instruction at 'loc'. 'altfmt' specifies an
214 * (optional) alternate format (altfmt for vax: don't assume 215 * (optional) alternate format (altfmt for vax: don't assume
215 * that each external label is a procedure entry mask). 216 * that each external label is a procedure entry mask).
216 * Return address of start of next instruction. 217 * Return address of start of next instruction.
217 * Since this function is used by 'examine' and by 'step' 218 * Since this function is used by 'examine' and by 'step'
218 * "next instruction" does NOT mean the next instruction to 219 * "next instruction" does NOT mean the next instruction to
219 * be executed but the 'linear' next instruction. 220 * be executed but the 'linear' next instruction.
220 */ 221 */
221#ifdef _LP64 
222#define DISASM_KERN_START MIPS_XKSEG_START 
223#else 
224#define DISASM_KERN_START MIPS_KSEG0_START 
225#endif 
226db_addr_t 222db_addr_t
227db_disasm(db_addr_t loc, bool altfmt) 223db_disasm(db_addr_t loc, bool altfmt)
228{ 224{
229 uint32_t instr; 225 uint32_t instr;
230 226
231 /* 227 /*
232 * Take some care with addresses to not UTLB here as it 228 * Take some care with addresses to not UTLB here as it
233 * loses the current debugging context. KSEG2 and XKSEG 229 * loses the current debugging context. KSEG2 and XKSEG
234 * are not checked. 230 * are not checked.
 231 * Update: db_read_bytes is supposed to do that, and now
 232 * does, so we can use that.
 233 *
 234 * XXX db_read_bytes_can't return failure but instead zeros
 235 * the output. That's ok here, but if ever improved the
 236 * proper thing here on error is to return the original loc.
235 */ 237 */
236 if (loc < (db_addr_t)DISASM_KERN_START) { 238 db_read_bytes(loc, sizeof(instr), (void *)&instr);
237#ifdef _KERNEL 
238 if (ufetch_32((void *)loc, &instr) != 0) { 
239 db_printf("invalid address.\n"); 
240 return loc; 
241 } 
242#else 
243 return loc; 
244#endif 
245 } else { 
246 instr = *(uint32_t *)loc; 
247 } 
248 239
249 return (db_disasm_insn(instr, loc, altfmt)); 240 return (db_disasm_insn(instr, loc, altfmt));
250} 241}
251 242
252 243
253/* 244/*
254 * Disassemble instruction 'insn' nominally at 'loc'. 245 * Disassemble instruction 'insn' nominally at 'loc'.
255 * 'loc' may in fact contain a breakpoint instruction. 246 * 'loc' may in fact contain a breakpoint instruction.
256 */ 247 */
257db_addr_t 248db_addr_t
258db_disasm_insn(int insn, db_addr_t loc, bool altfmt) 249db_disasm_insn(int insn, db_addr_t loc, bool altfmt)
259{ 250{
260 bool bdslot = false; 251 bool bdslot = false;

cvs diff -r1.93 -r1.94 src/sys/arch/mips/mips/db_interface.c (expand / switch to unified diff)

--- src/sys/arch/mips/mips/db_interface.c 2021/04/12 02:23:41 1.93
+++ src/sys/arch/mips/mips/db_interface.c 2021/05/23 23:22:55 1.94
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: db_interface.c,v 1.93 2021/04/12 02:23:41 mrg Exp $ */ 1/* $NetBSD: db_interface.c,v 1.94 2021/05/23 23:22:55 dholland Exp $ */
2 2
3/* 3/*
4 * Mach Operating System 4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University 5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission to use, copy, modify and distribute this software and its 8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright 9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the 10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions 11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation. 12 * thereof, and that both notices appear in supporting documentation.
13 * 13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * 17 *
18 * Carnegie Mellon requests users of this software to return to 18 * Carnegie Mellon requests users of this software to return to
19 * 19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science 21 * School of Computer Science
22 * Carnegie Mellon University 22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890 23 * Pittsburgh PA 15213-3890
24 * 24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon 25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes. 26 * the rights to redistribute these changes.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.93 2021/04/12 02:23:41 mrg Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.94 2021/05/23 23:22:55 dholland Exp $");
31 31
32#ifdef _KERNEL_OPT 32#ifdef _KERNEL_OPT
33#include "opt_multiprocessor.h" 33#include "opt_multiprocessor.h"
34#include "opt_cputype.h" /* which mips CPUs do we support? */ 34#include "opt_cputype.h" /* which mips CPUs do we support? */
35#include "opt_ddb.h" 35#include "opt_ddb.h"
36#include "opt_kgdb.h" 36#include "opt_kgdb.h"
37#endif 37#endif
38 38
39#define __PMAP_PRIVATE 39#define __PMAP_PRIVATE
40 40
41#include <sys/types.h> 41#include <sys/types.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/param.h> 43#include <sys/param.h>
@@ -170,51 +170,80 @@ cpu_Debugger(void) @@ -170,51 +170,80 @@ cpu_Debugger(void)
170{ 170{
171 171
172 __asm("break"); 172 __asm("break");
173} 173}
174#endif /* !KGDB */ 174#endif /* !KGDB */
175 175
176/* 176/*
177 * Read bytes from kernel address space for debugger. 177 * Read bytes from kernel address space for debugger.
178 */ 178 */
179void 179void
180db_read_bytes(vaddr_t addr, size_t size, char *data) 180db_read_bytes(vaddr_t addr, size_t size, char *data)
181{ 181{
182 const char *src = (char *)addr; 182 const char *src = (char *)addr;
 183 int err;
 184
 185 /*
 186 * If asked to fetch from userspace, do it safely.
 187 * Note that MIPS_KSEG0_START is the proper address for
 188 * both 32-bit and 64-bit kernels.
 189 */
 190 if (addr < (vaddr_t)MIPS_KSEG0_START) {
 191 err = copyin(src, data, size);
 192 if (err) {
 193#ifdef DDB
 194 db_printf("address %p is invalid\n", src);
 195#endif
 196 memset(data, 0, size);
 197 }
 198 return;
 199 }
183 200
184 if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0 201 if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0
185 && ((uintptr_t)data & (size-1)) == 0) { 202 && ((uintptr_t)data & (size-1)) == 0) {
186 if (size == sizeof(uint8_t)) 203 if (size == sizeof(uint8_t))
187 *(uint8_t *)data = *(const uint8_t *)src; 204 *(uint8_t *)data = *(const uint8_t *)src;
188 else if (size == sizeof(uint16_t)) 205 else if (size == sizeof(uint16_t))
189 *(uint16_t *)data = *(const uint16_t *)src; 206 *(uint16_t *)data = *(const uint16_t *)src;
190 else if (size == sizeof(uint32_t)) 207 else if (size == sizeof(uint32_t))
191 *(uint32_t *)data = *(const uint32_t *)src; 208 *(uint32_t *)data = *(const uint32_t *)src;
192 else 209 else
193 *(uint64_t *)data = *(const uint64_t *)src; 210 *(uint64_t *)data = *(const uint64_t *)src;
194 return; 211 return;
195 } 212 }
196 while (size--) 213 while (size--)
197 *data++ = *src++; 214 *data++ = *src++;
198} 215}
199 216
200/* 217/*
201 * Write bytes to kernel address space for debugger. 218 * Write bytes to kernel address space for debugger.
202 */ 219 */
203void 220void
204db_write_bytes(vaddr_t addr, size_t size, const char *data) 221db_write_bytes(vaddr_t addr, size_t size, const char *data)
205{ 222{
206 char *p = (char *)addr; 223 char *p = (char *)addr;
207 size_t n = size; 224 size_t n = size;
 225 int err;
 226
 227 /* If asked to fetch from userspace, do it safely */
 228 if (addr < (vaddr_t)MIPS_KSEG0_START) {
 229 err = copyout(data, p, size);
 230 if (err) {
 231#ifdef DDB
 232 db_printf("address %p is invalid\n", p);
 233#endif
 234 }
 235 return;
 236 }
208 237
209 if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0 238 if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0
210 && ((uintptr_t)data & (size-1)) == 0) { 239 && ((uintptr_t)data & (size-1)) == 0) {
211 if (size == sizeof(uint8_t)) 240 if (size == sizeof(uint8_t))
212 *(uint8_t *)p = *(const uint8_t *)data; 241 *(uint8_t *)p = *(const uint8_t *)data;
213 else if (size == sizeof(uint16_t)) 242 else if (size == sizeof(uint16_t))
214 *(uint16_t *)p = *(const uint16_t *)data; 243 *(uint16_t *)p = *(const uint16_t *)data;
215 else if (size == sizeof(uint32_t)) 244 else if (size == sizeof(uint32_t))
216 *(uint32_t *)p = *(const uint32_t *)data; 245 *(uint32_t *)p = *(const uint32_t *)data;
217 else 246 else
218 *(uint64_t *)p = *(const uint64_t *)data; 247 *(uint64_t *)p = *(const uint64_t *)data;
219 return; 248 return;
220 } 249 }

cvs diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/db_disasm.c (expand / switch to unified diff)

--- src/sys/arch/riscv/riscv/db_disasm.c 2021/05/01 06:48:51 1.7
+++ src/sys/arch/riscv/riscv/db_disasm.c 2021/05/23 23:22:55 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: db_disasm.c,v 1.7 2021/05/01 06:48:51 skrll Exp $ */ 1/* $NetBSD: db_disasm.c,v 1.8 2021/05/23 23:22:55 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,34 +21,35 @@ @@ -21,34 +21,35 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33 33
34__RCSID("$NetBSD: db_disasm.c,v 1.7 2021/05/01 06:48:51 skrll Exp $"); 34__RCSID("$NetBSD: db_disasm.c,v 1.8 2021/05/23 23:22:55 dholland Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38 38
39#include <riscv/db_machdep.h> 39#include <riscv/db_machdep.h>
40#include <riscv/insn.h> 40#include <riscv/insn.h>
41 41
 42#include <ddb/db_access.h>
42#include <ddb/db_user.h> 43#include <ddb/db_user.h>
43#include <ddb/db_interface.h> 44#include <ddb/db_interface.h>
44#include <ddb/db_output.h> 45#include <ddb/db_output.h>
45#include <ddb/db_extern.h> 46#include <ddb/db_extern.h>
46#include <ddb/db_sym.h> 47#include <ddb/db_sym.h>
47 48
48//////////////////////////////////////////////////////////// 49////////////////////////////////////////////////////////////
49// registers 50// registers
50 51
51static const char *riscv_registers[32] = { 52static const char *riscv_registers[32] = {
52 "zero", "ra", "sp", "gp", "tp", 53 "zero", "ra", "sp", "gp", "tp",
53 "t0", "t1", "t2", 54 "t0", "t1", "t2",
54 "s0", "s1", 55 "s0", "s1",
@@ -1453,43 +1454,36 @@ db_disasm_unknown(const uint16_t *insn,  @@ -1453,43 +1454,36 @@ db_disasm_unknown(const uint16_t *insn,
1453 db_printf("%02x", insn[i]); 1454 db_printf("%02x", insn[i]);
1454 } 1455 }
1455 db_printf("\n"); 1456 db_printf("\n");
1456} 1457}
1457 1458
1458db_addr_t 1459db_addr_t
1459db_disasm(db_addr_t loc, bool altfmt) 1460db_disasm(db_addr_t loc, bool altfmt)
1460{ 1461{
1461 /* instructions are up to 5 halfwords */ 1462 /* instructions are up to 5 halfwords */
1462 uint16_t insn[5]; 1463 uint16_t insn[5];
1463 unsigned n, i; 1464 unsigned n, i;
1464 uint32_t insn32; 1465 uint32_t insn32;
1465 1466
1466#ifdef _KERNEL 
1467 if ((intptr_t) loc >= 0) { 
1468 db_printf("%s: %#"PRIxVADDR" is not a kernel address\n", 
1469 __func__, loc); 
1470 return loc; 
1471 } 
1472#endif 
1473 
1474 /* 1467 /*
1475 * Fetch the instruction. The first halfword tells us how many 1468 * Fetch the instruction. The first halfword tells us how many
1476 * more there are, and they're always in little-endian order. 1469 * more there are, and they're always in little-endian order.
1477 */ 1470 */
1478 insn[0] = ((const uint16_t *)loc)[0]; 1471 db_read_bytes(loc, sizeof(insn[0]), (void *)&insn[0]);
1479 n = INSN_HALFWORDS(insn[0]); 1472 n = INSN_HALFWORDS(insn[0]);
1480 KASSERT(n > 0 && n <= 5); 1473 KASSERT(n > 0 && n <= 5);
1481 for (i = 1; i < n; i++) { 1474 for (i = 1; i < n; i++) {
1482 insn[i] = ((const uint16_t *)loc)[i]; 1475 db_read_bytes(loc + i * sizeof(insn[i]), sizeof(insn[i]),
 1476 (void *)&insn[i]);
1483 } 1477 }
1484 1478
1485 switch (n) { 1479 switch (n) {
1486 case 1: 1480 case 1:
1487 if (db_disasm_16(loc, insn[0], altfmt) != 0) { 1481 if (db_disasm_16(loc, insn[0], altfmt) != 0) {
1488 db_disasm_unknown(insn, n); 1482 db_disasm_unknown(insn, n);
1489 } 1483 }
1490 break; 1484 break;
1491 case 2: 1485 case 2:
1492 insn32 = ((uint32_t)insn[1] << 16) | insn[0]; 1486 insn32 = ((uint32_t)insn[1] << 16) | insn[0];
1493 if (db_disasm_32(loc, insn32, altfmt) != 0) { 1487 if (db_disasm_32(loc, insn32, altfmt) != 0) {
1494 db_disasm_unknown(insn, n); 1488 db_disasm_unknown(insn, n);
1495 } 1489 }

cvs diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/db_machdep.c (expand / switch to unified diff)

--- src/sys/arch/riscv/riscv/db_machdep.c 2021/04/14 06:32:20 1.7
+++ src/sys/arch/riscv/riscv/db_machdep.c 2021/05/23 23:22:55 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: db_machdep.c,v 1.7 2021/04/14 06:32:20 dholland Exp $ */ 1/* $NetBSD: db_machdep.c,v 1.8 2021/05/23 23:22:55 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,37 +21,38 @@ @@ -21,37 +21,38 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33 33
34__RCSID("$NetBSD: db_machdep.c,v 1.7 2021/04/14 06:32:20 dholland Exp $"); 34__RCSID("$NetBSD: db_machdep.c,v 1.8 2021/05/23 23:22:55 dholland Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37 37
38#include <riscv/insn.h> 38#include <riscv/insn.h>
39#include <riscv/db_machdep.h> 39#include <riscv/db_machdep.h>
40 40
41#include <ddb/db_access.h> 41#include <ddb/db_access.h>
42#include <ddb/db_interface.h> 42#include <ddb/db_interface.h>
43#include <ddb/db_extern.h> 43#include <ddb/db_extern.h>
44#include <ddb/db_variables.h> 44#include <ddb/db_variables.h>
 45#include <ddb/db_output.h>
45 46
46int db_active = 0; 47int db_active = 0;
47 48
48static int db_rw_ddbreg(const struct db_variable *, db_expr_t *, int); 49static int db_rw_ddbreg(const struct db_variable *, db_expr_t *, int);
49 50
50const struct db_variable db_regs[] = { 51const struct db_variable db_regs[] = {
51 { "ra", (void *)offsetof(struct trapframe, tf_ra), db_rw_ddbreg, NULL }, 52 { "ra", (void *)offsetof(struct trapframe, tf_ra), db_rw_ddbreg, NULL },
52 { "sp", (void *)offsetof(struct trapframe, tf_sp), db_rw_ddbreg, NULL }, 53 { "sp", (void *)offsetof(struct trapframe, tf_sp), db_rw_ddbreg, NULL },
53 { "gp", (void *)offsetof(struct trapframe, tf_gp), db_rw_ddbreg, NULL }, 54 { "gp", (void *)offsetof(struct trapframe, tf_gp), db_rw_ddbreg, NULL },
54 { "tp", (void *)offsetof(struct trapframe, tf_tp), db_rw_ddbreg, NULL }, 55 { "tp", (void *)offsetof(struct trapframe, tf_tp), db_rw_ddbreg, NULL },
55 { "s0", (void *)offsetof(struct trapframe, tf_s0), db_rw_ddbreg, NULL }, 56 { "s0", (void *)offsetof(struct trapframe, tf_s0), db_rw_ddbreg, NULL },
56 { "s1", (void *)offsetof(struct trapframe, tf_s1), db_rw_ddbreg, NULL }, 57 { "s1", (void *)offsetof(struct trapframe, tf_s1), db_rw_ddbreg, NULL },
57 { "s2", (void *)offsetof(struct trapframe, tf_s2), db_rw_ddbreg, NULL }, 58 { "s2", (void *)offsetof(struct trapframe, tf_s2), db_rw_ddbreg, NULL },
@@ -215,39 +216,66 @@ branch_taken(uint32_t insn, db_addr_t pc @@ -215,39 +216,66 @@ branch_taken(uint32_t insn, db_addr_t pc
215 return pc + displacement; 216 return pc + displacement;
216} 217}
217 218
218db_addr_t 219db_addr_t
219next_instr_address(db_addr_t pc, bool bdslot_p) 220next_instr_address(db_addr_t pc, bool bdslot_p)
220{ 221{
221 return pc + (bdslot_p ? 0 : 4); 222 return pc + (bdslot_p ? 0 : 4);
222} 223}
223 224
224void 225void
225db_read_bytes(db_addr_t addr, size_t len, char *data) 226db_read_bytes(db_addr_t addr, size_t len, char *data)
226{ 227{
227 const char *src = (char *)addr; 228 const char *src = (char *)addr;
 229 int err;
 230
 231 /* If asked to fetch from userspace, do it safely */
 232 if ((intptr_t)addr >= 0) {
 233 err = copyin(src, data, len);
 234 if (err) {
 235#ifdef DDB
 236 db_printf("address %p is invalid\n", src);
 237#endif
 238 memset(data, 0, len);
 239 }
 240 return;
 241 }
228 242
229 while (len--) { 243 while (len--) {
230 *data++ = *src++; 244 *data++ = *src++;
231 } 245 }
232} 246}
233 247
234/* 248/*
235 * Write bytes to kernel address space for debugger. 249 * Write bytes to kernel address space for debugger.
236 */ 250 */
237void 251void
238db_write_bytes(vaddr_t addr, size_t len, const char *data) 252db_write_bytes(vaddr_t addr, size_t len, const char *data)
239{ 253{
 254 int err;
 255
 256 /* If asked to fetch from userspace, do it safely */
 257 if ((intptr_t)addr >= 0) {
 258 err = copyout(data, (char *)addr, len);
 259 if (err) {
 260#ifdef DDB
 261 db_printf("address %p is invalid\n", (char *)addr);
 262#endif
 263 }
 264 return;
 265 }
 266
240 if (len == 8) { 267 if (len == 8) {
241 *(uint64_t *)addr = *(const uint64_t *) data; 268 *(uint64_t *)addr = *(const uint64_t *) data;
242 } else if (len == 4) { 269 } else if (len == 4) {
243 *(uint32_t *)addr = *(const uint32_t *) data; 270 *(uint32_t *)addr = *(const uint32_t *) data;
244 } else if (len == 2) { 271 } else if (len == 2) {
245 *(uint16_t *)addr = *(const uint16_t *) data; 272 *(uint16_t *)addr = *(const uint16_t *) data;
246 } else { 273 } else {
 274 KASSERT(len == 1);
247 *(uint8_t *)addr = *(const uint8_t *) data; 275 *(uint8_t *)addr = *(const uint8_t *) data;
248 } 276 }
249 __asm("fence rw,rw; fence.i"); 277 __asm("fence rw,rw; fence.i");
250} 278}
251 279
252 280
253 281