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

📄 dwarfread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Decode the type that this subroutine returns */  type = decode_die_type (dip);  /* Check to see if we already have a partially constructed user     defined type for this DIE, from a forward reference. */  if ((ftype = lookup_utype (dip -> die_ref)) == NULL)    {      /* This is the first reference to one of these types.  Make	 a new one and place it in the user defined types. */      ftype = lookup_function_type (type);      alloc_utype (dip -> die_ref, ftype);    }  else    {      /* We have an existing partially constructed type, so bash it	 into the correct type. */      TYPE_TARGET_TYPE (ftype) = type;      TYPE_FUNCTION_TYPE (type) = ftype;      TYPE_LENGTH (ftype) = 1;      TYPE_CODE (ftype) = TYPE_CODE_FUNC;    }}/*LOCAL FUNCTION	read_enumeration -- process dies which define an enumerationSYNOPSIS	static void read_enumeration (struct dieinfo *dip, char *thisdie,		char *enddie, struct objfile *objfile)DESCRIPTION	Given a pointer to a die which begins an enumeration, process all	the dies that define the members of the enumeration.NOTES	Note that we need to call enum_type regardless of whether or not we	have a symbol, since we might have an enum without a tag name (thus	no symbol for the tagname). */static voidread_enumeration (dip, thisdie, enddie, objfile)     struct dieinfo *dip;     char *thisdie;     char *enddie;     struct objfile *objfile;{  struct type *type;  struct symbol *sym;    type = enum_type (dip, objfile);  sym = new_symbol (dip, objfile);  if (sym != NULL)    {      SYMBOL_TYPE (sym) = type;      if (cu_language == language_cplus)	{	  synthesize_typedef (dip, objfile, type);	}    }}/*LOCAL FUNCTION	enum_type -- decode and return a type for an enumerationSYNOPSIS	static type *enum_type (struct dieinfo *dip, struct objfile *objfile)DESCRIPTION	Given a pointer to a die information structure for the die which	starts an enumeration, process all the dies that define the members	of the enumeration and return a type pointer for the enumeration.	At the same time, for each member of the enumeration, create a	symbol for it with namespace VAR_NAMESPACE and class LOC_CONST,	and give it the type of the enumeration itself.NOTES	Note that the DWARF specification explicitly mandates that enum	constants occur in reverse order from the source program order,	for "consistency" and because this ordering is easier for many	compilers to generate. (Draft 6, sec 3.8.5, Enumeration type	Entries).  Because gdb wants to see the enum members in program	source order, we have to ensure that the order gets reversed while	we are processing them. */static struct type *enum_type (dip, objfile)     struct dieinfo *dip;     struct objfile *objfile;{  struct type *type;  struct nextfield {    struct nextfield *next;    struct field field;  };  struct nextfield *list = NULL;  struct nextfield *new;  int nfields = 0;  int n;  char *scan;  char *listend;  unsigned short blocksz;  struct symbol *sym;  int nbytes;    if ((type = lookup_utype (dip -> die_ref)) == NULL)    {      /* No forward references created an empty type, so install one now */      type = alloc_utype (dip -> die_ref, NULL);    }  TYPE_CODE (type) = TYPE_CODE_ENUM;  /* Some compilers try to be helpful by inventing "fake" names for     anonymous enums, structures, and unions, like "~0fake" or ".0fake".     Thanks, but no thanks... */  if (dip -> at_name != NULL      && *dip -> at_name != '~'      && *dip -> at_name != '.')    {      TYPE_NAME (type) = obconcat (&objfile -> type_obstack, "enum",				   " ", dip -> at_name);    }  if (dip -> at_byte_size != 0)    {      TYPE_LENGTH (type) = dip -> at_byte_size;    }  if ((scan = dip -> at_element_list) != NULL)    {      if (dip -> short_element_list)	{	  nbytes = attribute_size (AT_short_element_list);	}      else	{	  nbytes = attribute_size (AT_element_list);	}      blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile);      listend = scan + nbytes + blocksz;      scan += nbytes;      while (scan < listend)	{	  new = (struct nextfield *) alloca (sizeof (struct nextfield));	  new -> next = list;	  list = new;	  list -> field.type = NULL;	  list -> field.bitsize = 0;	  list -> field.bitpos =	    target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,			    objfile);	  scan += TARGET_FT_LONG_SIZE (objfile);	  list -> field.name = obsavestring (scan, strlen (scan),					     &objfile -> type_obstack);	  scan += strlen (scan) + 1;	  nfields++;	  /* Handcraft a new symbol for this enum member. */	  sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,						 sizeof (struct symbol));	  memset (sym, 0, sizeof (struct symbol));	  SYMBOL_NAME (sym) = create_name (list -> field.name,					   &objfile->symbol_obstack);	  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;	  SYMBOL_CLASS (sym) = LOC_CONST;	  SYMBOL_TYPE (sym) = type;	  SYMBOL_VALUE (sym) = list -> field.bitpos;	  add_symbol_to_list (sym, list_in_scope);	}      /* Now create the vector of fields, and record how big it is. This is	 where we reverse the order, by pulling the members off the list in	 reverse order from how they were inserted.  If we have no fields	 (this is apparently possible in C++) then skip building a field	 vector. */      if (nfields > 0)	{	  TYPE_NFIELDS (type) = nfields;	  TYPE_FIELDS (type) = (struct field *)	    obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields);	  /* Copy the saved-up fields into the field vector.  */	  for (n = 0; (n < nfields) && (list != NULL); list = list -> next)	    {	      TYPE_FIELD (type, n++) = list -> field;	    }		}    }  return (type);}/*LOCAL FUNCTION	read_func_scope -- process all dies within a function scopeDESCRIPTION	Process all dies within a given function scope.  We are passed	a die information structure pointer DIP for the die which	starts the function scope, and pointers into the raw die data	that define the dies within the function scope.	For now, we ignore lexical block scopes within the function.	The problem is that AT&T cc does not define a DWARF lexical	block scope for the function itself, while gcc defines a	lexical block scope for the function.  We need to think about	how to handle this difference, or if it is even a problem.	(FIXME) */static voidread_func_scope (dip, thisdie, enddie, objfile)     struct dieinfo *dip;     char *thisdie;     char *enddie;     struct objfile *objfile;{  register struct context_stack *new;    if (objfile -> ei.entry_point >= dip -> at_low_pc &&      objfile -> ei.entry_point <  dip -> at_high_pc)    {      objfile -> ei.entry_func_lowpc = dip -> at_low_pc;      objfile -> ei.entry_func_highpc = dip -> at_high_pc;    }  if (STREQ (dip -> at_name, "main"))	/* FIXME: hardwired name */    {      objfile -> ei.main_func_lowpc = dip -> at_low_pc;      objfile -> ei.main_func_highpc = dip -> at_high_pc;    }  new = push_context (0, dip -> at_low_pc);  new -> name = new_symbol (dip, objfile);  list_in_scope = &local_symbols;  process_dies (thisdie + dip -> die_length, enddie, objfile);  new = pop_context ();  /* Make a block for the local symbols within.  */  finish_block (new -> name, &local_symbols, new -> old_blocks,		new -> start_addr, dip -> at_high_pc, objfile);  list_in_scope = &file_symbols;}/*LOCAL FUNCTION	handle_producer -- process the AT_producer attributeDESCRIPTION	Perform any operations that depend on finding a particular	AT_producer attribute. */static voidhandle_producer (producer)     char *producer;{  /* If this compilation unit was compiled with g++ or gcc, then set the     processing_gcc_compilation flag. */  processing_gcc_compilation =    STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))      || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));  /* Select a demangling style if we can identify the producer and if     the current style is auto.  We leave the current style alone if it     is not auto.  We also leave the demangling style alone if we find a     gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */#if 1 /* Works, but is experimental.  -fnf */  if (AUTO_DEMANGLING)    {      if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))	{	  set_demangling_style (GNU_DEMANGLING_STYLE_STRING);	}      else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))	{	  set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);	}      else if (STREQN (producer, CFRONT_PRODUCER, strlen (CFRONT_PRODUCER)))	{	  set_demangling_style (CFRONT_DEMANGLING_STYLE_STRING);	}    }#endif}/*LOCAL FUNCTION	read_file_scope -- process all dies within a file scopeDESCRIPTION	Process all dies within a given file scope.  We are passed a	pointer to the die information structure for the die which	starts the file scope, and pointers into the raw die data which	mark the range of dies within the file scope.	When the partial symbol table is built, the file offset for the line	number table for each compilation unit is saved in the partial symbol	table entry for that compilation unit.  As the symbols for each	compilation unit are read, the line number table is read into memory	and the variable lnbase is set to point to it.  Thus all we have to	do is use lnbase to access the line number table for the current	compilation unit. */static voidread_file_scope (dip, thisdie, enddie, objfile)     struct dieinfo *dip;     char *thisdie;     char *enddie;     struct objfile *objfile;{  struct cleanup *back_to;  struct symtab *symtab;    if (objfile -> ei.entry_point >= dip -> at_low_pc &&      objfile -> ei.entry_point <  dip -> at_high_pc)    {      objfile -> ei.entry_file_lowpc = dip -> at_low_pc;      objfile -> ei.entry_file_highpc = dip -> at_high_pc;    }  set_cu_language (dip);  if (dip -> at_producer != NULL)    {      handle_producer (dip -> at_producer);    }  numutypes = (enddie - thisdie) / 4;  utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));  back_to = make_cleanup (free, utypes);  memset (utypes, 0, numutypes * sizeof (struct type *));  start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc);  decode_line_numbers (lnbase);  process_dies (thisdie + dip -> die_length, enddie, objfile);  symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile);  if (symtab != NULL)    {      symtab -> language = cu_language;    }        do_cleanups (back_to);  utypes = NULL;  numutypes = 0;}/*LOCAL FUNCTION	process_dies -- process a range of DWARF Information EntriesSYNOPSIS	static void process_dies (char *thisdie, char *enddie,				  struct objfile *objfile)DESCRIPTION	Process all DIE's in a specified range.  May be (and almost	certainly will be) called recursively. */static voidprocess_dies (thisdie, enddie, objfile)     char *thisdie;     char *enddie;     struct objfile *objfile;{  char *nextdie;  struct dieinfo di;    while (thisdie < enddie)    {      basicdieinfo (&di, thisdie, objfile);      if (di.die_length < SIZEOF_DIE_LENGTH)	{	  break;	}      else if (di.die_tag == TAG_padding)	{	  nextdie = thisdie + di.die_length;	}      else	{	  completedieinfo (&di, objfile);	  if (di.at_sibling != 0)	    {	      nextdie = dbbase + di.at_sibling - dbroff;	    }	  else	    {	      nextdie = thisdie + di.die_length;	    }	  switch (di.die_tag)	    {	    case TAG_compile_unit:	      read_file_scope (&di, thisdie, nextdie, objfile);	      break;	    case TAG_global_subroutine:	    case TAG_subroutine:	      if (di.has_at_low_pc)		{		  read_func_scope (&di, thisdie, nextdie, objfile);		}	      break;	    case TAG_lexical_block:	      read_lexical_block_scope (&di, thisdie, nextdie, objfile);	      break;	    case TAG_class_type:	    case TAG_structure_type:	    case TAG_union_type:	      read_structure_scope (&di, thisdie, nextdie, objfile);	      break;	    case TAG_enumeration_type:	      read_enumeration (&di, thisdie, nextdie, objfile);	      break;	    case TAG_subroutine_type:	      read_subroutine_type (&di, thisdie, nextdie);	      break;	    case TAG_array_type:	      dwarf_read_array_type (&di);	      break;	    case TAG_pointer_type:	      read_tag_pointer_type (&di);	      break;	    default:	      new_symbol (&di, objfile);	      break;	    }	}      thisdie = nextdie;    }}/*LOCAL FUNCTION	decode_line_numbers -- decode a line number table fragmentSYNOPSIS	static void decode_line_numbers (char *tblscan, char *tblend,		long length, long base, long line, long pc)

⌨️ 快捷键说明

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