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

📄 dwarfread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      basicdieinfo (&mbr, thisdie, objfile);      completedieinfo (&mbr, objfile);      if (mbr.die_length <= SIZEOF_DIE_LENGTH)	{	  break;	}      else if (mbr.at_sibling != 0)	{	  nextdie = dbbase + mbr.at_sibling - dbroff;	}      else	{	  nextdie = thisdie + mbr.die_length;	}      switch (mbr.die_tag)	{	case TAG_member:	  /* Get space to record the next field's data.  */	  new = (struct nextfield *) alloca (sizeof (struct nextfield));	  new -> next = list;	  list = new;	  /* Save the data.  */	  list -> field.name =	      obsavestring (mbr.at_name, strlen (mbr.at_name),			    &objfile -> type_obstack);	  list -> field.type = decode_die_type (&mbr);	  list -> field.bitpos = 8 * locval (mbr.at_location);	  /* Handle bit fields. */	  list -> field.bitsize = mbr.at_bit_size;#if BITS_BIG_ENDIAN	  /* For big endian bits, the at_bit_offset gives the additional	     bit offset from the MSB of the containing anonymous object to	     the MSB of the field.  We don't have to do anything special	     since we don't need to know the size of the anonymous object. */	  list -> field.bitpos += mbr.at_bit_offset;#else	  /* For little endian bits, we need to have a non-zero at_bit_size,	     so that we know we are in fact dealing with a bitfield.  Compute	     the bit offset to the MSB of the anonymous object, subtract off	     the number of bits from the MSB of the field to the MSB of the	     object, and then subtract off the number of bits of the field	     itself.  The result is the bit offset of the LSB of the field. */	  if (mbr.at_bit_size > 0)	    {	      if (mbr.has_at_byte_size)		{		  /* The size of the anonymous object containing the bit field		     is explicit, so use the indicated size (in bytes). */		  anonymous_size = mbr.at_byte_size;		}	      else		{		  /* The size of the anonymous object containing the bit field		     matches the size of an object of the bit field's type.		     DWARF allows at_byte_size to be left out in such cases,		     as a debug information size optimization. */		  anonymous_size = TYPE_LENGTH (list -> field.type);		}	      list -> field.bitpos +=		anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size;	    }#endif	  nfields++;	  break;	default:	  process_dies (thisdie, nextdie, objfile);	  break;	}      thisdie = nextdie;    }  /* Now create the vector of fields, and record how big it is.  We may     not even have any fields, if this DIE was generated due to a reference     to an anonymous structure or union.  In this case, TYPE_FLAG_STUB is     set, which clues gdb in to the fact that it needs to search elsewhere     for the full structure definition. */  if (nfields == 0)    {      TYPE_FLAGS (type) |= TYPE_FLAG_STUB;    }  else    {      TYPE_NFIELDS (type) = nfields;      TYPE_FIELDS (type) = (struct field *)	TYPE_ALLOC (type, sizeof (struct field) * nfields);      /* Copy the saved-up fields into the field vector.  */      for (n = nfields; list; list = list -> next)	{	  TYPE_FIELD (type, --n) = list -> field;	}	    }  return (type);}/*LOCAL FUNCTION	read_structure_scope -- process all dies within struct or unionSYNOPSIS	static void read_structure_scope (struct dieinfo *dip,		char *thisdie, char *enddie, struct objfile *objfile)DESCRIPTION	Called when we find the DIE that starts a structure or union	scope (definition) to process all dies that define the members	of the structure or union.  DIP is a pointer to the die info	struct for the DIE that names the structure or union.NOTES	Note that we need to call struct_type regardless of whether or not	the DIE has an at_name attribute, since it might be an anonymous	structure or union.  This gets the type entered into our set of	user defined types.	However, if the structure is incomplete (an opaque struct/union)	then suppress creating a symbol table entry for it since gdb only	wants to find the one with the complete definition.  Note that if	it is complete, we just call new_symbol, which does it's own	checking about whether the struct/union is anonymous or not (and	suppresses creating a symbol table entry itself).	 */static voidread_structure_scope (dip, thisdie, enddie, objfile)     struct dieinfo *dip;     char *thisdie;     char *enddie;     struct objfile *objfile;{  struct type *type;  struct symbol *sym;    type = struct_type (dip, thisdie, enddie, objfile);  if (!(TYPE_FLAGS (type) & TYPE_FLAG_STUB))    {      sym = new_symbol (dip, objfile);      if (sym != NULL)	{	  SYMBOL_TYPE (sym) = type;	  if (cu_language == language_cplus)	    {	      synthesize_typedef (dip, objfile, type);	    }	}    }}/*LOCAL FUNCTION	decode_array_element_type -- decode type of the array elementsSYNOPSIS	static struct type *decode_array_element_type (char *scan, char *end)DESCRIPTION	As the last step in decoding the array subscript information for an	array DIE, we need to decode the type of the array elements.  We are	passed a pointer to this last part of the subscript information and	must return the appropriate type.  If the type attribute is not	recognized, just warn about the problem and return type int. */static struct type *decode_array_element_type (scan)     char *scan;{  struct type *typep;  DIE_REF die_ref;  unsigned short attribute;  unsigned short fundtype;  int nbytes;    attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED,			      current_objfile);  scan += SIZEOF_ATTRIBUTE;  if ((nbytes = attribute_size (attribute)) == -1)    {      SQUAWK (("bad array element type attribute 0x%x", attribute));      typep = lookup_fundamental_type (current_objfile, FT_INTEGER);    }  else    {      switch (attribute)	{	  case AT_fund_type:	    fundtype = target_to_host (scan, nbytes, GET_UNSIGNED,				       current_objfile);	    typep = decode_fund_type (fundtype);	    break;	  case AT_mod_fund_type:	    typep = decode_mod_fund_type (scan);	    break;	  case AT_user_def_type:	    die_ref = target_to_host (scan, nbytes, GET_UNSIGNED,				      current_objfile);	    if ((typep = lookup_utype (die_ref)) == NULL)	      {		typep = alloc_utype (die_ref, NULL);	      }	    break;	  case AT_mod_u_d_type:	    typep = decode_mod_u_d_type (scan);	    break;	  default:	    SQUAWK (("bad array element type attribute 0x%x", attribute));	    typep = lookup_fundamental_type (current_objfile, FT_INTEGER);	    break;	  }    }  return (typep);}/*LOCAL FUNCTION	decode_subscr_data -- decode array subscript and element type dataSYNOPSIS	static struct type *decode_subscr_data (char *scan, char *end)DESCRIPTION	The array subscripts and the data type of the elements of an	array are described by a list of data items, stored as a block	of contiguous bytes.  There is a data item describing each array	dimension, and a final data item describing the element type.	The data items are ordered the same as their appearance in the	source (I.E. leftmost dimension first, next to leftmost second,	etc).	We are passed a pointer to the start of the block of bytes	containing the data items, and a pointer to the first byte past	the data.  This function decodes the data and returns a type.BUGS	FIXME:  This code only implements the forms currently used	by the AT&T and GNU C compilers.	The end pointer is supplied for error checking, maybe we should	use it for that... */static struct type *decode_subscr_data (scan, end)     char *scan;     char *end;{  struct type *typep = NULL;  struct type *nexttype;  unsigned int format;  unsigned short fundtype;  unsigned long lowbound;  unsigned long highbound;  int nbytes;    format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED,			   current_objfile);  scan += SIZEOF_FORMAT_SPECIFIER;  switch (format)    {    case FMT_ET:      typep = decode_array_element_type (scan);      break;    case FMT_FT_C_C:      fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED,				 current_objfile);      scan += SIZEOF_FMT_FT;      if (fundtype != FT_integer && fundtype != FT_signed_integer	  && fundtype != FT_unsigned_integer)	{	  SQUAWK (("array subscripts must be integral types, not type 0x%x",		   fundtype));	}      else	{	  nbytes = TARGET_FT_LONG_SIZE (current_objfile);	  lowbound = target_to_host (scan, nbytes, GET_UNSIGNED,				     current_objfile);	  scan += nbytes;	  highbound = target_to_host (scan, nbytes, GET_UNSIGNED,				      current_objfile);	  scan += nbytes;	  nexttype = decode_subscr_data (scan, end);	  if (nexttype != NULL)	    {	      typep = alloc_type (current_objfile);	      TYPE_CODE (typep) = TYPE_CODE_ARRAY;	      TYPE_LENGTH (typep) = TYPE_LENGTH (nexttype);	      TYPE_LENGTH (typep) *= (highbound - lowbound) + 1;	      TYPE_TARGET_TYPE (typep) = nexttype;	    }		    	}      break;    case FMT_FT_C_X:    case FMT_FT_X_C:    case FMT_FT_X_X:    case FMT_UT_C_C:    case FMT_UT_C_X:    case FMT_UT_X_C:    case FMT_UT_X_X:      SQUAWK (("array subscript format 0x%x not handled yet", format));      break;    default:      SQUAWK (("unknown array subscript format %x", format));      break;    }  return (typep);}/*LOCAL FUNCTION	dwarf_read_array_type -- read TAG_array_type DIESYNOPSIS	static void dwarf_read_array_type (struct dieinfo *dip)DESCRIPTION	Extract all information from a TAG_array_type DIE and add to	the user defined type vector. */static voiddwarf_read_array_type (dip)     struct dieinfo *dip;{  struct type *type;  struct type *utype;  char *sub;  char *subend;  unsigned short blocksz;  int nbytes;    if (dip -> at_ordering != ORD_row_major)    {      /* FIXME:  Can gdb even handle column major arrays? */      SQUAWK (("array not row major; not handled correctly"));    }  if ((sub = dip -> at_subscr_data) != NULL)    {      nbytes = attribute_size (AT_subscr_data);      blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile);      subend = sub + nbytes + blocksz;      sub += nbytes;      type = decode_subscr_data (sub, subend);      if (type == NULL)	{	  if ((utype = lookup_utype (dip -> die_ref)) == NULL)	    {	      utype = alloc_utype (dip -> die_ref, NULL);	    }	  TYPE_CODE (utype) = TYPE_CODE_ARRAY;	  TYPE_TARGET_TYPE (utype) =       	    lookup_fundamental_type (current_objfile, FT_INTEGER);	  TYPE_LENGTH (utype) = 1 * TYPE_LENGTH (TYPE_TARGET_TYPE (utype));	}      else	{	  if ((utype = lookup_utype (dip -> die_ref)) == NULL)	    {	      alloc_utype (dip -> die_ref, type);	    }	  else	    {	      TYPE_CODE (utype) = TYPE_CODE_ARRAY;	      TYPE_LENGTH (utype) = TYPE_LENGTH (type);	      TYPE_TARGET_TYPE (utype) = TYPE_TARGET_TYPE (type);	    }	}    }}/*LOCAL FUNCTION	read_tag_pointer_type -- read TAG_pointer_type DIESYNOPSIS	static void read_tag_pointer_type (struct dieinfo *dip)DESCRIPTION	Extract all information from a TAG_pointer_type DIE and add to	the user defined type vector. */static voidread_tag_pointer_type (dip)     struct dieinfo *dip;{  struct type *type;  struct type *utype;    type = decode_die_type (dip);  if ((utype = lookup_utype (dip -> die_ref)) == NULL)    {      utype = lookup_pointer_type (type);      alloc_utype (dip -> die_ref, utype);    }  else    {      TYPE_TARGET_TYPE (utype) = type;      TYPE_POINTER_TYPE (type) = utype;      /* We assume the machine has only one representation for pointers!  */      /* FIXME:  This confuses host<->target data representations, and is a	 poor assumption besides. */            TYPE_LENGTH (utype) = sizeof (char *);      TYPE_CODE (utype) = TYPE_CODE_PTR;    }}/*LOCAL FUNCTION	read_subroutine_type -- process TAG_subroutine_type diesSYNOPSIS	static void read_subroutine_type (struct dieinfo *dip, char thisdie,		char *enddie)DESCRIPTION	Handle DIES due to C code like:	struct foo {	    int (*funcp)(int a, long l);  (Generates TAG_subroutine_type DIE)	    int b;	};NOTES	The parameter DIES are currently ignored.  See if gdb has a way to	include this info in it's type system, and decode them if so.  Is	this what the type structure's "arg_types" field is for?  (FIXME) */static voidread_subroutine_type (dip, thisdie, enddie)     struct dieinfo *dip;     char *thisdie;     char *enddie;{  struct type *type;		/* Type that this function returns */  struct type *ftype;		/* Function that returns above type */

⌨️ 快捷键说明

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