debug.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,665 行 · 第 1/5 页

C
2,665
字号
struct debug_type_compare_list{  /* Next type on list.  */  struct debug_type_compare_list *next;  /* The types we are comparing.  */  struct debug_type *t1;  struct debug_type *t2;};/* During debug_get_real_type, a linked list of these structures is   kept on the stack to avoid infinite recursion.  */struct debug_type_real_list{  /* Next type on list.  */  struct debug_type_real_list *next;  /* The type we are checking.  */  struct debug_type *t;};/* Local functions.  */static void debug_error PARAMS ((const char *));static struct debug_name *debug_add_to_namespace  PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,	   enum debug_object_kind, enum debug_object_linkage));static struct debug_name *debug_add_to_current_namespace  PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,	   enum debug_object_linkage));static struct debug_type *debug_make_type  PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));static struct debug_type *debug_get_real_type  PARAMS ((PTR, debug_type, struct debug_type_real_list *));static boolean debug_write_name  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   struct debug_name *));static boolean debug_write_type  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   struct debug_type *, struct debug_name *));static boolean debug_write_class_type  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   struct debug_type *, const char *));static boolean debug_write_function  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   const char *, enum debug_object_linkage, struct debug_function *));static boolean debug_write_block  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   struct debug_block *));static boolean debug_write_linenos  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,	   bfd_vma));static boolean debug_set_class_id  PARAMS ((struct debug_handle *, const char *, struct debug_type *));static boolean debug_type_samep  PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));static boolean debug_class_type_samep  PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));/* Issue an error message.  */static voiddebug_error (message)     const char *message;{  fprintf (stderr, "%s\n", message);}/* Add an object to a namespace.  */static struct debug_name *debug_add_to_namespace (info, nsp, name, kind, linkage)     struct debug_handle *info ATTRIBUTE_UNUSED;     struct debug_namespace **nsp;     const char *name;     enum debug_object_kind kind;     enum debug_object_linkage linkage;{  struct debug_name *n;  struct debug_namespace *ns;  n = (struct debug_name *) xmalloc (sizeof *n);  memset (n, 0, sizeof *n);  n->name = name;  n->kind = kind;  n->linkage = linkage;  ns = *nsp;  if (ns == NULL)    {      ns = (struct debug_namespace *) xmalloc (sizeof *ns);      memset (ns, 0, sizeof *ns);      ns->tail = &ns->list;      *nsp = ns;    }  *ns->tail = n;  ns->tail = &n->next;  return n;}/* Add an object to the current namespace.  */static struct debug_name *debug_add_to_current_namespace (info, name, kind, linkage)     struct debug_handle *info;     const char *name;     enum debug_object_kind kind;     enum debug_object_linkage linkage;{  struct debug_namespace **nsp;  if (info->current_unit == NULL      || info->current_file == NULL)    {      debug_error (_("debug_add_to_current_namespace: no current file"));      return NULL;    }  if (info->current_block != NULL)    nsp = &info->current_block->locals;  else    nsp = &info->current_file->globals;  return debug_add_to_namespace (info, nsp, name, kind, linkage);}/* Return a handle for debugging information.  */PTRdebug_init (){  struct debug_handle *ret;  ret = (struct debug_handle *) xmalloc (sizeof *ret);  memset (ret, 0, sizeof *ret);  return (PTR) ret;}/* Set the source filename.  This implicitly starts a new compilation   unit.  */booleandebug_set_filename (handle, name)     PTR handle;     const char *name;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_file *nfile;  struct debug_unit *nunit;  if (name == NULL)    name = "";  nfile = (struct debug_file *) xmalloc (sizeof *nfile);  memset (nfile, 0, sizeof *nfile);  nfile->filename = name;  nunit = (struct debug_unit *) xmalloc (sizeof *nunit);  memset (nunit, 0, sizeof *nunit);  nunit->files = nfile;  info->current_file = nfile;  if (info->current_unit != NULL)    info->current_unit->next = nunit;  else    {      assert (info->units == NULL);      info->units = nunit;    }  info->current_unit = nunit;  info->current_function = NULL;  info->current_block = NULL;  info->current_lineno = NULL;  return true;}/* Change source files to the given file name.  This is used for   include files in a single compilation unit.  */booleandebug_start_source (handle, name)     PTR handle;     const char *name;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_file *f, **pf;  if (name == NULL)    name = "";  if (info->current_unit == NULL)    {      debug_error (_("debug_start_source: no debug_set_filename call"));      return false;    }  for (f = info->current_unit->files; f != NULL; f = f->next)    {      if (f->filename[0] == name[0]	  && f->filename[1] == name[1]	  && strcmp (f->filename, name) == 0)	{	  info->current_file = f;	  return true;	}    }  f = (struct debug_file *) xmalloc (sizeof *f);  memset (f, 0, sizeof *f);  f->filename = name;  for (pf = &info->current_file->next;       *pf != NULL;       pf = &(*pf)->next)    ;  *pf = f;  info->current_file = f;  return true;}/* Record a function definition.  This implicitly starts a function   block.  The debug_type argument is the type of the return value.   The boolean indicates whether the function is globally visible.   The bfd_vma is the address of the start of the function.  Currently   the parameter types are specified by calls to   debug_record_parameter.  FIXME: There is no way to specify nested   functions.  */booleandebug_record_function (handle, name, return_type, global, addr)     PTR handle;     const char *name;     debug_type return_type;     boolean global;     bfd_vma addr;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_function *f;  struct debug_block *b;  struct debug_name *n;  if (name == NULL)    name = "";  if (return_type == NULL)    return false;  if (info->current_unit == NULL)    {      debug_error (_("debug_record_function: no debug_set_filename call"));      return false;    }  f = (struct debug_function *) xmalloc (sizeof *f);  memset (f, 0, sizeof *f);  f->return_type = return_type;  b = (struct debug_block *) xmalloc (sizeof *b);  memset (b, 0, sizeof *b);  b->start = addr;  b->end = (bfd_vma) -1;  f->blocks = b;  info->current_function = f;  info->current_block = b;  /* FIXME: If we could handle nested functions, this would be the     place: we would want to use a different namespace.  */  n = debug_add_to_namespace (info,			      &info->current_file->globals,			      name,			      DEBUG_OBJECT_FUNCTION,			      (global			       ? DEBUG_LINKAGE_GLOBAL			       : DEBUG_LINKAGE_STATIC));  if (n == NULL)    return false;  n->u.function = f;  return true;}/* Record a parameter for the current function.  */booleandebug_record_parameter (handle, name, type, kind, val)     PTR handle;     const char *name;     debug_type type;     enum debug_parm_kind kind;     bfd_vma val;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_parameter *p, **pp;  if (name == NULL || type == NULL)    return false;  if (info->current_unit == NULL      || info->current_function == NULL)    {      debug_error (_("debug_record_parameter: no current function"));      return false;    }  p = (struct debug_parameter *) xmalloc (sizeof *p);  memset (p, 0, sizeof *p);  p->name = name;  p->type = type;  p->kind = kind;  p->val = val;  for (pp = &info->current_function->parameters;       *pp != NULL;       pp = &(*pp)->next)    ;  *pp = p;  return true;}/* End a function.  FIXME: This should handle function nesting.  */booleandebug_end_function (handle, addr)     PTR handle;     bfd_vma addr;{  struct debug_handle *info = (struct debug_handle *) handle;  if (info->current_unit == NULL      || info->current_block == NULL      || info->current_function == NULL)    {      debug_error (_("debug_end_function: no current function"));      return false;    }  if (info->current_block->parent != NULL)    {      debug_error (_("debug_end_function: some blocks were not closed"));      return false;    }  info->current_block->end = addr;  info->current_function = NULL;  info->current_block = NULL;  return true;}/* Start a block in a function.  All local information will be   recorded in this block, until the matching call to debug_end_block.   debug_start_block and debug_end_block may be nested.  The bfd_vma   argument is the address at which this block starts.  */booleandebug_start_block (handle, addr)     PTR handle;     bfd_vma addr;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_block *b, **pb;  /* We must always have a current block: debug_record_function sets     one up.  */  if (info->current_unit == NULL      || info->current_block == NULL)    {      debug_error (_("debug_start_block: no current block"));      return false;    }  b = (struct debug_block *) xmalloc (sizeof *b);  memset (b, 0, sizeof *b);  b->parent = info->current_block;  b->start = addr;  b->end = (bfd_vma) -1;  /* This new block is a child of the current block.  */  for (pb = &info->current_block->children;       *pb != NULL;       pb = &(*pb)->next)    ;  *pb = b;  info->current_block = b;  return true;}/* Finish a block in a function.  This matches the call to   debug_start_block.  The argument is the address at which this block   ends.  */booleandebug_end_block (handle, addr)     PTR handle;     bfd_vma addr;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_block *parent;  if (info->current_unit == NULL      || info->current_block == NULL)    {      debug_error (_("debug_end_block: no current block"));      return false;    }  parent = info->current_block->parent;  if (parent == NULL)    {      debug_error (_("debug_end_block: attempt to close top level block"));      return false;    }  info->current_block->end = addr;  info->current_block = parent;  return true;}/* Associate a line number in the current source file and function   with a given address.  */booleandebug_record_line (handle, lineno, addr)     PTR handle;     unsigned long lineno;     bfd_vma addr;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_lineno *l;  unsigned int i;  if (info->current_unit == NULL)    {      debug_error (_("debug_record_line: no current unit"));      return false;    }  l = info->current_lineno;  if (l != NULL && l->file == info->current_file)    {      for (i = 0; i < DEBUG_LINENO_COUNT; i++)	{	  if (l->linenos[i] == (unsigned long) -1)	    {	      l->linenos[i] = lineno;	      l->addrs[i] = addr;	      return true;	    }	}    }  /* If we get here, then either 1) there is no current_lineno     structure, which means this is the first line number in this     compilation unit, 2) the current_lineno structure is for a     different file, or 3) the current_lineno structure is full.     Regardless, we want to allocate a new debug_lineno structure, put     it in the right place, and make it the new current_lineno     structure.  */  l = (struct debug_lineno *) xmalloc (sizeof *l);  memset (l, 0, sizeof *l);  l->file = info->current_file;  l->linenos[0] = lineno;  l->addrs[0] = addr;  for (i = 1; i < DEBUG_LINENO_COUNT; i++)    l->linenos[i] = (unsigned long) -1;  if (info->current_lineno != NULL)    info->current_lineno->next = l;  else    info->current_unit->linenos = l;  info->current_lineno = l;  return true;}/* Start a named common block.  This is a block of variables that may   move in memory.  */booleandebug_start_common_block (handle, name)     PTR handle ATTRIBUTE_UNUSED;     const char *name ATTRIBUTE_UNUSED;{  /* FIXME */  debug_error (_("debug_start_common_block: not implemented"));  return false;}/* End a named common block.  */booleandebug_end_common_block (handle, name)     PTR handle ATTRIBUTE_UNUSED;     const char *name ATTRIBUTE_UNUSED;{  /* FIXME */  debug_error (_("debug_end_common_block: not implemented"));  return false;}/* Record a named integer constant.  */booleandebug_record_int_const (handle, name, val)     PTR handle;

⌨️ 快捷键说明

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