debug.c

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

C
2,665
字号
     PTR handle;     const char *name;     enum debug_type_kind kind;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_unit *u;  /* We search the globals of all the compilation units.  I don't know     if this is correct or not.  It would be easy to change.  */  for (u = info->units; u != NULL; u = u->next)    {      struct debug_file *f;      for (f = u->files; f != NULL; f = f->next)	{	  struct debug_name *n;	  if (f->globals != NULL)	    {	      for (n = f->globals->list; n != NULL; n = n->next)		{		  if (n->kind == DEBUG_OBJECT_TAG		      && (kind == DEBUG_KIND_ILLEGAL			  || n->u.tag->kind == kind)		      && n->name[0] == name[0]		      && strcmp (n->name, name) == 0)		    return n->u.tag;		}	    }	}    }  return DEBUG_TYPE_NULL;}/* Get a base type.  We build a linked list on the stack to avoid   crashing if the type is defined circularly.  */static struct debug_type *debug_get_real_type (handle, type, list)     PTR handle;     debug_type type;     struct debug_type_real_list *list;{  struct debug_type_real_list *l;  struct debug_type_real_list rl;  switch (type->kind)    {    default:      return type;    case DEBUG_KIND_INDIRECT:    case DEBUG_KIND_NAMED:    case DEBUG_KIND_TAGGED:      break;    }  for (l = list; l != NULL; l = l->next)    {      if (l->t == type)	{	  fprintf (stderr,		   _("debug_get_real_type: circular debug information for %s\n"),		   debug_get_type_name (handle, type));	  return NULL;	}    }  rl.next = list;  rl.t = type;  switch (type->kind)    {      /* The default case is just here to avoid warnings.  */    default:    case DEBUG_KIND_INDIRECT:      if (*type->u.kindirect->slot != NULL)	return debug_get_real_type (handle, *type->u.kindirect->slot, &rl);      return type;    case DEBUG_KIND_NAMED:    case DEBUG_KIND_TAGGED:      return debug_get_real_type (handle, type->u.knamed->type, &rl);    }  /*NOTREACHED*/}/* Get the kind of a type.  */enum debug_type_kinddebug_get_type_kind (handle, type)     PTR handle;     debug_type type;{  if (type == NULL)    return DEBUG_KIND_ILLEGAL;  type = debug_get_real_type (handle, type, NULL);  if (type == NULL)    return DEBUG_KIND_ILLEGAL;  return type->kind;}/* Get the name of a type.  */const char *debug_get_type_name (handle, type)     PTR handle;     debug_type type;{  if (type->kind == DEBUG_KIND_INDIRECT)    {      if (*type->u.kindirect->slot != NULL)	return debug_get_type_name (handle, *type->u.kindirect->slot);      return type->u.kindirect->tag;    }  if (type->kind == DEBUG_KIND_NAMED      || type->kind == DEBUG_KIND_TAGGED)    return type->u.knamed->name->name;  return NULL;}/* Get the size of a type.  */bfd_vmadebug_get_type_size (handle, type)     PTR handle;     debug_type type;{  if (type == NULL)    return 0;  /* We don't call debug_get_real_type, because somebody might have     called debug_record_type_size on a named or indirect type.  */  if (type->size != 0)    return type->size;  switch (type->kind)    {    default:      return 0;    case DEBUG_KIND_INDIRECT:      if (*type->u.kindirect->slot != NULL)	return debug_get_type_size (handle, *type->u.kindirect->slot);      return 0;    case DEBUG_KIND_NAMED:    case DEBUG_KIND_TAGGED:      return debug_get_type_size (handle, type->u.knamed->type);    }  /*NOTREACHED*/}/* Get the return type of a function or method type.  */debug_typedebug_get_return_type (handle, type)     PTR handle;     debug_type type;{  if (type == NULL)    return DEBUG_TYPE_NULL;  type = debug_get_real_type (handle, type, NULL);  if (type == NULL)    return DEBUG_TYPE_NULL;  switch (type->kind)    {    default:      return DEBUG_TYPE_NULL;    case DEBUG_KIND_FUNCTION:      return type->u.kfunction->return_type;    case DEBUG_KIND_METHOD:      return type->u.kmethod->return_type;    }  /*NOTREACHED*/      }/* Get the parameter types of a function or method type (except that   we don't currently store the parameter types of a function).  */const debug_type *debug_get_parameter_types (handle, type, pvarargs)     PTR handle;     debug_type type;     boolean *pvarargs;{  if (type == NULL)    return NULL;  type = debug_get_real_type (handle, type, NULL);  if (type == NULL)    return NULL;  switch (type->kind)    {    default:      return NULL;    case DEBUG_KIND_FUNCTION:      *pvarargs = type->u.kfunction->varargs;      return type->u.kfunction->arg_types;    case DEBUG_KIND_METHOD:      *pvarargs = type->u.kmethod->varargs;      return type->u.kmethod->arg_types;    }  /*NOTREACHED*/}/* Get the target type of a type.  */debug_typedebug_get_target_type (handle, type)     PTR handle;     debug_type type;{  if (type == NULL)    return NULL;  type = debug_get_real_type (handle, type, NULL);  if (type == NULL)    return NULL;  switch (type->kind)    {    default:      return NULL;    case DEBUG_KIND_POINTER:      return type->u.kpointer;    case DEBUG_KIND_REFERENCE:      return type->u.kreference;    case DEBUG_KIND_CONST:      return type->u.kconst;    case DEBUG_KIND_VOLATILE:      return type->u.kvolatile;    }  /*NOTREACHED*/}/* Get the NULL terminated array of fields for a struct, union, or   class.  */const debug_field *debug_get_fields (handle, type)     PTR handle;     debug_type type;{  if (type == NULL)    return NULL;  type = debug_get_real_type (handle, type, NULL);  if (type == NULL)    return NULL;  switch (type->kind)    {    default:      return NULL;    case DEBUG_KIND_STRUCT:    case DEBUG_KIND_UNION:    case DEBUG_KIND_CLASS:    case DEBUG_KIND_UNION_CLASS:      return type->u.kclass->fields;    }  /*NOTREACHED*/}/* Get the type of a field.  *//*ARGSUSED*/debug_typedebug_get_field_type (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL)    return NULL;  return field->type;}/* Get the name of a field.  *//*ARGSUSED*/const char *debug_get_field_name (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL)    return NULL;  return field->name;}/* Get the bit position of a field.  *//*ARGSUSED*/bfd_vmadebug_get_field_bitpos (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL || field->static_member)    return (bfd_vma) -1;  return field->u.f.bitpos;}/* Get the bit size of a field.  *//*ARGSUSED*/bfd_vmadebug_get_field_bitsize (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL || field->static_member)    return (bfd_vma) -1;  return field->u.f.bitsize;}/* Get the visibility of a field.  *//*ARGSUSED*/enum debug_visibilitydebug_get_field_visibility (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL)    return DEBUG_VISIBILITY_IGNORE;  return field->visibility;}/* Get the physical name of a field.  */const char *debug_get_field_physname (handle, field)     PTR handle ATTRIBUTE_UNUSED;     debug_field field;{  if (field == NULL || ! field->static_member)    return NULL;  return field->u.s.physname;}/* Write out the debugging information.  This is given a handle to   debugging information, and a set of function pointers to call.  */booleandebug_write (handle, fns, fhandle)     PTR handle;     const struct debug_write_fns *fns;     PTR fhandle;{  struct debug_handle *info = (struct debug_handle *) handle;  struct debug_unit *u;  /* We use a mark to tell whether we have already written out a     particular name.  We use an integer, so that we don't have to     clear the mark fields if we happen to write out the same     information more than once.  */  ++info->mark;  /* The base_id field holds an ID value which will never be used, so     that we can tell whether we have assigned an ID during this call     to debug_write.  */  info->base_id = info->class_id;  /* We keep a linked list of classes for which was have assigned ID's     during this call to debug_write.  */  info->id_list = NULL;  for (u = info->units; u != NULL; u = u->next)    {      struct debug_file *f;      boolean first_file;      info->current_write_lineno = u->linenos;      info->current_write_lineno_index = 0;      if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))	return false;      first_file = true;      for (f = u->files; f != NULL; f = f->next)	{	  struct debug_name *n;	  if (first_file)	    first_file = false;	  else	    {	      if (! (*fns->start_source) (fhandle, f->filename))		return false;	    }	  if (f->globals != NULL)	    {	      for (n = f->globals->list; n != NULL; n = n->next)		{		  if (! debug_write_name (info, fns, fhandle, n))		    return false;		}	    }	}      /* Output any line number information which hasn't already been         handled.  */      if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))	return false;    }  return true;}/* Write out an element in a namespace.  */static booleandebug_write_name (info, fns, fhandle, n)     struct debug_handle *info;     const struct debug_write_fns *fns;     PTR fhandle;     struct debug_name *n;{  switch (n->kind)    {    case DEBUG_OBJECT_TYPE:      if (! debug_write_type (info, fns, fhandle, n->u.type, n)	  || ! (*fns->typdef) (fhandle, n->name))	return false;      return true;    case DEBUG_OBJECT_TAG:      if (! debug_write_type (info, fns, fhandle, n->u.tag, n))	return false;      return (*fns->tag) (fhandle, n->name);    case DEBUG_OBJECT_VARIABLE:      if (! debug_write_type (info, fns, fhandle, n->u.variable->type,			      (struct debug_name *) NULL))	return false;      return (*fns->variable) (fhandle, n->name, n->u.variable->kind,			       n->u.variable->val);    case DEBUG_OBJECT_FUNCTION:      return debug_write_function (info, fns, fhandle, n->name,				   n->linkage, n->u.function);    case DEBUG_OBJECT_INT_CONSTANT:      return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);    case DEBUG_OBJECT_FLOAT_CONSTANT:      return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);    case DEBUG_OBJECT_TYPED_CONSTANT:      if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,			      (struct debug_name *) NULL))	return false;      return (*fns->typed_constant) (fhandle, n->name,				     n->u.typed_constant->val);    default:      abort ();      return false;    }  /*NOTREACHED*/}/* Write out a type.  If the type is DEBUG_KIND_NAMED or   DEBUG_KIND_TAGGED, then the name argument is the name for which we   are about to call typedef or tag.  If the type is anything else,   then the name argument is a tag from a DEBUG_KIND_TAGGED type which   points to this one.  */static booleandebug_write_type (info, fns, fhandle, type, name)     struct debug_handle *info;     const struct debug_write_fns *fns;     PTR fhandle;     struct debug_type *type;     struct debug_name *name;{  unsigned int i;  int is;  const char *tag = NULL;  /* If we have a name for this type, just output it.  We only output     typedef names after they have been defined.  We output type tags     whenever we are not actually defining them.  */  if ((type->kind == DEBUG_KIND_NAMED       || type->kind == DEBUG_KIND_TAGGED)      && (type->u.knamed->name->mark == info->mark	  || (type->kind == DEBUG_KIND_TAGGED	      && type->u.knamed->name != name)))    {      if (type->kind == DEBUG_KIND_NAMED)	return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);      else	{	  struct debug_type *real;	  unsigned int id;	  real = debug_get_real_type ((PTR) info, type, NULL);	  if (real == NULL)	    return (*fns->empty_type) (fhandle);	  id = 0;	  if ((real->kind == DEBUG_KIND_STRUCT	       || real->kind == DEBUG_KIND_UNION	       || real->kind == DEBUG_KIND_CLASS	       || real->kind == DEBUG_KIND_UNION_CLASS)	      && real->u.kclass != NULL)	    {	      if (real->u.kclass->id <= info->base_id)		{		  if (! debug_set_class_id (info,					    type->u.knamed->name->name,					    real))		    return false;		}	      id = real->u.kclass->id;	    }	  return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,				   real->kind);	}    }  /* Mark the name after we have already looked for a known name, so     that we don't just define a type in terms of itself.  We need to     mark the name here so that a struct containing a pointer to     itself will work.  */  if (name != NULL)    name->mark = info->mark;  if (name != NULL      && type->kind != DEBUG_KIND_NAMED      && type->kind != DEBUG_KIND_TAGGED)    {      assert (name->kind == DEBUG_OBJECT_TAG);      tag = name->name;    }  switch (type->kind)    {    case DEBUG_KIND_ILLEGAL:      debug_error (_("debug_write_type: illegal type encountered"));      return false;    case DEBUG_KIND_INDIRECT:      if (*type->u.ki

⌨️ 快捷键说明

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