1c21bc6f3SBojan Novković /*- 2637e67e0SBojan Novković * SPDX-License-Identifier: BSD-2-Clause 3c21bc6f3SBojan Novković * 4c21bc6f3SBojan Novković * Copyright (c) 2022 Bojan Novković <bnovkov@freebsd.org> 5c21bc6f3SBojan Novković * 6c21bc6f3SBojan Novković * Redistribution and use in source and binary forms, with or without 7c21bc6f3SBojan Novković * modification, are permitted provided that the following conditions 8c21bc6f3SBojan Novković * are met: 9c21bc6f3SBojan Novković * 1. Redistributions of source code must retain the above copyright 10c21bc6f3SBojan Novković * notice, this list of conditions and the following disclaimer. 11c21bc6f3SBojan Novković * 2. Redistributions in binary form must reproduce the above copyright 12c21bc6f3SBojan Novković * notice, this list of conditions and the following disclaimer in the 13c21bc6f3SBojan Novković * documentation and/or other materials provided with the distribution. 14c21bc6f3SBojan Novković * 15c21bc6f3SBojan Novković * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16c21bc6f3SBojan Novković * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c21bc6f3SBojan Novković * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c21bc6f3SBojan Novković * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19c21bc6f3SBojan Novković * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c21bc6f3SBojan Novković * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c21bc6f3SBojan Novković * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c21bc6f3SBojan Novković * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c21bc6f3SBojan Novković * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c21bc6f3SBojan Novković * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c21bc6f3SBojan Novković * SUCH DAMAGE. 26c21bc6f3SBojan Novković */ 27c21bc6f3SBojan Novković 28c21bc6f3SBojan Novković #include <sys/param.h> 29c21bc6f3SBojan Novković #include <sys/systm.h> 30c21bc6f3SBojan Novković #include <sys/ctype.h> 31c21bc6f3SBojan Novković #include <sys/linker.h> 32c21bc6f3SBojan Novković 33c21bc6f3SBojan Novković #include <machine/stdarg.h> 34c21bc6f3SBojan Novković 35c21bc6f3SBojan Novković #include <ddb/ddb.h> 36c21bc6f3SBojan Novković #include <ddb/db_ctf.h> 37c21bc6f3SBojan Novković #include <ddb/db_lex.h> 38c21bc6f3SBojan Novković #include <ddb/db_sym.h> 39c21bc6f3SBojan Novković #include <ddb/db_access.h> 40c21bc6f3SBojan Novković 41c21bc6f3SBojan Novković #define DB_PPRINT_DEFAULT_DEPTH 1 42c21bc6f3SBojan Novković 43c21bc6f3SBojan Novković static void db_pprint_type(db_addr_t addr, struct ctf_type_v3 *type, 44c21bc6f3SBojan Novković u_int depth); 45c21bc6f3SBojan Novković 46c21bc6f3SBojan Novković static u_int max_depth = DB_PPRINT_DEFAULT_DEPTH; 47c21bc6f3SBojan Novković static struct db_ctf_sym_data sym_data; 48*1cbd613fSBojan Novković static const char *asteriskstr = "*****"; 49c21bc6f3SBojan Novković 50c21bc6f3SBojan Novković /* 51c21bc6f3SBojan Novković * Pretty-prints a CTF_INT type. 52c21bc6f3SBojan Novković */ 53c21bc6f3SBojan Novković static inline void 54c21bc6f3SBojan Novković db_pprint_int(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 55c21bc6f3SBojan Novković { 56c21bc6f3SBojan Novković uint32_t data; 57c21bc6f3SBojan Novković size_t type_struct_size; 58c21bc6f3SBojan Novković 59c21bc6f3SBojan Novković type_struct_size = (type->ctt_size == CTF_V3_LSIZE_SENT) ? 60c21bc6f3SBojan Novković sizeof(struct ctf_type_v3) : 61c21bc6f3SBojan Novković sizeof(struct ctf_stype_v3); 62c21bc6f3SBojan Novković 63c21bc6f3SBojan Novković data = db_get_value((db_expr_t)type + type_struct_size, 64c21bc6f3SBojan Novković sizeof(uint32_t), 0); 65c21bc6f3SBojan Novković u_int bits = CTF_INT_BITS(data); 66c21bc6f3SBojan Novković boolean_t sign = !!(CTF_INT_ENCODING(data) & CTF_INT_SIGNED); 67c21bc6f3SBojan Novković 68c21bc6f3SBojan Novković if (db_pager_quit) { 69c21bc6f3SBojan Novković return; 70c21bc6f3SBojan Novković } 71c21bc6f3SBojan Novković if (bits > 64) { 72c21bc6f3SBojan Novković db_printf("Invalid size '%d' found for integer type\n", bits); 73c21bc6f3SBojan Novković return; 74c21bc6f3SBojan Novković } 75c21bc6f3SBojan Novković db_printf("0x%lx", 76d722901fSMark Johnston (long)db_get_value(addr, (bits / 8) ? (bits / 8) : 1, sign)); 77c21bc6f3SBojan Novković } 78c21bc6f3SBojan Novković 79c21bc6f3SBojan Novković /* 80c21bc6f3SBojan Novković * Pretty-prints a struct. Nested structs are pretty-printed up 'depth' nested 81c21bc6f3SBojan Novković * levels. 82c21bc6f3SBojan Novković */ 83c21bc6f3SBojan Novković static inline void 84c21bc6f3SBojan Novković db_pprint_struct(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 85c21bc6f3SBojan Novković { 86c21bc6f3SBojan Novković size_t type_struct_size; 87c21bc6f3SBojan Novković size_t struct_size; 88c21bc6f3SBojan Novković struct ctf_type_v3 *mtype; 89c21bc6f3SBojan Novković const char *mname; 90c21bc6f3SBojan Novković db_addr_t maddr; 91c21bc6f3SBojan Novković u_int vlen; 92c21bc6f3SBojan Novković 93c21bc6f3SBojan Novković type_struct_size = (type->ctt_size == CTF_V3_LSIZE_SENT) ? 94c21bc6f3SBojan Novković sizeof(struct ctf_type_v3) : 95c21bc6f3SBojan Novković sizeof(struct ctf_stype_v3); 96c21bc6f3SBojan Novković struct_size = ((type->ctt_size == CTF_V3_LSIZE_SENT) ? 97c21bc6f3SBojan Novković CTF_TYPE_LSIZE(type) : 98c21bc6f3SBojan Novković type->ctt_size); 99c21bc6f3SBojan Novković vlen = CTF_V3_INFO_VLEN(type->ctt_info); 100c21bc6f3SBojan Novković 101c21bc6f3SBojan Novković if (db_pager_quit) { 102c21bc6f3SBojan Novković return; 103c21bc6f3SBojan Novković } 104c21bc6f3SBojan Novković if (depth > max_depth) { 105c21bc6f3SBojan Novković db_printf("{ ... }"); 106c21bc6f3SBojan Novković return; 107c21bc6f3SBojan Novković } 108c21bc6f3SBojan Novković db_printf("{\n"); 109c21bc6f3SBojan Novković 110c21bc6f3SBojan Novković if (struct_size < CTF_V3_LSTRUCT_THRESH) { 111c21bc6f3SBojan Novković struct ctf_member_v3 *mp, *endp; 112c21bc6f3SBojan Novković 113c21bc6f3SBojan Novković mp = (struct ctf_member_v3 *)((db_addr_t)type + 114c21bc6f3SBojan Novković type_struct_size); 115c21bc6f3SBojan Novković endp = mp + vlen; 116c21bc6f3SBojan Novković for (; mp < endp; mp++) { 117c21bc6f3SBojan Novković if (db_pager_quit) { 118c21bc6f3SBojan Novković return; 119c21bc6f3SBojan Novković } 120c21bc6f3SBojan Novković mtype = db_ctf_typeid_to_type(&sym_data, mp->ctm_type); 12182f5dfc1SBojan Novković maddr = addr + (mp->ctm_offset / NBBY); 122c21bc6f3SBojan Novković mname = db_ctf_stroff_to_str(&sym_data, mp->ctm_name); 123c21bc6f3SBojan Novković db_indent = depth; 124c21bc6f3SBojan Novković if (mname != NULL) { 125c21bc6f3SBojan Novković db_iprintf("%s = ", mname); 126c21bc6f3SBojan Novković } else { 127c21bc6f3SBojan Novković db_iprintf(""); 128c21bc6f3SBojan Novković } 129c21bc6f3SBojan Novković 130c21bc6f3SBojan Novković db_pprint_type(maddr, mtype, depth + 1); 131c21bc6f3SBojan Novković db_printf(",\n"); 132c21bc6f3SBojan Novković } 133c21bc6f3SBojan Novković } else { 134c21bc6f3SBojan Novković struct ctf_lmember_v3 *mp, *endp; 135c21bc6f3SBojan Novković 136c21bc6f3SBojan Novković mp = (struct ctf_lmember_v3 *)((db_addr_t)type + 137c21bc6f3SBojan Novković type_struct_size); 138c21bc6f3SBojan Novković endp = mp + vlen; 139c21bc6f3SBojan Novković for (; mp < endp; mp++) { 140c21bc6f3SBojan Novković if (db_pager_quit) { 141c21bc6f3SBojan Novković return; 142c21bc6f3SBojan Novković } 143c21bc6f3SBojan Novković mtype = db_ctf_typeid_to_type(&sym_data, mp->ctlm_type); 14482f5dfc1SBojan Novković maddr = addr + (CTF_LMEM_OFFSET(mp) / NBBY); 145c21bc6f3SBojan Novković mname = db_ctf_stroff_to_str(&sym_data, mp->ctlm_name); 146c21bc6f3SBojan Novković db_indent = depth; 147c21bc6f3SBojan Novković if (mname != NULL) { 148c21bc6f3SBojan Novković db_iprintf("%s = ", mname); 149c21bc6f3SBojan Novković } else { 150c21bc6f3SBojan Novković db_iprintf(""); 151c21bc6f3SBojan Novković } 152c21bc6f3SBojan Novković 153c21bc6f3SBojan Novković db_pprint_type(maddr, mtype, depth + 1); 154c21bc6f3SBojan Novković db_printf(","); 155c21bc6f3SBojan Novković } 156c21bc6f3SBojan Novković } 157c21bc6f3SBojan Novković db_indent = depth - 1; 158c21bc6f3SBojan Novković db_iprintf("}"); 159c21bc6f3SBojan Novković } 160c21bc6f3SBojan Novković 161c21bc6f3SBojan Novković /* 162c21bc6f3SBojan Novković * Pretty-prints an array. Each array member is printed out in a separate line 163c21bc6f3SBojan Novković * indented with 'depth' spaces. 164c21bc6f3SBojan Novković */ 165c21bc6f3SBojan Novković static inline void 166c21bc6f3SBojan Novković db_pprint_arr(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 167c21bc6f3SBojan Novković { 168c21bc6f3SBojan Novković struct ctf_type_v3 *elem_type; 169c21bc6f3SBojan Novković struct ctf_array_v3 *arr; 170c21bc6f3SBojan Novković db_addr_t elem_addr, end; 171c21bc6f3SBojan Novković size_t type_struct_size; 172c21bc6f3SBojan Novković size_t elem_size; 173c21bc6f3SBojan Novković 174c21bc6f3SBojan Novković type_struct_size = (type->ctt_size == CTF_V3_LSIZE_SENT) ? 175c21bc6f3SBojan Novković sizeof(struct ctf_type_v3) : 176c21bc6f3SBojan Novković sizeof(struct ctf_stype_v3); 177c21bc6f3SBojan Novković arr = (struct ctf_array_v3 *)((db_addr_t)type + type_struct_size); 178c21bc6f3SBojan Novković elem_type = db_ctf_typeid_to_type(&sym_data, arr->cta_contents); 179c21bc6f3SBojan Novković elem_size = ((elem_type->ctt_size == CTF_V3_LSIZE_SENT) ? 180c21bc6f3SBojan Novković CTF_TYPE_LSIZE(elem_type) : 181c21bc6f3SBojan Novković elem_type->ctt_size); 182c21bc6f3SBojan Novković elem_addr = addr; 183c21bc6f3SBojan Novković end = addr + (arr->cta_nelems * elem_size); 184c21bc6f3SBojan Novković 185c21bc6f3SBojan Novković db_indent = depth; 186c21bc6f3SBojan Novković db_printf("[\n"); 187c21bc6f3SBojan Novković /* Loop through and print individual elements. */ 188c21bc6f3SBojan Novković for (; elem_addr < end; elem_addr += elem_size) { 189c21bc6f3SBojan Novković if (db_pager_quit) { 190c21bc6f3SBojan Novković return; 191c21bc6f3SBojan Novković } 192c21bc6f3SBojan Novković db_iprintf(""); 193c21bc6f3SBojan Novković db_pprint_type(elem_addr, elem_type, depth); 194c21bc6f3SBojan Novković if ((elem_addr + elem_size) < end) { 195c21bc6f3SBojan Novković db_printf(",\n"); 196c21bc6f3SBojan Novković } 197c21bc6f3SBojan Novković } 198c21bc6f3SBojan Novković db_printf("\n"); 199c21bc6f3SBojan Novković db_indent = depth - 1; 200c21bc6f3SBojan Novković db_iprintf("]"); 201c21bc6f3SBojan Novković } 202c21bc6f3SBojan Novković 203c21bc6f3SBojan Novković /* 204c21bc6f3SBojan Novković * Pretty-prints an enum value. Also prints out symbolic name of value, if any. 205c21bc6f3SBojan Novković */ 206c21bc6f3SBojan Novković static inline void 207c21bc6f3SBojan Novković db_pprint_enum(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 208c21bc6f3SBojan Novković { 209c21bc6f3SBojan Novković struct ctf_enum *ep, *endp; 210c21bc6f3SBojan Novković size_t type_struct_size; 211c21bc6f3SBojan Novković const char *valname; 212c21bc6f3SBojan Novković db_expr_t val; 213c21bc6f3SBojan Novković u_int vlen; 214c21bc6f3SBojan Novković 215c21bc6f3SBojan Novković type_struct_size = (type->ctt_size == CTF_V3_LSIZE_SENT) ? 216c21bc6f3SBojan Novković sizeof(struct ctf_type_v3) : 217c21bc6f3SBojan Novković sizeof(struct ctf_stype_v3); 218c21bc6f3SBojan Novković vlen = CTF_V3_INFO_VLEN(type->ctt_info); 219c21bc6f3SBojan Novković val = db_get_value(addr, sizeof(int), 0); 220c21bc6f3SBojan Novković 221c21bc6f3SBojan Novković if (db_pager_quit) { 222c21bc6f3SBojan Novković return; 223c21bc6f3SBojan Novković } 224c21bc6f3SBojan Novković ep = (struct ctf_enum *)((db_addr_t)type + type_struct_size); 225c21bc6f3SBojan Novković endp = ep + vlen; 226c21bc6f3SBojan Novković for (; ep < endp; ep++) { 227c21bc6f3SBojan Novković if (val == ep->cte_value) { 228c21bc6f3SBojan Novković valname = db_ctf_stroff_to_str(&sym_data, ep->cte_name); 229aada453dSBojan Novković if (valname != NULL) { 230d627293fSMark Johnston db_printf("%s (0x%lx)", valname, (long)val); 231c21bc6f3SBojan Novković break; 232c21bc6f3SBojan Novković } 233c21bc6f3SBojan Novković } 234c21bc6f3SBojan Novković } 235aada453dSBojan Novković if (ep == endp) 236d627293fSMark Johnston db_printf("0x%lx", (long)val); 237aada453dSBojan Novković } 238c21bc6f3SBojan Novković 239c21bc6f3SBojan Novković /* 240c21bc6f3SBojan Novković * Pretty-prints a pointer. If the 'depth' parameter is less than the 241c21bc6f3SBojan Novković * 'max_depth' global var, the pointer is "dereference", i.e. the contents of 242c21bc6f3SBojan Novković * the memory it points to are also printed. The value of the pointer is printed 243c21bc6f3SBojan Novković * otherwise. 244c21bc6f3SBojan Novković */ 245c21bc6f3SBojan Novković static inline void 246c21bc6f3SBojan Novković db_pprint_ptr(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 247c21bc6f3SBojan Novković { 248c21bc6f3SBojan Novković struct ctf_type_v3 *ref_type; 249c21bc6f3SBojan Novković const char *qual = ""; 250c21bc6f3SBojan Novković const char *name; 251c21bc6f3SBojan Novković db_addr_t val; 252*1cbd613fSBojan Novković uint32_t tid; 253c21bc6f3SBojan Novković u_int kind; 254*1cbd613fSBojan Novković int ptrcnt; 255c21bc6f3SBojan Novković 256*1cbd613fSBojan Novković ptrcnt = 1; 257*1cbd613fSBojan Novković tid = type->ctt_type; 258*1cbd613fSBojan Novković again: 259*1cbd613fSBojan Novković ref_type = db_ctf_typeid_to_type(&sym_data, tid); 260c21bc6f3SBojan Novković kind = CTF_V3_INFO_KIND(ref_type->ctt_info); 261c21bc6f3SBojan Novković switch (kind) { 262c21bc6f3SBojan Novković case CTF_K_STRUCT: 263c21bc6f3SBojan Novković qual = "struct "; 264c21bc6f3SBojan Novković break; 265c21bc6f3SBojan Novković case CTF_K_VOLATILE: 266c21bc6f3SBojan Novković qual = "volatile "; 267*1cbd613fSBojan Novković tid = ref_type->ctt_type; 268*1cbd613fSBojan Novković goto again; 269c21bc6f3SBojan Novković case CTF_K_CONST: 270c21bc6f3SBojan Novković qual = "const "; 271*1cbd613fSBojan Novković tid = ref_type->ctt_type; 272*1cbd613fSBojan Novković goto again; 273*1cbd613fSBojan Novković case CTF_K_RESTRICT: 274*1cbd613fSBojan Novković qual = "restrict "; 275*1cbd613fSBojan Novković tid = ref_type->ctt_type; 276*1cbd613fSBojan Novković goto again; 277*1cbd613fSBojan Novković case CTF_K_POINTER: 278*1cbd613fSBojan Novković ptrcnt++; 279*1cbd613fSBojan Novković tid = ref_type->ctt_type; 280*1cbd613fSBojan Novković goto again; 281*1cbd613fSBojan Novković case CTF_K_TYPEDEF: 282*1cbd613fSBojan Novković tid = ref_type->ctt_type; 283*1cbd613fSBojan Novković goto again; 284c21bc6f3SBojan Novković default: 285c21bc6f3SBojan Novković break; 286c21bc6f3SBojan Novković } 287c21bc6f3SBojan Novković 288*1cbd613fSBojan Novković ptrcnt = min(ptrcnt, strlen(asteriskstr)); 289*1cbd613fSBojan Novković val = (addr != 0) ? db_get_value(addr, sizeof(db_addr_t), false) : 0; 290*1cbd613fSBojan Novković if (depth < max_depth && (val != 0)) { 291c21bc6f3SBojan Novković /* Print contents of memory pointed to by this pointer. */ 292*1cbd613fSBojan Novković db_pprint_type(val, ref_type, depth + 1); 293c21bc6f3SBojan Novković } else { 294c21bc6f3SBojan Novković name = db_ctf_stroff_to_str(&sym_data, ref_type->ctt_name); 295c21bc6f3SBojan Novković db_indent = depth; 296c21bc6f3SBojan Novković if (name != NULL) 297*1cbd613fSBojan Novković db_printf("(%s%s %.*s) 0x%lx", qual, name, ptrcnt, 298*1cbd613fSBojan Novković asteriskstr, (long)val); 299c21bc6f3SBojan Novković else 300*1cbd613fSBojan Novković db_printf("(%s %.*s) 0x%lx", qual, ptrcnt, asteriskstr, 301*1cbd613fSBojan Novković (long)val); 302c21bc6f3SBojan Novković } 303c21bc6f3SBojan Novković } 304c21bc6f3SBojan Novković 305c21bc6f3SBojan Novković /* 306c21bc6f3SBojan Novković * Pretty-print dispatching function. 307c21bc6f3SBojan Novković */ 308c21bc6f3SBojan Novković static void 309c21bc6f3SBojan Novković db_pprint_type(db_addr_t addr, struct ctf_type_v3 *type, u_int depth) 310c21bc6f3SBojan Novković { 311c21bc6f3SBojan Novković 312c21bc6f3SBojan Novković if (db_pager_quit) { 313c21bc6f3SBojan Novković return; 314c21bc6f3SBojan Novković } 315c21bc6f3SBojan Novković if (type == NULL) { 316c21bc6f3SBojan Novković db_printf("unknown type"); 317c21bc6f3SBojan Novković return; 318c21bc6f3SBojan Novković } 319c21bc6f3SBojan Novković 320c21bc6f3SBojan Novković switch (CTF_V3_INFO_KIND(type->ctt_info)) { 321c21bc6f3SBojan Novković case CTF_K_INTEGER: 322c21bc6f3SBojan Novković db_pprint_int(addr, type, depth); 323c21bc6f3SBojan Novković break; 324c21bc6f3SBojan Novković case CTF_K_UNION: 325c21bc6f3SBojan Novković case CTF_K_STRUCT: 326c21bc6f3SBojan Novković db_pprint_struct(addr, type, depth); 327c21bc6f3SBojan Novković break; 328c21bc6f3SBojan Novković case CTF_K_FUNCTION: 329c21bc6f3SBojan Novković case CTF_K_FLOAT: 330c21bc6f3SBojan Novković db_indent = depth; 331d722901fSMark Johnston db_iprintf("0x%lx", (long)addr); 332c21bc6f3SBojan Novković break; 333c21bc6f3SBojan Novković case CTF_K_POINTER: 334c21bc6f3SBojan Novković db_pprint_ptr(addr, type, depth); 335c21bc6f3SBojan Novković break; 336c21bc6f3SBojan Novković case CTF_K_TYPEDEF: 337c21bc6f3SBojan Novković case CTF_K_VOLATILE: 338c21bc6f3SBojan Novković case CTF_K_RESTRICT: 339c21bc6f3SBojan Novković case CTF_K_CONST: { 340c21bc6f3SBojan Novković struct ctf_type_v3 *ref_type = db_ctf_typeid_to_type(&sym_data, 341c21bc6f3SBojan Novković type->ctt_type); 342c21bc6f3SBojan Novković db_pprint_type(addr, ref_type, depth); 343c21bc6f3SBojan Novković break; 344c21bc6f3SBojan Novković } 345c21bc6f3SBojan Novković case CTF_K_ENUM: 346c21bc6f3SBojan Novković db_pprint_enum(addr, type, depth); 347c21bc6f3SBojan Novković break; 348c21bc6f3SBojan Novković case CTF_K_ARRAY: 349c21bc6f3SBojan Novković db_pprint_arr(addr, type, depth); 350c21bc6f3SBojan Novković break; 351c21bc6f3SBojan Novković case CTF_K_UNKNOWN: 352c21bc6f3SBojan Novković case CTF_K_FORWARD: 353c21bc6f3SBojan Novković default: 354c21bc6f3SBojan Novković break; 355c21bc6f3SBojan Novković } 356c21bc6f3SBojan Novković } 357c21bc6f3SBojan Novković 358c21bc6f3SBojan Novković /* 359c21bc6f3SBojan Novković * Symbol pretty-printing command. 360c21bc6f3SBojan Novković * Syntax: pprint [/d depth] <sym_name> 361c21bc6f3SBojan Novković */ 362c21bc6f3SBojan Novković static void 363c21bc6f3SBojan Novković db_pprint_symbol_cmd(const char *name) 364c21bc6f3SBojan Novković { 365c21bc6f3SBojan Novković db_addr_t addr; 366c21bc6f3SBojan Novković int db_indent_old; 367c21bc6f3SBojan Novković const char *type_name = NULL; 368c21bc6f3SBojan Novković struct ctf_type_v3 *type = NULL; 369c21bc6f3SBojan Novković 370c21bc6f3SBojan Novković if (db_pager_quit) { 371c21bc6f3SBojan Novković return; 372c21bc6f3SBojan Novković } 373c21bc6f3SBojan Novković /* Clear symbol and CTF info */ 374c21bc6f3SBojan Novković memset(&sym_data, 0, sizeof(struct db_ctf_sym_data)); 375c21bc6f3SBojan Novković if (db_ctf_find_symbol(name, &sym_data) != 0) { 376c21bc6f3SBojan Novković db_error("Symbol not found\n"); 377c21bc6f3SBojan Novković } 378c21bc6f3SBojan Novković if (ELF_ST_TYPE(sym_data.sym->st_info) != STT_OBJECT) { 379c21bc6f3SBojan Novković db_error("Symbol is not a variable\n"); 380c21bc6f3SBojan Novković } 381c21bc6f3SBojan Novković addr = sym_data.sym->st_value; 382c21bc6f3SBojan Novković type = db_ctf_sym_to_type(&sym_data); 383c21bc6f3SBojan Novković if (type == NULL) { 384c21bc6f3SBojan Novković db_error("Can't find CTF type info\n"); 385c21bc6f3SBojan Novković } 386c21bc6f3SBojan Novković type_name = db_ctf_stroff_to_str(&sym_data, type->ctt_name); 387c21bc6f3SBojan Novković if (type_name != NULL) 388c21bc6f3SBojan Novković db_printf("%s ", type_name); 389c21bc6f3SBojan Novković db_printf("%s = ", name); 390c21bc6f3SBojan Novković 391c21bc6f3SBojan Novković db_indent_old = db_indent; 392c21bc6f3SBojan Novković db_pprint_type(addr, type, 0); 393c21bc6f3SBojan Novković db_indent = db_indent_old; 394c21bc6f3SBojan Novković } 395c21bc6f3SBojan Novković 396c21bc6f3SBojan Novković /* 397c21bc6f3SBojan Novković * Command for pretty-printing arbitrary addresses. 398c21bc6f3SBojan Novković * Syntax: pprint [/d depth] struct <struct_name> <addr> 399c21bc6f3SBojan Novković */ 400c21bc6f3SBojan Novković static void 401c21bc6f3SBojan Novković db_pprint_struct_cmd(db_expr_t addr, const char *struct_name) 402c21bc6f3SBojan Novković { 403c21bc6f3SBojan Novković int db_indent_old; 404c21bc6f3SBojan Novković struct ctf_type_v3 *type = NULL; 405c21bc6f3SBojan Novković 406c21bc6f3SBojan Novković type = db_ctf_find_typename(&sym_data, struct_name); 407c21bc6f3SBojan Novković if (type == NULL) { 408c21bc6f3SBojan Novković db_error("Can't find CTF type info\n"); 409c21bc6f3SBojan Novković return; 410c21bc6f3SBojan Novković } 411c21bc6f3SBojan Novković 412c21bc6f3SBojan Novković db_printf("struct %s ", struct_name); 413c21bc6f3SBojan Novković db_printf("%p = ", (void *)addr); 414c21bc6f3SBojan Novković 415c21bc6f3SBojan Novković db_indent_old = db_indent; 416c21bc6f3SBojan Novković db_pprint_type(addr, type, 0); 417c21bc6f3SBojan Novković db_indent = db_indent_old; 418c21bc6f3SBojan Novković } 419c21bc6f3SBojan Novković 420c21bc6f3SBojan Novković /* 421c21bc6f3SBojan Novković * Pretty print an address or a symbol. 422c21bc6f3SBojan Novković */ 423c21bc6f3SBojan Novković void 424c21bc6f3SBojan Novković db_pprint_cmd(db_expr_t addr, bool have_addr, db_expr_t count, char *modif) 425c21bc6f3SBojan Novković { 426c21bc6f3SBojan Novković int t = 0; 427c21bc6f3SBojan Novković const char *name; 428c21bc6f3SBojan Novković 429c21bc6f3SBojan Novković /* Set default depth */ 430c21bc6f3SBojan Novković max_depth = DB_PPRINT_DEFAULT_DEPTH; 431c21bc6f3SBojan Novković /* Parse print modifiers */ 432c21bc6f3SBojan Novković t = db_read_token(); 433c21bc6f3SBojan Novković if (t == tSLASH) { 434c21bc6f3SBojan Novković t = db_read_token(); 435c21bc6f3SBojan Novković if (t != tIDENT) { 436c21bc6f3SBojan Novković db_error("Invalid flag passed\n"); 437c21bc6f3SBojan Novković } 438c21bc6f3SBojan Novković /* Parse desired depth level */ 439c21bc6f3SBojan Novković if (strcmp(db_tok_string, "d") == 0) { 440c21bc6f3SBojan Novković t = db_read_token(); 441c21bc6f3SBojan Novković if (t != tNUMBER) { 442c21bc6f3SBojan Novković db_error("Invalid depth provided\n"); 443c21bc6f3SBojan Novković } 444c21bc6f3SBojan Novković max_depth = db_tok_number; 445c21bc6f3SBojan Novković } else { 446c21bc6f3SBojan Novković db_error("Invalid flag passed\n"); 447c21bc6f3SBojan Novković } 448c21bc6f3SBojan Novković /* Fetch next token */ 449c21bc6f3SBojan Novković t = db_read_token(); 450c21bc6f3SBojan Novković } 451c21bc6f3SBojan Novković /* Parse subcomannd */ 452c21bc6f3SBojan Novković if (t == tIDENT) { 453c21bc6f3SBojan Novković if (strcmp(db_tok_string, "struct") == 0) { 454c21bc6f3SBojan Novković t = db_read_token(); 455c21bc6f3SBojan Novković 456c21bc6f3SBojan Novković if (t != tIDENT) { 457c21bc6f3SBojan Novković db_error("Invalid struct type name provided\n"); 458c21bc6f3SBojan Novković } 459c21bc6f3SBojan Novković name = db_tok_string; 460c21bc6f3SBojan Novković 461c21bc6f3SBojan Novković if (db_expression(&addr) == 0) { 462c21bc6f3SBojan Novković db_error("Address not provided\n"); 463c21bc6f3SBojan Novković } 464c21bc6f3SBojan Novković db_pprint_struct_cmd(addr, name); 465c21bc6f3SBojan Novković } else { 466c21bc6f3SBojan Novković name = db_tok_string; 467c21bc6f3SBojan Novković db_pprint_symbol_cmd(name); 468c21bc6f3SBojan Novković } 469c21bc6f3SBojan Novković } else { 470c21bc6f3SBojan Novković db_error("Invalid subcommand\n"); 471c21bc6f3SBojan Novković } 472c21bc6f3SBojan Novković db_skip_to_eol(); 473c21bc6f3SBojan Novković } 474