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

📄 coffread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     int nsyms;     struct objfile *objfile;{  FILE *stream;   register struct coff_context_stack *new;  struct coff_symbol coff_symbol;  register struct coff_symbol *cs = &coff_symbol;  static struct internal_syment main_sym;  static union internal_auxent main_aux;  struct coff_symbol fcn_cs_saved;  static struct internal_syment fcn_sym_saved;  static union internal_auxent fcn_aux_saved;  struct symtab *s;    /* A .file is open.  */  int in_source_file = 0;  int num_object_files = 0;  int next_file_symnum = -1;  /* Name of the current file.  */  char *filestring = "";  int depth = 0;  int fcn_first_line = 0;  int fcn_last_line = 0;  int fcn_start_addr = 0;  long fcn_line_ptr = 0;  struct cleanup *old_chain;  int val;  stream = fopen (objfile->name, FOPEN_RB);  if (!stream)   perror_with_name(objfile->name);  /* Position to read the symbol table. */  val = fseek (stream, (long)symtab_offset, 0);  if (val < 0)    perror_with_name (objfile->name);  /* These cleanups will be discarded below if we succeed.  */  old_chain = make_cleanup (free_objfile, objfile);  make_cleanup (fclose, stream);  current_objfile = objfile;  nlist_stream_global = stream;  nlist_nsyms_global = nsyms;  last_source_file = NULL;  memset (opaque_type_chain, 0, sizeof opaque_type_chain);  if (type_vector)			/* Get rid of previous one */    free ((PTR)type_vector);  type_vector_length = 160;  type_vector = (struct type **)		xmalloc (type_vector_length * sizeof (struct type *));  memset (type_vector, 0, type_vector_length * sizeof (struct type *));  coff_start_symtab ();  symnum = 0;  while (symnum < nsyms)    {      QUIT;			/* Make this command interruptable.  */      read_one_sym (cs, &main_sym, &main_aux);#ifdef SEM      temp_sem_val = cs->c_name[0] << 24 | cs->c_name[1] << 16 |                     cs->c_name[2] << 8 | cs->c_name[3];      if (int_sem_val == temp_sem_val)        last_coffsem = (int) strtol (cs->c_name+4, (char **) NULL, 10);#endif      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)	{	  if (last_source_file)	    coff_end_symtab (objfile);	  coff_start_symtab ();	  complete_symtab ("_globals_", 0, first_object_file_end);	  /* done with all files, everything from here on out is globals */	}      /* Special case for file with type declarations only, no text.  */      if (!last_source_file && SDB_TYPE (cs->c_type)	  && cs->c_secnum == N_DEBUG)	complete_symtab (filestring, 0, 0);      /* Typedefs should not be treated as symbol definitions.  */      if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)	{	  /* record as a minimal symbol.  if we get '.bf' next,	   * then we undo this step	   */	  record_minimal_symbol (cs->c_name, cs->c_value, mst_text);	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;	  fcn_start_addr = cs->c_value;	  fcn_cs_saved = *cs;	  fcn_sym_saved = main_sym;	  fcn_aux_saved = main_aux;	  continue;	}      switch (cs->c_sclass)	{	  case C_EFCN:	  case C_EXTDEF:	  case C_ULABEL:	  case C_USTATIC:	  case C_LINE:	  case C_ALIAS:	  case C_HIDDEN:	    complain (&bad_sclass_complaint, cs->c_name);	    break;	  case C_FILE:	    /*	     * c_value field contains symnum of next .file entry in table	     * or symnum of first global after last .file.	     */	    next_file_symnum = cs->c_value;	    filestring = getfilename (&main_aux);	    /*	     * Complete symbol table for last object file	     * containing debugging information.	     */	    if (last_source_file)	      {		coff_end_symtab (objfile);		coff_start_symtab ();	      }	    in_source_file = 1;	    break;          case C_STAT:	    if (cs->c_name[0] == '.') {		    if (strcmp (cs->c_name, ".text") == 0) {			    /* FIXME:  don't wire in ".text" as section name				       or symbol name! */			    if (++num_object_files == 1) {				    /* last address of startup file */				    first_object_file_end = cs->c_value +					    main_aux.x_scn.x_scnlen;			    }			    /* Check for in_source_file deals with case of			       a file with debugging symbols			       followed by a later file with no symbols.  */			    if (in_source_file)			      complete_symtab (filestring, cs->c_value,					       main_aux.x_scn.x_scnlen);			    in_source_file = 0;		    }		    /* flush rest of '.' symbols */		    break;	    }	    else if (!SDB_TYPE (cs->c_type)		     && cs->c_name[0] == 'L'		     && (strncmp (cs->c_name, "LI%", 3) == 0			 || strncmp (cs->c_name, "LF%", 3) == 0			 || strncmp (cs->c_name,"LC%",3) == 0			 || strncmp (cs->c_name,"LP%",3) == 0			 || strncmp (cs->c_name,"LPB%",4) == 0			 || strncmp (cs->c_name,"LBB%",4) == 0			 || strncmp (cs->c_name,"LBE%",4) == 0			 || strncmp (cs->c_name,"LPBX%",5) == 0))	      /* At least on a 3b1, gcc generates swbeg and string labels		 that look like this.  Ignore them.  */	      break;	    /* fall in for static symbols that don't start with '.' */	  case C_EXT:	    if (!SDB_TYPE (cs->c_type)) {		/* FIXME: This is BOGUS Will Robinson! 	 	Coff should provide the SEC_CODE flag for executable sections,	 	then if we could look up sections by section number we  	 	could see if the flags indicate SEC_CODE.  If so, then	 	record this symbol as a function in the minimal symbol table.		But why are absolute syms recorded as functions, anyway?  */		    if (cs->c_secnum <= text_bfd_scnum+1) {/* text or abs */			    record_minimal_symbol (cs->c_name, cs->c_value,						   mst_text);			    break;		    } else {			    record_minimal_symbol (cs->c_name, cs->c_value,						   mst_data);			    break;		    }	    }	    process_coff_symbol (cs, &main_aux, objfile);	    break;	  case C_FCN:	    if (strcmp (cs->c_name, ".bf") == 0)	      {		within_function = 1;		/* value contains address of first non-init type code */		/* main_aux.x_sym.x_misc.x_lnsz.x_lnno			    contains line number of '{' } */		if (cs->c_naux != 1)		  complain (&bf_no_aux_complaint, (char *) cs->c_symnum);		fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;		new = (struct coff_context_stack *)		  xmalloc (sizeof (struct coff_context_stack));		new->depth = depth = 0;		new->next = 0;		coff_context_stack = new;		new->locals = 0;		new->old_blocks = pending_blocks;		new->start_addr = fcn_start_addr;		fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);		new->name = process_coff_symbol (&fcn_cs_saved,						 &fcn_aux_saved, objfile);	      }	    else if (strcmp (cs->c_name, ".ef") == 0)	      {		      /* the value of .ef is the address of epilogue code;		       * not useful for gdb		       */		/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno			    contains number of lines to '}' */		new = coff_context_stack;		if (new == 0)		  {		    complain (&ef_complaint, (char *) cs->c_symnum);		    within_function = 0;		    break;		  }		if (cs->c_naux != 1) {		  complain (&ef_no_aux_complaint, (char *) cs->c_symnum);		  fcn_last_line = 0x7FFFFFFF;		} else {		  fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;		}		enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line);		coff_finish_block (new->name, &coff_local_symbols, new->old_blocks,			      new->start_addr,#if defined (FUNCTION_EPILOGUE_SIZE)			      /* This macro should be defined only on				 machines where the				 fcn_aux_saved.x_sym.x_misc.x_fsize				 field is always zero.				 So use the .bf record information that				 points to the epilogue and add the size				 of the epilogue.  */			      cs->c_value + FUNCTION_EPILOGUE_SIZE,#else			      fcn_cs_saved.c_value +			          fcn_aux_saved.x_sym.x_misc.x_fsize,#endif			      objfile			      );		coff_context_stack = 0;		within_function = 0;		free ((PTR)new);	      }	    break;	  case C_BLOCK:	    if (strcmp (cs->c_name, ".bb") == 0)	      {		new = (struct coff_context_stack *)			    xmalloc (sizeof (struct coff_context_stack));		depth++;		new->depth = depth;		new->next = coff_context_stack;		coff_context_stack = new;		new->locals = coff_local_symbols;		new->old_blocks = pending_blocks;		new->start_addr = cs->c_value;		new->name = 0;		coff_local_symbols = 0;	      }	    else if (strcmp (cs->c_name, ".eb") == 0)	      {		new = coff_context_stack;		if (new == 0 || depth != new->depth)		  error ("Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.",			 symnum);		if (coff_local_symbols && coff_context_stack->next)		  {		    /* Make a block for the local symbols within.  */		    coff_finish_block (0, &coff_local_symbols, new->old_blocks,				  new->start_addr, cs->c_value, objfile);		  }		depth--;		coff_local_symbols = new->locals;		coff_context_stack = new->next;		free ((PTR)new);	      }	    break;	  default:	    process_coff_symbol (cs, &main_aux, objfile);	    break;	}    }  if (last_source_file)    coff_end_symtab (objfile);  fclose (stream);  /* Patch up any opaque types (references to types that are not defined     in the file where they are referenced, e.g. "struct foo *bar").  */  ALL_OBJFILE_SYMTABS (objfile, s)    patch_opaque_types (s);  discard_cleanups (old_chain);  current_objfile = NULL;}/* Routines for reading headers and symbols from executable.  */#ifdef FIXME/* Move these XXXMAGIC symbol defns into BFD!  *//* Read COFF file header, check magic number,   and return number of symbols. */read_file_hdr (chan, file_hdr)    int chan;    FILHDR *file_hdr;{  lseek (chan, 0L, 0);  if (myread (chan, (char *)file_hdr, FILHSZ) < 0)    return -1;  switch (file_hdr->f_magic)    {#ifdef MC68MAGIC    case MC68MAGIC:#endif#ifdef NS32GMAGIC      case NS32GMAGIC:      case NS32SMAGIC:#endif#ifdef I386MAGIC    case I386MAGIC:#endif#ifdef CLIPPERMAGIC    case CLIPPERMAGIC:#endif#if defined (MC68KWRMAGIC) \  && (!defined (MC68MAGIC) || MC68KWRMAGIC != MC68MAGIC)    case MC68KWRMAGIC:#endif#ifdef MC68KROMAGIC    case MC68KROMAGIC:    case MC68KPGMAGIC:#endif#ifdef MC88DGMAGIC    case MC88DGMAGIC:#endif      #ifdef MC88MAGIC    case MC88MAGIC:#endif      #ifdef I960ROMAGIC    case I960ROMAGIC:		/* Intel 960 */#endif#ifdef I960RWMAGIC    case I960RWMAGIC:		/* Intel 960 */#endif	return file_hdr->f_nsyms;      default:#ifdef BADMAG	if (BADMAG(file_hdr))	  return -1;	else	  return file_hdr->f_nsyms;#else	return -1;#endif    }}#endif/* Read the next symbol, swap it, and return it in both internal_syment   form, and coff_symbol form.  Also return its first auxent, if any,   in internal_auxent form, and skip any other auxents.  */static voidread_one_sym (cs, sym, aux)    register struct coff_symbol *cs;    register struct internal_syment *sym;    register union internal_auxent *aux;{  int i;  cs->c_symnum = symnum;  fread (temp_sym, local_symesz, 1, nlist_stream_global);  bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *)sym);  cs->c_naux = sym->n_numaux & 0xff;  if (cs->c_naux >= 1)    {    fread (temp_aux, local_auxesz, 1, nlist_stream_global);    bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,			  (char *)aux);    /* If more than one aux entry, read past it (only the first aux       is important). */    for (i = 1; i < cs->c_naux; i++)      fread (temp_aux, local_auxesz, 1, nlist_stream_global);    }  cs->c_name = getsymname (sym);  cs->c_value = sym->n_value;  cs->c_sclass = (sym->n_sclass & 0xff);  cs->c_secnum = sym->n_scnum;  cs->c_type = (unsigned) sym->n_type;  if (!SDB_TYPE (cs->c_type))    cs->c_type = 0;  symnum += 1 + cs->c_naux;}/* Support for string table handling */static char *stringtab = NULL;static intinit_stringtab (chan, offset)    int chan;    long offset;{  long length;  int val;  unsigned char lengthbuf[4];  if (stringtab)    {      free (stringtab);      stringtab = NULL;    }  if (lseek (chan, offset, 0) < 0)    return -1;  val = myread (chan, (char *)lengthbuf, sizeof lengthbuf);  length = bfd_h_get_32 (symfile_bfd, lengthbuf);

⌨️ 快捷键说明

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