📄 convex-tdep.c
字号:
else fprintf_filtered (stream, "%#llx", val); return; }}/* Change the default output radix to 10 or 16, or set it to 0 (heuristic). This command is mostly obsolete now that the print command allows formats to apply to aggregates, but is still handy occasionally. */static voidset_base_command (arg) char *arg;{ int new_radix; if (!arg) output_radix = 0; else { new_radix = atoi (arg); if (new_radix != 10 && new_radix != 16 && new_radix != 8) error ("base must be 8, 10 or 16, or null"); else output_radix = new_radix; }}/* Turn pipelining on or off in the inferior. */static voidset_pipelining_command (arg) char *arg;{ if (!arg) { sequential = !sequential; printf_filtered ("%s\n", sequential ? "off" : "on"); } else if (!strcmp (arg, "on")) sequential = 0; else if (!strcmp (arg, "off")) sequential = 1; else error ("valid args are `on', to allow instructions to overlap, or\n\`off', to prevent it and thereby pinpoint exceptions.");}/* Enable, disable, or force parallel execution in the inferior. */static voidset_parallel_command (arg) char *arg;{ struct rlimit rl; int prevparallel = parallel; if (!strncmp (arg, "fixed", strlen (arg))) parallel = 2; else if (!strcmp (arg, "on")) parallel = 1; else if (!strcmp (arg, "off")) parallel = 0; else error ("valid args are `on', to allow multiple threads, or\n\`fixed', to force multiple threads, or\n\`off', to run with one thread only."); if ((prevparallel == 0) != (parallel == 0) && inferior_pid) printf_filtered ("will take effect at next run.\n"); getrlimit (RLIMIT_CONCUR, &rl); rl.rlim_cur = parallel ? rl.rlim_max : 1; setrlimit (RLIMIT_CONCUR, &rl); if (inferior_pid) set_fixed_scheduling (inferior_pid, parallel == 2);}/* Add a new name for an existing command. */static void alias_command (arg) char *arg;{ static char *aliaserr = "usage is `alias NEW OLD', no args allowed"; char *newname = arg; struct cmd_list_element *new, *old; if (!arg) error_no_arg ("newname oldname"); new = lookup_cmd (&arg, cmdlist, "", -1); if (new && !strncmp (newname, new->name, strlen (new->name))) { newname = new->name; if (!(*arg == '-' || (*arg >= 'a' && *arg <= 'z') || (*arg >= 'A' && *arg <= 'Z') || (*arg >= '0' && *arg <= '9'))) error (aliaserr); } else { arg = newname; while (*arg == '-' || (*arg >= 'a' && *arg <= 'z') || (*arg >= 'A' && *arg <= 'Z') || (*arg >= '0' && *arg <= '9')) arg++; if (*arg != ' ' && *arg != '\t') error (aliaserr); *arg = '\0'; arg++; } old = lookup_cmd (&arg, cmdlist, "", 0); if (*arg != '\0') error (aliaserr); if (new && !strncmp (newname, new->name, strlen (new->name))) { char *tem; if (new->class == (int) class_user || new->class == (int) class_alias) tem = "Redefine command \"%s\"? "; else tem = "Really redefine built-in command \"%s\"? "; if (!query (tem, new->name)) error ("Command \"%s\" not redefined.", new->name); } add_com (newname, class_alias, old->function, old->doc);}/* Print the current thread number, and any threads with signals in the queue. */thread_info (){ struct threadpid *p; if (have_inferior_p ()) { ps.pi_buffer = (char *) &comm_registers; ps.pi_nbytes = sizeof comm_registers; ps.pi_offset = 0; ps.pi_thread = inferior_thread; ioctl (inferior_fd, PIXRDCREGS, &ps); } printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n", inferior_thread, stop_signal, stop_sigcode, subsig_name (stop_signal, stop_sigcode)); for (p = signal_stack; p->pid; p--) printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n", p->thread, p->signo, p->subsig, subsig_name (p->signo, p->subsig)); if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13)) printf_filtered ("New thread start pc %#x\n", (long) (comm_registers.crreg.pcpsw >> 32));}/* Return string describing a signal.subcode number */static char *subsig_name (signo, subcode) int signo, subcode;{ static char *subsig4[] = { "error exit", "privileged instruction", "unknown", "unknown", "undefined opcode", 0}; static char *subsig5[] = {0, "breakpoint", "single step", "fork trap", "exec trap", "pfork trap", "join trap", "idle trap", "last thread", "wfork trap", "process breakpoint", "trap instruction", 0}; static char *subsig8[] = {0, "int overflow", "int divide check", "float overflow", "float divide check", "float underflow", "reserved operand", "sqrt error", "exp error", "ln error", "sin error", "cos error", 0}; static char *subsig10[] = {0, "invalid inward ring address", "invalid outward ring call", "invalid inward ring return", "invalid syscall gate", "invalid rtn frame length", "invalid comm reg address", "invalid trap gate", 0}; static char *subsig11[] = {0, "read access denied", "write access denied", "execute access denied", "segment descriptor fault", "page table fault", "data reference fault", "i/o access denied", "levt pte invalid", 0}; static char **subsig_list[] = {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0}; int i; char *p; if ((p = strsignal (signo)) == NULL) p = "unknown"; if (signo >= (sizeof subsig_list / sizeof *subsig_list) || !subsig_list[signo]) return p; for (i = 1; subsig_list[signo][i]; i++) if (i == subcode) return subsig_list[signo][subcode]; return p;}/* Print a compact display of thread status, essentially x/i $pc for all active threads. */static voidthreadstat (){ int t; for (t = 0; t < n_threads; t++) if (thread_state[t] == PI_TALIVE) { printf_filtered ("%d%c %08x%c %d.%d ", t, (t == inferior_thread ? '*' : ' '), thread_pc[t], (thread_is_in_kernel[t] ? '#' : ' '), thread_signal[t], thread_sigcode[t]); print_insn (thread_pc[t], stdout); printf_filtered ("\n"); }}/* Change the current thread to ARG. */set_thread_command (arg) char *arg;{ int thread; if (!arg) { threadstat (); return; } thread = parse_and_eval_address (arg); if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE) error ("no such thread."); select_thread (thread); stop_pc = read_pc (); flush_cached_frames (); set_current_frame (create_new_frame (read_register (FP_REGNUM), read_pc ())); select_frame (get_current_frame (), 0); print_stack_frame (selected_frame, selected_frame_level, -1);}/* Here on CONT command; gdb's dispatch address is changed to come here. Set global variable ALL_CONTINUE to tell resume() that it should start up all threads, and that a thread switch will not blow gdb's mind. */static voidconvex_cont_command (proc_count_exp, from_tty) char *proc_count_exp; int from_tty;{ all_continue = 1; cont_command (proc_count_exp, from_tty);}/* Here on 1CONT command. Resume only the current thread. */one_cont_command (proc_count_exp, from_tty) char *proc_count_exp; int from_tty;{ cont_command (proc_count_exp, from_tty);}/* Print the contents and lock bits of all communication registers, or just register ARG if ARG is a communication register, or the 3-word resource structure in memory at address ARG. */comm_registers_info (arg) char *arg;{ int i, regnum; if (arg) { if (sscanf (arg, "$c%d", ®num) == 1) { ; } else if (sscanf (arg, "$C%d", ®num) == 1) { ; } else { regnum = parse_and_eval_address (arg); if (regnum > 0) regnum &= ~0x8000; } if (regnum >= 64) error ("%s: invalid register name.", arg); /* if we got a (user) address, examine the resource struct there */ if (regnum < 0) { static int buf[3]; read_memory (regnum, buf, sizeof buf); printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2], buf[0] & 0xff ? " locked" : ""); return; } } ps.pi_buffer = (char *) &comm_registers; ps.pi_nbytes = sizeof comm_registers; ps.pi_offset = 0; ps.pi_thread = inferior_thread; ioctl (inferior_fd, PIXRDCREGS, &ps); for (i = 0; i < 64; i++) if (!arg || i == regnum) printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i, comm_registers.crreg.r4[i], (iscrlbit (comm_registers.crctl.lbits.cc, i) ? " locked" : ""));}/* Print the psw */static void psw_info (arg) char *arg;{ struct pswbit { int bit; int pos; char *text; }; static struct pswbit pswbit[] = { { 0x80000000, -1, "A carry" }, { 0x40000000, -1, "A integer overflow" }, { 0x20000000, -1, "A zero divide" }, { 0x10000000, -1, "Integer overflow enable" }, { 0x08000000, -1, "Trace" }, { 0x06000000, 25, "Frame length" }, { 0x01000000, -1, "Sequential" }, { 0x00800000, -1, "S carry" }, { 0x00400000, -1, "S integer overflow" }, { 0x00200000, -1, "S zero divide" }, { 0x00100000, -1, "Zero divide enable" }, { 0x00080000, -1, "Floating underflow" }, { 0x00040000, -1, "Floating overflow" }, { 0x00020000, -1, "Floating reserved operand" }, { 0x00010000, -1, "Floating zero divide" }, { 0x00008000, -1, "Floating error enable" }, { 0x00004000, -1, "Floating underflow enable" }, { 0x00002000, -1, "IEEE" }, { 0x00001000, -1, "Sequential stores" }, { 0x00000800, -1, "Intrinsic error" }, { 0x00000400, -1, "Intrinsic error enable" }, { 0x00000200, -1, "Trace thread creates" }, { 0x00000100, -1, "Thread init trap" }, { 0x000000e0, 5, "Reserved" }, { 0x0000001f, 0, "Intrinsic error code" }, {0, 0, 0}, }; long psw; struct pswbit *p; if (arg) psw = parse_and_eval_address (arg); else psw = read_register (PS_REGNUM); for (p = pswbit; p->bit; p++) { if (p->pos < 0) printf_filtered ("%08x %s %s\n", p->bit, (psw & p->bit) ? "yes" : "no ", p->text); else printf_filtered ("%08x %3d %s\n", p->bit, (psw & p->bit) >> p->pos, p->text); }}_initialize_convex_dep (){ add_com ("alias", class_support, alias_command, "Add a new name for an existing command."); add_cmd ("base", class_vars, set_base_command, "Change the integer output radix to 8, 10 or 16\n\or use just `set base' with no args to return to the ad-hoc default,\n\which is 16 for integers that look like addresses, 10 otherwise.", &setlist); add_cmd ("pipeline", class_run, set_pipelining_command, "Enable or disable overlapped execution of instructions.\n\With `set pipe off', exceptions are reported with\n\$pc pointing at the instruction after the faulting one.\n\The default is `set pipe on', which runs faster.", &setlist); add_cmd ("parallel", class_run, set_parallel_command, "Enable or disable multi-threaded execution of parallel code.\n\`set parallel off' means run the program on a single CPU.\n\`set parallel fixed' means run the program with all CPUs assigned to it.\n\`set parallel on' means run the program on any CPUs that are available.", &setlist); add_com ("1cont", class_run, one_cont_command, "Continue the program, activating only the current thread.\n\Args are the same as the `cont' command."); add_com ("thread", class_run, set_thread_command, "Change the current thread, the one under scrutiny and control.\n\With no arg, show the active threads, the current one marked with *."); add_info ("threads", thread_info, "List status of active threads."); add_info ("comm-registers", comm_registers_info, "List communication registers and their contents.\n\A communication register name as argument means describe only that register.\n\An address as argument means describe the resource structure at that address.\n\`Locked' means that the register has been sent to but not yet received from."); add_info ("psw", psw_info, "Display $ps, the processor status word, bit by bit.\n\An argument means display that value's interpretation as a psw."); add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\32-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\64-bit registers $S0-7 $V0-7 $C0-63\n\\n\info threads display info on stopped threads waiting to signal\n\thread display list of active threads\n\thread N select thread N (its registers, stack, memory, etc.)\n\step, next, etc step selected thread only\n\1cont continue selected thread only\n\cont continue all threads\n\info comm-registers display contents of comm register(s) or a resource struct\n\info psw display processor status word $ps\n\set base N change integer radix used by `print' without a format\n\set pipeline off exceptions are precise, $pc points after the faulting insn\n\set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\set parallel off program runs on a single CPU\n\set parallel fixed all CPUs are assigned to the program\n\set parallel on normal mode, parallel execution on random available CPUs\n\", &cmdlist);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -