📄 xenitp.c
字号:
}void print_rr (vcpu_guest_context_t *ctx){ struct vcpu_guest_context_regs *regs = &ctx->regs; int i; printf (" rr: rid ps ve\n"); for (i = 0; i < 8; i++) print_a_rr (i, regs->rr[i]);}void print_db (vcpu_guest_context_t *ctx){ struct vcpu_guest_context_regs *regs = &ctx->regs; int i; for (i = 0; i < 7; i += 2) printf (" ibr[%d]: %016lx ibr[%d]: %016lx\n", i, regs->ibr[i], i + 1, regs->ibr[i + 1]); printf ("\n"); for (i = 0; i < 7; i += 2) printf (" dbr[%d]: %016lx dbr[%d]: %016lx\n", i, regs->dbr[i], i + 1, regs->dbr[i + 1]);}struct bit_descr { const char *name; unsigned char sz;};const struct bit_descr psr_bits[] = { {"", 1 }, {"be", 1 }, {"up", 1 }, {"ac", 1 }, {"mfl", 1 }, {"mfh", 1 }, {"", 7 }, {"ic", 1 }, {"i", 1 }, {"pk", 1 }, {"", 1 }, {"dt", 1 }, {"dfl", 1 }, {"dfh", 1 }, {"sp", 1 }, {"pp", 1 }, {"di", 1 }, {"si", 1 }, {"db", 1 }, {"lp", 1 }, {"tb", 1 }, {"rt", 1 }, {"", 4 }, {"cpl", 2 }, {"is", 1 }, {"mc", 1 }, {"it", 1 }, {"id", 1 }, {"da", 1 }, {"dd", 1 }, {"ss", 1 }, {"ri", 2 }, {"ed", 1 }, {"bn", 1 }, {"ia", 1 }, {"vm", 1 }, {NULL, 0 } };void print_bits (const struct bit_descr *desc, unsigned long val){ const struct bit_descr *d; unsigned int off; /* Reverse order. */ for (d = desc, off = 0; d->name; d++) off += d->sz; d--; while (1) { off -= d->sz; if (*d->name) { if (d->sz != 1 || ((val >> off) & 1)) printf (" %s", d->name); if (d->sz != 1) printf ("=%lx", (val >> off) & ((1 << d->sz) - 1)); } if (d == desc) break; d--; }} void print_tr (vcpu_guest_context_t *ctx){ struct vcpu_tr_regs *tr = &ctx->regs.tr; int i; printf ("\n itr: P rid va pa ps ed pl " "ar a d ma key\n"); for (i = 0; i < sizeof (tr->itrs) / sizeof (tr->itrs[0]); i++) print_a_tr (i, &tr->itrs[i]); printf ("\n dtr: P rid va pa ps ed pl " "ar a d ma key\n"); for (i = 0; i < sizeof (tr->dtrs) / sizeof (tr->dtrs[0]); i++) print_a_tr (i, &tr->dtrs[i]);}int lock_pages (void *addr, size_t len);void unlock_pages (void *addr, size_t len);int do_xen_hypercall (int xc_handle, privcmd_hypercall_t *hypercall);#ifdef HAVE_DEBUG_OPstatic int do_ia64_debug_op (int xc_handle, unsigned long cmd, unsigned long domain, xen_ia64_debug_op_t *op){ int ret = -1; privcmd_hypercall_t hypercall; hypercall.op = __HYPERVISOR_ia64_debug_op; hypercall.arg[0] = cmd; hypercall.arg[1] = domain; hypercall.arg[2] = (unsigned long)op; if (lock_pages (op, sizeof (*op)) != 0) { perror ("Could not lock memory for Xen hypercall"); goto out1; } ret = do_xen_hypercall (xc_handle, &hypercall); if (ret < 0) { if (errno == EACCES) fprintf (stderr,"domctl operation failed -- need to " "rebuild the user-space tool set?\n"); } unlock_pages (op, sizeof (*op));out1: return ret;}#endifstatic volatile int ctrl_c_hit;void ctrl_c_handler (int sig){ ctrl_c_hit = 1;}int wait_domain (int vcpu, vcpu_guest_context_t *ctx){ struct timespec ts; xc_dominfo_t dominfo; int ret; int cnt = 0; ts.tv_sec = 0; ts.tv_nsec = 10*1000*1000; ret = xc_domain_unpause (xc_handle, domid); if (ret < 0) perror ("xc_domain_unpause"); ctrl_c_hit = 0; while (1) { ret = xc_domain_getinfo (xc_handle, domid, 1, &dominfo); if (ret < 0) perror ("xc_domain_getinfo"); if (dominfo.paused) break; if (ctrl_c_hit) { fflush (stdout); /* Force pause. */ ret = xc_domain_pause (xc_handle, domid); if (ret < 0) perror ("xc_domain_pause"); break; } printf ("%c\b", "/-\\|"[(cnt++) % 4]); fflush (stdout); nanosleep (&ts, NULL); } return xc_vcpu_getcontext (xc_handle, domid, vcpu, ctx);}int virt_to_phys (int is_inst, unsigned long vaddr, unsigned long *paddr){ struct vcpu_tr_regs *trs = &cur_ctx->regs.tr; struct ia64_tr_entry *tr; int i; int num; /* Search in tr. */ if (is_inst) { tr = trs->itrs; num = sizeof (trs->itrs) / sizeof (trs->itrs[0]); } else { tr = trs->dtrs; num = sizeof (trs->dtrs) / sizeof (trs->dtrs[0]); } for (i = 0; i < num; i++, tr++) { int ps_val = (tr->itir >> ITIR_PS_SHIFT) & ITIR_PS_MASK; unsigned long ps_mask = (-1L) << ps_val; if ((tr->vadr & ps_mask) == (vaddr & ps_mask)) { *paddr = ((tr->pte & (PTE_PPN_MASK << PTE_PPN_SHIFT)) & ps_mask) | (vaddr & ~ps_mask); return 0; } } return -1;}unsigned long *get_reg_addr (const char *name){ if (strcmp (name, "ip") == 0) return &cur_ctx->regs.ip; else if (strcmp (name, "psr") == 0) return &cur_ctx->regs.psr; else if (strcmp (name, "iip") == 0) return &cur_ctx->regs.cr.iip; else if (strcmp (name, "b0") == 0) return &cur_ctx->regs.b[0]; else return 0;}enum prio_expr {EXPR_BASE, EXPR_SUM, EXPR_LOGIC, EXPR_PROD};int parse_expr (char **buf, unsigned long *res, enum prio_expr prio);int next_char (char **buf){ char *b; b = *buf; while (isspace ((unsigned char)*b)) b++; *buf = b; return *b;}int parse_unary (char **buf, unsigned long *res){ char c; c = next_char (buf); switch (c) { case '0' ... '9': { char *e; *res = strtoul (*buf, &e, 0); if (e == *buf) { printf ("bad literal\n"); return -1; } *buf = e; } break; case '+': (*buf)++; return parse_unary (buf, res); case '$': { char *b; char *e; char c; unsigned long *reg; int len; b = *buf; e = b + 1; while ((*e >= 'a' && *e <= 'z') || (*e >= 'A' && *e <= 'Z') || (*e >= '0' && *e <= '9') || (*e == '_' || *e == '.')) e++; if (b == e) { printf ("identifier missing after '$'\n"); return -1; } b++; len = e - b; c = b[len]; b[len] = 0; reg = get_reg_addr (b); b[len] = c; if (reg != NULL) *res = *reg; else if (strncmp (b, "d2p", len) == 0 || strncmp (b, "i2p", len) == 0) { unsigned long vaddr; *buf = e; if (parse_unary (buf, &vaddr) != 0) return -1; if (virt_to_phys (*b == 'i', vaddr, res) != 0) { printf ("cannot find vaddr %016lx in tr\n", vaddr); return -1; } return 0; } else { printf ("unknown symbol\n"); return -1; } *buf = e; } break; case '(': (*buf)++; if (parse_expr (buf, res, EXPR_BASE) != 0) return -1; if (next_char (buf) != ')') { printf ("missing ')'\n"); return -1; } else (*buf)++; break; default: printf ("unknown operand '%c' in expression\n", c); return -1; } return 0;}int parse_expr (char **buf, unsigned long *res, enum prio_expr prio){ unsigned long val = 0; unsigned long val1; char c; if (parse_unary (buf, &val) != 0) return -1; while (1) { c = next_char (buf); switch (c) { case '+': case '-': if (prio > EXPR_SUM) return 0; (*buf)++; if (parse_expr (buf, &val1, EXPR_SUM) < 0) return -1; if (c == '+') val += val1; else val -= val1; break; case '*': if (prio > EXPR_PROD) return 0; (*buf)++; if (parse_expr (buf, &val1, EXPR_SUM) < 0) return -1; val *= val1; break; default: *res = val; return 0; } }}char *parse_arg (char **buf){ char *res; char *b = *buf; /* Eat leading spaces. */ while (isspace ((unsigned char)*b)) b++; res = b; while (*b && !isspace ((unsigned char)*b)) b++; /* Set the NUL terminator. */ if (*b) *b++ = 0; *buf = b; return res;}vcpu_guest_context_t vcpu_ctx[MAX_VIRT_CPUS];int vcpu_setcontext (int vcpu){ int ret; ret = xc_vcpu_setcontext (xc_handle, domid, vcpu, &vcpu_ctx[vcpu]); if (ret < 0) perror ("xc_vcpu_setcontext"); return ret;}enum cmd_status { CMD_ERROR, CMD_OK, CMD_REPEAT, CMD_QUIT };struct command_desc{ const char *name; const char *help; enum cmd_status (*cmd)(char *line);};static enum cmd_statuscmd_registers (char *line){ print_ctx (cur_ctx); return CMD_OK;}static enum cmd_statuscmd_sstep (char *line){ /* Set psr.dd and psr.id to skip over current breakpoint. */ cur_ctx->regs.psr |= PSR_SS | PSR_DD | PSR_ID; cur_ctx->regs.psr &= ~PSR_TB; if (vcpu_setcontext (cur_vcpu) < 0) return CMD_ERROR; if (wait_domain (cur_vcpu, cur_ctx) < 0) { perror ("wait_domain"); return CMD_ERROR; } print_ctx (cur_ctx); return CMD_REPEAT;}static enum cmd_statuscmd_go (char *line){ unsigned long n = 1; if (*line != 0) { if (parse_expr (&line, &n, 0) < 0) return CMD_ERROR; } while (n > 0) { /* Set psr.dd and psr.id to skip over current breakpoint. */ if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB | PSR_DB)) != 0) { cur_ctx->regs.psr &= ~(PSR_SS | PSR_TB); cur_ctx->regs.psr |= PSR_DD | PSR_ID; if (vcpu_setcontext (cur_vcpu) < 0) return CMD_ERROR; } if (wait_domain (cur_vcpu, cur_ctx) < 0) { perror ("wait_domain"); return CMD_ERROR; } print_ctx (cur_ctx); n--; } return CMD_REPEAT;}static enum cmd_statuscmd_cb (char *line){ if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB)) != PSR_TB) { cur_ctx->regs.psr &= ~PSR_SS; cur_ctx->regs.psr |= PSR_TB; if (vcpu_setcontext (cur_vcpu) < 0) return CMD_ERROR; } if (wait_domain (cur_vcpu, cur_ctx) < 0) { perror ("wait_domain"); return CMD_ERROR; } print_ctx (cur_ctx); return CMD_REPEAT;}static int quit_paused;static enum cmd_statuscmd_quit (char *line){ if (!strcmp (line, "paused")) quit_paused = 1; return CMD_QUIT;}static enum cmd_statuscmd_echo (char *line){ printf ("%s", line); return CMD_OK;}static enum cmd_statuscmd_disassemble (char *args){ static unsigned long addr; unsigned long end_addr = addr + 16; if (*args != 0) { if (parse_expr (&args, &addr, 0) < 0) return CMD_ERROR; if (*args != 0) { if (parse_expr (&args, &end_addr, 0) < 0) return CMD_ERROR; } else end_addr = addr + 16; } target_disas (stdout, addr, end_addr - addr); addr = end_addr; return CMD_REPEAT;}static enum cmd_statuscmd_break (char *args){ unsigned long addr; int i; for (i = 0; i < 4; i++) if (cur_ctx->regs.ibr[2 * i] == 0 && cur_ctx->regs.ibr[2 * i + 1] == 0) break; if (i == 4) { printf ("no availabe break points\n"); return CMD_ERROR; } if (parse_expr (&args, &addr, 0) < 0) return CMD_ERROR; cur_ctx->regs.ibr[2 * i] = addr; cur_ctx->regs.ibr[2 * i + 1] = 0x87fffffffffffff0UL; cur_ctx->regs.psr |= PSR_DB; if (vcpu_setcontext (cur_vcpu) < 0) return CMD_ERROR; else return CMD_OK;}static enum cmd_statuscmd_watch (char *args){ unsigned long addr; unsigned long mask; int i; for (i = 0; i < 4; i++) if (cur_ctx->regs.dbr[2 * i] == 0 && cur_ctx->regs.dbr[2 * i + 1] == 0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -