xref: /netbsd-src/sys/ddb/db_access.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: db_access.c,v 1.19 2009/03/07 22:02:17 ad Exp $	*/
2 
3 /*
4  * Mach Operating System
5  * Copyright (c) 1991,1990 Carnegie Mellon University
6  * All Rights Reserved.
7  *
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie the
26  * rights to redistribute these changes.
27  *
28  *	Author: David B. Golub, Carnegie Mellon University
29  *	Date:	7/90
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: db_access.c,v 1.19 2009/03/07 22:02:17 ad Exp $");
34 
35 #include <sys/param.h>
36 #include <sys/proc.h>
37 #include <sys/endian.h>
38 
39 #include <ddb/ddb.h>
40 
41 /*
42  * Access unaligned data items on aligned (longword)
43  * boundaries.
44  */
45 
46 const int db_extend[] = {	/* table for sign-extending */
47 	0,
48 	0xFFFFFF80,
49 	0xFFFF8000,
50 	0xFF800000
51 };
52 
53 db_expr_t
54 db_get_value(db_addr_t addr, size_t size, bool is_signed)
55 {
56 	char data[sizeof(db_expr_t)];
57 	db_expr_t value;
58 	size_t i;
59 
60 	db_read_bytes(addr, size, data);
61 
62 	value = 0;
63 #if BYTE_ORDER == LITTLE_ENDIAN
64 	for (i = size; i-- > 0;)
65 #else /* BYTE_ORDER == BIG_ENDIAN */
66 	for (i = 0; i < size; i++)
67 #endif /* BYTE_ORDER */
68 		value = (value << 8) + (data[i] & 0xFF);
69 
70 	if (size < 4 && is_signed && (value & db_extend[size]) != 0)
71 		value |= db_extend[size];
72 	return (value);
73 }
74 
75 void
76 db_put_value(db_addr_t addr, size_t size, db_expr_t value)
77 {
78 	char data[sizeof(db_expr_t)];
79 	size_t i;
80 
81 #if BYTE_ORDER == LITTLE_ENDIAN
82 	for (i = 0; i < size; i++)
83 #else /* BYTE_ORDER == BIG_ENDIAN */
84 	for (i = size; i-- > 0;)
85 #endif /* BYTE_ORDER */
86 	{
87 		data[i] = value & 0xFF;
88 		value >>= 8;
89 	}
90 
91 	db_write_bytes(addr, size, data);
92 }
93 
94 void *
95 db_read_ptr(const char *name)
96 {
97 	db_expr_t val;
98 	void *p;
99 
100 	if (!db_value_of_name(name, &val)) {
101 		db_printf("db_read_ptr: cannot find `%s'\n", name);
102 		db_error(NULL);
103 		/* NOTREACHED */
104 	}
105 	db_read_bytes((db_addr_t)val, sizeof(p), (char *)&p);
106 	return p;
107 }
108 
109 int
110 db_read_int(const char *name)
111 {
112 	db_expr_t val;
113 	int p;
114 
115 	if (!db_value_of_name(name, &val)) {
116 		db_printf("db_read_int: cannot find `%s'\n", name);
117 		db_error(NULL);
118 		/* NOTREACHED */
119 	}
120 	db_read_bytes((db_addr_t)val, sizeof(p), (char *)&p);
121 	return p;
122 }
123