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

📄 coffread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Read coff symbol tables and convert to internal format, for GDB.   Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).   Copyright 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "symtab.h"#include "gdbtypes.h"#include "breakpoint.h"#include "bfd.h"#include "symfile.h"#include "objfiles.h"#include "buildsym.h"#include <obstack.h>#include <string.h>#include "coff/internal.h"	/* Internal format of COFF symbols in BFD */#include "libcoff.h"		/* FIXME secret internal data from BFD *//* To be an sdb debug type, type must have at least a basic or primary   derived type.  Using this rather than checking against T_NULL is   said to prevent core dumps if we try to operate on Michael Bloom   dbx-in-coff file.  */#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK))/* * Convert from an sdb register number to an internal gdb register number. * This should be defined in tm.h, if REGISTER_NAMES is not set up * to map one to one onto the sdb register numbers. */#ifndef SDB_REG_TO_REGNUM# define SDB_REG_TO_REGNUM(value)     (value)#endif/* Core address of start and end of text of current source file.   This comes from a ".text" symbol where x_nlinno > 0.  */static CORE_ADDR cur_src_start_addr;static CORE_ADDR cur_src_end_addr;/* Core address of the end of the first object file.  */static CORE_ADDR first_object_file_end;/* The addresses of the symbol table stream and number of symbols   of the object file we are reading (as copied into core).  */static FILE *nlist_stream_global;static int nlist_nsyms_global;/* Vector of line number information.  */static struct linetable *line_vector;/* Index of next entry to go in line_vector_index.  */static int line_vector_index;/* Last line number recorded in the line vector.  */static int prev_line_number;/* Number of elements allocated for line_vector currently.  */static int line_vector_length;/* Pointers to scratch storage, used for reading raw symbols and auxents.  */static char *temp_sym;static char *temp_aux;/* Local variables that hold the shift and mask values for the   COFF file that we are currently reading.  These come back to us   from BFD, and are referenced by their macro names, as well as   internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF   macros from ../internalcoff.h .  */static unsigned	local_n_btmask;static unsigned	local_n_btshft;static unsigned	local_n_tmask;static unsigned	local_n_tshift;#define	N_BTMASK	local_n_btmask#define	N_BTSHFT	local_n_btshft#define	N_TMASK		local_n_tmask#define	N_TSHIFT	local_n_tshift /* Local variables that hold the sizes in the file of various COFF structures.   (We only need to know this to read them from the file -- BFD will then   translate the data in them, into `internal_xxx' structs in the right   byte order, alignment, etc.)  */static unsigned	local_linesz;static unsigned	local_symesz;static unsigned	local_auxesz;/* Chain of typedefs of pointers to empty struct/union types.   They are chained thru the SYMBOL_VALUE_CHAIN.  */static struct symbol *opaque_type_chain[HASHSIZE];/* Record the symbols defined for each context in a list.   We don't create a struct block for the context until we   know how long to make it.  */struct coff_pending{  struct coff_pending *next;  struct symbol *symbol;};/* Here are the three lists that symbols are put on.  */struct coff_pending *coff_file_symbols;	/* static at top level, and types */struct coff_pending *coff_global_symbols;  /* global functions and variables */struct coff_pending *coff_local_symbols;  /* everything local to lexical context *//* List of unclosed lexical contexts   (that will become blocks, eventually).  */struct coff_context_stack{  struct coff_context_stack *next;  struct coff_pending *locals;  struct pending_block *old_blocks;  struct symbol *name;  CORE_ADDR start_addr;  int depth;};struct coff_context_stack *coff_context_stack;/* Nonzero if within a function (so symbols should be local,   if nothing says specifically).  */int within_function;#if 0/* The type of the function we are currently reading in.  This is   used by define_symbol to record the type of arguments to a function. */struct type *in_function_type;#endifstruct pending_block *pending_blocks;/* Complaints about various problems in the file being read  */struct complaint ef_complaint =   {"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};struct complaint bf_no_aux_complaint =  {"`.bf' symbol %d has no aux entry", 0, 0};struct complaint ef_no_aux_complaint =  {"`.ef' symbol %d has no aux entry", 0, 0};struct complaint lineno_complaint =  {"Line number pointer %d lower than start of line numbers", 0, 0};struct complaint unexpected_type_complaint =  {"Unexpected type for symbol %s", 0, 0};struct complaint bad_sclass_complaint =  {"Bad n_sclass for symbol %s", 0, 0};struct complaint misordered_blocks_complaint =  {"Blocks out of order at address %x", 0, 0};struct complaint tagndx_bad_complaint =  {"Symbol table entry for %s has bad tagndx value", 0, 0};/* Simplified internal version of coff symbol table information */struct coff_symbol {  char *c_name;  int c_symnum;		/* symbol number of this entry */  int c_naux;		/* 0 if syment only, 1 if syment + auxent, etc */  long c_value;  int c_sclass;  int c_secnum;  unsigned int c_type;};static struct type *coff_read_struct_type PARAMS ((int, int, int));static struct type *decode_base_type PARAMS ((struct coff_symbol *, unsigned int,			  union internal_auxent *));static struct type *decode_type PARAMS ((struct coff_symbol *, unsigned int,		     union internal_auxent *));static struct type *decode_function_type PARAMS ((struct coff_symbol *, unsigned int,			      union internal_auxent *));static struct type *coff_read_enum_type PARAMS ((int, int, int));static struct blockvector *make_blockvector PARAMS ((struct objfile *));static struct symbol *process_coff_symbol PARAMS ((struct coff_symbol *, union internal_auxent *,			     struct objfile *));static voidpatch_opaque_types PARAMS ((struct symtab *));static voidpatch_type PARAMS ((struct type *, struct type *));static voidenter_linenos PARAMS ((long, int, int));static intinit_lineno PARAMS ((int, long, int));static char *getfilename PARAMS ((union internal_auxent *));static char *getsymname PARAMS ((struct internal_syment *));static voidfree_stringtab PARAMS ((void));static intinit_stringtab PARAMS ((int, long));static voidread_one_sym PARAMS ((struct coff_symbol *, struct internal_syment *,		      union internal_auxent *));static voidread_coff_symtab PARAMS ((long, int, struct objfile *));static voidfind_linenos PARAMS ((bfd *, sec_ptr, PTR));static voidcoff_symfile_init PARAMS ((struct objfile *));static voidcoff_new_init PARAMS ((struct objfile *));static voidcoff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));static voidcoff_symfile_finish PARAMS ((struct objfile *));static voidrecord_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type));static voidcoff_end_symtab PARAMS ((struct objfile *));static voidcomplete_symtab PARAMS ((char *, CORE_ADDR, unsigned int));static voidcoff_start_symtab PARAMS ((void));static voidcoff_record_line PARAMS ((int, CORE_ADDR));static voidcoff_finish_block PARAMS ((struct symbol *, struct coff_pending **,			   struct pending_block *, CORE_ADDR, CORE_ADDR,			   struct objfile *));static voidcoff_add_symbol_to_list PARAMS ((struct symbol *, struct coff_pending **));static struct type *coff_alloc_type PARAMS ((int));static struct type **coff_lookup_type PARAMS ((int));/* Look up a coff type-number index.  Return the address of the slot   where the type for that index is stored.   The type-number is in INDEX.    This can be used for finding the type associated with that index   or for associating a new type with the index.  */static struct type **coff_lookup_type (index)     register int index;{  if (index >= type_vector_length)    {      int old_vector_length = type_vector_length;      type_vector_length *= 2;      if (type_vector_length < index) {	type_vector_length = index * 2;      }      type_vector = (struct type **)	xrealloc ((char *) type_vector,		  type_vector_length * sizeof (struct type *));      memset (&type_vector[old_vector_length], 0,	     (type_vector_length - old_vector_length) * sizeof(struct type *));    }  return &type_vector[index];}/* Make sure there is a type allocated for type number index   and return the type object.   This can create an empty (zeroed) type object.  */static struct type *coff_alloc_type (index)     int index;{  register struct type **type_addr = coff_lookup_type (index);  register struct type *type = *type_addr;  /* If we are referring to a type not known at all yet,     allocate an empty type for it.     We will fill it in later if we find out how.  */  if (type == NULL)    {      type = alloc_type (current_objfile);      *type_addr = type;    }  return type;}/* maintain the lists of symbols and blocks *//* Add a symbol to one of the lists of symbols.  */static voidcoff_add_symbol_to_list (symbol, listhead)     struct symbol *symbol;     struct coff_pending **listhead;{  register struct coff_pending *link    = (struct coff_pending *) xmalloc (sizeof (struct coff_pending));  link->next = *listhead;  link->symbol = symbol;  *listhead = link;}/* Take one of the lists of symbols and make a block from it.   Put the block on the list of pending blocks.  */static voidcoff_finish_block (symbol, listhead, old_blocks, start, end, objfile)     struct symbol *symbol;     struct coff_pending **listhead;     struct pending_block *old_blocks;     CORE_ADDR start, end;     struct objfile *objfile;{  register struct coff_pending *next, *next1;  register struct block *block;  register struct pending_block *pblock;  struct pending_block *opblock;  register int i;  /* Count the length of the list of symbols.  */  for (next = *listhead, i = 0; next; next = next->next, i++);  block = (struct block *)	    obstack_alloc (&objfile->symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *));  /* Copy the symbols into the block.  */  BLOCK_NSYMS (block) = i;  for (next = *listhead; next; next = next->next)    BLOCK_SYM (block, --i) = next->symbol;  BLOCK_START (block) = start;  BLOCK_END (block) = end;  BLOCK_SUPERBLOCK (block) = 0;	/* Filled in when containing block is made */  /* Put the block in as the value of the symbol that names it.  */  if (symbol)    {      SYMBOL_BLOCK_VALUE (symbol) = block;      BLOCK_FUNCTION (block) = symbol;    }  else    BLOCK_FUNCTION (block) = 0;  /* Now free the links of the list, and empty the list.  */  for (next = *listhead; next; next = next1)    {      next1 = next->next;      free ((PTR)next);    }  *listhead = 0;  /* Install this block as the superblock     of all blocks made since the start of this scope     that don't have superblocks yet.  */  opblock = 0;  for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)    {      if (BLOCK_SUPERBLOCK (pblock->block) == 0)	BLOCK_SUPERBLOCK (pblock->block) = block;      opblock = pblock;    }  /* Record this block on the list of all blocks in the file.     Put it after opblock, or at the beginning if opblock is 0.

⌨️ 快捷键说明

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