⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 target.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
   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_ops *st, *prev;  for (prev = 0, st = current_target;       st;       prev = st, st = st->to_next) {    if ((int)(t->to_stratum) >= (int)(st->to_stratum))      break;  }  while (t->to_stratum == st->to_stratum) {    /* There's already something on this stratum.  Close it off.  */    (st->to_close) (0);    if (prev)      prev->to_next = st->to_next;	/* Unchain old target_ops */    else      current_target = st->to_next;	/* Unchain first on list */    st = st->to_next;  }  /* We have removed all targets in our stratum, now add ourself.  */  t->to_next = st;  if (prev)    prev->to_next = t;  else    current_target = t;  cleanup_target (current_target);  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 unless bug).  */intunpush_target (t)     struct target_ops *t;{  struct target_ops *u, *v;  int result = 0;  for (u = current_target, v = 0;       u;       v = u, u = u->to_next)    if (u == t)      {	if (v == 0)	  pop_target();			/* unchain top copy */	else {	  (t->to_close)(0);		/* Let it clean up */	  v->to_next = t->to_next;	/* unchain middle copy */	}	result++;      }  return result;}voidpop_target (){  (current_target->to_close)(0);	/* Let it clean up */  current_target = current_target->to_next;  if (!current_target)		/* At bottom, push dummy.  */    push_target (&dummy_target);}#define MIN(A, B) (((A) <= (B)) ? (A) : (B))/* target_read_string -- read a null terminated string from MEMADDR in target.   The read may also be terminated early by getting an error from target_xfer_   memory.   LEN is the size of the buffer pointed to by MYADDR.  Note that a terminating   null will only be written if there is sufficient room.  The return value is   is the number of bytes (including the null) actually transferred.*/inttarget_read_string (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  int tlen, origlen, offset, i;  char buf[4];  origlen = len;  while (len > 0)    {      tlen = MIN (len, 4 - (memaddr & 3));      offset = memaddr & 3;      if (target_xfer_memory (memaddr & ~3, buf, 4, 0))	return origlen - len;      for (i = 0; i < tlen; i++)	{	  *myaddr++ = buf[i + offset];	  if (buf[i + offset] == '\000')	    return (origlen - len) + i + 1;	}      memaddr += tlen;      len -= tlen;    }  return origlen;}/* 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_read_memory (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  return target_xfer_memory (memaddr, myaddr, len, 0);}inttarget_write_memory (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  return target_xfer_memory (memaddr, myaddr, len, 1);} inttarget_xfer_memory (memaddr, myaddr, len, write)     CORE_ADDR memaddr;     char *myaddr;     int len;     int write;{  int curlen;  int res;  struct target_ops *t;    /* 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 (t = current_target;	   t;	   t = t->to_has_all_memory? 0: t->to_next)	{	  res = t->to_xfer_memory(memaddr, myaddr, curlen, write, t);	  if (res > 0) break;	/* Handled all or part of xfer */	  if (res == 0) continue;	/* Handled none */	  curlen = -res;	/* Could handle once we get past res bytes */	}      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;  int has_all_mem = 0;    if (symfile_objfile != NULL)    printf ("Symbols from \"%s\".\n", symfile_objfile->name);#ifdef FILES_INFO_HOOK  if (FILES_INFO_HOOK ())    return;#endif  for (t = current_target;       t;       t = t->to_next)    {      if ((int)(t->to_stratum) <= (int)dummy_stratum)	continue;      if (has_all_mem)	printf("\tWhile running this, gdb does not access memory from...\n");      printf("%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.");    }}/* 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;  int count;  count = 0;  for (t = target_structs; t < target_structs + target_struct_size;       ++t)    {      if (target_can_run(*t))	{	  runable = *t;	  ++count;	}    }  if (count != 1)    error ("Don't know how to %s.  Try \"help target\".", do_mesg);  return runable;}voidfind_default_attach (args, from_tty)     char *args;     int from_tty;{  struct target_ops *t;  t = find_default_run_target("attach");  (t->to_attach) (args, from_tty);  return;}voidfind_default_create_inferior (exec_file, allargs, env)     char *exec_file;     char *allargs;     char **env;{  struct target_ops *t;  t = find_default_run_target("run");  (t->to_create_inferior) (exec_file, allargs, env);  return;}static intreturn_zero (){  return 0;}struct target_ops *find_core_target (){  struct target_ops **t;  struct target_ops *runable;  int count;    count = 0;    for (t = target_structs; t < target_structs + target_struct_size;       ++t)    {      if ((*t)->to_stratum == core_stratum)	{	  runable = *t;	  ++count;	}    }    return(count == 1 ? runable : NULL);}  static char targ_desc[] =     "Names of targets and files being debugged.\n\Shows the entire stack of targets currently in use (including the exec-file,\n\core-file, and process, if any), as well as the symbol file name.";void_initialize_targets (){  current_target = &dummy_target;  cleanup_target (current_target);  add_info ("target", target_info, targ_desc);  add_info ("files", target_info, targ_desc);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -