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