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 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/reg.h> 29 #include <sys/privregs.h> 30 #include <sys/stack.h> 31 #include <sys/frame.h> 32 33 #include <mdb/mdb_target_impl.h> 34 #include <mdb/mdb_kreg_impl.h> 35 #include <mdb/mdb_debug.h> 36 #include <mdb/mdb_modapi.h> 37 #include <mdb/mdb_amd64util.h> 38 #include <mdb/mdb_ctf.h> 39 #include <mdb/mdb_err.h> 40 #include <mdb/mdb.h> 41 42 #include <saveargs.h> 43 44 /* 45 * This array is used by the getareg and putareg entry points, and also by our 46 * register variable discipline. 47 */ 48 49 const mdb_tgt_regdesc_t mdb_amd64_kregs[] = { 50 { "savfp", KREG_SAVFP, MDB_TGT_R_EXPORT }, 51 { "savpc", KREG_SAVPC, MDB_TGT_R_EXPORT }, 52 { "rdi", KREG_RDI, MDB_TGT_R_EXPORT }, 53 { "rsi", KREG_RSI, MDB_TGT_R_EXPORT }, 54 { "rdx", KREG_RDX, MDB_TGT_R_EXPORT }, 55 { "rcx", KREG_RCX, MDB_TGT_R_EXPORT }, 56 { "r8", KREG_R8, MDB_TGT_R_EXPORT }, 57 { "r9", KREG_R9, MDB_TGT_R_EXPORT }, 58 { "rax", KREG_RAX, MDB_TGT_R_EXPORT }, 59 { "rbx", KREG_RBX, MDB_TGT_R_EXPORT }, 60 { "rbp", KREG_RBP, MDB_TGT_R_EXPORT }, 61 { "r10", KREG_R10, MDB_TGT_R_EXPORT }, 62 { "r11", KREG_R11, MDB_TGT_R_EXPORT }, 63 { "r12", KREG_R12, MDB_TGT_R_EXPORT }, 64 { "r13", KREG_R13, MDB_TGT_R_EXPORT }, 65 { "r14", KREG_R14, MDB_TGT_R_EXPORT }, 66 { "r15", KREG_R15, MDB_TGT_R_EXPORT }, 67 { "ds", KREG_DS, MDB_TGT_R_EXPORT }, 68 { "es", KREG_ES, MDB_TGT_R_EXPORT }, 69 { "fs", KREG_FS, MDB_TGT_R_EXPORT }, 70 { "gs", KREG_GS, MDB_TGT_R_EXPORT }, 71 { "trapno", KREG_TRAPNO, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, 72 { "err", KREG_ERR, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, 73 { "rip", KREG_RIP, MDB_TGT_R_EXPORT }, 74 { "cs", KREG_CS, MDB_TGT_R_EXPORT }, 75 { "rflags", KREG_RFLAGS, MDB_TGT_R_EXPORT }, 76 { "rsp", KREG_RSP, MDB_TGT_R_EXPORT }, 77 { "ss", KREG_SS, MDB_TGT_R_EXPORT }, 78 { NULL, 0, 0 } 79 }; 80 81 void 82 mdb_amd64_printregs(const mdb_tgt_gregset_t *gregs) 83 { 84 const kreg_t *kregs = &gregs->kregs[0]; 85 kreg_t rflags = kregs[KREG_RFLAGS]; 86 87 #define GETREG2(x) ((uintptr_t)kregs[(x)]), ((uintptr_t)kregs[(x)]) 88 89 mdb_printf("%%rax = 0x%0?p %15A %%r9 = 0x%0?p %A\n", 90 GETREG2(KREG_RAX), GETREG2(KREG_R9)); 91 mdb_printf("%%rbx = 0x%0?p %15A %%r10 = 0x%0?p %A\n", 92 GETREG2(KREG_RBX), GETREG2(KREG_R10)); 93 mdb_printf("%%rcx = 0x%0?p %15A %%r11 = 0x%0?p %A\n", 94 GETREG2(KREG_RCX), GETREG2(KREG_R11)); 95 mdb_printf("%%rdx = 0x%0?p %15A %%r12 = 0x%0?p %A\n", 96 GETREG2(KREG_RDX), GETREG2(KREG_R12)); 97 mdb_printf("%%rsi = 0x%0?p %15A %%r13 = 0x%0?p %A\n", 98 GETREG2(KREG_RSI), GETREG2(KREG_R13)); 99 mdb_printf("%%rdi = 0x%0?p %15A %%r14 = 0x%0?p %A\n", 100 GETREG2(KREG_RDI), GETREG2(KREG_R14)); 101 mdb_printf("%%r8 = 0x%0?p %15A %%r15 = 0x%0?p %A\n\n", 102 GETREG2(KREG_R8), GETREG2(KREG_R15)); 103 104 mdb_printf("%%rip = 0x%0?p %A\n", GETREG2(KREG_RIP)); 105 mdb_printf("%%rbp = 0x%0?p\n", kregs[KREG_RBP]); 106 mdb_printf("%%rsp = 0x%0?p\n", kregs[KREG_RSP]); 107 108 mdb_printf("%%rflags = 0x%08x\n", rflags); 109 110 mdb_printf(" id=%u vip=%u vif=%u ac=%u vm=%u rf=%u nt=%u iopl=0x%x\n", 111 (rflags & KREG_EFLAGS_ID_MASK) >> KREG_EFLAGS_ID_SHIFT, 112 (rflags & KREG_EFLAGS_VIP_MASK) >> KREG_EFLAGS_VIP_SHIFT, 113 (rflags & KREG_EFLAGS_VIF_MASK) >> KREG_EFLAGS_VIF_SHIFT, 114 (rflags & KREG_EFLAGS_AC_MASK) >> KREG_EFLAGS_AC_SHIFT, 115 (rflags & KREG_EFLAGS_VM_MASK) >> KREG_EFLAGS_VM_SHIFT, 116 (rflags & KREG_EFLAGS_RF_MASK) >> KREG_EFLAGS_RF_SHIFT, 117 (rflags & KREG_EFLAGS_NT_MASK) >> KREG_EFLAGS_NT_SHIFT, 118 (rflags & KREG_EFLAGS_IOPL_MASK) >> KREG_EFLAGS_IOPL_SHIFT); 119 120 mdb_printf(" status=<%s,%s,%s,%s,%s,%s,%s,%s,%s>\n\n", 121 (rflags & KREG_EFLAGS_OF_MASK) ? "OF" : "of", 122 (rflags & KREG_EFLAGS_DF_MASK) ? "DF" : "df", 123 (rflags & KREG_EFLAGS_IF_MASK) ? "IF" : "if", 124 (rflags & KREG_EFLAGS_TF_MASK) ? "TF" : "tf", 125 (rflags & KREG_EFLAGS_SF_MASK) ? "SF" : "sf", 126 (rflags & KREG_EFLAGS_ZF_MASK) ? "ZF" : "zf", 127 (rflags & KREG_EFLAGS_AF_MASK) ? "AF" : "af", 128 (rflags & KREG_EFLAGS_PF_MASK) ? "PF" : "pf", 129 (rflags & KREG_EFLAGS_CF_MASK) ? "CF" : "cf"); 130 131 mdb_printf("%24s%%cs = 0x%04x\t%%ds = 0x%04x\t%%es = 0x%04x\n", 132 " ", kregs[KREG_CS], kregs[KREG_DS], kregs[KREG_ES]); 133 134 mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n", 135 kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff), 136 (kregs[KREG_GS] & 0xffff)); 137 mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]); 138 } 139 140 /* 141 * We expect all proper Solaris core files to have STACK_ALIGN-aligned stacks. 142 * Hence the name. However, if the core file resulted from a 143 * hypervisor-initiated panic, the hypervisor's frames may only be 64-bit 144 * aligned instead of 128. 145 */ 146 static int 147 fp_is_aligned(uintptr_t fp, int xpv_panic) 148 { 149 if (!xpv_panic && (fp & (STACK_ALIGN -1))) 150 return (0); 151 if ((fp & sizeof (uintptr_t) - 1)) 152 return (0); 153 return (1); 154 } 155 156 int 157 mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, 158 mdb_tgt_stack_f *func, void *arg) 159 { 160 mdb_tgt_gregset_t gregs; 161 kreg_t *kregs = &gregs.kregs[0]; 162 int got_pc = (gsp->kregs[KREG_RIP] != 0); 163 uint_t argc, reg_argc; 164 long fr_argv[32]; 165 int start_index; /* index to save_instr where to start comparison */ 166 int i; 167 168 struct { 169 uintptr_t fr_savfp; 170 uintptr_t fr_savpc; 171 } fr; 172 173 uintptr_t fp = gsp->kregs[KREG_RBP]; 174 uintptr_t pc = gsp->kregs[KREG_RIP]; 175 uintptr_t lastfp, curpc; 176 177 ssize_t size; 178 ssize_t insnsize; 179 uint8_t ins[SAVEARGS_INSN_SEQ_LEN]; 180 181 GElf_Sym s; 182 mdb_syminfo_t sip; 183 mdb_ctf_funcinfo_t mfp; 184 int xpv_panic = 0; 185 #ifndef _KMDB 186 int xp; 187 188 if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0)) 189 xpv_panic = 1; 190 #endif 191 192 bcopy(gsp, &gregs, sizeof (gregs)); 193 194 while (fp != 0) { 195 int args_style = 0; 196 197 curpc = pc; 198 199 if (!fp_is_aligned(fp, xpv_panic)) 200 return (set_errno(EMDB_STKALIGN)); 201 202 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) 203 return (-1); /* errno has been set for us */ 204 205 if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, 206 NULL, 0, &s, &sip) == 0) && 207 (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) { 208 int return_type = mdb_ctf_type_kind(mfp.mtf_return); 209 mdb_ctf_id_t args_types[5]; 210 211 argc = mfp.mtf_argc; 212 213 /* 214 * If the function returns a structure or union 215 * greater than 16 bytes in size %rdi contains the 216 * address in which to store the return value rather 217 * than for an argument. 218 */ 219 if ((return_type == CTF_K_STRUCT || 220 return_type == CTF_K_UNION) && 221 mdb_ctf_type_size(mfp.mtf_return) > 16) 222 start_index = 1; 223 else 224 start_index = 0; 225 226 /* 227 * If any of the first 5 arguments are a structure 228 * less than 16 bytes in size, it will be passed 229 * spread across two argument registers, and we will 230 * not cope. 231 */ 232 if (mdb_ctf_func_args(&mfp, 5, args_types) == CTF_ERR) 233 argc = 0; 234 235 for (i = 0; i < MIN(5, argc); i++) { 236 int t = mdb_ctf_type_kind(args_types[i]); 237 238 if (((t == CTF_K_STRUCT) || 239 (t == CTF_K_UNION)) && 240 mdb_ctf_type_size(args_types[i]) <= 16) { 241 argc = 0; 242 break; 243 } 244 } 245 } else { 246 argc = 0; 247 } 248 249 /* 250 * The number of instructions to search for argument saving is 251 * limited such that only instructions prior to %pc are 252 * considered such that we never read arguments from a 253 * function where the saving code has not in fact yet 254 * executed. 255 */ 256 insnsize = MIN(MIN(s.st_size, SAVEARGS_INSN_SEQ_LEN), 257 pc - s.st_value); 258 259 if (mdb_tgt_vread(t, ins, insnsize, s.st_value) != insnsize) 260 argc = 0; 261 262 if ((argc != 0) && 263 ((args_style = saveargs_has_args(ins, insnsize, argc, 264 start_index)) != SAVEARGS_NO_ARGS)) { 265 /* Up to 6 arguments are passed via registers */ 266 reg_argc = MIN((6 - start_index), mfp.mtf_argc); 267 size = reg_argc * sizeof (long); 268 269 /* 270 * If Studio pushed a structure return address as an 271 * argument, we need to read one more argument than 272 * actually exists (the addr) to make everything line 273 * up. 274 */ 275 if (args_style == SAVEARGS_STRUCT_ARGS) 276 size += sizeof (long); 277 278 if (mdb_tgt_vread(t, fr_argv, size, (fp - size)) 279 != size) 280 return (-1); /* errno has been set for us */ 281 282 /* 283 * Arrange the arguments in the right order for 284 * printing. 285 */ 286 for (i = 0; i < (reg_argc / 2); i++) { 287 long t = fr_argv[i]; 288 289 fr_argv[i] = fr_argv[reg_argc - i - 1]; 290 fr_argv[reg_argc - i - 1] = t; 291 } 292 293 if (argc > reg_argc) { 294 size = MIN((argc - reg_argc) * sizeof (long), 295 sizeof (fr_argv) - 296 (reg_argc * sizeof (long))); 297 298 if (mdb_tgt_vread(t, &fr_argv[reg_argc], size, 299 fp + sizeof (fr)) != size) 300 return (-1); /* errno has been set */ 301 } 302 } else { 303 argc = 0; 304 } 305 306 if (got_pc && func(arg, pc, argc, fr_argv, &gregs) != 0) 307 break; 308 309 kregs[KREG_RSP] = kregs[KREG_RBP]; 310 311 lastfp = fp; 312 fp = fr.fr_savfp; 313 /* 314 * The Xen hypervisor marks a stack frame as belonging to 315 * an exception by inverting the bits of the pointer to 316 * that frame. We attempt to identify these frames by 317 * inverting the pointer and seeing if it is within 0xfff 318 * bytes of the last frame. 319 */ 320 if (xpv_panic) 321 if ((fp != 0) && (fp < lastfp) && 322 ((lastfp ^ ~fp) < 0xfff)) 323 fp = ~fp; 324 325 kregs[KREG_RBP] = fp; 326 kregs[KREG_RIP] = pc = fr.fr_savpc; 327 328 if (curpc == pc) 329 break; 330 331 got_pc = (pc != 0); 332 } 333 334 return (0); 335 } 336 337 /* 338 * Determine the return address for the current frame. Typically this is the 339 * fr_savpc value from the current frame, but we also perform some special 340 * handling to see if we are stopped on one of the first two instructions of 341 * a typical function prologue, in which case %rbp will not be set up yet. 342 */ 343 int 344 mdb_amd64_step_out(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, kreg_t fp, kreg_t sp, 345 mdb_instr_t curinstr) 346 { 347 struct frame fr; 348 GElf_Sym s; 349 char buf[1]; 350 351 enum { 352 M_PUSHQ_RBP = 0x55, /* pushq %rbp */ 353 M_REX_W = 0x48, /* REX prefix with only W set */ 354 M_MOVL_RBP = 0x8b /* movq %rsp, %rbp with prefix */ 355 }; 356 357 if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, 358 buf, 0, &s, NULL) == 0) { 359 if (pc == s.st_value && curinstr == M_PUSHQ_RBP) 360 fp = sp - 8; 361 else if (pc == s.st_value + 1 && curinstr == M_REX_W) { 362 if (mdb_tgt_vread(t, &curinstr, sizeof (curinstr), 363 pc + 1) == sizeof (curinstr) && curinstr == 364 M_MOVL_RBP) 365 fp = sp; 366 } 367 } 368 369 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) == sizeof (fr)) { 370 *p = fr.fr_savpc; 371 return (0); 372 } 373 374 return (-1); /* errno is set for us */ 375 } 376 377 /*ARGSUSED*/ 378 int 379 mdb_amd64_next(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, mdb_instr_t curinstr) 380 { 381 mdb_tgt_addr_t npc; 382 mdb_tgt_addr_t callpc; 383 384 enum { 385 M_CALL_REL = 0xe8, /* call near with relative displacement */ 386 M_CALL_REG = 0xff, /* call near indirect or call far register */ 387 388 M_REX_LO = 0x40, 389 M_REX_HI = 0x4f 390 }; 391 392 /* 393 * If the opcode is a near call with relative displacement, assume the 394 * displacement is a rel32 from the next instruction. 395 */ 396 if (curinstr == M_CALL_REL) { 397 *p = pc + sizeof (mdb_instr_t) + sizeof (uint32_t); 398 return (0); 399 } 400 401 /* Skip the rex prefix, if any */ 402 callpc = pc; 403 while (curinstr >= M_REX_LO && curinstr <= M_REX_HI) { 404 if (mdb_tgt_vread(t, &curinstr, sizeof (curinstr), ++callpc) != 405 sizeof (curinstr)) 406 return (-1); /* errno is set for us */ 407 } 408 409 if (curinstr != M_CALL_REG) { 410 /* It's not a call */ 411 return (set_errno(EAGAIN)); 412 } 413 414 if ((npc = mdb_dis_nextins(mdb.m_disasm, t, MDB_TGT_AS_VIRT, pc)) == pc) 415 return (-1); /* errno is set for us */ 416 417 *p = npc; 418 return (0); 419 } 420 421 /*ARGSUSED*/ 422 int 423 mdb_amd64_kvm_frame(void *arglim, uintptr_t pc, uint_t argc, const long *argv, 424 const mdb_tgt_gregset_t *gregs) 425 { 426 argc = MIN(argc, (uintptr_t)arglim); 427 mdb_printf("%a(", pc); 428 429 if (argc != 0) { 430 mdb_printf("%lr", *argv++); 431 for (argc--; argc != 0; argc--) 432 mdb_printf(", %lr", *argv++); 433 } 434 435 mdb_printf(")\n"); 436 return (0); 437 } 438 439 int 440 mdb_amd64_kvm_framev(void *arglim, uintptr_t pc, uint_t argc, const long *argv, 441 const mdb_tgt_gregset_t *gregs) 442 { 443 /* 444 * Historically adb limited stack trace argument display to a fixed- 445 * size number of arguments since no symbolic debugging info existed. 446 * On amd64 we can detect the true number of saved arguments so only 447 * respect an arglim of zero; otherwise display the entire argv[]. 448 */ 449 if (arglim == 0) 450 argc = 0; 451 452 mdb_printf("%0?lr %a(", gregs->kregs[KREG_RBP], pc); 453 454 if (argc != 0) { 455 mdb_printf("%lr", *argv++); 456 for (argc--; argc != 0; argc--) 457 mdb_printf(", %lr", *argv++); 458 } 459 460 mdb_printf(")\n"); 461 return (0); 462 } 463