1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _MDB_MODAPI_H 27 #define _MDB_MODAPI_H 28 29 /* 30 * MDB Module API 31 * 32 * The debugger provides a set of interfaces for use in writing loadable 33 * debugger modules. Modules that call functions not listed in this header 34 * file may not be compatible with future versions of the debugger. 35 */ 36 37 #include <sys/types.h> 38 #include <gelf.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* 45 * Make sure that NULL, TRUE, FALSE, MIN, and MAX have the usual definitions 46 * so module writers can depend on these macros and defines. 47 */ 48 #ifndef NULL 49 #if defined(_LP64) && !defined(__cplusplus) 50 #define NULL 0L 51 #else 52 #define NULL 0 53 #endif 54 #endif 55 56 #ifndef TRUE 57 #define TRUE 1 58 #endif 59 60 #ifndef FALSE 61 #define FALSE 0 62 #endif 63 64 #ifndef MIN 65 #define MIN(x, y) ((x) < (y) ? (x) : (y)) 66 #endif 67 68 #ifndef MAX 69 #define MAX(x, y) ((x) > (y) ? (x) : (y)) 70 #endif 71 72 #define MDB_API_VERSION 3 /* Current API version number */ 73 74 /* 75 * Debugger command function flags: 76 */ 77 #define DCMD_ADDRSPEC 0x01 /* Dcmd invoked with explicit address */ 78 #define DCMD_LOOP 0x02 /* Dcmd invoked in loop with ,cnt syntax */ 79 #define DCMD_LOOPFIRST 0x04 /* Dcmd invoked as first iteration of LOOP */ 80 #define DCMD_PIPE 0x08 /* Dcmd invoked with input from pipe */ 81 #define DCMD_PIPE_OUT 0x10 /* Dcmd invoked with output set to pipe */ 82 83 #define DCMD_HDRSPEC(fl) (((fl) & DCMD_LOOPFIRST) || !((fl) & DCMD_LOOP)) 84 85 /* 86 * Debugger command function return values: 87 */ 88 #define DCMD_OK 0 /* Dcmd completed successfully */ 89 #define DCMD_ERR 1 /* Dcmd failed due to an error */ 90 #define DCMD_USAGE 2 /* Dcmd usage error; abort and print usage */ 91 #define DCMD_NEXT 3 /* Invoke next dcmd in precedence list */ 92 #define DCMD_ABORT 4 /* Dcmd failed; abort current loop or pipe */ 93 94 #define OFFSETOF(s, m) (size_t)(&(((s *)0)->m)) 95 96 extern int mdb_prop_postmortem; /* Are we looking at a static dump? */ 97 extern int mdb_prop_kernel; /* Are we looking at a kernel? */ 98 99 typedef enum { 100 MDB_TYPE_STRING, /* a_un.a_str is valid */ 101 MDB_TYPE_IMMEDIATE, /* a_un.a_val is valid */ 102 MDB_TYPE_CHAR /* a_un.a_char is valid */ 103 } mdb_type_t; 104 105 typedef struct mdb_arg { 106 mdb_type_t a_type; 107 union { 108 const char *a_str; 109 uintmax_t a_val; 110 char a_char; 111 } a_un; 112 } mdb_arg_t; 113 114 typedef int mdb_dcmd_f(uintptr_t, uint_t, int, const mdb_arg_t *); 115 116 typedef struct mdb_dcmd { 117 const char *dc_name; /* Command name */ 118 const char *dc_usage; /* Usage message (optional) */ 119 const char *dc_descr; /* Description */ 120 mdb_dcmd_f *dc_funcp; /* Command function */ 121 void (*dc_help)(void); /* Command help function (or NULL) */ 122 } mdb_dcmd_t; 123 124 #define WALK_ERR -1 /* Walk fatal error (terminate walk) */ 125 #define WALK_NEXT 0 /* Walk should continue to next step */ 126 #define WALK_DONE 1 /* Walk is complete (no errors) */ 127 128 typedef int (*mdb_walk_cb_t)(uintptr_t, const void *, void *); 129 130 typedef struct mdb_walk_state { 131 mdb_walk_cb_t walk_callback; /* Callback to issue */ 132 void *walk_cbdata; /* Callback private data */ 133 uintptr_t walk_addr; /* Current address */ 134 void *walk_data; /* Walk private data */ 135 void *walk_arg; /* Walk private argument */ 136 const void *walk_layer; /* Data from underlying layer */ 137 } mdb_walk_state_t; 138 139 typedef struct mdb_walker { 140 const char *walk_name; /* Walk type name */ 141 const char *walk_descr; /* Walk description */ 142 int (*walk_init)(mdb_walk_state_t *); /* Walk constructor */ 143 int (*walk_step)(mdb_walk_state_t *); /* Walk iterator */ 144 void (*walk_fini)(mdb_walk_state_t *); /* Walk destructor */ 145 void *walk_init_arg; /* Walk constructor argument */ 146 } mdb_walker_t; 147 148 typedef struct mdb_modinfo { 149 ushort_t mi_dvers; /* Debugger version number */ 150 const mdb_dcmd_t *mi_dcmds; /* NULL-terminated list of dcmds */ 151 const mdb_walker_t *mi_walkers; /* NULL-terminated list of walks */ 152 } mdb_modinfo_t; 153 154 typedef struct mdb_bitmask { 155 const char *bm_name; /* String name to print */ 156 u_longlong_t bm_mask; /* Mask for bits */ 157 u_longlong_t bm_bits; /* Result required for value & mask */ 158 } mdb_bitmask_t; 159 160 typedef struct mdb_pipe { 161 uintptr_t *pipe_data; /* Array of pipe values */ 162 size_t pipe_len; /* Array length */ 163 } mdb_pipe_t; 164 165 typedef struct mdb_object { 166 const char *obj_name; /* name of object */ 167 const char *obj_fullname; /* full name of object */ 168 uintptr_t obj_base; /* base address of object */ 169 uintptr_t obj_size; /* in memory size of object in bytes */ 170 } mdb_object_t; 171 172 extern int mdb_pwalk(const char *, mdb_walk_cb_t, void *, uintptr_t); 173 extern int mdb_walk(const char *, mdb_walk_cb_t, void *); 174 175 extern int mdb_pwalk_dcmd(const char *, const char *, 176 int, const mdb_arg_t *, uintptr_t); 177 178 extern int mdb_walk_dcmd(const char *, const char *, int, const mdb_arg_t *); 179 180 extern int mdb_layered_walk(const char *, mdb_walk_state_t *); 181 182 extern int mdb_call_dcmd(const char *, uintptr_t, 183 uint_t, int, const mdb_arg_t *); 184 185 extern int mdb_add_walker(const mdb_walker_t *); 186 extern int mdb_remove_walker(const char *); 187 188 extern ssize_t mdb_vread(void *, size_t, uintptr_t); 189 extern ssize_t mdb_vwrite(const void *, size_t, uintptr_t); 190 191 extern ssize_t mdb_fread(void *, size_t, uintptr_t); 192 extern ssize_t mdb_fwrite(const void *, size_t, uintptr_t); 193 194 extern ssize_t mdb_pread(void *, size_t, uint64_t); 195 extern ssize_t mdb_pwrite(const void *, size_t, uint64_t); 196 197 extern ssize_t mdb_readstr(char *, size_t, uintptr_t); 198 extern ssize_t mdb_writestr(const char *, uintptr_t); 199 200 extern ssize_t mdb_readsym(void *, size_t, const char *); 201 extern ssize_t mdb_writesym(const void *, size_t, const char *); 202 203 extern ssize_t mdb_readvar(void *, const char *); 204 extern ssize_t mdb_writevar(const void *, const char *); 205 206 #define MDB_SYM_NAMLEN 1024 /* Recommended max name len */ 207 208 #define MDB_SYM_FUZZY 0 /* Match closest address */ 209 #define MDB_SYM_EXACT 1 /* Match exact address only */ 210 211 #define MDB_OBJ_EXEC ((const char *)0L) /* Primary executable file */ 212 #define MDB_OBJ_RTLD ((const char *)1L) /* Run-time link-editor */ 213 #define MDB_OBJ_EVERY ((const char *)-1L) /* All known symbols */ 214 215 extern int mdb_lookup_by_name(const char *, GElf_Sym *); 216 extern int mdb_lookup_by_obj(const char *, const char *, GElf_Sym *); 217 extern int mdb_lookup_by_addr(uintptr_t, uint_t, char *, size_t, GElf_Sym *); 218 219 typedef uintptr_t mdb_tid_t; 220 typedef uint64_t mdb_reg_t; 221 222 extern int mdb_getareg(mdb_tid_t, const char *, mdb_reg_t *); 223 224 #define MDB_OPT_SETBITS 1 /* Set specified flag bits */ 225 #define MDB_OPT_CLRBITS 2 /* Clear specified flag bits */ 226 #define MDB_OPT_STR 3 /* const char * argument */ 227 #define MDB_OPT_UINTPTR 4 /* uintptr_t argument */ 228 #define MDB_OPT_UINT64 5 /* uint64_t argument */ 229 #define MDB_OPT_UINTPTR_SET 6 /* boolean_t+uintptr_t args */ 230 231 extern int mdb_getopts(int, const mdb_arg_t *, ...); 232 233 extern u_longlong_t mdb_strtoull(const char *); 234 235 #define UM_NOSLEEP 0x0 /* Do not call failure handler; may fail */ 236 #define UM_SLEEP 0x1 /* Can block for memory; will always succeed */ 237 #define UM_GC 0x2 /* Garbage-collect this block automatically */ 238 239 extern void *mdb_alloc(size_t, uint_t); 240 extern void *mdb_zalloc(size_t, uint_t); 241 extern void mdb_free(void *, size_t); 242 243 extern size_t mdb_snprintf(char *, size_t, const char *, ...); 244 extern void mdb_printf(const char *, ...); 245 extern void mdb_warn(const char *, ...); 246 extern void mdb_flush(void); 247 248 extern int mdb_ffs(uintmax_t); 249 250 extern void mdb_nhconvert(void *, const void *, size_t); 251 252 #define MDB_DUMP_RELATIVE 0x0001 /* Start numbering at 0 */ 253 #define MDB_DUMP_ALIGN 0x0002 /* Enforce paragraph alignment */ 254 #define MDB_DUMP_PEDANT 0x0004 /* Full-width addresses */ 255 #define MDB_DUMP_ASCII 0x0008 /* Display ASCII values */ 256 #define MDB_DUMP_HEADER 0x0010 /* Display a header */ 257 #define MDB_DUMP_TRIM 0x0020 /* Trim at boundaries */ 258 #define MDB_DUMP_SQUISH 0x0040 /* Eliminate redundant lines */ 259 #define MDB_DUMP_NEWDOT 0x0080 /* Update dot when done */ 260 #define MDB_DUMP_ENDIAN 0x0100 /* Adjust for endianness */ 261 #define MDB_DUMP_WIDTH(x) ((((x) - 1) & 0xf) << 16) /* paragraphs/line */ 262 #define MDB_DUMP_GROUP(x) ((((x) - 1) & 0xff) << 20) /* bytes/group */ 263 264 typedef ssize_t (*mdb_dumpptr_cb_t)(void *, size_t, uintptr_t, void *); 265 typedef ssize_t (*mdb_dump64_cb_t)(void *, size_t, uint64_t, void *); 266 267 extern int mdb_dumpptr(uintptr_t, size_t, uint_t, mdb_dumpptr_cb_t, void *); 268 extern int mdb_dump64(uint64_t, uint64_t, uint_t, mdb_dump64_cb_t, void *); 269 270 extern const char *mdb_one_bit(int, int, int); 271 extern const char *mdb_inval_bits(int, int, int); 272 273 extern ulong_t mdb_inc_indent(ulong_t); 274 extern ulong_t mdb_dec_indent(ulong_t); 275 276 extern int mdb_eval(const char *); 277 extern void mdb_set_dot(uintmax_t); 278 extern uintmax_t mdb_get_dot(void); 279 280 extern void mdb_get_pipe(mdb_pipe_t *); 281 extern void mdb_set_pipe(const mdb_pipe_t *); 282 283 extern ssize_t mdb_get_xdata(const char *, void *, size_t); 284 285 typedef int (*mdb_object_cb_t)(mdb_object_t *, void *); 286 extern int mdb_object_iter(mdb_object_cb_t, void *); 287 288 #define MDB_STATE_IDLE 0 /* Target is idle (not running yet) */ 289 #define MDB_STATE_RUNNING 1 /* Target is currently executing */ 290 #define MDB_STATE_STOPPED 2 /* Target is stopped */ 291 #define MDB_STATE_UNDEAD 3 /* Target is undead (zombie) */ 292 #define MDB_STATE_DEAD 4 /* Target is dead (core dump) */ 293 #define MDB_STATE_LOST 5 /* Target lost by debugger */ 294 295 extern int mdb_get_state(void); 296 297 #define MDB_CALLBACK_STCHG 1 298 #define MDB_CALLBACK_PROMPT 2 299 300 typedef void (*mdb_callback_f)(void *); 301 302 extern void *mdb_callback_add(int, mdb_callback_f, void *); 303 extern void mdb_callback_remove(void *); 304 305 extern size_t strlcat(char *, const char *, size_t); 306 extern char *strcat(char *, const char *); 307 extern char *strcpy(char *, const char *); 308 extern char *strncpy(char *, const char *, size_t); 309 310 /* Need to be consistent with <string.h> C++ definitions */ 311 #if __cplusplus >= 199711L 312 extern const char *strchr(const char *, int); 313 #ifndef _STRCHR_INLINE 314 #define _STRCHR_INLINE 315 extern "C++" { 316 inline char *strchr(char *__s, int __c) { 317 return (char *)strchr((const char *)__s, __c); 318 } 319 } 320 #endif /* _STRCHR_INLINE */ 321 extern const char *strrchr(const char *, int); 322 #ifndef _STRRCHR_INLINE 323 #define _STRRCHR_INLINE 324 extern "C++" { 325 inline char *strrchr(char *__s, int __c) { 326 return (char *)strrchr((const char *)__s, __c); 327 } 328 } 329 #endif /* _STRRCHR_INLINE */ 330 extern const char *strstr(const char *, const char *); 331 #ifndef _STRSTR_INLINE 332 #define _STRSTR_INLINE 333 extern "C++" { 334 inline char *strstr(char *__s1, const char *__s2) { 335 return (char *)strstr((const char *)__s1, __s2); 336 } 337 } 338 #endif /* _STRSTR_INLINE */ 339 #else 340 extern char *strchr(const char *, int); 341 extern char *strrchr(const char *, int); 342 extern char *strstr(const char *, const char *); 343 #endif /* __cplusplus >= 199711L */ 344 345 extern int strcmp(const char *, const char *); 346 extern int strncmp(const char *, const char *, size_t); 347 extern int strcasecmp(const char *, const char *); 348 extern int strncasecmp(const char *, const char *, size_t); 349 350 extern size_t strlen(const char *); 351 352 extern int bcmp(const void *, const void *, size_t); 353 extern void bcopy(const void *, void *, size_t); 354 extern void bzero(void *, size_t); 355 356 extern void *memcpy(void *, const void *, size_t); 357 extern void *memmove(void *, const void *, size_t); 358 extern int memcmp(const void *, const void *, size_t); 359 /* Need to be consistent with <string.h> C++ definitions */ 360 #if __cplusplus >= 199711L 361 extern const void *memchr(const void *, int, size_t); 362 #ifndef _MEMCHR_INLINE 363 #define _MEMCHR_INLINE 364 extern "C++" { 365 inline void *memchr(void * __s, int __c, size_t __n) { 366 return (void *)memchr((const void *)__s, __c, __n); 367 } 368 } 369 #endif /* _MEMCHR_INLINE */ 370 #else 371 extern void *memchr(const void *, int, size_t); 372 #endif /* __cplusplus >= 199711L */ 373 extern void *memset(void *, int, size_t); 374 extern void *memccpy(void *, const void *, int, size_t); 375 376 extern void *bsearch(const void *, const void *, size_t, size_t, 377 int (*)(const void *, const void *)); 378 379 extern void qsort(void *, size_t, size_t, 380 int (*)(const void *, const void *)); 381 382 #ifdef __cplusplus 383 } 384 #endif 385 386 #endif /* _MDB_MODAPI_H */ 387