📄 xcoffread.c
字号:
/* Read AIX xcoff symbol tables and convert to internal format, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc. Derived from coffread.c, dbxread.c, and a lot of hacking. Contributed by IBM Corporation.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 "bfd.h"#if defined(IBM6000_HOST) && defined(IBM6000_TARGET)/* Native only: Need struct tbtable in <sys/debug.h> from host, and need xcoff_add_toc_to_loadinfo in rs6000-tdep.c from target. *//* AIX XCOFF names have a preceeding dot `.' */#define NAMES_HAVE_DOT 1#include <sys/types.h>#include <fcntl.h>#include <ctype.h>#include "obstack.h"#include <sys/param.h>#ifndef NO_SYS_FILE#include <sys/file.h>#endif#include <sys/stat.h>#include <sys/debug.h>#include "symtab.h"#include "gdbtypes.h"#include "symfile.h"#include "objfiles.h"#include "buildsym.h"#include "stabsread.h"#include "gdb-stabs.h"#include "coff/internal.h" /* FIXME, internal data from BFD */#include "libcoff.h" /* FIXME, internal data from BFD */#include "coff/rs6000.h" /* FIXME, raw file-format guts of xcoff *//* Define this if you want gdb use the old xcoff symbol processing. This way it won't use common `define_symbol()' function and Sun dbx stab string grammar. And likely it won't be able to do G++ debugging. *//* #define NO_DEFINE_SYMBOL 1 *//* Define this if you want gdb to ignore typdef stabs. This was needed for one of Transarc, to reduce the size of the symbol table. Types won't be recognized, but tag names will be. *//* #define NO_TYPEDEFS 1 *//* Simplified internal version of coff symbol table information */struct coff_symbol { char *c_name; int c_symnum; /* symbol number of this entry */ int c_nsyms; /* 0 if syment only, 1 if syment + auxent */ long c_value; int c_sclass; int c_secnum; unsigned int c_type;};/* The COFF line table, in raw form. */static char *linetab = NULL; /* Its actual contents */static long linetab_offset; /* Its offset in the file */static unsigned long linetab_size; /* Its size *//* last function's saved coff symbol `cs' */static struct coff_symbol fcn_cs_saved;static bfd *symfile_bfd;/* Core address of start and end of text of current source file. This is calculated from the first function seen after a C_FILE symbol. */static CORE_ADDR cur_src_end_addr;/* Core address of the end of the first object file. */static CORE_ADDR first_object_file_end;/* pointer to the string table */static char *strtbl;/* length of the string table */static int strtbl_len;/* pointer to debug section */static char *debugsec;/* pointer to the a.out symbol table */static char *symtbl;/* initial symbol-table-debug-string vector length */#define INITIAL_STABVECTOR_LENGTH 40/* Nonzero if within a function (so symbols should be local, if nothing says specifically). */int within_function;/* 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_btshft;static unsigned local_n_tmask;#undef N_BTSHFT#define N_BTSHFT local_n_btshft#undef N_TMASK#define N_TMASK local_n_tmask /* 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_symesz;/* coff_symfile_init() is the coff-specific initialization routine for reading symbols. It is passed a struct sym_fns which contains, among other things, the BFD for the file whose symbols are being read, and a slot for a pointer to "private data" which we fill with cookies and other treats for coff_symfile_read(). We will only be called if this is a COFF or COFF-like file. BFD handles figuring out the format of the file, and code in symtab.c uses BFD's determination to vector to us. The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */struct coff_symfile_info { file_ptr min_lineno_offset; /* Where in file lowest line#s are */ file_ptr max_lineno_offset; /* 1+last byte of line#s in file */};static voidenter_line_range PARAMS ((struct subfile *, unsigned, unsigned, CORE_ADDR, CORE_ADDR, unsigned *));static voidfree_debugsection PARAMS ((void));static intinit_debugsection PARAMS ((bfd *));static intinit_stringtab PARAMS ((bfd *, file_ptr, struct objfile *));static voidxcoff_symfile_init PARAMS ((struct objfile *));static voidxcoff_new_init PARAMS ((struct objfile *));#ifdef __STDC__struct section_offset;#endifstatic voidxcoff_symfile_read PARAMS ((struct objfile *, struct section_offset *, int));static voidxcoff_symfile_finish PARAMS ((struct objfile *));static struct section_offsets *xcoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));static intinit_lineno PARAMS ((bfd *, file_ptr, int));static voidfind_linenos PARAMS ((bfd *, sec_ptr, PTR));static intread_symbol_lineno PARAMS ((char *, int));static intread_symbol_nvalue PARAMS ((char *, int));static struct symbol *process_xcoff_symbol PARAMS ((struct coff_symbol *, struct objfile *));static voidread_xcoff_symtab PARAMS ((struct objfile *, int));static voidadd_stab_to_list PARAMS ((char *, struct pending_stabs **));static voidsort_syms PARAMS ((void));static intcompare_symbols PARAMS ((const void *, const void *));/* Call sort_syms to sort alphabetically the symbols of each block of each symtab. */static intcompare_symbols (s1p, s2p) const PTR s1p; const PTR s2p;{ /* Names that are less should come first. */ register struct symbol **s1 = (struct symbol **) s1p; register struct symbol **s2 = (struct symbol **) s2p; register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)); if (namediff != 0) return namediff; /* For symbols of the same name, registers should come first. */ return ((SYMBOL_CLASS (*s2) == LOC_REGISTER) - (SYMBOL_CLASS (*s1) == LOC_REGISTER));}/* Sort a vector of symbols by their value. */static voidsort_syms (){ register struct symtab *s; register struct objfile *objfile; register int i, nbl; register struct blockvector *bv; register struct block *b; for (objfile = object_files; objfile != NULL; objfile = objfile -> next) { for (s = objfile -> symtabs; s != NULL; s = s -> next) { bv = BLOCKVECTOR (s); nbl = BLOCKVECTOR_NBLOCKS (bv); for (i = 0; i < nbl; i++) { b = BLOCKVECTOR_BLOCK (bv, i); if (BLOCK_SHOULD_SORT (b)) { qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), sizeof (struct symbol *), compare_symbols); } } } }}/* add a given stab string into given stab vector. */static voidadd_stab_to_list (stabname, stabvector)char *stabname;struct pending_stabs **stabvector;{ if ( *stabvector == NULL) { *stabvector = (struct pending_stabs *) xmalloc (sizeof (struct pending_stabs) + INITIAL_STABVECTOR_LENGTH * sizeof (char*)); (*stabvector)->count = 0; (*stabvector)->length = INITIAL_STABVECTOR_LENGTH; } else if ((*stabvector)->count >= (*stabvector)->length) { (*stabvector)->length += INITIAL_STABVECTOR_LENGTH; *stabvector = (struct pending_stabs *) xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) + (*stabvector)->length * sizeof (char*)); } (*stabvector)->stab [(*stabvector)->count++] = stabname;}#if 0/* for all the stabs in a given stab vector, build appropriate types and fix their symbols in given symbol vector. */voidpatch_block_stabs (symbols, stabs)struct pending *symbols;struct pending_stabs *stabs;{ int ii; if (!stabs) return; /* for all the stab entries, find their corresponding symbols and patch their types! */ for (ii=0; ii < stabs->count; ++ii) { char *name = stabs->stab[ii]; char *pp = (char*) index (name, ':'); struct symbol *sym = find_symbol_in_list (symbols, name, pp-name); if (!sym) { ; /* printf ("ERROR! stab symbol not found!\n"); */ /* FIXME */ /* The above is a false alarm. There are cases the we can have a stab, without its symbol. xlc generates this for the extern definitions in inner blocks. */ } else { pp += 2; if (*(pp-1) == 'F' || *(pp-1) == 'f') SYMBOL_TYPE (sym) = lookup_function_type (read_type (&pp)); else SYMBOL_TYPE (sym) = read_type (&pp, objfile); } }}#endif/* compare line table entry addresses. */ static intcompare_lte (lte1, lte2) struct linetable_entry *lte1, *lte2;{ return lte1->pc - lte2->pc;}/* Give a line table with function entries are marked, arrange its functions in assending order and strip off function entry markers and return it in a newly created table. If the old one is good enough, return the old one. */static struct linetable *arrange_linetable (oldLineTb) struct linetable *oldLineTb; /* old linetable */{ int ii, jj, newline, /* new line count */ function_count; /* # of functions */ struct linetable_entry *fentry; /* function entry vector */ int fentry_size; /* # of function entries */ struct linetable *newLineTb; /* new line table */#define NUM_OF_FUNCTIONS 20 fentry_size = NUM_OF_FUNCTIONS; fentry = (struct linetable_entry*) malloc (fentry_size * sizeof (struct linetable_entry)); for (function_count=0, ii=0; ii <oldLineTb->nitems; ++ii) { if (oldLineTb->item[ii].line == 0) { /* function entry found. */ if (function_count >= fentry_size) { /* make sure you have room. */ fentry_size *= 2; fentry = (struct linetable_entry*) realloc (fentry, fentry_size * sizeof (struct linetable_entry)); } fentry[function_count].line = ii; fentry[function_count].pc = oldLineTb->item[ii].pc; ++function_count; } } if (function_count == 0) { free (fentry); return oldLineTb; } else if (function_count > 1) qsort (fentry, function_count, sizeof(struct linetable_entry), compare_lte); /* allocate a new line table. */ newLineTb = (struct linetable*) malloc (sizeof (struct linetable) + (oldLineTb->nitems - function_count) * sizeof (struct linetable_entry)); /* if line table does not start with a function beginning, copy up until a function begin. */ newline = 0; if (oldLineTb->item[0].line != 0) for (newline=0; newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline) newLineTb->item[newline] = oldLineTb->item[newline]; /* Now copy function lines one by one. */ for (ii=0; ii < function_count; ++ii) { for (jj = fentry[ii].line + 1; jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; ++jj, ++newline) newLineTb->item[newline] = oldLineTb->item[jj]; } free (fentry); newLineTb->nitems = oldLineTb->nitems - function_count; return newLineTb; } /* We try to detect the beginning of a compilation unit. That info will be used as an entry in line number recording routines (enter_line_range) */static unsigned first_fun_line_offset;static unsigned first_fun_bf;#define mark_first_line(OFFSET, SYMNUM) \ if (!first_fun_line_offset) { \ first_fun_line_offset = OFFSET; \ first_fun_bf = SYMNUM; \ } /* include file support: C_BINCL/C_EINCL pairs will be kept in the following `IncludeChain'. At the end of each symtab (end_symtab), we will determine if we should create additional symtab's to represent if (the include files. */typedef struct _inclTable { char *name; /* include filename */ int begin, end; /* offsets to the line table */ struct subfile *subfile; unsigned funStartLine; /* start line # of its function */} InclTable;#define INITIAL_INCLUDE_TABLE_LENGTH 20static InclTable *inclTable; /* global include table */static int inclIndx; /* last entry to table */static int inclLength; /* table length */static int inclDepth; /* nested include depth */static voidrecord_include_begin (cs)struct coff_symbol *cs;{ /* In xcoff, we assume include files cannot be nested (not in .c files
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -