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

📄 coffread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
staticstruct type *decode_type (cs, c_type, aux)     register struct coff_symbol *cs;     unsigned int c_type;     register union internal_auxent *aux;{  register struct type *type = 0;  unsigned int new_c_type;  if (c_type & ~N_BTMASK)    {      new_c_type = DECREF (c_type);      if (ISPTR (c_type))	{	  type = decode_type (cs, new_c_type, aux);	  type = lookup_pointer_type (type);	}      else if (ISFCN (c_type))	{	  type = decode_type (cs, new_c_type, aux);	  type = lookup_function_type (type);	}      else if (ISARY (c_type))	{	  int i, n;	  register unsigned short *dim;	  struct type *base_type;	  /* Define an array type.  */	  /* auxent refers to array, not base type */	  if (aux->x_sym.x_tagndx.l == 0)	    cs->c_naux = 0;	  /* shift the indices down */	  dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];	  i = 1;	  n = dim[0];	  for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)	    *dim = *(dim + 1);	  *dim = 0;	  type = alloc_type (current_objfile);	  base_type = decode_type (cs, new_c_type, aux);	  TYPE_CODE (type) = TYPE_CODE_ARRAY;	  TYPE_TARGET_TYPE (type) = base_type;	  TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type);	}      return type;    }  /* Reference to existing type.  This only occurs with the     struct, union, and enum types.  EPI a29k coff     fakes us out by producing aux entries with a nonzero     x_tagndx for definitions of structs, unions, and enums, so we     have to check the c_sclass field.  */  if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)    {      if  (cs->c_sclass != C_STRTAG	&& cs->c_sclass != C_UNTAG	&& cs->c_sclass != C_ENTAG)	{	  type = coff_alloc_type (aux->x_sym.x_tagndx.l);	  return type;	} else {	  complain (&tagndx_bad_complaint, cs->c_name);	  /* And fall through to decode_base_type... */	}    }  return decode_base_type (cs, BTYPE (c_type), aux);}/* Decode a coff type specifier for function definition;   return the type that the function returns.  */staticstruct type *decode_function_type (cs, c_type, aux)     register struct coff_symbol *cs;     unsigned int c_type;     register union internal_auxent *aux;{  if (aux->x_sym.x_tagndx.l == 0)    cs->c_naux = 0;	/* auxent refers to function, not base type */  return decode_type (cs, DECREF (c_type), aux);}/* basic C types */staticstruct type *decode_base_type (cs, c_type, aux)     register struct coff_symbol *cs;     unsigned int c_type;     register union internal_auxent *aux;{  struct type *type;  switch (c_type)    {      case T_NULL:        /* shows up with "void (*foo)();" structure members */	return lookup_fundamental_type (current_objfile, FT_VOID);#if 0/* DGUX actually defines both T_ARG and T_VOID to the same value.  */#ifdef T_ARG      case T_ARG:	/* Shows up in DGUX, I think.  Not sure where.  */	return lookup_fundamental_type (current_objfile, FT_VOID);	/* shouldn't show up here */#endif#endif /* 0 */#ifdef T_VOID      case T_VOID:	/* Intel 960 COFF has this symbol and meaning.  */	return lookup_fundamental_type (current_objfile, FT_VOID);#endif      case T_CHAR:	return lookup_fundamental_type (current_objfile, FT_CHAR);      case T_SHORT:	return lookup_fundamental_type (current_objfile, FT_SHORT);      case T_INT:	return lookup_fundamental_type (current_objfile, FT_INTEGER);      case T_LONG:	return lookup_fundamental_type (current_objfile, FT_LONG);      case T_FLOAT:	return lookup_fundamental_type (current_objfile, FT_FLOAT);      case T_DOUBLE:	return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);      case T_STRUCT:	if (cs->c_naux != 1)	  {	    /* anonymous structure type */	    type = coff_alloc_type (cs->c_symnum);	    TYPE_CODE (type) = TYPE_CODE_STRUCT;	    TYPE_NAME (type) = concat ("struct ", "<opaque>", NULL);	    INIT_CPLUS_SPECIFIC(type);	    TYPE_LENGTH (type) = 0;	    TYPE_FIELDS (type) = 0;	    TYPE_NFIELDS (type) = 0;	  }	else	  {	    type = coff_read_struct_type (cs->c_symnum,				    aux->x_sym.x_misc.x_lnsz.x_size,				    aux->x_sym.x_fcnary.x_fcn.x_endndx.l);	  }	return type;      case T_UNION:	if (cs->c_naux != 1)	  {	    /* anonymous union type */	    type = coff_alloc_type (cs->c_symnum);	    TYPE_NAME (type) = concat ("union ", "<opaque>", NULL);	    INIT_CPLUS_SPECIFIC(type);	    TYPE_LENGTH (type) = 0;	    TYPE_LENGTH (type) = 0;	    TYPE_FIELDS (type) = 0;	    TYPE_NFIELDS (type) = 0;	  }	else	  {	    type = coff_read_struct_type (cs->c_symnum,				    aux->x_sym.x_misc.x_lnsz.x_size,				    aux->x_sym.x_fcnary.x_fcn.x_endndx.l);	  }	TYPE_CODE (type) = TYPE_CODE_UNION;	return type;      case T_ENUM:	return coff_read_enum_type (cs->c_symnum,				    aux->x_sym.x_misc.x_lnsz.x_size,				    aux->x_sym.x_fcnary.x_fcn.x_endndx.l);      case T_MOE:	/* shouldn't show up here */	break;      case T_UCHAR:	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR);      case T_USHORT:	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT);      case T_UINT:	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);      case T_ULONG:	return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);    }  complain (&unexpected_type_complaint, cs->c_name);  return lookup_fundamental_type (current_objfile, FT_VOID);}/* This page contains subroutines of read_type.  *//* Read the description of a structure (or union type)   and return an object describing the type.  */static struct type *coff_read_struct_type (index, length, lastsym)     int index;     int length;     int lastsym;{  struct nextfield    {      struct nextfield *next;      struct field field;    };  register struct type *type;  register struct nextfield *list = 0;  struct nextfield *new;  int nfields = 0;  register int n;  char *name;#ifdef NAMES_HAVE_UNDERSCORE  int offset = 1;#else  int offset = 0;#endif  struct coff_symbol member_sym;  register struct coff_symbol *ms = &member_sym;  struct internal_syment sub_sym;  union internal_auxent sub_aux;  int done = 0;  type = coff_alloc_type (index);  TYPE_CODE (type) = TYPE_CODE_STRUCT;  INIT_CPLUS_SPECIFIC(type);  TYPE_LENGTH (type) = length;  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)    {      read_one_sym (ms, &sub_sym, &sub_aux);      name = ms->c_name;      name = (name[0] == '_' ? name + offset : name);      switch (ms->c_sclass)	{	  case C_MOS:	  case C_MOU:	    /* 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 = savestring (name, strlen (name));	    list->field.type = decode_type (ms, ms->c_type, &sub_aux);	    list->field.bitpos = 8 * ms->c_value;	    list->field.bitsize = 0;	    nfields++;	    break;	  case C_FIELD:	    /* 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 = savestring (name, strlen (name));	    list->field.type = decode_type (ms, ms->c_type, &sub_aux);	    list->field.bitpos = ms->c_value;	    list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size;	    nfields++;	    break;	  case C_EOS:	    done = 1;	    break;	}    }  /* Now create the vector of fields, and record how big it is.  */  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;}/* Read a definition of an enumeration type,   and create and return a suitable type object.   Also defines the symbols that represent the values of the type.  *//* Currently assumes it's sizeof (int) and doesn't use length.  *//* ARGSUSED */static struct type *coff_read_enum_type (index, length, lastsym)     int index;     int length;     int lastsym;{  register struct symbol *sym;  register struct type *type;  int nsyms = 0;  int done = 0;  struct coff_pending **symlist;  struct coff_symbol member_sym;  register struct coff_symbol *ms = &member_sym;  struct internal_syment sub_sym;  union internal_auxent sub_aux;  struct coff_pending *osyms, *syms;  register int n;  char *name;#ifdef NAMES_HAVE_UNDERSCORE  int offset = 1;#else  int offset = 0;#endif  type = coff_alloc_type (index);  if (within_function)    symlist = &coff_local_symbols;  else    symlist = &coff_file_symbols;  osyms = *symlist;  while (!done && symnum < lastsym && symnum < nlist_nsyms_global)    {      read_one_sym (ms, &sub_sym, &sub_aux);      name = ms->c_name;      name = (name[0] == '_' ? name + offset : name);      switch (ms->c_sclass)	{	  case C_MOE:	    sym = (struct symbol *) xmalloc (sizeof (struct symbol));	    memset (sym, 0, sizeof (struct symbol));	    SYMBOL_NAME (sym) = savestring (name, strlen (name));	    SYMBOL_CLASS (sym) = LOC_CONST;	    SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;	    SYMBOL_VALUE (sym) = ms->c_value;	    coff_add_symbol_to_list (sym, symlist);	    nsyms++;	    break;	  case C_EOS:	    /* Sometimes the linker (on 386/ix 2.0.2 at least) screws	       up the count of how many symbols to read.  So stop	       on .eos.  */	    done = 1;	    break;	}    }  /* Now fill in the fields of the type-structure.  */  TYPE_LENGTH (type) =  TARGET_INT_BIT / TARGET_CHAR_BIT;  TYPE_CODE (type) = TYPE_CODE_ENUM;  TYPE_NFIELDS (type) = nsyms;  TYPE_FIELDS (type) = (struct field *)    TYPE_ALLOC (type, sizeof (struct field) * nsyms);  /* Find the symbols for the values and put them into the type.     The symbols can be found in the symlist that we put them on     to cause them to be defined.  osyms contains the old value     of that symlist; everything up to there was defined by us.  */  for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next)    {      SYMBOL_TYPE (syms->symbol) = type;      TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol);      TYPE_FIELD_VALUE (type, n) = 0;      TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (syms->symbol);      TYPE_FIELD_BITSIZE (type, n) = 0;    }  /* Is this Modula-2's BOOLEAN type?  Flag it as such if so. */  if(TYPE_NFIELDS(type) == 2 &&     ((!strcmp(TYPE_FIELD_NAME(type,0),"TRUE") &&       !strcmp(TYPE_FIELD_NAME(type,1),"FALSE")) ||      (!strcmp(TYPE_FIELD_NAME(type,1),"TRUE") &&       !strcmp(TYPE_FIELD_NAME(type,0),"FALSE"))))     TYPE_CODE(type) = TYPE_CODE_BOOL;  return type;}/* Fake up support for relocating symbol addresses.  FIXME.  */struct section_offsets coff_symfile_faker = {0};struct section_offsets *coff_symfile_offsets (objfile, addr)     struct objfile *objfile;     CORE_ADDR addr;{  return &coff_symfile_faker;}/* Register our ability to parse symbols for coff BFD files */static struct sym_fns coff_sym_fns ={  "coff",		/* sym_name: name or name prefix of BFD target type */  4,			/* sym_namelen: number of significant sym_name chars */  coff_new_init,	/* sym_new_init: init anything gbl to entire symtab */  coff_symfile_init,	/* sym_init: read initial info, setup for sym_read() */  coff_symfile_read,	/* sym_read: read a symbol file into symtab */  coff_symfile_finish,	/* sym_finish: finished with file, cleanup */  coff_symfile_offsets, /* sym_offsets:  xlate external to internal form */  NULL			/* next: pointer to next struct sym_fns */};void_initialize_coffread (){  add_symtab_fns(&coff_sym_fns);}

⌨️ 快捷键说明

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