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