📄 dbxread.c
字号:
/* Read dbx symbol tables and convert to internal format, for GDB. Copyright 1986, 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. *//* This module provides three functions: dbx_symfile_init, which initializes to read a symbol file; dbx_new_init, which discards existing cached information when all symbols are being discarded; and dbx_symfile_read, which reads a symbol table from a file. dbx_symfile_read only does the minimum work necessary for letting the user "name" things symbolically; it does not read the entire symtab. Instead, it reads the external and static symbols and puts them in partial symbol tables. When more extensive information is requested of a file, the corresponding partial symbol table is mutated into a full fledged symbol table by going back and reading the symbols for real. dbx_psymtab_to_symtab() is the function that does this */#include "defs.h"#include <string.h>#if defined(USG) || defined(__CYGNUSCLIB__)#include <sys/types.h>#include <fcntl.h>#define L_SET 0#define L_INCR 1#endif#ifdef GDB_TARGET_IS_HPPA/* We don't want to use HP-UX's nlists. */#define _NLIST_INCLUDED#endif#include <obstack.h>#include <sys/param.h>#ifndef NO_SYS_FILE#include <sys/file.h>#endif#include <sys/stat.h>#include <ctype.h>#include "symtab.h"#include "breakpoint.h"#include "command.h"#include "target.h"#include "gdbcore.h" /* for bfd stuff */#include "libbfd.h" /* FIXME Secret internal BFD stuff (bfd_read) */#ifdef GDB_TARGET_IS_HPPA#include "libhppa.h"#include "syms.h"#else#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */#endif#include "symfile.h"#include "objfiles.h"#include "buildsym.h"#include "stabsread.h"#include "gdb-stabs.h"#include "demangle.h"#include "aout/aout64.h"#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now *//* Each partial symbol table entry contains a pointer to private data for the read_symtab() function to use when expanding a partial symbol table entry to a full symbol table entry. For dbxread this structure contains the offset within the file symbol table of first local symbol for this file, and length (in bytes) of the section of the symbol table devoted to this file's symbols (actually, the section bracketed may contain more than just this file's symbols). It also contains further information needed to locate the symbols if they are in an ELF file. If ldsymlen is 0, the only reason for this thing's existence is the dependency list. Nothing else will happen when it is read in. */#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)struct symloc { int ldsymoff; int ldsymlen; int symbol_size; int symbol_offset; int string_offset; int file_string_offset;};/* Macro to determine which symbols to ignore when reading the first symbol of a file. Some machines override this definition. */#ifndef IGNORE_SYMBOL/* This code is used on Ultrix systems. Ignore it */#define IGNORE_SYMBOL(type) (type == (int)N_NSYMS)#endif/* Macro for name of symbol to indicate a file compiled with gcc. */#ifndef GCC_COMPILED_FLAG_SYMBOL#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."#endif/* Macro for name of symbol to indicate a file compiled with gcc2. */#ifndef GCC2_COMPILED_FLAG_SYMBOL#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."#endif/* Define this as 1 if a pcc declaration of a char or short argument gives the correct address. Otherwise assume pcc gives the address of the corresponding int, which is not the same on a big-endian machine. */#ifndef BELIEVE_PCC_PROMOTION#define BELIEVE_PCC_PROMOTION 0#endif/* Nonzero means give verbose info on gdb action. From main.c. */extern int info_verbose;/* The BFD for this file -- implicit parameter to next_symbol_text. */static bfd *symfile_bfd;/* The size of each symbol in the symbol file (in external form). This is set by dbx_symfile_read when building psymtabs, and by dbx_psymtab_to_symtab when building symtabs. */static unsigned symbol_size;/* This is the offset of the symbol table in the executable file */static unsigned symbol_table_offset;/* This is the offset of the string table in the executable file */static unsigned string_table_offset;/* For elf+stab executables, the n_strx field is not a simple index into the string table. Instead, each .o file has a base offset in the string table, and the associated symbols contain offsets from this base. The following two variables contain the base offset for the current and next .o files. */static unsigned int file_string_table_offset;static unsigned int next_file_string_table_offset;/* Complaints about the symbols we have encountered. */struct complaint lbrac_complaint = {"bad block start address patched", 0, 0};struct complaint string_table_offset_complaint = {"bad string table offset in symbol %d", 0, 0};struct complaint unknown_symtype_complaint = {"unknown symbol type %s", 0, 0};struct complaint lbrac_rbrac_complaint = {"block start larger than block end", 0, 0};struct complaint lbrac_unmatched_complaint = {"unmatched N_LBRAC before symtab pos %d", 0, 0};struct complaint lbrac_mismatch_complaint = {"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0};struct complaint repeated_header_complaint = {"\"repeated\" header file not previously seen, at symtab pos %d", 0, 0};struct complaint repeated_header_name_complaint = {"\"repeated\" header file not previously seen, named %s", 0, 0};/* During initial symbol readin, we need to have a structure to keep track of which psymtabs have which bincls in them. This structure is used during readin to setup the list of dependencies within each partial symbol table. */struct header_file_location{ char *name; /* Name of header file */ int instance; /* See above */ struct partial_symtab *pst; /* Partial symtab that has the BINCL/EINCL defs for this file */};/* The actual list and controling variables */static struct header_file_location *bincl_list, *next_bincl;static int bincls_allocated;/* Local function prototypes */static voidfree_header_files PARAMS ((void));static voidinit_header_files PARAMS ((void));static struct pending *copy_pending PARAMS ((struct pending *, int, struct pending *));static struct symtab *read_ofile_symtab PARAMS ((struct objfile *, int, int, CORE_ADDR, int, struct section_offsets *));static voiddbx_psymtab_to_symtab PARAMS ((struct partial_symtab *));static voiddbx_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));static voidread_dbx_symtab PARAMS ((struct section_offsets *, struct objfile *, CORE_ADDR, int));static voidfree_bincl_list PARAMS ((struct objfile *));static struct partial_symtab *find_corresponding_bincl_psymtab PARAMS ((char *, int));static voidadd_bincl_to_list PARAMS ((struct partial_symtab *, char *, int));static voidinit_bincl_list PARAMS ((int, struct objfile *));static voidinit_psymbol_list PARAMS ((struct objfile *));static char *dbx_next_symbol_text PARAMS ((void));static voidfill_symbuf PARAMS ((bfd *));static voiddbx_symfile_init PARAMS ((struct objfile *));static voiddbx_new_init PARAMS ((struct objfile *));static voiddbx_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));static voiddbx_symfile_finish PARAMS ((struct objfile *));static voidrecord_minimal_symbol PARAMS ((char *, CORE_ADDR, int, struct objfile *));static voidadd_new_header_file PARAMS ((char *, int));static voidadd_old_header_file PARAMS ((char *, int));static voidadd_this_object_header_file PARAMS ((int));/* Free up old header file tables */static voidfree_header_files (){ register int i; if (header_files != NULL) { for (i = 0; i < n_header_files; i++) { free (header_files[i].name); } free ((PTR)header_files); header_files = NULL; n_header_files = 0; } if (this_object_header_files) { free ((PTR)this_object_header_files); this_object_header_files = NULL; } n_allocated_header_files = 0; n_allocated_this_object_header_files = 0;}/* Allocate new header file tables */static voidinit_header_files (){ n_header_files = 0; n_allocated_header_files = 10; header_files = (struct header_file *) xmalloc (10 * sizeof (struct header_file)); n_allocated_this_object_header_files = 10; this_object_header_files = (int *) xmalloc (10 * sizeof (int));}/* Add header file number I for this object file at the next successive FILENUM. */static voidadd_this_object_header_file (i) int i;{ if (n_this_object_header_files == n_allocated_this_object_header_files) { n_allocated_this_object_header_files *= 2; this_object_header_files = (int *) xrealloc ((char *) this_object_header_files, n_allocated_this_object_header_files * sizeof (int)); } this_object_header_files[n_this_object_header_files++] = i;}/* Add to this file an "old" header file, one already seen in a previous object file. NAME is the header file's name. INSTANCE is its instance code, to select among multiple symbol tables for the same header file. */static voidadd_old_header_file (name, instance) char *name; int instance;{ register struct header_file *p = header_files; register int i; for (i = 0; i < n_header_files; i++) if (!strcmp (p[i].name, name) && instance == p[i].instance) { add_this_object_header_file (i); return; } complain (&repeated_header_complaint, (char *)symnum); complain (&repeated_header_name_complaint, name);}/* Add to this file a "new" header file: definitions for its types follow. NAME is the header file's name. Most often this happens only once for each distinct header file, but not necessarily. If it happens more than once, INSTANCE has a different value each time, and references to the header file use INSTANCE values to select among them. dbx output contains "begin" and "end" markers for each new header file, but at this level we just need to know which files there have been; so we record the file when its "begin" is seen and ignore the "end". */static voidadd_new_header_file (name, instance) char *name; int instance;{ register int i; /* Make sure there is room for one more header file. */ if (n_header_files == n_allocated_header_files) { n_allocated_header_files *= 2; header_files = (struct header_file *) xrealloc ((char *) header_files, (n_allocated_header_files * sizeof (struct header_file))); } /* Create an entry for this header file. */ i = n_header_files++; header_files[i].name = savestring (name, strlen(name)); header_files[i].instance = instance; header_files[i].length = 10; header_files[i].vector = (struct type **) xmalloc (10 * sizeof (struct type *)); memset (header_files[i].vector, 0, 10 * sizeof (struct type *)); add_this_object_header_file (i);}#if 0static struct type **explicit_lookup_type (real_filenum, index) int real_filenum, index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -