1 /* $OpenBSD: db_struct.c,v 1.1 2009/08/09 23:04:49 miod Exp $ */
4 * Copyright (c) 2009 Miodrag Vallat.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * ddb routines to describe struct information
23 #include <sys/param.h>
24 #include <sys/systm.h>
26 #include <machine/db_machdep.h>
28 #include <ddb/db_lex.h>
29 #include <ddb/db_output.h>
30 #include <ddb/db_access.h>
31 #include <ddb/db_command.h>
32 #include <ddb/db_extern.h>
33 #include <ddb/db_interface.h>
34 #include <ddb/db_var.h>
36 #include "db_structinfo.h"
38 void db_struct_print_field(uint
, int, db_expr_t
);
41 * Flags to pass db_struct_printf().
44 #define DBSP_STRUCT_NAME 0x01 /* prepend struct name */
45 #define DBSP_VALUE 0x02 /* display field value */
48 db_struct_print_field(uint fidx
, int flags
, db_expr_t baseaddr
)
50 const struct ddb_field_info
*field
;
51 const struct ddb_struct_info
*struc
;
55 int width
, basecol
, curcol
;
58 field
= &ddb_field_info
[fidx
];
61 if (ISSET(flags
, DBSP_STRUCT_NAME
)) {
62 struc
= &ddb_struct_info
[field
->sidx
];
63 namelen
= strlen(struc
->name
);
64 db_printf("%-30s ", struc
->name
);
66 basecol
+= namelen
+ 1;
71 namelen
= strlen(field
->name
);
72 if (field
->nitems
== 1) {
73 db_printf("%-30s ", field
->name
);
75 basecol
+= namelen
+ 1;
85 if (namelen
>= width
) {
86 db_printf("%s[%zu] ", field
->name
, field
->nitems
);
87 basecol
+= namelen
+ (30 - width
) + 1;
89 db_printf("%s[%zu]%*s ", field
->name
, field
->nitems
,
90 width
- (int)namelen
, "");
91 /* namelen + (30-width) + (width-namelen) + 1 */
96 if (field
->size
== 0) {
97 db_printf("bitfield");
98 /* basecol irrelevant from there on */
100 snprintf(tmpfmt
, sizeof tmpfmt
, "%zu", field
->size
);
101 basecol
+= strlen(tmpfmt
) + 1;
102 db_printf("%s ", tmpfmt
);
105 if (ISSET(flags
, DBSP_VALUE
)) {
106 /* only print the field value if it has a friendly size. */
107 switch (field
->size
) {
126 baseaddr
+= field
->offs
;
128 for (tmp
= field
->nitems
; tmp
!= 0; tmp
--) {
129 value
= db_get_value(baseaddr
, field
->size
,
130 FALSE
); /* assume unsigned */
131 db_format(tmpfmt
, sizeof tmpfmt
, (long)value
,
132 DB_FORMAT_N
, 0, width
);
133 if (field
->nitems
> 1)
134 db_printf("%s", tmpfmt
);
136 db_printf("%20s", tmpfmt
);
137 baseaddr
+= field
->size
;
140 * Try to fit array elements on as few lines
143 if (field
->nitems
> 1 && tmp
> 1) {
145 if (basecol
>= db_max_width
||
146 curcol
+ width
>= db_max_width
) {
149 if (basecol
+ width
>=
170 * show offset <value>: displays the list of struct fields which exist
171 * at that particular offset from the beginning of the struct.
174 db_struct_offset_cmd(db_expr_t addr
, int have_addr
, db_expr_t count
,
177 db_expr_t offset
= 0;
178 const struct ddb_field_offsets
*field
;
185 * Read the offset from the debuggger input.
186 * We don't want to get it from the standard parsing code, because
187 * this would set `dot' to this value, which doesn't make sense.
190 if (!db_expression(&offset
) || offset
< 0) {
191 db_printf("not a valid offset\n");
198 for (field
= ddb_field_offsets
, oidx
= 0; oidx
< NOFFS
; field
++, oidx
++)
199 if (field
->offs
== (size_t)offset
)
203 db_format(tmpfmt
, sizeof tmpfmt
, (long)offset
,
204 DB_FORMAT_N
, 0, width
);
205 db_printf("no known structure element at offset %-*s\n",
211 db_printf("%-30s %-30s size\n", "struct", "member");
212 for (fidx
= field
->list
; *fidx
!= 0; fidx
++)
213 db_struct_print_field(*fidx
, DBSP_STRUCT_NAME
, 0);
217 * show struct <struct name> [addr]: displays the data starting at addr
218 * (`dot' if unspecified) as a struct of the given type.
221 db_struct_layout_cmd(db_expr_t addr
, int have_addr
, db_expr_t count
,
224 const struct ddb_struct_info
*struc
;
229 * Read the struct name from the debugger input.
234 db_printf("Bad struct name\n");
239 for (struc
= ddb_struct_info
, sidx
= 0; sidx
< NSTRUCT
;
241 if (strcmp(struc
->name
, db_tok_string
) == 0)
244 if (sidx
== NSTRUCT
) {
245 db_printf("unknown struct %s\n", db_tok_string
);
251 * Read the address, if any, from the debugger input.
252 * In that case, update `dot' value.
255 if (db_expression(&addr
)) {
256 db_dot
= (db_addr_t
)addr
;
257 db_last_addr
= db_dot
;
259 addr
= (db_expr_t
)db_dot
;
264 * Display the structure contents.
267 db_printf("struct %s at %p (%zu bytes)\n", struc
->name
, (vaddr_t
)addr
,
269 for (fidx
= struc
->fmin
; fidx
<= struc
->fmax
; fidx
++)
270 db_struct_print_field(fidx
, DBSP_VALUE
, addr
);