find_default_run_target PARAMS ((char *));  static void update_current_target PARAMS ((void));  static void debug_to_open PARAMS ((char *, int));  static void debug_to_close PARAMS ((int));  static void debug_to_attach PARAMS ((char *, int));  static void debug_to_detach PARAMS ((char *, int));  static void debug_to_resume PARAMS ((int, int, enum target_signal));  static int debug_to_wait PARAMS ((int, struct target_waitstatus *));  static void debug_to_fetch_registers PARAMS ((int));  static void debug_to_store_registers PARAMS ((int));  static void debug_to_prepare_to_store PARAMS ((void));  static int debug_to_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));  static void debug_to_files_info PARAMS ((struct target_ops *));  static int debug_to_insert_breakpoint PARAMS ((CORE_ADDR, char *));  static int debug_to_remove_breakpoint PARAMS ((CORE_ADDR, char *));  static void debug_to_terminal_init PARAMS ((void));  static void debug_to_terminal_inferior PARAMS ((void));  static void debug_to_terminal_ours_for_output PARAMS ((void));  static void debug_to_terminal_ours PARAMS ((void));  static void debug_to_terminal_info PARAMS ((char *, int));  static void debug_to_kill PARAMS ((void));  static void debug_to_load PARAMS ((char *, int));  static int debug_to_lookup_symbol PARAMS ((char *, CORE_ADDR *));  static void debug_to_create_inferior PARAMS ((char *, char *, char **));  static void debug_to_mourn_inferior PARAMS ((void));  static int debug_to_can_run PARAMS ((void));  static void debug_to_notice_signals PARAMS ((int));  static int debug_to_thread_alive PARAMS ((int));  static void debug_to_stop PARAMS ((void));   struct target_ops **target_structs; unsigned target_struct_size; unsigned target_struct_index; unsigned target_struct_allocsize; #define	DEFAULT_ALLOCSIZE	10    struct target_ops dummy_target = { "None",			 "None",			 "",				 0,				 0,				 find_default_attach,		 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 find_default_create_inferior,	 0,				 0,				 0,				 0,				 0,				 dummy_stratum,		 0,				 0,				 0,				 0,				 0,				 0,				 0,				 0,				 OPS_MAGIC,			 };    struct target_stack_item *target_stack;    struct target_ops current_target;    static struct cmd_list_element *targetlist = NULL;    int attach_flag;  #ifdef MAINTENANCE_CMDS   static int targetdebug = 0;  static void setup_target_debug PARAMS ((void));  #endif     static void target_command (arg, from_tty) char *arg; int from_tty; { fputs_filtered ("Argument required (target name).  Try `help target'\n", gdb_stdout); }    void add_target (t) struct target_ops *t; { if (!target_structs) { target_struct_allocsize = DEFAULT_ALLOCSIZE; target_structs = (struct target_ops **) xmalloc (target_struct_allocsize * sizeof (*target_structs)); } if (target_struct_size >= target_struct_allocsize) { target_struct_allocsize *= 2; target_structs = (struct target_ops **) xrealloc ((char *) target_structs, target_struct_allocsize * sizeof (*target_structs)); } target_structs[target_struct_size++] = t;   if (targetlist == NULL) add_prefix_cmd ("target", class_run, target_command, "Connect to a target machine or process.\n\ The first argument is the type or protocol of the target machine.\n\ Remaining arguments are interpreted by the target protocol.  For more\n\ information on the arguments for a particular protocol, type\n\ `help target ' followed by the protocol name.", &targetlist, "target ", 0, &cmdlist); add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist); }    static void ignore () { }   static int nomemory (memaddr, myaddr, len, write, t) CORE_ADDR memaddr; char *myaddr; int len; int write; struct target_ops *t; { errno = EIO;		 return 0;		 }  static void tcomplain () { error ("You can't do that when your target is `%s'", current_target.to_shortname); }  void noprocess () { error ("You can't do that without a process to debug"); }   static int nosymbol (name, addrp) char *name; CORE_ADDR *addrp; { return 1;		 }   static void default_terminal_info (args, from_tty) char *args; int from_tty; { printf_unfiltered("No saved terminal information.\n"); }    static void kill_or_be_killed (from_tty) int from_tty; { if (target_has_execution) { printf_unfiltered ("You are already running a program:\n"); target_files_info (); if (query ("Kill it? ")) { target_kill (); if (target_has_execution) error ("Killing the program did not help."); return; } else { error ("Program not killed."); } } tcomplain(); }  static void maybe_kill_then_attach (args, from_tty) char *args; int from_tty; { kill_or_be_killed (from_tty); target_attach (args, from_tty); }  static void maybe_kill_then_create_inferior (exec, args, env) char *exec; char *args; char **env; { kill_or_be_killed (0); target_create_inferior (exec, args, env); }    static void cleanup_target (t) struct target_ops *t; {  #define de_fault(field, value) \ if (!t->field)	t->field = value    de_fault (to_open, 			(void (*) PARAMS((char *, int))) tcomplain); de_fault (to_close, 			(void (*) PARAMS((int))) ignore); de_fault (to_attach, 			maybe_kill_then_attach); de_fault (to_detach, 			(void (*) PARAMS((char *, int))) ignore); de_fault (to_resume, 			(void (*) PARAMS((int, int, enum target_signal))) noprocess); de_fault (to_wait, 			(int (*) PARAMS((int, struct target_waitstatus *))) noprocess); de_fault (to_fetch_registers, 	(void (*) PARAMS((int))) ignore); de_fault (to_store_registers,		(void (*) PARAMS((int))) noprocess); de_fault (to_prepare_to_store,	(void (*) PARAMS((void))) noprocess); de_fault (to_xfer_memory,		(int (*) PARAMS((CORE_ADDR, char *, int, int, struct target_ops *))) nomemory); de_fault (to_files_info,		(void (*) PARAMS((struct target_ops *))) ignore); de_fault (to_insert_breakpoint,	memory_insert_breakpoint); de_fault (to_remove_breakpoint,	memory_remove_breakpoint); de_fault (to_terminal_init,		(void (*) PARAMS((void))) ignore); de_fault (to_terminal_inferior,	(void (*) PARAMS ((void))) ignore); de_fault (to_terminal_ours_for_output,(void (*) PARAMS ((void))) ignore); de_fault (to_terminal_ours,		(void (*) PARAMS ((void))) ignore); de_fault (to_terminal_info,		default_terminal_info); de_fault (to_kill,			(void (*) PARAMS((void))) noprocess); de_fault (to_load,			(void (*) PARAMS((char *, int))) tcomplain); de_fault (to_lookup_symbol,		(int (*) PARAMS ((char *, CORE_ADDR *))) nosymbol); de_fault (to_create_inferior,		maybe_kill_then_create_inferior); de_fault (to_mourn_inferior,		(void (*) PARAMS((void))) noprocess); de_fault (to_can_run,			return_zero); de_fault (to_notice_signals,		(void (*) PARAMS((int))) ignore); de_fault (to_thread_alive,		(int (*) PARAMS((int))) ignore); de_fault (to_stop,			(void (*) PARAMS((void))) ignore);  #undef de_fault }    static void update_current_target () { struct target_stack_item *item; struct target_ops *t;   memset (&current_target, 0, sizeof current_target);  for (item = target_stack; item; item = item->next) { t = item->target_ops;  #define INHERIT(FIELD, TARGET) \ if (!current_target.FIELD) \ current_target.FIELD = TARGET->FIELD  INHERIT (to_shortname, t); INHERIT (to_longname, t); INHERIT (to_doc, t); INHERIT (to_open, t); INHERIT (to_close, t); INHERIT (to_attach, t); INHERIT (to_detach, t); INHERIT (to_resume, t); INHERIT (to_wait, t); INHERIT (to_fetch_registers, t); INHERIT (to_store_registers, t); INHERIT (to_prepare_to_store, t); INHERIT (to_xfer_memory, t); INHERIT (to_files_info, t); INHERIT (to_insert_breakpoint, t); INHERIT (to_remove_breakpoint, t); INHERIT (to_terminal_init, t); INHERIT (to_terminal_inferior, t); INHERIT (to_terminal_ours_for_output, t); INHERIT (to_terminal_ours, t); INHERIT (to_terminal_info, t); INHERIT (to_kill, t); INHERIT (to_load, t); INHERIT (to_lookup_symbol, t); INHERIT (to_create_inferior, t); INHERIT (to_mourn_inferior, t); INHERIT (to_can_run, t); INHERIT (to_notice_signals, t); INHERIT (to_thread_alive, t); INHERIT (to_stop, t); INHERIT (to_stratum, t); INHERIT (DONT_USE, t); INHERIT (to_has_all_memory, t); INHERIT (to_has_memory, t); INHERIT (to_has_stack, t); INHERIT (to_has_registers, t); INHERIT (to_has_execution, t); INHERIT (to_sections, t); INHERIT (to_sections_end, t); INHERIT (to_magic, t);  #undef INHERIT } }    int push_target (t) struct target_ops *t; { struct target_stack_item *cur, *prev, *tmp;   if (t->to_magic != OPS_MAGIC) { fprintf_unfiltered(gdb_stderr, "Magic number of %s target struct wrong\n", t->to_shortname); abort(); }    for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next) { if ((int)(t->to_stratum) >= (int)(cur->target_ops->to_stratum)) break; }    if (cur) while (t->to_stratum == cur->target_ops->to_stratum) {  if (cur->target_ops->to_close) (cur->target_ops->to_close) (0); if (prev) prev->next = cur->next;  else target_stack = cur->next;  tmp = cur->next; free (cur); cur = tmp; }    tmp = (struct target_stack_item *) xmalloc (sizeof (struct target_stack_item)); tmp->next = cur; tmp->target_ops = t;  if (prev) prev->next = tmp; else target_stack = tmp;  update_current_target ();  cleanup_target (&current_target);   #ifdef MAINTENANCE_CMDS if (targetdebug) setup_target_debug (); #endif  return prev != 0; }    int unpush_target (t) struct target_ops *t; { struct target_stack_item *cur, *prev;  if (t->to_close) t->to_close (0);		    for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next) if (cur->target_ops == t) break;  if (!cur) return 0;			    if (!prev) target_stack = cur->next; else prev->next = cur->next;  free (cur);			  update_current_target (); cleanup_target (&current_target);  return 1; }  void pop_target () { (current_target.to_close)(0);	 if (unpush_target (target_stack->target_ops) == 1) return;  fprintf_unfiltered(gdb_stderr, "pop_target couldn't find target %s\n", current_target.to_shortname); abort(); }  #undef	MIN #define MIN(A, B) (((A) <= (B)) ? (A) : (B))    int target_read_string (memaddr, string, len, errnop) CORE_ADDR memaddr; char **string; int len; int *errnop; { int tlen, origlen, offset, i; char buf[4]; int errcode = 0; char *buffer; int buffer_allocated; char *bufptr; unsigned int nbytes_read = 0;   buffer_allocated = 4; buffer = xmalloc (buffer_allocated); bufptr = buffer;  origlen = len;  while (len > 0) { tlen = MIN (len, 4 - (memaddr & 3)); offset = memaddr & 3;  errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0); if (errcode != 0) goto done;  if (bufptr - buffer + tlen > buffer_allocated) { unsigned int bytes; bytes = bufptr - buffer; buffer_allocated *= 2; buffer = xrealloc (buffer, buffer_allocated); bufptr = buffer + bytes; }  for (i = 0; i < tlen; i++) { *bufptr++ = buf[i + offset]; if (buf[i + offset] == '\000') { nbytes_read += i + 1; goto done; } }  memaddr += tlen; len -= tlen; nbytes_read += tlen; } done: if (errnop != NULL) *errnop = errcode; if (string != NULL) *string = buffer; return nbytes_read; }    int target_read_memory (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len; { return target_xfer_memory (memaddr, myaddr, len, 0); }    int target_read_memory_partial (memaddr, myaddr, len, errnoptr) CORE_ADDR memaddr; char *myaddr; int len; int *errnoptr; { int nread;	 int errcode;	   errcode = target_xfer_memory (memaddr, myaddr, len, 0); if (errcode == 0) {  nread = len; } else {  for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--) { errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0); }  if (errcode != 0) { nread--; } } if (errnoptr != NULL) { *errnoptr = errcode; } return (nread); }  int target_write_memory (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len; { return target_xfer_memory (memaddr, myaddr, len, 1); }    int target_xfer_memory (memaddr, myaddr, len, write) CORE_ADDR memaddr; char *myaddr; int len; int write; { int curlen; int res; struct target_ops *t; struct target_stack_item *item;   errno = 0;   res = current_target.to_xfer_memory (memaddr, myaddr, len, write, &current_target); if (res == len) return 0;  if (res > 0) goto bump;   for (; len > 0;) { curlen = len;		 for (item = target_stack; item; item = item->next) { t = item->target_ops; if (!t->to_has_memory) continue;  res = t->to_xfer_memory (memaddr, myaddr, curlen, write, t); if (res > 0) break;		 if (t->to_has_all_memory) break; }  if (res <= 0) {  if (!write) memset (myaddr, 0, len); if (errno == 0) return EIO; else return errno; } bump: memaddr += res; myaddr  += res; len     -= res; } return 0;			 }    static void target_info (args, from_tty) char *args; int from_tty; { struct target_ops *t; struct target_stack_item *item; int has_all_mem = 0;  if (symfile_objfile != NULL) printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name);  #ifdef FILES_INFO_HOOK if (FILES_INFO_HOOK ()) return; #endif  for (item = target_stack; item; item = item->next) { t = item->target_ops;  if (!t->to_has_memory) continue;  if ((int)(t->to_stratum) <= (int)dummy_stratum) continue; if (has_all_mem) printf_unfiltered("\tWhile running this, GDB does not access memory from...\n"); printf_unfiltered("%s:\n", t->to_longname); (t->to_files_info)(t); has_all_mem = t->to_has_all_memory; } }    void target_preopen (from_tty) int from_tty; { dont_repeat();  if (target_has_execution) { if (query ("A program is being debugged already.  Kill it? ")) target_kill (); else error ("Program not killed."); }    if (target_has_execution) pop_target (); }    void target_detach (args, from_tty) char *args; int from_tty; {  #ifdef DO_DEFERRED_STORES DO_DEFERRED_STORES; #endif (current_target.to_detach) (args, from_tty); }  void target_link (modname, t_reloc) char *modname; CORE_ADDR *t_reloc; { if (STREQ(current_target.to_shortname, "rombug")) { (current_target.to_lookup_symbol) (modname, t_reloc); if (*t_reloc == 0) error("Unable to link to %s and get relocation in rombug", modname); } else *t_reloc = (CORE_ADDR)-1; }    static struct target_ops * find_default_run_target (do_mesg) char *do_mesg;
find_default_run_target (char *do_mesg)
find_default_run_target PARAMS ((char *));static voidupdate_current_target PARAMS ((void));static voiddebug_to_open PARAMS ((char *, int));static voiddebug_to_close PARAMS ((int));static voiddebug_to_attach PARAMS ((char *, int));static voiddebug_to_detach PARAMS ((char *, int));static voiddebug_to_resume PARAMS ((int, int, enum target_signal));static intdebug_to_wait PARAMS ((int, struct target_waitstatus *));static voiddebug_to_fetch_registers PARAMS ((int));static voiddebug_to_store_registers PARAMS ((int));static voiddebug_to_prepare_to_store PARAMS ((void));static intdebug_to_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));static voiddebug_to_files_info PARAMS ((struct target_ops *));static intdebug_to_insert_breakpoint PARAMS ((CORE_ADDR, char *));static intdebug_to_remove_breakpoint PARAMS ((CORE_ADDR, char *));static voiddebug_to_terminal_init PARAMS ((void));static voiddebug_to_terminal_inferior PARAMS ((void));static voiddebug_to_terminal_ours_for_output PARAMS ((void));static voiddebug_to_terminal_ours PARAMS ((void));static voiddebug_to_terminal_info PARAMS ((char *, int));static voiddebug_to_kill PARAMS ((void));static voiddebug_to_load PARAMS ((char *, int));static intdebug_to_lookup_symbol PARAMS ((char *, CORE_ADDR *));static voiddebug_to_create_inferior PARAMS ((char *, char *, char **));static voiddebug_to_mourn_inferior PARAMS ((void));static intdebug_to_can_run PARAMS ((void));static voiddebug_to_notice_signals PARAMS ((int));static intdebug_to_thread_alive PARAMS ((int));static voiddebug_to_stop PARAMS ((void));/* Pointer to array of target architecture structures; the size of the   array; the current index into the array; the allocated size of the    array.  */struct target_ops **target_structs;unsigned target_struct_size;unsigned target_struct_index;unsigned target_struct_allocsize;#define	DEFAULT_ALLOCSIZE	10/* The initial current target, so that there is always a semi-valid   current target.  */struct target_ops dummy_target = {  "None",			/* to_shortname */  "None",			/* to_longname */  "",				/* to_doc */  0,				/* to_open */  0,				/* to_close */  find_default_attach,		/* to_attach */  0,				/* to_detach */  0,				/* to_resume */  0,				/* to_wait */  0,				/* to_fetch_registers */  0,				/* to_store_registers */  0,				/* to_prepare_to_store */  0,				/* to_xfer_memory */  0,				/* to_files_info */  0,				/* to_insert_breakpoint */  0,				/* to_remove_breakpoint */  0,				/* to_terminal_init */  0,				/* to_terminal_inferior */  0,				/* to_terminal_ours_for_output */  0,				/* to_terminal_ours */  0,				/* to_terminal_info */  0,				/* to_kill */  0,				/* to_load */  0,				/* to_lookup_symbol */  find_default_create_inferior,	/* to_create_inferior */  0,				/* to_mourn_inferior */  0,				/* to_can_run */  0,				/* to_notice_signals */  0,				/* to_thread_alive */  0,				/* to_stop */  dummy_stratum,		/* to_stratum */  0,				/* to_next */  0,				/* to_next */  0,				/* to_has_all_memory */  0,				/* to_has_memory */  0,				/* to_has_registers */  0,				/* to_has_execution */  0,				/* to_sections */  0,				/* to_sections_end */  OPS_MAGIC,			/* to_magic */};/* Top of target stack.  */struct target_stack_item *target_stack;/* The target structure we are currently using to talk to a process   or file or whatever "inferior" we have.  */struct target_ops current_target;/* Command list for target.  */static struct cmd_list_element *targetlist = NULL;/* Nonzero if we are debugging an attached outside process   rather than an inferior.  */int attach_flag;#ifdef MAINTENANCE_CMDS/* Non-zero if we want to see trace of target level stuff.  */static int targetdebug = 0;static void setup_target_debug PARAMS ((void));#endif/* The user just typed 'target' without the name of a target.  *//* ARGSUSED */static voidtarget_command (arg, from_tty)     char *arg;     int from_tty;{  fputs_filtered ("Argument required (target name).  Try `help target'\n",		  gdb_stdout);}/* Add a possible target architecture to the list.  */voidadd_target (t)     struct target_ops *t;{  if (!target_structs)    {      target_struct_allocsize = DEFAULT_ALLOCSIZE;      target_structs = (struct target_ops **) xmalloc	(target_struct_allocsize * sizeof (*target_structs));    }  if (target_struct_size >= target_struct_allocsize)    {      target_struct_allocsize *= 2;      target_structs = (struct target_ops **)	  xrealloc ((char *) target_structs, 		    target_struct_allocsize * sizeof (*target_structs));    }  target_structs[target_struct_size++] = t;/*  cleanup_target (t);*/  if (targetlist == NULL)    add_prefix_cmd ("target", class_run, target_command,		    "Connect to a target machine or process.\n\The first argument is the type or protocol of the target machine.\n\Remaining arguments are interpreted by the target protocol.  For more\n\information on the arguments for a particular protocol, type\n\`help target ' followed by the protocol name.",		    &targetlist, "target ", 0, &cmdlist);  add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist);}/* Stub functions */static voidignore (){}/* ARGSUSED */static intnomemory (memaddr, myaddr, len, write, t)     CORE_ADDR memaddr;     char *myaddr;     int len;     int write;     struct target_ops *t;{  errno = EIO;		/* Can't read/write this location */  return 0;		/* No bytes handled */}static voidtcomplain (){  error ("You can't do that when your target is `%s'",	 current_target.to_shortname);}voidnoprocess (){  error ("You can't do that without a process to debug");}/* ARGSUSED */static intnosymbol (name, addrp)     char *name;     CORE_ADDR *addrp;{  return 1;		/* Symbol does not exist in target env */}/* ARGSUSED */static voiddefault_terminal_info (args, from_tty)     char *args;     int from_tty;{  printf_unfiltered("No saved terminal information.\n");}/* This is the default target_create_inferior and target_attach function.   If the current target is executing, it asks whether to kill it off.   If this function returns without calling error(), it has killed off   the target, and the operation should be attempted.  */static voidkill_or_be_killed (from_tty)     int from_tty;{  if (target_has_execution)    {      printf_unfiltered ("You are already running a program:\n");      target_files_info ();      if (query ("Kill it? ")) {	target_kill ();	if (target_has_execution)	  error ("Killing the program did not help.");	return;      } else {	error ("Program not killed.");      }    }  tcomplain();}static voidmaybe_kill_then_attach (args, from_tty)     char *args;     int from_tty;{  kill_or_be_killed (from_tty);  target_attach (args, from_tty);}static voidmaybe_kill_then_create_inferior (exec, args, env)     char *exec;     char *args;     char **env;{  kill_or_be_killed (0);  target_create_inferior (exec, args, env);}/* Clean up a target struct so it no longer has any zero pointers in it.   We default entries, at least to stubs that print error messages.  */static voidcleanup_target (t)     struct target_ops *t;{#define de_fault(field, value) \  if (!t->field)	t->field = value  /*        FIELD			DEFAULT VALUE        */  de_fault (to_open, 			(void (*) PARAMS((char *, int))) tcomplain);  de_fault (to_close, 			(void (*) PARAMS((int))) ignore);  de_fault (to_attach, 			maybe_kill_then_attach);  de_fault (to_detach, 			(void (*) PARAMS((char *, int))) ignore);  de_fault (to_resume, 			(void (*) PARAMS((int, int, enum target_signal))) noprocess);  de_fault (to_wait, 			(int (*) PARAMS((int, struct target_waitstatus *))) noprocess);  de_fault (to_fetch_registers, 	(void (*) PARAMS((int))) ignore);  de_fault (to_store_registers,		(void (*) PARAMS((int))) noprocess);  de_fault (to_prepare_to_store,	(void (*) PARAMS((void))) noprocess);  de_fault (to_xfer_memory,		(int (*) PARAMS((CORE_ADDR, char *, int, int, struct target_ops *))) nomemory);  de_fault (to_files_info,		(void (*) PARAMS((struct target_ops *))) ignore);  de_fault (to_insert_breakpoint,	memory_insert_breakpoint);  de_fault (to_remove_breakpoint,	memory_remove_breakpoint);  de_fault (to_terminal_init,		(void (*) PARAMS((void))) ignore);  de_fault (to_terminal_inferior,	(void (*) PARAMS ((void))) ignore);  de_fault (to_terminal_ours_for_output,(void (*) PARAMS ((void))) ignore);  de_fault (to_terminal_ours,		(void (*) PARAMS ((void))) ignore);  de_fault (to_terminal_info,		default_terminal_info);  de_fault (to_kill,			(void (*) PARAMS((void))) noprocess);  de_fault (to_load,			(void (*) PARAMS((char *, int))) tcomplain);  de_fault (to_lookup_symbol,		(int (*) PARAMS ((char *, CORE_ADDR *))) nosymbol);  de_fault (to_create_inferior,		maybe_kill_then_create_inferior);  de_fault (to_mourn_inferior,		(void (*) PARAMS((void))) noprocess);  de_fault (to_can_run,			return_zero);  de_fault (to_notice_signals,		(void (*) PARAMS((int))) ignore);  de_fault (to_thread_alive,		(int (*) PARAMS((int))) ignore);  de_fault (to_stop,			(void (*) PARAMS((void))) ignore);#undef de_fault}/* Go through the target stack from top to bottom, copying over zero entries in   current_target.  In effect, we are doing class inheritance through the   pushed target vectors.  */static voidupdate_current_target (){  struct target_stack_item *item;  struct target_ops *t;  /* First, reset current_target */  memset (&current_target, 0, sizeof current_target);  for (item = target_stack; item; item = item->next)    {      t = item->target_ops;#define INHERIT(FIELD, TARGET) \      if (!current_target.FIELD) \	current_target.FIELD = TARGET->FIELD      INHERIT (to_shortname, t);      INHERIT (to_longname, t);      INHERIT (to_doc, t);      INHERIT (to_open, t);      INHERIT (to_close, t);      INHERIT (to_attach, t);      INHERIT (to_detach, t);      INHERIT (to_resume, t);      INHERIT (to_wait, t);      INHERIT (to_fetch_registers, t);      INHERIT (to_store_registers, t);      INHERIT (to_prepare_to_store, t);      INHERIT (to_xfer_memory, t);      INHERIT (to_files_info, t);      INHERIT (to_insert_breakpoint, t);      INHERIT (to_remove_breakpoint, t);      INHERIT (to_terminal_init, t);      INHERIT (to_terminal_inferior, t);      INHERIT (to_terminal_ours_for_output, t);      INHERIT (to_terminal_ours, t);      INHERIT (to_terminal_info, t);      INHERIT (to_kill, t);      INHERIT (to_load, t);      INHERIT (to_lookup_symbol, t);      INHERIT (to_create_inferior, t);      INHERIT (to_mourn_inferior, t);      INHERIT (to_can_run, t);      INHERIT (to_notice_signals, t);      INHERIT (to_thread_alive, t);      INHERIT (to_stop, t);      INHERIT (to_stratum, t);      INHERIT (DONT_USE, t);      INHERIT (to_has_all_memory, t);      INHERIT (to_has_memory, t);      INHERIT (to_has_stack, t);      INHERIT (to_has_registers, t);      INHERIT (to_has_execution, t);      INHERIT (to_sections, t);      INHERIT (to_sections_end, t);      INHERIT (to_magic, t);#undef INHERIT    }}/* Push a new target type into the stack of the existing target accessors,   possibly superseding some of the existing accessors.   Result is zero if the pushed target ended up on top of the stack,   nonzero if at least one target is on top of it.   Rather than allow an empty stack, we always have the dummy target at   the bottom stratum, so we can call the function vectors without   checking them.  */intpush_target (t)     struct target_ops *t;{  struct target_stack_item *cur, *prev, *tmp;  /* Check magic number.  If wrong, it probably means someone changed     the struct definition, but not all the places that initialize one.  */  if (t->to_magic != OPS_MAGIC)    {      fprintf_unfiltered(gdb_stderr,			 "Magic number of %s target struct wrong\n", 			 t->to_shortname);      abort();    }  /* Find the proper stratum to install this target in. */  for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next)    {      if ((int)(t->to_stratum) >= (int)(cur->target_ops->to_stratum))	break;    }  /* If there's already targets at this stratum, remove them. */  if (cur)    while (t->to_stratum == cur->target_ops->to_stratum)      {	/* There's already something on this stratum.  Close it off.  */	if (cur->target_ops->to_close)	  (cur->target_ops->to_close) (0);	if (prev)	  prev->next = cur->next; /* Unchain old target_ops */	else	  target_stack = cur->next; /* Unchain first on list */	tmp = cur->next;	free (cur);	cur = tmp;      }  /* We have removed all targets in our stratum, now add the new one.  */  tmp = (struct target_stack_item *)    xmalloc (sizeof (struct target_stack_item));  tmp->next = cur;  tmp->target_ops = t;  if (prev)    prev->next = tmp;  else    target_stack = tmp;  update_current_target ();  cleanup_target (&current_target); /* Fill in the gaps */#ifdef MAINTENANCE_CMDS  if (targetdebug)    setup_target_debug ();#endif  return prev != 0;}/* Remove a target_ops vector from the stack, wherever it may be.    Return how many times it was removed (0 or 1).  */intunpush_target (t)     struct target_ops *t;{  struct target_stack_item *cur, *prev;  if (t->to_close)    t->to_close (0);		/* Let it clean up */  /* Look for the specified target.  Note that we assume that a target     can only occur once in the target stack. */  for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next)    if (cur->target_ops == t)      break;  if (!cur)    return 0;			/* Didn't find target_ops, quit now */  /* Unchain the target */  if (!prev)    target_stack = cur->next;  else    prev->next = cur->next;  free (cur);			/* Release the target_stack_item */  update_current_target ();  cleanup_target (&current_target);  return 1;}voidpop_target (){  (current_target.to_close)(0);	/* Let it clean up */  if (unpush_target (target_stack->target_ops) == 1)    return;  fprintf_unfiltered(gdb_stderr,		     "pop_target couldn't find target %s\n", 		     current_target.to_shortname);  abort();}#undef	MIN#define MIN(A, B) (((A) <= (B)) ? (A) : (B))/* target_read_string -- read a null terminated string, up to LEN bytes,   from MEMADDR in target.  Set *ERRNOP to the errno code, or 0 if successful.   Set *STRING to a pointer to malloc'd memory containing the data; the caller   is responsible for freeing it.  Return the number of bytes successfully   read.  */inttarget_read_string (memaddr, string, len, errnop)     CORE_ADDR memaddr;     char **string;     int len;     int *errnop;{  int tlen, origlen, offset, i;  char buf[4];  int errcode = 0;  char *buffer;  int buffer_allocated;  char *bufptr;  unsigned int nbytes_read = 0;  /* Small for testing.  */  buffer_allocated = 4;  buffer = xmalloc (buffer_allocated);  bufptr = buffer;  origlen = len;  while (len > 0)    {      tlen = MIN (len, 4 - (memaddr & 3));      offset = memaddr & 3;      errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);      if (errcode != 0)	goto done;      if (bufptr - buffer + tlen > buffer_allocated)	{	  unsigned int bytes;	  bytes = bufptr - buffer;	  buffer_allocated *= 2;	  buffer = xrealloc (buffer, buffer_allocated);	  bufptr = buffer + bytes;	}      for (i = 0; i < tlen; i++)	{	  *bufptr++ = buf[i + offset];	  if (buf[i + offset] == '\000')	    {	      nbytes_read += i + 1;	      goto done;	    }	}      memaddr += tlen;      len -= tlen;      nbytes_read += tlen;    } done:  if (errnop != NULL)    *errnop = errcode;  if (string != NULL)    *string = buffer;  return nbytes_read;}/* Read LEN bytes of target memory at address MEMADDR, placing the results in   GDB's memory at MYADDR.  Returns either 0 for success or an errno value   if any error occurs.   If an error occurs, no guarantee is made about the contents of the data at   MYADDR.  In particular, the caller should not depend upon partial reads   filling the buffer with good data.  There is no way for the caller to know   how much good data might have been transfered anyway.  Callers that can   deal with partial reads should call target_read_memory_partial. */inttarget_read_memory (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  return target_xfer_memory (memaddr, myaddr, len, 0);}/* Read LEN bytes of target memory at address MEMADDR, placing the results   in GDB's memory at MYADDR.  Returns a count of the bytes actually read,   and optionally an errno value in the location pointed to by ERRNOPTR   if ERRNOPTR is non-null. */inttarget_read_memory_partial (memaddr, myaddr, len, errnoptr)     CORE_ADDR memaddr;     char *myaddr;     int len;     int *errnoptr;{  int nread;	/* Number of bytes actually read. */  int errcode;	/* Error from last read. */  /* First try a complete read. */  errcode = target_xfer_memory (memaddr, myaddr, len, 0);  if (errcode == 0)    {      /* Got it all. */      nread = len;    }  else    {      /* Loop, reading one byte at a time until we get as much as we can. */      for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)	{	  errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0);	}      /* If an error, the last read was unsuccessful, so adjust count. */      if (errcode != 0)	{	  nread--;	}    }  if (errnoptr != NULL)    {      *errnoptr = errcode;    }  return (nread);}inttarget_write_memory (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  return target_xfer_memory (memaddr, myaddr, len, 1);} /* Move memory to or from the targets.  Iterate until all of it has   been moved, if necessary.  The top target gets priority; anything   it doesn't want, is offered to the next one down, etc.  Note the   business with curlen:  if an early target says "no, but I have a   boundary overlapping this xfer" then we shorten what we offer to   the subsequent targets so the early guy will get a chance at the   tail before the subsequent ones do.    Result is 0 or errno value.  */inttarget_xfer_memory (memaddr, myaddr, len, write)     CORE_ADDR memaddr;     char *myaddr;     int len;     int write;{  int curlen;  int res;  struct target_ops *t;  struct target_stack_item *item;  /* to_xfer_memory is not guaranteed to set errno, even when it returns     0.  */  errno = 0;  /* The quick case is that the top target does it all.  */  res = current_target.to_xfer_memory			(memaddr, myaddr, len, write, &current_target);  if (res == len)    return 0;  if (res > 0)    goto bump;  /* If res <= 0 then we call it again in the loop.  Ah well.  */  for (; len > 0;)    {      curlen = len;		/* Want to do it all */      for (item = target_stack; item; item = item->next)	{	  t = item->target_ops;	  if (!t->to_has_memory)	    continue;	  res = t->to_xfer_memory (memaddr, myaddr, curlen, write, t);	  if (res > 0)	    break;		/* Handled all or part of xfer */	  if (t->to_has_all_memory)	    break;	}      if (res <= 0)	{	  /* If this address is for nonexistent memory,	     read zeros if reading, or do nothing if writing.  Return error. */	  if (!write)	    memset (myaddr, 0, len);	  if (errno == 0)	    return EIO;	  else	    return errno;	}bump:      memaddr += res;      myaddr  += res;      len     -= res;    }  return 0;			/* We managed to cover it all somehow. */}/* ARGSUSED */static voidtarget_info (args, from_tty)     char *args;     int from_tty;{  struct target_ops *t;  struct target_stack_item *item;  int has_all_mem = 0;    if (symfile_objfile != NULL)    printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name);#ifdef FILES_INFO_HOOK  if (FILES_INFO_HOOK ())    return;#endif  for (item = target_stack; item; item = item->next)    {      t = item->target_ops;      if (!t->to_has_memory)	continue;      if ((int)(t->to_stratum) <= (int)dummy_stratum)	continue;      if (has_all_mem)	printf_unfiltered("\tWhile running this, GDB does not access memory from...\n");      printf_unfiltered("%s:\n", t->to_longname);      (t->to_files_info)(t);      has_all_mem = t->to_has_all_memory;    }}/* This is to be called by the open routine before it does   anything.  */voidtarget_preopen (from_tty)     int from_tty;{  dont_repeat();  if (target_has_execution)    {         if (query ("A program is being debugged already.  Kill it? "))        target_kill ();      else        error ("Program not killed.");    }  /* Calling target_kill may remove the target from the stack.  But if     it doesn't (which seems like a win for UDI), remove it now.  */  if (target_has_execution)    pop_target ();}/* Detach a target after doing deferred register stores.  */voidtarget_detach (args, from_tty)     char *args;     int from_tty;{  /* Handle any optimized stores to the inferior.  */#ifdef DO_DEFERRED_STORES  DO_DEFERRED_STORES;#endif  (current_target.to_detach) (args, from_tty);}voidtarget_link (modname, t_reloc)     char *modname;     CORE_ADDR *t_reloc;{  if (STREQ(current_target.to_shortname, "rombug"))    {      (current_target.to_lookup_symbol) (modname, t_reloc);      if (*t_reloc == 0)      error("Unable to link to %s and get relocation in rombug", modname);    }  else    *t_reloc = (CORE_ADDR)-1;}/* Look through the list of possible targets for a target that can   execute a run or attach command without any other data.  This is   used to locate the default process stratum.   Result is always valid (error() is called for errors).  */static struct target_ops *find_default_run_target (do_mesg)     char *do_mesg;{  struct target_ops **t;  struct target_ops *runable = NULL;  int count;  count = 0;  for (t = target_structs; t < target_structs + target_struct_size;       ++t)    {      if ((*t)->to_can_run && target_can_run(*t))	{	  runable = *t;	  ++count;	}    }  if (count != 1)    error ("Don't know how to %s.  Try \"help target\".", do_mesg);  return runable;}