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

📄 dwarfread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* DWARF debugging format support for GDB.   Copyright (C) 1991, 1992 Free Software Foundation, Inc.   Written by Fred Fish at Cygnus Support.  Portions based on dbxread.c,   mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.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.  *//*FIXME: Figure out how to get the frame pointer register number in theexecution environment of the target.  Remove R_FP kludgeFIXME: Add generation of dependencies list to partial symtab code.FIXME: Resolve minor differences between what information we put in thepartial symbol table and what dbxread puts in.  For example, we don't yetput enum constants there.  And dbxread seems to invent a lot of typedefswe never see.  Use the new printpsym command to see the partial symbol tablecontents.FIXME: Figure out a better way to tell gdb about the name of the functioncontain the user's entry point (I.E. main())FIXME: See other FIXME's and "ifdef 0" scattered throughout the code forother things to work on, if you get bored. :-)*/#include "defs.h"#include "bfd.h"#include "symtab.h"#include "gdbtypes.h"#include "symfile.h"#include "objfiles.h"#include "libbfd.h"	/* FIXME Secret Internal BFD stuff (bfd_read) */#include "elf/dwarf.h"#include "buildsym.h"#include "demangle.h"#include <varargs.h>#include <fcntl.h>#include <string.h>#include <sys/types.h>#ifndef	NO_SYS_FILE#include <sys/file.h>#endif/* FIXME -- convert this to SEEK_SET a la POSIX, move to config files.  */#ifndef L_SET#define L_SET 0#endif#ifdef MAINTENANCE	/* Define to 1 to compile in some maintenance stuff */#define SQUAWK(stuff) dwarfwarn stuff#else#define SQUAWK(stuff)#endif#ifndef R_FP		/* FIXME */#define R_FP 14		/* Kludge to get frame pointer register number */#endiftypedef unsigned int DIE_REF;	/* Reference to a DIE */#ifndef GCC_PRODUCER#define GCC_PRODUCER "GNU C "#endif#ifndef GPLUS_PRODUCER#define GPLUS_PRODUCER "GNU C++ "#endif#ifndef LCC_PRODUCER#define LCC_PRODUCER "NCR C/C++"#endif#ifndef CFRONT_PRODUCER#define CFRONT_PRODUCER "CFRONT "	/* A wild a** guess... */#endif#define STREQ(a,b)		(strcmp(a,b)==0)#define STREQN(a,b,n)		(strncmp(a,b,n)==0)/* Flags to target_to_host() that tell whether or not the data object is   expected to be signed.  Used, for example, when fetching a signed   integer in the target environment which is used as a signed integer   in the host environment, and the two environments have different sized   ints.  In this case, *somebody* has to sign extend the smaller sized   int. */#define GET_UNSIGNED	0	/* No sign extension required */#define GET_SIGNED	1	/* Sign extension required *//* Defines for things which are specified in the document "DWARF Debugging   Information Format" published by UNIX International, Programming Languages   SIG.  These defines are based on revision 1.0.0, Jan 20, 1992. */#define SIZEOF_DIE_LENGTH	4#define SIZEOF_DIE_TAG		2#define SIZEOF_ATTRIBUTE	2#define SIZEOF_FORMAT_SPECIFIER	1#define SIZEOF_FMT_FT		2#define SIZEOF_LINETBL_LENGTH	4#define SIZEOF_LINETBL_LINENO	4#define SIZEOF_LINETBL_STMT	2#define SIZEOF_LINETBL_DELTA	4#define SIZEOF_LOC_ATOM_CODE	1#define FORM_FROM_ATTR(attr)	((attr) & 0xF)	/* Implicitly specified *//* Macros that return the sizes of various types of data in the target   environment.   FIXME:  Currently these are just compile time constants (as they are in   other parts of gdb as well).  They need to be able to get the right size   either from the bfd or possibly from the DWARF info.  It would be nice if   the DWARF producer inserted DIES that describe the fundamental types in   the target environment into the DWARF info, similar to the way dbx stabs   producers produce information about their fundamental types. */#define TARGET_FT_POINTER_SIZE(objfile)	(TARGET_PTR_BIT / TARGET_CHAR_BIT)#define TARGET_FT_LONG_SIZE(objfile)	(TARGET_LONG_BIT / TARGET_CHAR_BIT)/* The Amiga SVR4 header file <dwarf.h> defines AT_element_list as a   FORM_BLOCK2, and this is the value emitted by the AT&T compiler.   However, the Issue 2 DWARF specification from AT&T defines it as   a FORM_BLOCK4, as does the latest specification from UI/PLSIG.   For backwards compatibility with the AT&T compiler produced executables   we define AT_short_element_list for this variant. */#define	AT_short_element_list	 (0x00f0|FORM_BLOCK2)/* External variables referenced. */extern int info_verbose;		/* From main.c; nonzero => verbose */extern char *warning_pre_print;		/* From utils.c *//* The DWARF debugging information consists of two major pieces,   one is a block of DWARF Information Entries (DIE's) and the other   is a line number table.  The "struct dieinfo" structure contains   the information for a single DIE, the one currently being processed.   In order to make it easier to randomly access the attribute fields   of the current DIE, which are specifically unordered within the DIE,   each DIE is scanned and an instance of the "struct dieinfo"   structure is initialized.   Initialization is done in two levels.  The first, done by basicdieinfo(),   just initializes those fields that are vital to deciding whether or not   to use this DIE, how to skip past it, etc.  The second, done by the   function completedieinfo(), fills in the rest of the information.   Attributes which have block forms are not interpreted at the time   the DIE is scanned, instead we just save pointers to the start   of their value fields.   Some fields have a flag <name>_p that is set when the value of the   field is valid (I.E. we found a matching attribute in the DIE).  Since   we may want to test for the presence of some attributes in the DIE,   such as AT_low_pc, without restricting the values of the field,   we need someway to note that we found such an attribute.    */   typedef char BLOCK;struct dieinfo {  char *		die;		/* Pointer to the raw DIE data */  unsigned long 	die_length;	/* Length of the raw DIE data */  DIE_REF		die_ref;	/* Offset of this DIE */  unsigned short	die_tag;	/* Tag for this DIE */  unsigned long		at_padding;  unsigned long		at_sibling;  BLOCK *		at_location;  char *		at_name;  unsigned short	at_fund_type;  BLOCK *		at_mod_fund_type;  unsigned long		at_user_def_type;  BLOCK *		at_mod_u_d_type;  unsigned short	at_ordering;  BLOCK *		at_subscr_data;  unsigned long		at_byte_size;  unsigned short	at_bit_offset;  unsigned long		at_bit_size;  BLOCK *		at_element_list;  unsigned long		at_stmt_list;  unsigned long		at_low_pc;  unsigned long		at_high_pc;  unsigned long		at_language;  unsigned long		at_member;  unsigned long		at_discr;  BLOCK *		at_discr_value;  BLOCK *		at_string_length;  char *		at_comp_dir;  char *		at_producer;  unsigned long		at_start_scope;  unsigned long		at_stride_size;  unsigned long		at_src_info;  char *		at_prototyped;  unsigned int		has_at_low_pc:1;  unsigned int		has_at_stmt_list:1;  unsigned int		has_at_byte_size:1;  unsigned int		short_element_list:1;};static int diecount;	/* Approximate count of dies for compilation unit */static struct dieinfo *curdie;	/* For warnings and such */static char *dbbase;	/* Base pointer to dwarf info */static int dbsize;	/* Size of dwarf info in bytes */static int dbroff;	/* Relative offset from start of .debug section */static char *lnbase;	/* Base pointer to line section */static int isreg;	/* Kludge to identify register variables */static int offreg;	/* Kludge to identify basereg references *//* This value is added to each symbol value.  FIXME:  Generalize to    the section_offsets structure used by dbxread.  */static CORE_ADDR baseaddr;	/* Add to each symbol value *//* The section offsets used in the current psymtab or symtab.  FIXME,   only used to pass one value (baseaddr) at the moment.  */static struct section_offsets *base_section_offsets;/* 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 DWARF debugging info, this data is   contained in the following structure and macros are provided for easy   access to the members given a pointer to a partial symbol table entry.   dbfoff	Always the absolute file offset to the start of the ".debug"		section for the file containing the DIE's being accessed.   dbroff	Relative offset from the start of the ".debug" access to the		first DIE to be accessed.  When building the partial symbol		table, this value will be zero since we are accessing the		entire ".debug" section.  When expanding a partial symbol		table entry, this value will be the offset to the first		DIE for the compilation unit containing the symbol that		triggers the expansion.   dblength	The size of the chunk of DIE's being examined, in bytes.   lnfoff	The absolute file offset to the line table fragment.  Ignored		when building partial symbol tables, but used when expanding		them, and contains the absolute file offset to the fragment		of the ".line" section containing the line numbers for the		current compilation unit. */struct dwfinfo {  file_ptr dbfoff;	/* Absolute file offset to start of .debug section */  int dbroff;		/* Relative offset from start of .debug section */  int dblength;		/* Size of the chunk of DIE's being examined */  file_ptr lnfoff;	/* Absolute file offset to line table fragment */};#define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)#define DBROFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbroff)#define DBLENGTH(p) (((struct dwfinfo *)((p)->read_symtab_private))->dblength)#define LNFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->lnfoff)/* The generic symbol table building routines have separate lists for   file scope symbols and all all other scopes (local scopes).  So   we need to select the right one to pass to add_symbol_to_list().   We do it by keeping a pointer to the correct list in list_in_scope.   FIXME:  The original dwarf code just treated the file scope as the first   local scope, and all other local scopes as nested local scopes, and worked   fine.  Check to see if we really need to distinguish these in buildsym.c */struct pending **list_in_scope = &file_symbols;/* DIES which have user defined types or modified user defined types refer to   other DIES for the type information.  Thus we need to associate the offset   of a DIE for a user defined type with a pointer to the type information.   Originally this was done using a simple but expensive algorithm, with an   array of unsorted structures, each containing an offset/type-pointer pair.   This array was scanned linearly each time a lookup was done.  The result   was that gdb was spending over half it's startup time munging through this   array of pointers looking for a structure that had the right offset member.   The second attempt used the same array of structures, but the array was   sorted using qsort each time a new offset/type was recorded, and a binary   search was used to find the type pointer for a given DIE offset.  This was   even slower, due to the overhead of sorting the array each time a new   offset/type pair was entered.   The third attempt uses a fixed size array of type pointers, indexed by a   value derived from the DIE offset.  Since the minimum DIE size is 4 bytes,   we can divide any DIE offset by 4 to obtain a unique index into this fixed   size array.  Since each element is a 4 byte pointer, it takes exactly as   much memory to hold this array as to hold the DWARF info for a given   compilation unit.  But it gets freed as soon as we are done with it. */static struct type **utypes;	/* Pointer to array of user type pointers */static int numutypes;		/* Max number of user type pointers *//* Record the language for the compilation unit which is currently being   processed.  We know it once we have seen the TAG_compile_unit DIE,   and we need it while processing the DIE's for that compilation unit.   It is eventually saved in the symtab structure, but we don't finalize   the symtab struct until we have processed all the DIE's for the   compilation unit. */static enum language cu_language;/* Forward declarations of static functions so we don't have to worry   about ordering within this file.  */static intattribute_size PARAMS ((unsigned int));static unsigned longtarget_to_host PARAMS ((char *, int, int, struct objfile *));static voidadd_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *));static voidhandle_producer PARAMS ((char *));static voidread_file_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *));static voidread_func_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *));static voidread_lexical_block_scope PARAMS ((struct dieinfo *, char *, char *,				  struct objfile *));static voiddwarfwarn ();static voidscan_partial_symbols PARAMS ((char *, char *, struct objfile *));static voidscan_compilation_units PARAMS ((char *, char *, file_ptr,				file_ptr, struct objfile *));static voidadd_partial_symbol PARAMS ((struct dieinfo *, struct objfile *));static voidinit_psymbol_list PARAMS ((struct objfile *, int));static voidbasicdieinfo PARAMS ((struct dieinfo *, char *, struct objfile *));static voidcompletedieinfo PARAMS ((struct dieinfo *, struct objfile *));static voiddwarf_psymtab_to_symtab PARAMS ((struct partial_symtab *));static voidpsymtab_to_symtab_1 PARAMS ((struct partial_symtab *));static struct symtab *read_ofile_symtab PARAMS ((struct partial_symtab *));static voidprocess_dies PARAMS ((char *, char *, struct objfile *));static voidread_structure_scope PARAMS ((struct dieinfo *, char *, char *,			      struct objfile *));static struct type *decode_array_element_type PARAMS ((char *));static struct type *decode_subscr_data PARAMS ((char *, char *));static voiddwarf_read_array_type PARAMS ((struct dieinfo *));static voidread_tag_pointer_type PARAMS ((struct dieinfo *dip));static voidread_subroutine_type PARAMS ((struct dieinfo *, char *, char *));static voidread_enumeration PARAMS ((struct dieinfo *, char *, char *, struct objfile *));static struct type *struct_type PARAMS ((struct dieinfo *, char *, char *, struct objfile *));static struct type *enum_type PARAMS ((struct dieinfo *, struct objfile *));static voiddecode_line_numbers PARAMS ((char *));static struct type *decode_die_type PARAMS ((struct dieinfo *));static struct type *decode_mod_fund_type PARAMS ((char *));static struct type *decode_mod_u_d_type PARAMS ((char *));static struct type *decode_modified_type PARAMS ((char *, unsigned int, int));static struct type *decode_fund_type PARAMS ((unsigned int));static char *create_name PARAMS ((char *, struct obstack *));static struct type *lookup_utype PARAMS ((DIE_REF));static struct type *alloc_utype PARAMS ((DIE_REF, struct type *));static struct symbol *new_symbol PARAMS ((struct dieinfo *, struct objfile *));static voidsynthesize_typedef PARAMS ((struct dieinfo *, struct objfile *,			    struct type *));static intlocval PARAMS ((char *));static voidrecord_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,			       struct objfile *));static voidset_cu_language PARAMS ((struct dieinfo *));/*LOCAL FUNCTION	set_cu_language -- set local copy of language for compilation unitSYNOPSIS	void	set_cu_language (struct dieinfo *dip)DESCRIPTION

⌨️ 快捷键说明

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