📄 remote-es1800.c
字号:
MEMADDR is the address in the remote memory space. MYADDR is the address of the buffer in our space. LEN is the number of bytes. memaddr - the target's address myaddr - gdb's address len - number of bytes */static voides1800_write_bytes (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len;{ char buf[PBUFSIZ]; int i; char *p; p = myaddr; for (i = 0; i < len; i++) { sprintf (buf, "@.B$%x=$%x", memaddr+i, (*p++) & 0xff); send_with_reply (buf, buf, sizeof (buf)); /* FIXME send_command? */ }}/* Read memory data directly from the emulator. This does not use the data cache; the data cache uses this. memaddr - the target's address myaddr - gdb's address len - number of bytes */static voides1800_read_bytes (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len;{ static int DB_tab[16] = {8,11,14,17,20,23,26,29,34,37,40,43,46,49,52,55}; char buf[PBUFSIZ]; int i; int low_addr; char *p; char *b; if (len > PBUFSIZ / 2 - 1) { abort (); } if (len == 1) /* The emulator does not like expressions like: */ { len = 2; /* DB.B $20018 TO $20018 */ } /* Reply describes registers byte by byte, each byte encoded as two hex characters. */ sprintf (buf, "DB.B $%x TO $%x", memaddr, memaddr+len-1); send_with_reply (buf, buf, sizeof (buf)); b = buf; low_addr = memaddr&0x0f; for (i = low_addr; i < low_addr + len; i++) { if ((!(i % 16)) && i) { /* if (i = 16,32,48) */ while (*p++!='\n') {;} b = p; } p = b + DB_tab[i%16] + (m68020 ? 2 : 0); if (p[0] == 32 || p[1] == 32) { error ("Emulator reply is too short: %s", buf); } myaddr[i-low_addr] = fromhex (p[0]) * 16 + fromhex (p[1]); }}/* Information about the current target */static voides1800_files_info (tops) struct target_ops *tops; /* Unused */{ printf ("ES1800 Attached to %s at %d baud in %s mode\n", savename, 19200, MODE);}/* We read the contents of the target location and stash it, then overwrite it with a breakpoint instruction. addr - is the target location in the target machine. contents_cache - is a pointer to memory allocated for saving the target contents. It is guaranteed by the caller to be long enough to save sizeof BREAKPOINT bytes. FIXME: This size is target_arch dependent and should be available in the target_arch transfer vector, if we ever have one... */static intes1800_insert_breakpoint (addr, contents_cache) CORE_ADDR addr; char *contents_cache;{ int val; val = target_read_memory (addr, contents_cache, sizeof (es1800_break_insn)); if (val == 0) { val = target_write_memory (addr, es1800_break_insn, sizeof (es1800_break_insn)); } return (val);}/* Write back the stashed instruction addr - is the target location in the target machine. contents_cache - is a pointer to memory allocated for saving the target contents. It is guaranteed by the caller to be long enough to save sizeof BREAKPOINT bytes. */ static intes1800_remove_breakpoint (addr, contents_cache) CORE_ADDR addr; char *contents_cache;{ return (target_write_memory (addr, contents_cache, sizeof (es1800_break_insn)));}/* create_break_insn () Primitive datastructures containing the es1800 breakpoint instruction */static voides1800_create_break_insn (ins, vec) char *ins; int vec;{ if (vec == 15) { ins[0] = 0x4e; ins[1] = 0x4f; }}/* verify_break () Seach for breakpoint routine in emulator memory. returns non-zero on failure vec - trap vector used for breakpoints */static intverify_break (vec) int vec;{ CORE_ADDR memaddress; char buf[8]; char *instr = "NqNqNqNs"; /* breakpoint routine */ int status; get_break_addr (vec, &memaddress); if (memaddress) { status = target_read_memory (memaddress, buf, 8); if (status != 0) { memory_error (status, memaddress); } return (strcmp (instr, buf)); } return (-1);}/* get_break_addr () find address of breakpint routine vec - trap vector used for breakpoints addrp - store the address here */static voidget_break_addr (vec, addrp) int vec; CORE_ADDR *addrp;{ CORE_ADDR memaddress = 0; int status; int k; char buf[PBUFSIZ]; char base_addr[4]; char *p; if (m68020) { send_with_reply ("VBR ", buf, sizeof (buf)); p = buf; for (k = 0; k < 4; k++) { if ((p[k*2 + 1] == 0) || (p[k*2 + 2] == 0)) { error ("Emulator reply is too short: %s", buf); } base_addr[k] = (fromhex (p[k*2 + 1]) * 16) + fromhex (p[k*2 + 2]); } /* base addr of exception vector table */ memaddress = *((CORE_ADDR *) base_addr); } memaddress += (vec + 32) * 4; /* address of trap vector */ status = target_read_memory (memaddress, (char *) addrp, 4); if (status != 0) { memory_error (status, memaddress); }}/* Kill an inferior process */static voides1800_kill (){ if (inferior_pid != 0) { inferior_pid = 0; es1800_mourn_inferior (); }}/* Load a file to the ES1800 emulator. Converts the file from a.out format into Extended Tekhex format before the file is loaded. Also loads the trap routine, and sets the ES1800 breakpoint on it filename - the a.out to be loaded from_tty - says whether to be verbose or not FIXME Uses emulator overlay memory for trap routine */ static voides1800_load (filename, from_tty) char *filename; int from_tty;{ FILE *instream; char loadname[15]; char buf[160]; struct cleanup *old_chain; int es1800_load_format = 5; if (es1800_desc < 0) { printf ("No emulator attached, type emulator-command first\n"); return; } filename = tilde_expand (filename); make_cleanup (free, filename); switch (es1800_load_format) { case 2: /* Extended Tekhex */ if (from_tty) { printf ("Converting \"%s\" to Extended Tekhex Format\n", filename); } sprintf (buf, "tekhex %s", filename); system (buf); sprintf (loadname, "out.hex"); break; case 5: /* Motorola S-rec */ if (from_tty) { printf ("Converting \"%s\" to Motorola S-record format\n", filename); } /* in the future the source code in copy (part of binutils-1.93) will be included in this file */ sprintf (buf, "copy -s \"a.out-sunos-big\" -d \"srec\" %s /tmp/out.hex", filename); system (buf); sprintf (loadname, "/tmp/out.hex"); break; default: error ("Downloading format not defined\n"); } mark_breakpoints_out (); inferior_pid = 0; if (from_tty) { printf ("Downloading \"%s\" to the ES 1800\n",filename); } if ((instream = fopen (loadname, "r")) == NULL) { perror_with_name ("fopen:"); } old_chain = make_cleanup (fclose, instream); immediate_quit++; es1800_reset (0); download (instream, from_tty, es1800_load_format); /* if breakpoint routine is not present anymore we have to check whether to download a new breakpoint routine or not */ if ((verify_break (es1800_break_vec) != 0) && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? ")) { char buf[128]; printf ("Using break vector 0x%x\n", es1800_break_vec); sprintf (buf, "0x%x ", es1800_break_vec); printf ("Give the start address of the breakpoint routine: "); fgets (buf + strlen (buf), sizeof (buf) - strlen (buf), stdin); es1800_init_break (buf, 0); } do_cleanups (old_chain); expect_prompt (); readchar (); /* FIXME I am getting a ^G = 7 after the prompt */ printf ("\n"); if (fclose (instream) == EOF) { ; } if (es1800_load_format != 2) { sprintf (buf, "/usr/bin/rm %s", loadname); system (buf); } symbol_file_command (filename, from_tty); /* reading symbol table */ immediate_quit--;}#if 0#define NUMCPYBYTES 20static voidbfd_copy (from_bfd, to_bfd) bfd *from_bfd; bfd *to_bfd;{ asection *p, *new; int i; char buf[NUMCPYBYTES]; for (p = from_bfd->sections; p != NULL; p = p->next) { printf (" Copying section %s. Size = %x.\n", p->name, p->_cooked_size); printf (" vma = %x, offset = %x, output_sec = %x\n", p->vma, p->output_offset, p->output_section); new = bfd_make_section (to_bfd, p->name); if (p->_cooked_size && !bfd_set_section_size (to_bfd, new, p->_cooked_size)) { error ("Wrong BFD size!\n"); } if (!bfd_set_section_flags (to_bfd, new, p->flags)) { error ("bfd_set_section_flags"); } new->vma = p->vma; for (i = 0; (i + NUMCPYBYTES) < p->_cooked_size ; i += NUMCPYBYTES) { if (!bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i, (bfd_size_type) NUMCPYBYTES)) { error ("bfd_get_section_contents\n"); } if (!bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i, (bfd_size_type) NUMCPYBYTES)) { error ("bfd_set_section_contents\n"); } } bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i, (bfd_size_type) (p->_cooked_size - i)); bfd_set_section_contents (to_bfd, new, (PTR) buf,(file_ptr) i, (bfd_size_type) (p->_cooked_size - i)); }}#endif/* Start an process on the es1800 and set inferior_pid to the new process' pid. execfile - the file to run args - arguments passed to the program env - the environment vector to pass */static voides1800_create_inferior (execfile, args, env) char *execfile; char *args; char **env;{ int entry_pt; int pid;#if 0 struct expression *expr; register struct cleanup *old_chain = 0; register value val;#endif if (args && *args) { error ("Can't pass arguments to remote ES1800 process"); }#if 0 if (query ("Use 'start' as entry point? ")) { expr = parse_c_expression ("start"); old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); entry_pt = (val->location).address; } else { printf ("Enter the program's entry point (in hexadecimal): "); scanf ("%x", &entry_pt); }#endif if (execfile == 0 || exec_bfd == 0) { error ("No exec file specified"); } entry_pt = (int) bfd_get_start_address (exec_bfd); pid = 42; /* Now that we have a child process, make it our target. */ push_target (&es1800_child_ops); /* The "process" (board) is already stopped awaiting our commands, and the program is already downloaded. We just set its PC and go. */ inferior_pid = pid; /* Needed for wait_for_inferior below */ clear_proceed_status (); /* Tell wait_for_inferior that we've started a new process. */ init_wait_for_inferior (); /* Set up the "saved terminal modes" of the inferior based on what modes we are starting it with. */ target_terminal_init (); /* Install inferior's terminal modes. */ target_terminal_inferior (); /* remote_start (args); */ /* trap_expected = 0; */ /* insert_step_breakpoint (); FIXME, do we need this? */ proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */}/* The process has died, clean up. */static voides1800_mourn_inferior (){ remove_breakpoints (); unpush_target (&es1800_child_ops); generic_mourn_inferior (); /* Do all the proper things now */}/* ES1800-protocol specific routines *//* Keep discarding input from the remote system, until STRING is found. Let the user break out immediately. string - the string to expect nowait - break out if string not the emulator's first respond otherwise read until string is found (== 0) */ static voidexpect (string, nowait) char *string; int nowait;{ char c; char *p = string; immediate_quit++; while (1) { c = readchar (); if (isalpha (c)) { c = toupper (c); } if (c == toupper (*p)) { p++; if (*p == '\0') { immediate_quit--; return; } } else if (!nowait) { p = string; } else { printf ("\'%s\' expected\n" , string); printf ("char %d is %d", p - string, c); error ("\n" ); } }}/* Keep discarding input until we see the prompt. */static voidexpect_prompt (){ expect (">", 0);}/* Read one character */#ifdef DEBUG_STDIN/* read from stdin */static intreadchar (){ char buf[1]; buf[0] = '\0'; printf ("readchar, give one character\n"); read (0, buf, 1);#if defined (LOG_FILE) putc (buf[0] & 0x7f, log_file);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -