?? remote-eb.c
字號:
{ need_gi = 0; write (eb_desc, "gi\n", 3); /* Swallow the echo of "gi". */ expect ("gi\r"); } else { write (eb_desc, "GR\n", 3); /* Swallow the echo. */ expect ("GR\r"); } }}/* Wait until the remote machine stops, then return, storing status in STATUS just as `wait' would. */inteb_wait (status) WAITTYPE *status;{ /* Strings to look for. '?' means match any single character. Note that with the algorithm we use, the initial character of the string cannot recur in the string, or we will not find some cases of the string in the input. */ static char bpt[] = "Invalid interrupt taken - #0x50 - "; /* It would be tempting to look for "\n[__exit + 0x8]\n" but that requires loading symbols with "yc i" and even if we did do that we don't know that the file has symbols. */ static char exitmsg[] = "\n@????????I JMPTI GR121,LR0"; char *bp = bpt; char *ep = exitmsg; /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */ char swallowed[50]; /* Current position in swallowed. */ char *swallowed_p = swallowed; int ch; int ch_handled; int old_timeout = timeout; WSETEXIT ((*status), 0); if (need_artificial_trap != 0) { WSETSTOP ((*status), SIGTRAP); need_artificial_trap--; return 0; } timeout = 0; /* Don't time out -- user program is running. */ while (1) { ch_handled = 0; ch = readchar (); if (ch == *bp) { bp++; if (*bp == '\0') break; ch_handled = 1; *swallowed_p++ = ch; } else bp = bpt; if (ch == *ep || *ep == '?') { ep++; if (*ep == '\0') break; if (!ch_handled) *swallowed_p++ = ch; ch_handled = 1; } else ep = exitmsg; if (!ch_handled) { char *p; /* Print out any characters which have been swallowed. */ for (p = swallowed; p < swallowed_p; ++p) putc (*p, stdout); swallowed_p = swallowed; putc (ch, stdout); } } expect_prompt (); if (*bp== '\0') WSETSTOP ((*status), SIGTRAP); else WSETEXIT ((*status), 0); timeout = old_timeout; return 0;}/* Return the name of register number REGNO in the form input and output by EBMON. Returns a pointer to a static buffer containing the answer. */static char *get_reg_name (regno) int regno;{ static char buf[80]; if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96); else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) sprintf (buf, "LR%03d", regno - LR0_REGNUM); else if (regno == Q_REGNUM) strcpy (buf, "SR131"); else if (regno >= BP_REGNUM && regno <= CR_REGNUM) sprintf (buf, "SR%03d", regno - BP_REGNUM + 133); else if (regno == ALU_REGNUM) strcpy (buf, "SR132"); else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM) sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128); else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM) sprintf (buf, "SR%03d", regno - VAB_REGNUM); else if (regno == GR1_REGNUM) strcpy (buf, "GR001"); return buf;}/* Read the remote registers into the block REGS. */static voideb_fetch_registers (){ int reg_index; int regnum_index; char tempbuf[10]; int i;#if 0 /* This should not be necessary, because one is supposed to read the registers only when the inferior is stopped (at least with ptrace() and why not make it the same for remote?). */ /* ^A is the "normal character" used to make sure we are talking to EBMON and not to the program being debugged. */ write (eb_desc, "\001\n"); expect_prompt ();#endif write (eb_desc, "dw gr96,gr127\n", 14); for (reg_index = 96, regnum_index = GR96_REGNUM; reg_index < 128; reg_index += 4, regnum_index += 4) { sprintf (tempbuf, "GR%03d ", reg_index); expect (tempbuf); get_hex_regs (4, regnum_index); expect ("\n"); } for (i = 0; i < 128; i += 32) { /* The PC has a tendency to hang if we get these all in one fell swoop ("dw lr0,lr127"). */ sprintf (tempbuf, "dw lr%d\n", i); write (eb_desc, tempbuf, strlen (tempbuf)); for (reg_index = i, regnum_index = LR0_REGNUM + i; reg_index < i + 32; reg_index += 4, regnum_index += 4) { sprintf (tempbuf, "LR%03d ", reg_index); expect (tempbuf); get_hex_regs (4, regnum_index); expect ("\n"); } } write (eb_desc, "dw sr133,sr133\n", 15); expect ("SR133 "); get_hex_regs (1, BP_REGNUM); expect ("\n"); write (eb_desc, "dw sr134,sr134\n", 15); expect ("SR134 "); get_hex_regs (1, FC_REGNUM); expect ("\n"); write (eb_desc, "dw sr135,sr135\n", 15); expect ("SR135 "); get_hex_regs (1, CR_REGNUM); expect ("\n"); write (eb_desc, "dw sr131,sr131\n", 15); expect ("SR131 "); get_hex_regs (1, Q_REGNUM); expect ("\n"); write (eb_desc, "dw sr0,sr14\n", 12); for (reg_index = 0, regnum_index = VAB_REGNUM; regnum_index <= LRU_REGNUM; regnum_index += 4, reg_index += 4) { sprintf (tempbuf, "SR%03d ", reg_index); expect (tempbuf); get_hex_regs (reg_index == 12 ? 3 : 4, regnum_index); expect ("\n"); } /* There doesn't seem to be any way to get these. */ { int val = -1; supply_register (FPE_REGNUM, &val); supply_register (INTE_REGNUM, &val); supply_register (FPS_REGNUM, &val); supply_register (EXO_REGNUM, &val); } write (eb_desc, "dw gr1,gr1\n", 11); expect ("GR001 "); get_hex_regs (1, GR1_REGNUM); expect_prompt ();}/* Fetch register REGNO, or all registers if REGNO is -1. Returns errno value. */voideb_fetch_register (regno) int regno;{ if (regno == -1) eb_fetch_registers (); else { char *name = get_reg_name (regno); fprintf (eb_stream, "dw %s,%s\n", name, name); expect (name); expect (" "); get_hex_regs (1, regno); expect_prompt (); } return;}/* Store the remote registers from the contents of the block REGS. */static voideb_store_registers (){ int i, j; fprintf (eb_stream, "s gr1,%x\n", read_register (GR1_REGNUM)); expect_prompt (); for (j = 0; j < 32; j += 16) { fprintf (eb_stream, "s gr%d,", j + 96); for (i = 0; i < 15; ++i) fprintf (eb_stream, "%x,", read_register (GR96_REGNUM + j + i)); fprintf (eb_stream, "%x\n", read_register (GR96_REGNUM + j + 15)); expect_prompt (); } for (j = 0; j < 128; j += 16) { fprintf (eb_stream, "s lr%d,", j); for (i = 0; i < 15; ++i) fprintf (eb_stream, "%x,", read_register (LR0_REGNUM + j + i)); fprintf (eb_stream, "%x\n", read_register (LR0_REGNUM + j + 15)); expect_prompt (); } fprintf (eb_stream, "s sr133,%x,%x,%x\n", read_register (BP_REGNUM), read_register (FC_REGNUM), read_register (CR_REGNUM)); expect_prompt (); fprintf (eb_stream, "s sr131,%x\n", read_register (Q_REGNUM)); expect_prompt (); fprintf (eb_stream, "s sr0,"); for (i = 0; i < 11; ++i) fprintf (eb_stream, "%x,", read_register (VAB_REGNUM + i)); fprintf (eb_stream, "%x\n", read_register (VAB_REGNUM + 11)); expect_prompt ();}/* Store register REGNO, or all if REGNO == 0. Return errno value. */voideb_store_register (regno) int regno;{ if (regno == -1) eb_store_registers (); else { char *name = get_reg_name (regno); fprintf (eb_stream, "s %s,%x\n", name, read_register (regno)); /* Setting GR1 changes the numbers of all the locals, so invalidate the register cache. Do this *after* calling read_register, because we want read_register to return the value that write_register has just stuffed into the registers array, not the value of the register fetched from the inferior. */ if (regno == GR1_REGNUM) registers_changed (); expect_prompt (); }}/* Get ready to modify the registers array. On machines which store individual registers, this doesn't need to do anything. On machines which store all the registers in one fell swoop, this makes sure that registers contains all the registers from the program being debugged. */voideb_prepare_to_store (){ /* Do nothing, since we can store individual regs */}/* FIXME-someday! Merge these two. */inteb_xfer_inferior_memory (memaddr, myaddr, len, write, target) CORE_ADDR memaddr; char *myaddr; int len; int write; struct target_ops *target; /* ignored */{ if (write) return eb_write_inferior_memory (memaddr, myaddr, len); else return eb_read_inferior_memory (memaddr, myaddr, len);}voideb_files_info (){ printf ("\tAttached to %s at %d baud and running program %s.\n", dev_name, baudrate, prog_name);}/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory at MEMADDR. Returns length moved. */inteb_write_inferior_memory (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len;{ int i; for (i = 0; i < len; i++) { if ((i % 16) == 0) fprintf (eb_stream, "sb %x,", memaddr + i); if ((i % 16) == 15 || i == len - 1) { fprintf (eb_stream, "%x\n", ((unsigned char *)myaddr)[i]); expect_prompt (); } else fprintf (eb_stream, "%x,", ((unsigned char *)myaddr)[i]); } return len;}/* Read LEN bytes from inferior memory at MEMADDR. Put the result at debugger address MYADDR. Returns length moved. */inteb_read_inferior_memory(memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len;{ int i; /* Number of bytes read so far. */ int count; /* Starting address of this pass. */ unsigned long startaddr; /* Number of bytes to read in this pass. */ int len_this_pass; /* Note that this code works correctly if startaddr is just less than UINT_MAX (well, really CORE_ADDR_MAX if there was such a thing). That is, something like eb_read_bytes (CORE_ADDR_MAX - 4, foo, 4) works--it never adds len to memaddr and gets 0. */ /* However, something like eb_read_bytes (CORE_ADDR_MAX - 3, foo, 4) doesn't need to work. Detect it and give up if there's an attempt to do that. */ if (((memaddr - 1) + len) < memaddr) { errno = EIO; return 0; } startaddr = memaddr; count = 0; while (count < len) { len_this_pass = 16; if ((startaddr % 16) != 0) len_this_pass -= startaddr % 16; if (len_this_pass > (len - count)) len_this_pass = (len - count); fprintf (eb_stream, "db %x,%x\n", startaddr, (startaddr - 1) + len_this_pass); expect ("\n"); /* Look for 8 hex digits. */ i = 0; while (1) { if (isxdigit (readchar ())) ++i; else { expect_prompt (); error ("Hex digit expected from remote system."); } if (i >= 8) break; } expect (" "); for (i = 0; i < len_this_pass; i++) get_hex_byte (&myaddr[count++]); expect_prompt (); startaddr += len_this_pass; } return len;}static voideb_kill (args, from_tty) char *args; int from_tty;{ return; /* Ignore attempts to kill target system */}/* Clean up when a program exits. The program actually lives on in the remote processor's RAM, and may be run again without a download. Don't leave it full of breakpoint instructions. */voideb_mourn_inferior (){ remove_breakpoints (); generic_mourn_inferior (); /* Do all the proper things now */}/* Define the target subroutine names */struct target_ops eb_ops = { "amd-eb", "Remote serial AMD EBMON target", "Use a remote computer running EBMON connected by a serial line.\n\Arguments are the name of the device for the serial line,\n\the speed to connect at in bits per second, and the filename of the\n\executable as it exists on the remote computer. For example,\n\ target amd-eb /dev/ttya 9600 demo", eb_open, eb_close, 0, eb_detach, eb_resume, eb_wait, eb_fetch_register, eb_store_register, eb_prepare_to_store, eb_xfer_inferior_memory, eb_files_info, 0, 0, /* Breakpoints */ 0, 0, 0, 0, 0, /* Terminal handling */ eb_kill, 0, /* load */ 0, /* lookup_symbol */ eb_create_inferior, eb_mourn_inferior, 0, /* can_run */ 0, /* notice_signals */ process_stratum, 0, /* next */ 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */ 0, 0, /* Section pointers */ OPS_MAGIC, /* Always the last thing */};void_initialize_remote_eb (){ add_target (&eb_ops);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -