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

📄 dbxread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Given a name, value pair, find the corresponding   bincl in the list.  Return the partial symtab associated   with that header_file_location.  */static struct partial_symtab *find_corresponding_bincl_psymtab (name, instance)     char *name;     int instance;{  struct header_file_location *bincl;  for (bincl = bincl_list; bincl < next_bincl; bincl++)    if (bincl->instance == instance	&& !strcmp (name, bincl->name))      return bincl->pst;  return (struct partial_symtab *) 0;}/* Free the storage allocated for the bincl list.  */static voidfree_bincl_list (objfile)     struct objfile *objfile;{  mfree (objfile -> md, (PTR)bincl_list);  bincls_allocated = 0;}/* Given pointers to an a.out symbol table in core containing dbx   style data, setup partial_symtab's describing each source file for   which debugging information is available.   SYMFILE_NAME is the name of the file we are reading from   and SECTION_OFFSETS is the set of offsets for the various sections   of the file (a set of zeros if the mainline program).  */static voidread_dbx_symtab (section_offsets, objfile, text_addr, text_size)     struct section_offsets *section_offsets;     struct objfile *objfile;     CORE_ADDR text_addr;     int text_size;{  register struct internal_nlist *bufp = 0;	/* =0 avoids gcc -Wall glitch */  register char *namestring;  int nsl;  int past_first_source_file = 0;  CORE_ADDR last_o_file_start = 0;  struct cleanup *old_chain;  bfd *abfd;#ifdef GDB_TARGET_IS_HPPA  /* HP stuff */  struct symbol_dictionary_record *hp_bufp;  int hp_symnum;  /* A hack: the first text symbol in the debugging library */  int dbsubc_addr = 0;#endif  /* End of the text segment of the executable file.  */  CORE_ADDR end_of_text_addr;  /* Current partial symtab */  struct partial_symtab *pst;  /* List of current psymtab's include files */  char **psymtab_include_list;  int includes_allocated;  int includes_used;  /* Index within current psymtab dependency list */  struct partial_symtab **dependency_list;  int dependencies_used, dependencies_allocated;  /* FIXME.  We probably want to change stringtab_global rather than add this     while processing every symbol entry.  FIXME.  */  file_string_table_offset = 0;  next_file_string_table_offset = 0;#ifdef GDB_TARGET_IS_HPPA  stringtab_global = HP_STRINGTAB (objfile);#else  stringtab_global = DBX_STRINGTAB (objfile);#endif    pst = (struct partial_symtab *) 0;  includes_allocated = 30;  includes_used = 0;  psymtab_include_list = (char **) alloca (includes_allocated *					   sizeof (char *));  dependencies_allocated = 30;  dependencies_used = 0;  dependency_list =    (struct partial_symtab **) alloca (dependencies_allocated *				       sizeof (struct partial_symtab *));  old_chain = make_cleanup (free_objfile, objfile);  /* Init bincl list */  init_bincl_list (20, objfile);  make_cleanup (free_bincl_list, objfile);  last_source_file = NULL;#ifdef END_OF_TEXT_DEFAULT  end_of_text_addr = END_OF_TEXT_DEFAULT;#else  end_of_text_addr = text_addr + section_offsets->offsets[SECT_OFF_TEXT]			       + text_size;	/* Relocate */#endif  symfile_bfd = objfile->obfd;	/* For next_text_symbol */  abfd = objfile->obfd;  symbuf_end = symbuf_idx = 0;  next_symbol_text_func = dbx_next_symbol_text;#ifdef GDB_TARGET_IS_HPPA  /* On pa machines, the global symbols are all in the regular HP-UX     symbol table. Read them in first. */  hp_symbuf_end = hp_symbuf_idx = 0;  bfd_seek (abfd, HP_SYMTAB_OFFSET (objfile), L_SET);  for (hp_symnum = 0; hp_symnum < HP_SYMCOUNT (objfile); hp_symnum++)    {      int dbx_type;      QUIT;      if (hp_symbuf_idx == hp_symbuf_end)        fill_hp_symbuf (abfd);      hp_bufp = &hp_symbuf[hp_symbuf_idx++];      switch (hp_bufp->symbol_type)        {        case ST_SYM_EXT:        case ST_ARG_EXT:          continue;        case ST_CODE:        case ST_PRI_PROG:        case ST_SEC_PROG:        case ST_ENTRY:        case ST_MILLICODE:          dbx_type = N_TEXT;          hp_bufp->symbol_value &= ~3; /* clear out permission bits */          break;        case ST_DATA:          dbx_type = N_DATA;          break;#ifdef KERNELDEBUG        case ST_ABSOLUTE:          {            extern int kernel_debugging;            if (!kernel_debugging)              continue;            dbx_type = N_ABS;            break;          }#endif        default:          continue;        }      /* Use the address of dbsubc to finish the last psymtab. */      if (hp_bufp->symbol_type == ST_CODE &&          HP_STRINGTAB (objfile)[hp_bufp->name.n_strx] == '_' &&          !strcmp (HP_STRINGTAB (objfile) + hp_bufp->name.n_strx, "_dbsubc"))        dbsubc_addr = hp_bufp->symbol_value;      if (hp_bufp->symbol_scope == SS_UNIVERSAL)        {          if (hp_bufp->name.n_strx > HP_STRINGTAB_SIZE (objfile))            error ("Invalid symbol data; bad HP string table offset: %d",                   hp_bufp->name.n_strx);          /* A hack, but gets the job done. */          if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), 		       "$START$"))	    objfile -> ei.entry_file_lowpc = hp_bufp->symbol_value;          if (!strcmp (hp_bufp->name.n_strx + HP_STRINGTAB (objfile), 		       "_sr4export"))	    objfile -> ei.entry_file_highpc = hp_bufp->symbol_value;          record_minimal_symbol (hp_bufp->name.n_strx + HP_STRINGTAB (objfile),				 hp_bufp->symbol_value, dbx_type | N_EXT, 				 objfile);        }    }  bfd_seek (abfd, DBX_SYMTAB_OFFSET (objfile), L_SET);#endif  for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)    {      /* Get the symbol for this run and pull out some info */      QUIT;	/* allow this to be interruptable */      if (symbuf_idx == symbuf_end)	fill_symbuf (abfd);      bufp = &symbuf[symbuf_idx++];      /*       * Special case to speed up readin.       */      if (bufp->n_type == (unsigned char)N_SLINE) continue;      SWAP_SYMBOL (bufp, abfd);      /* Ok.  There is a lot of code duplicated in the rest of this         switch statement (for efficiency reasons).  Since I don't         like duplicating code, I will do my penance here, and         describe the code which is duplicated:	 *) The assignment to namestring.	 *) The call to strchr.	 *) The addition of a partial symbol the the two partial	    symbol lists.  This last is a large section of code, so	    I've imbedded it in the following macro.	 */      /* Set namestring based on bufp.  If the string table index is invalid,    give a fake name, and print a single error message per symbol file read,   rather than abort the symbol reading or flood the user with messages.  *//*FIXME: Too many adds and indirections in here for the inner loop.  */#define SET_NAMESTRING()\  if (((unsigned)bufp->n_strx + file_string_table_offset) >=		\      DBX_STRINGTAB_SIZE (objfile)) {					\    complain (&string_table_offset_complaint, (char *) symnum);		\    namestring = "foo";							\  } else								\    namestring = bufp->n_strx + file_string_table_offset +		\		 DBX_STRINGTAB (objfile)#define CUR_SYMBOL_TYPE bufp->n_type#define CUR_SYMBOL_VALUE bufp->n_value#define DBXREAD_ONLY#define START_PSYMTAB(ofile,secoff,fname,low,symoff,global_syms,static_syms)\  start_psymtab(ofile, secoff, fname, low, symoff, global_syms, static_syms)#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\  end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)#include "partial-stab.h"    }  /* If there's stuff to be cleaned up, clean it up.  */#ifndef GDB_TARGET_IS_HPPA  if (DBX_SYMCOUNT (objfile) > 0			/* We have some syms *//*FIXME, does this have a bug at start address 0? */      && last_o_file_start      && objfile -> ei.entry_point < bufp->n_value      && objfile -> ei.entry_point >= last_o_file_start)    {      objfile -> ei.entry_file_lowpc = last_o_file_start;      objfile -> ei.entry_file_highpc = bufp->n_value;    }#endif  if (pst)    {#ifdef GDB_TARGET_IS_HPPA      end_psymtab (pst, psymtab_include_list, includes_used,		   symnum * symbol_size, dbsubc_addr,		   dependency_list, dependencies_used);#else      end_psymtab (pst, psymtab_include_list, includes_used,		   symnum * symbol_size, end_of_text_addr,		   dependency_list, dependencies_used);#endif    }  free_bincl_list (objfile);  discard_cleanups (old_chain);}/* Allocate and partially fill a partial symtab.  It will be   completely filled at the end of the symbol list.   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR   is the address relative to which its symbols are (incremental) or 0   (normal). */struct partial_symtab *start_psymtab (objfile, section_offsets,	       filename, textlow, ldsymoff, global_syms, static_syms)     struct objfile *objfile;     struct section_offsets *section_offsets;     char *filename;     CORE_ADDR textlow;     int ldsymoff;     struct partial_symbol *global_syms;     struct partial_symbol *static_syms;{  struct partial_symtab *result =      start_psymtab_common(objfile, section_offsets,			   filename, textlow, global_syms, static_syms);  result->read_symtab_private = (char *)    obstack_alloc (&objfile -> psymbol_obstack, sizeof (struct symloc));  LDSYMOFF(result) = ldsymoff;  result->read_symtab = dbx_psymtab_to_symtab;  SYMBOL_SIZE(result) = symbol_size;  SYMBOL_OFFSET(result) = symbol_table_offset;  STRING_OFFSET(result) = string_table_offset;  FILE_STRING_OFFSET(result) = file_string_table_offset;  /* If we're handling an ELF file, drag some section-relocation info     for this source file out of the ELF symbol table, to compensate for     Sun brain death.  This replaces the section_offsets in this psymtab,     if successful.  */#ifdef notdef  elfstab_offset_sections (objfile, result);#endif  return result;}/* Close off the current usage of a partial_symbol table entry.  This   involves setting the correct number of includes (with a realloc),   setting the high text mark, setting the symbol length in the   executable, and setting the length of the global and static lists   of psymbols.   The global symbols and static symbols are then seperately sorted.   Then the partial symtab is put on the global list.   *** List variables and peculiarities of same. ***   */voidend_psymtab (pst, include_list, num_includes, capping_symbol_offset,	     capping_text, dependency_list, number_dependencies)     struct partial_symtab *pst;     char **include_list;     int num_includes;     int capping_symbol_offset;     CORE_ADDR capping_text;     struct partial_symtab **dependency_list;     int number_dependencies;/*     struct partial_symbol *capping_global, *capping_static;*/{  int i;  struct partial_symtab *p1;  struct objfile *objfile = pst -> objfile;  if (capping_symbol_offset != -1)      LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);  pst->texthigh = capping_text;  /* Under Solaris, the N_SO symbols always have a value of 0,     instead of the usual address of the .o file.  Therefore,     we have to do some tricks to fill in texthigh and textlow.     The first trick is in partial-stab.h: if we see a static     or global function, and the textlow for the current pst     is still 0, then we use that function's address for      the textlow of the pst.     Now, to fill in texthigh, we remember the last function seen     in the .o file (also in partial-stab.h).  Also, there's a hack in     bfd/elf.c and gdb/elfread.c to pass the ELF st_size field     to here via the misc_info field.  Therefore, we can fill in     a reliable texthigh by taking the address plus size of the     last function in the file.     Unfortunately, that does not cover the case where the last function     in the file is static.  See the paragraph below for more comments     on this situation.     Finally, if we have a valid textlow for the current file, we run     down the partial_symtab_list filling in previous texthighs that     are still unknown.  */  if (pst->texthigh == 0 && last_function_name) {    char *p;    int n;    struct minimal_symbol *minsym;    p = strchr (last_function_name, ':');    if (p == NULL)      p = last_function_name;    n = p - last_function_name;    p = alloca (n + 1);    strncpy (p, last_function_name, n);    p[n] = 0;        minsym = lookup_minimal_symbol (p, objfile);    if (minsym) {      pst->texthigh = minsym->address + (int)minsym->info;    } else {      /* This file ends with a static function, and it's	 difficult to imagine how hard it would be to track down	 the elf symbol.  Luckily, most of the time no one will notice,	 since the next file will likely be compiled with -g, so	 the code below will copy the first fuction's start address 	 back to our texthigh variable.  (Also, if this file is the	 last one in a dynamically linked program, texthigh already	 has the right value.)  If the next file isn't compiled	 with -g, then the last function in this file winds up owning	 all of the text space up to the next -g file, or the end (minus	 shared libraries).  This only matters for single stepping,	 and even then it will still work, except that it will single	 step through all of the covered functions, instead of setting	 breakpoints around them as it usualy does.  This makes it

⌨️ 快捷键说明

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