xref: /netbsd-src/sys/ddb/db_access.c (revision 8339635ecf640a367c707c2f00b79a116ac10508)
1*8339635eSandvar /*	$NetBSD: db_access.c,v 1.27 2023/09/01 10:55:23 andvar Exp $	*/
2cf92afd6Scgd 
361f28255Scgd /*
461f28255Scgd  * Mach Operating System
561f28255Scgd  * Copyright (c) 1991,1990 Carnegie Mellon University
661f28255Scgd  * All Rights Reserved.
761f28255Scgd  *
861f28255Scgd  * Permission to use, copy, modify and distribute this software and its
961f28255Scgd  * documentation is hereby granted, provided that both the copyright
1061f28255Scgd  * notice and this permission notice appear in all copies of the
1161f28255Scgd  * software, derivative works or modified versions, and any portions
1261f28255Scgd  * thereof, and that both notices appear in supporting documentation.
1361f28255Scgd  *
14b13e5d14Spk  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
1561f28255Scgd  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
1661f28255Scgd  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1761f28255Scgd  *
1861f28255Scgd  * Carnegie Mellon requests users of this software to return to
1961f28255Scgd  *
2061f28255Scgd  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
2161f28255Scgd  *  School of Computer Science
2261f28255Scgd  *  Carnegie Mellon University
2361f28255Scgd  *  Pittsburgh PA 15213-3890
2461f28255Scgd  *
2561f28255Scgd  * any improvements or extensions that they make and grant Carnegie the
2661f28255Scgd  * rights to redistribute these changes.
2737cabe30Scgd  *
2861f28255Scgd  *	Author: David B. Golub, Carnegie Mellon University
2961f28255Scgd  *	Date:	7/90
3061f28255Scgd  */
31f1a5c330Smycroft 
321ac69d9cSlukem #include <sys/cdefs.h>
33*8339635eSandvar __KERNEL_RCSID(0, "$NetBSD: db_access.c,v 1.27 2023/09/01 10:55:23 andvar Exp $");
3435bc16c5Sbsh 
351c34311dSbsh #if defined(_KERNEL_OPT)
3635bc16c5Sbsh #include "opt_kgdb.h"
371c34311dSbsh #endif
381ac69d9cSlukem 
39f1a5c330Smycroft #include <sys/param.h>
40f1a5c330Smycroft #include <sys/proc.h>
41cd6b1c8fSad #include <sys/endian.h>
42f1a5c330Smycroft 
43cd6b1c8fSad #include <ddb/ddb.h>
4490856010Smycroft 
4561f28255Scgd /*
4661f28255Scgd  * Access unaligned data items on aligned (longword)
4761f28255Scgd  * boundaries.
4835bc16c5Sbsh  *
491c34311dSbsh  * This file is shared by ddb, kgdb and crash(8).
5061f28255Scgd  */
5161f28255Scgd 
521c34311dSbsh #if defined(DDB) || !defined(DDB) && !defined(KGDB)
531c34311dSbsh #define	_COMPILE_THIS
541c34311dSbsh #endif
551c34311dSbsh 
561c34311dSbsh #if defined(_COMPILE_THIS) || defined(KGDB) && defined(SOFTWARE_SSTEP)
5735bc16c5Sbsh 
5861f28255Scgd db_expr_t
db_get_value(db_addr_t addr,size_t size,bool is_signed)59712239e3Sthorpej db_get_value(db_addr_t addr, size_t size, bool is_signed)
6061f28255Scgd {
6112f31456Smatt 	char data[sizeof(db_expr_t)] __aligned(sizeof(db_expr_t));
6247022302Skamil 	uintmax_t uvalue;
635e3d7e53Saugustss 	db_expr_t value;
645e3d7e53Saugustss 	size_t i;
6561f28255Scgd 
6661f28255Scgd 	db_read_bytes(addr, size, data);
6761f28255Scgd 
6847022302Skamil 	uvalue = 0;
6907dbafe7Smycroft #if BYTE_ORDER == LITTLE_ENDIAN
706282a103Spk 	for (i = size; i-- > 0;)
7107dbafe7Smycroft #else /* BYTE_ORDER == BIG_ENDIAN */
7207dbafe7Smycroft 	for (i = 0; i < size; i++)
7307dbafe7Smycroft #endif /* BYTE_ORDER */
7447022302Skamil 		uvalue = (uvalue << 8) + (data[i] & 0xFF);
7547022302Skamil 
7647022302Skamil 	value = (db_expr_t)uvalue;
7761f28255Scgd 
7812f31456Smatt 	if (size < sizeof(db_expr_t) && is_signed
7912f31456Smatt 	    && (value & ((db_expr_t)1 << (8*size - 1)))) {
80604bbcaaSmrg 		value |= (unsigned long)~(db_expr_t)0 << (8*size - 1);
8112f31456Smatt 	}
8261f28255Scgd 	return (value);
8361f28255Scgd }
8461f28255Scgd 
856e5e6fa9Sryo quad_t
db_get_qvalue(db_addr_t addr,size_t size,bool is_signed)866e5e6fa9Sryo db_get_qvalue(db_addr_t addr, size_t size, bool is_signed)
876e5e6fa9Sryo {
886e5e6fa9Sryo 	uint64_t data;
896e5e6fa9Sryo 
9072ca669cSryo 	if (size < sizeof(uint64_t)) {
916e5e6fa9Sryo 		if (is_signed)
926e5e6fa9Sryo 			return db_get_value(addr, size, true);
936e5e6fa9Sryo 		return (uint32_t)db_get_value(addr, size, false);
946e5e6fa9Sryo 	}
956e5e6fa9Sryo 
966e5e6fa9Sryo 	if (size != sizeof(data)) {
97*8339635eSandvar 		db_error("unsupported size\n");
986e5e6fa9Sryo 		/*NOTREACHED*/
996e5e6fa9Sryo 	}
1006e5e6fa9Sryo 
1016e5e6fa9Sryo 	db_read_bytes(addr, sizeof(data), (char *)&data);
1026e5e6fa9Sryo 	return data;
1036e5e6fa9Sryo }
1046e5e6fa9Sryo 
10561f28255Scgd void
db_put_value(db_addr_t addr,size_t size,db_expr_t value)1064eaa4d66Ssimonb db_put_value(db_addr_t addr, size_t size, db_expr_t value)
10761f28255Scgd {
10812f31456Smatt 	char data[sizeof(db_expr_t)] __aligned(sizeof(db_expr_t));
1095e3d7e53Saugustss 	size_t i;
11061f28255Scgd 
11107dbafe7Smycroft #if BYTE_ORDER == LITTLE_ENDIAN
11261f28255Scgd 	for (i = 0; i < size; i++)
11307dbafe7Smycroft #else /* BYTE_ORDER == BIG_ENDIAN */
1146282a103Spk 	for (i = size; i-- > 0;)
11507dbafe7Smycroft #endif /* BYTE_ORDER */
11661f28255Scgd 	{
11761f28255Scgd 		data[i] = value & 0xFF;
11861f28255Scgd 		value >>= 8;
11961f28255Scgd 	}
12061f28255Scgd 
12161f28255Scgd 	db_write_bytes(addr, size, data);
12261f28255Scgd }
123cd6b1c8fSad 
1241c34311dSbsh #endif	/* _COMPILE_THIS || KGDB && SOFTWARE_SSTEP */
12535bc16c5Sbsh 
1261c34311dSbsh #ifdef	_COMPILE_THIS
12735bc16c5Sbsh 
128cd6b1c8fSad void *
db_read_ptr(const char * name)129cd6b1c8fSad db_read_ptr(const char *name)
130cd6b1c8fSad {
131cd6b1c8fSad 	db_expr_t val;
132cd6b1c8fSad 	void *p;
133cd6b1c8fSad 
134cd6b1c8fSad 	if (!db_value_of_name(name, &val)) {
135cd6b1c8fSad 		db_printf("db_read_ptr: cannot find `%s'\n", name);
136cd6b1c8fSad 		db_error(NULL);
137cd6b1c8fSad 		/* NOTREACHED */
138cd6b1c8fSad 	}
139cd6b1c8fSad 	db_read_bytes((db_addr_t)val, sizeof(p), (char *)&p);
140cd6b1c8fSad 	return p;
141cd6b1c8fSad }
142cd6b1c8fSad 
143cd6b1c8fSad int
db_read_int(const char * name)144cd6b1c8fSad db_read_int(const char *name)
145cd6b1c8fSad {
146cd6b1c8fSad 	db_expr_t val;
147cd6b1c8fSad 	int p;
148cd6b1c8fSad 
149cd6b1c8fSad 	if (!db_value_of_name(name, &val)) {
150cd6b1c8fSad 		db_printf("db_read_int: cannot find `%s'\n", name);
151cd6b1c8fSad 		db_error(NULL);
152cd6b1c8fSad 		/* NOTREACHED */
153cd6b1c8fSad 	}
154cd6b1c8fSad 	db_read_bytes((db_addr_t)val, sizeof(p), (char *)&p);
155cd6b1c8fSad 	return p;
156cd6b1c8fSad }
15735bc16c5Sbsh 
1581c34311dSbsh #endif	/* _COMPILE_THIS */
159