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

📄 coffread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If no string table is needed, then the file may end immediately     after the symbols.  Just return with `stringtab' set to null. */  if (val != sizeof length || length < sizeof length)    return 0;  stringtab = (char *) xmalloc (length);  if (stringtab == NULL)    return -1;  memcpy (stringtab, &length, sizeof length);  if (length == sizeof length)		/* Empty table -- just the count */    return 0;  val = myread (chan, stringtab + sizeof length, length - sizeof length);  if (val != length - sizeof length || stringtab[length - 1] != '\0')    return -1;  return 0;}static voidfree_stringtab (){  if (stringtab)    free (stringtab);  stringtab = NULL;}static char *getsymname (symbol_entry)    struct internal_syment *symbol_entry;{  static char buffer[SYMNMLEN+1];  char *result;  if (symbol_entry->_n._n_n._n_zeroes == 0)    {      result = stringtab + symbol_entry->_n._n_n._n_offset;    }  else    {      strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN);      buffer[SYMNMLEN] = '\0';      result = buffer;    }  return result;}static char *getfilename (aux_entry)    union internal_auxent *aux_entry;{  static char buffer[BUFSIZ];  register char *temp;  char *result;#ifndef COFF_NO_LONG_FILE_NAMES#if defined (x_zeroes)  /* Data General.  */  if (aux_entry->x_zeroes == 0)    strcpy (buffer, stringtab + aux_entry->x_offset);#else /* no x_zeroes */  if (aux_entry->x_file.x_n.x_zeroes == 0)    strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);#endif /* no x_zeroes */  else#endif /* COFF_NO_LONG_FILE_NAMES */    {#if defined (x_name)      /* Data General.  */      strncpy (buffer, aux_entry->x_name, FILNMLEN);#else      strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);#endif      buffer[FILNMLEN] = '\0';    }  result = buffer;  if ((temp = strrchr (result, '/')) != NULL)    result = temp + 1;  return (result);}/* Support for line number handling */static char *linetab = NULL;static long linetab_offset;static unsigned long linetab_size;/* Read in all the line numbers for fast lookups later.  Leave them in   external (unswapped) format in memory; we'll swap them as we enter   them into GDB's data structures.  */ static intinit_lineno (chan, offset, size)    int chan;    long offset;    int size;{  int val;  linetab_offset = offset;  linetab_size = size;  if (size == 0)    return 0;  if (lseek (chan, offset, 0) < 0)    return -1;    /* Allocate the desired table, plus a sentinel */  linetab = (char *) xmalloc (size + local_linesz);  val = myread (chan, linetab, size);  if (val != size)    return -1;  /* Terminate it with an all-zero sentinel record */  memset (linetab + size, 0, local_linesz);  make_cleanup (free, linetab);		/* Be sure it gets de-allocated. */  return 0;}#if !defined (L_LNNO32)#define L_LNNO32(lp) ((lp)->l_lnno)#endifstatic voidenter_linenos (file_offset, first_line, last_line)    long file_offset;    register int first_line;    register int last_line;{  register char *rawptr;  struct internal_lineno lptr;  if (file_offset < linetab_offset)    {      complain (&lineno_complaint, (char *) file_offset);      if (file_offset > linetab_size)	/* Too big to be an offset? */	return;      file_offset += linetab_offset;  /* Try reading at that linetab offset */    }    rawptr = &linetab[file_offset - linetab_offset];  /* skip first line entry for each function */  rawptr += local_linesz;  /* line numbers start at one for the first line of the function */  first_line--;  for (;;) {    bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);    rawptr += local_linesz;    /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */    if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)      coff_record_line (first_line + L_LNNO32 (&lptr), lptr.l_addr.l_paddr);    else      break;  } }static voidpatch_type (type, real_type)    struct type *type;    struct type *real_type;{  register struct type *target = TYPE_TARGET_TYPE (type);  register struct type *real_target = TYPE_TARGET_TYPE (real_type);  int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);  TYPE_LENGTH (target) = TYPE_LENGTH (real_target);  TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);  memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);  if (TYPE_NAME (real_target))    {      if (TYPE_NAME (target))	free (TYPE_NAME (target));      TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL);    }}/* Patch up all appropriate typedef symbols in the opaque_type_chains   so that they can be used to print out opaque data structures properly.  */static voidpatch_opaque_types (s)     struct symtab *s;{  register struct block *b;  register int i;  register struct symbol *real_sym;    /* Go through the per-file symbols only */  b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);  for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)    {      /* Find completed typedefs to use to fix opaque ones.	 Remove syms from the chain when their types are stored,	 but search the whole chain, as there may be several syms	 from different files with the same name.  */      real_sym = BLOCK_SYM (b, i);      if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&	  SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&	  TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&	  TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)	{	  register char *name = SYMBOL_NAME (real_sym);	  register int hash = hashname (name);	  register struct symbol *sym, *prev;	  	  prev = 0;	  for (sym = opaque_type_chain[hash]; sym;)	    {	      if (name[0] == SYMBOL_NAME (sym)[0] &&		  !strcmp (name + 1, SYMBOL_NAME (sym) + 1))		{		  if (prev)		    {		      SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);		    }		  else		    {		      opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym);		    }		  		  patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));		  		  if (prev)		    {		      sym = SYMBOL_VALUE_CHAIN (prev);		    }		  else		    {		      sym = opaque_type_chain[hash];		    }		}	      else		{		  prev = sym;		  sym = SYMBOL_VALUE_CHAIN (sym);		}	    }	}    }}static struct symbol *process_coff_symbol (cs, aux, objfile)     register struct coff_symbol *cs;     register union internal_auxent *aux;     struct objfile *objfile;{  register struct symbol *sym    = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));  char *name;#ifdef NAMES_HAVE_UNDERSCORE  int offset = 1;#else  int offset = 0;#endif  struct type *temptype;  memset (sym, 0, sizeof (struct symbol));  name = cs->c_name;  name = (name[0] == '_' ? name + offset : name);  SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name, strlen (name));  /* default assumptions */  SYMBOL_VALUE (sym) = cs->c_value;  SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;  if (ISFCN (cs->c_type))    {#if 0       /* FIXME:  This has NOT been tested.  The DBX version has.. */       /* Generate a template for the type of this function.  The 	  types of the arguments will be added as we read the symbol 	  table. */       struct type *new = (struct type *)		    obstack_alloc (&objfile->symbol_obstack, sizeof (struct type));              memcpy (new, lookup_function_type (decode_function_type (cs, cs->c_type, aux)),		      sizeof(struct type));       SYMBOL_TYPE (sym) = new;       in_function_type = SYMBOL_TYPE(sym);#else       SYMBOL_TYPE(sym) = 	 lookup_function_type (decode_function_type (cs, cs->c_type, aux));#endif      SYMBOL_CLASS (sym) = LOC_BLOCK;      if (cs->c_sclass == C_STAT)	coff_add_symbol_to_list (sym, &coff_file_symbols);      else if (cs->c_sclass == C_EXT)	coff_add_symbol_to_list (sym, &coff_global_symbols);    }  else    {      SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);      switch (cs->c_sclass)	{	  case C_NULL:	    break;	  case C_AUTO:	    SYMBOL_CLASS (sym) = LOC_LOCAL;	    coff_add_symbol_to_list (sym, &coff_local_symbols);	    break;	  case C_EXT:	    SYMBOL_CLASS (sym) = LOC_STATIC;	    SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;	    coff_add_symbol_to_list (sym, &coff_global_symbols);	    break;	  case C_STAT:	    SYMBOL_CLASS (sym) = LOC_STATIC;	    SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;	    if (within_function) {	      /* Static symbol of local scope */	      coff_add_symbol_to_list (sym, &coff_local_symbols);	    }	    else {	      /* Static symbol at top level of file */	      coff_add_symbol_to_list (sym, &coff_file_symbols);	    }	    break;#ifdef C_GLBLREG		/* AMD coff */	  case C_GLBLREG:#endif	  case C_REG:	    SYMBOL_CLASS (sym) = LOC_REGISTER;	    SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value);	    coff_add_symbol_to_list (sym, &coff_local_symbols);	    break;	  case C_LABEL:	    break;	  case C_ARG:	    SYMBOL_CLASS (sym) = LOC_ARG;#if 0	    /* FIXME:  This has not been tested. */	    /* Add parameter to function.  */	    add_param_to_type(&in_function_type,sym);#endif	    coff_add_symbol_to_list (sym, &coff_local_symbols);#if !defined (BELIEVE_PCC_PROMOTION)	    /* If PCC says a parameter is a short or a char,	       it is really an int.  */	    temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);	    if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)		&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)		{		    SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))			? lookup_fundamental_type (current_objfile,						   FT_UNSIGNED_INTEGER)			    : temptype;		}#endif	    break;	  case C_REGPARM:	    SYMBOL_CLASS (sym) = LOC_REGPARM;	    SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value);	    coff_add_symbol_to_list (sym, &coff_local_symbols);#if !defined (BELIEVE_PCC_PROMOTION)	    /* If PCC says a parameter is a short or a char,	       it is really an int.  */	    temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);	    if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)		&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)		{		    SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))			? lookup_fundamental_type (current_objfile,						   FT_UNSIGNED_INTEGER)			    : temptype;		}#endif	    break;	    	  case C_TPDEF:	    SYMBOL_CLASS (sym) = LOC_TYPEDEF;	    SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;	    /* If type has no name, give it one */	    if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)	      TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL);	    /* Keep track of any type which points to empty structured type,		so it can be filled from a definition from another file.  A		simple forward reference (TYPE_CODE_UNDEF) is not an		empty structured type, though; the forward references		work themselves out via the magic of coff_lookup_type.  */	    if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&		TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&		TYPE_CODE   (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=						TYPE_CODE_UNDEF)	      {		register int i = hashname (SYMBOL_NAME (sym));		SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];		opaque_type_chain[i] = sym;	      }	    coff_add_symbol_to_list (sym, &coff_file_symbols);	    break;	  case C_STRTAG:	  case C_UNTAG:	  case C_ENTAG:	    SYMBOL_CLASS (sym) = LOC_TYPEDEF;	    SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;	    if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)	      TYPE_NAME (SYMBOL_TYPE (sym))		= concat ("",			  (cs->c_sclass == C_ENTAG			   ? "enum "			   : (cs->c_sclass == C_STRTAG			      ? "struct " : "union ")),			  SYMBOL_NAME (sym), NULL);	    coff_add_symbol_to_list (sym, &coff_file_symbols);	    break;	  default:	    break;	}    }  return sym;}/* Decode a coff type specifier;   return the type that is meant.  */

⌨️ 快捷键说明

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