📄 dwarfout.c
字号:
/* Output Dwarf format symbol table information from the GNU C compiler. Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices.This file is part of GNU CC.GNU CC 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, or (at your option)any later version.GNU CC 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 GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#include "config.h"#ifdef DWARF_DEBUGGING_INFO#include <stdio.h>#include "dwarf.h"#include "tree.h"#include "flags.h"#include "rtl.h"#include "hard-reg-set.h"#include "insn-config.h"#include "reload.h"#include "output.h"#include "defaults.h"#if defined(DWARF_TIMESTAMPS)#if defined(POSIX)#include <time.h>#else /* !defined(POSIX) */#include <sys/types.h>#if defined(__STDC__)extern time_t time (time_t *);#else /* !defined(__STDC__) */extern time_t time ();#endif /* !defined(__STDC__) */#endif /* !defined(POSIX) */#endif /* defined(DWARF_TIMESTAMPS) */#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#else#ifdef HAVE_STRINGS_H#include <strings.h>#endif#endif/* We cannot use <assert.h> in GCC source, since that would include GCC's assert.h, which may not be compatible with the host compiler. */#undef assert#ifdef NDEBUG# define assert(e)#else# define assert(e) do { if (! (e)) abort (); } while (0)#endifextern char *getpwd ();#ifdef NEED_DECLARATION_INDEXextern char *index ();#endif#ifdef NEED_DECLARATION_RINDEXextern char *rindex ();#endif/* IMPORTANT NOTE: Please see the file README.DWARF for important details regarding the GNU implementation of Dwarf. *//* NOTE: In the comments in this file, many references are made to so called "Debugging Information Entries". For the sake of brevity, this term is abbreviated to `DIE' throughout the remainder of this file. *//* Note that the implementation of C++ support herein is (as yet) unfinished. If you want to try to complete it, more power to you. */#if !defined(__GNUC__) || (NDEBUG != 1)#define inline#endif/* How to start an assembler comment. */#ifndef ASM_COMMENT_START#define ASM_COMMENT_START ";#"#endif/* How to print out a register name. */#ifndef PRINT_REG#define PRINT_REG(RTX, CODE, FILE) \ fprintf ((FILE), "%s", reg_names[REGNO (RTX)])#endif/* Define a macro which returns non-zero for any tagged type which is used (directly or indirectly) in the specification of either some function's return type or some formal parameter of some function. We use this macro when we are operating in "terse" mode to help us know what tagged types have to be represented in Dwarf (even in terse mode) and which ones don't. A flag bit with this meaning really should be a part of the normal GCC ..._TYPE nodes, but at the moment, there is no such bit defined for these nodes. For now, we have to just fake it. It it safe for us to simply return zero for all complete tagged types (which will get forced out anyway if they were used in the specification of some formal or return type) and non-zero for all incomplete tagged types.*/#define TYPE_USED_FOR_FUNCTION(tagged_type) (TYPE_SIZE (tagged_type) == 0)/* Define a macro which returns non-zero for a TYPE_DECL which was implicitly generated for a tagged type. Note that unlike the gcc front end (which generates a NULL named TYPE_DECL node for each complete tagged type, each array type, and each function type node created) the g++ front end generates a _named_ TYPE_DECL node for each tagged type node created. These TYPE_DECLs have DECL_ARTIFICIAL set, so we know not to generate a DW_TAG_typedef DIE for them. */#define TYPE_DECL_IS_STUB(decl) \ (DECL_NAME (decl) == NULL \ || (DECL_ARTIFICIAL (decl) \ && is_tagged_type (TREE_TYPE (decl)) \ && decl == TYPE_STUB_DECL (TREE_TYPE (decl))))extern int flag_traditional;extern char *version_string;extern char *language_string;/* Maximum size (in bytes) of an artificially generated label. */#define MAX_ARTIFICIAL_LABEL_BYTES 30/* Make sure we know the sizes of the various types dwarf can describe. These are only defaults. If the sizes are different for your target, you should override these values by defining the appropriate symbols in your tm.h file. */#ifndef CHAR_TYPE_SIZE#define CHAR_TYPE_SIZE BITS_PER_UNIT#endif#ifndef SHORT_TYPE_SIZE#define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2)#endif#ifndef INT_TYPE_SIZE#define INT_TYPE_SIZE BITS_PER_WORD#endif#ifndef LONG_TYPE_SIZE#define LONG_TYPE_SIZE BITS_PER_WORD#endif#ifndef LONG_LONG_TYPE_SIZE#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)#endif#ifndef WCHAR_TYPE_SIZE#define WCHAR_TYPE_SIZE INT_TYPE_SIZE#endif#ifndef WCHAR_UNSIGNED#define WCHAR_UNSIGNED 0#endif#ifndef FLOAT_TYPE_SIZE#define FLOAT_TYPE_SIZE BITS_PER_WORD#endif#ifndef DOUBLE_TYPE_SIZE#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)#endif#ifndef LONG_DOUBLE_TYPE_SIZE#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)#endif/* Structure to keep track of source filenames. */struct filename_entry { unsigned number; char * name;};typedef struct filename_entry filename_entry;/* Pointer to an array of elements, each one having the structure above. */static filename_entry *filename_table;/* Total number of entries in the table (i.e. array) pointed to by `filename_table'. This is the *total* and includes both used and unused slots. */static unsigned ft_entries_allocated;/* Number of entries in the filename_table which are actually in use. */static unsigned ft_entries;/* Size (in elements) of increments by which we may expand the filename table. Actually, a single hunk of space of this size should be enough for most typical programs. */#define FT_ENTRIES_INCREMENT 64/* Local pointer to the name of the main input file. Initialized in dwarfout_init. */static char *primary_filename;/* Pointer to the most recent filename for which we produced some line info. */static char *last_filename;/* For Dwarf output, we must assign lexical-blocks id numbers in the order in which their beginnings are encountered. We output Dwarf debugging info that refers to the beginnings and ends of the ranges of code for each lexical block with assembler labels ..Bn and ..Bn.e, where n is the block number. The labels themselves are generated in final.c, which assigns numbers to the blocks in the same way. */static unsigned next_block_number = 2;/* Counter to generate unique names for DIEs. */static unsigned next_unused_dienum = 1;/* Number of the DIE which is currently being generated. */static unsigned current_dienum;/* Number to use for the special "pubname" label on the next DIE which represents a function or data object defined in this compilation unit which has "extern" linkage. */static next_pubname_number = 0;#define NEXT_DIE_NUM pending_sibling_stack[pending_siblings-1]/* Pointer to a dynamically allocated list of pre-reserved and still pending sibling DIE numbers. Note that this list will grow as needed. */static unsigned *pending_sibling_stack;/* Counter to keep track of the number of pre-reserved and still pending sibling DIE numbers. */static unsigned pending_siblings;/* The currently allocated size of the above list (expressed in number of list elements). */static unsigned pending_siblings_allocated;/* Size (in elements) of increments by which we may expand the pending sibling stack. Actually, a single hunk of space of this size should be enough for most typical programs. */#define PENDING_SIBLINGS_INCREMENT 64/* Non-zero if we are performing our file-scope finalization pass and if we should force out Dwarf descriptions of any and all file-scope tagged types which are still incomplete types. */static int finalizing = 0;/* A pointer to the base of a list of pending types which we haven't generated DIEs for yet, but which we will have to come back to later on. */static tree *pending_types_list;/* Number of elements currently allocated for the pending_types_list. */static unsigned pending_types_allocated;/* Number of elements of pending_types_list currently in use. */static unsigned pending_types;/* Size (in elements) of increments by which we may expand the pending types list. Actually, a single hunk of space of this size should be enough for most typical programs. */#define PENDING_TYPES_INCREMENT 64/* Pointer to an artificial RECORD_TYPE which we create in dwarfout_init. This is used in a hack to help us get the DIEs describing types of formal parameters to come *after* all of the DIEs describing the formal parameters themselves. That's necessary in order to be compatible with what the brain-damaged svr4 SDB debugger requires. */static tree fake_containing_scope;/* The number of the current function definition that we are generating debugging information for. These numbers range from 1 up to the maximum number of function definitions contained within the current compilation unit. These numbers are used to create unique labels for various things contained within various function definitions. */static unsigned current_funcdef_number = 1;/* A pointer to the ..._DECL node which we have most recently been working on. We keep this around just in case something about it looks screwy and we want to tell the user what the source coordinates for the actual declaration are. */static tree dwarf_last_decl;/* A flag indicating that we are emitting the member declarations of a class, so member functions and variables should not be entirely emitted. This is a kludge to avoid passing a second argument to output_*_die. */static int in_class;/* Forward declarations for functions defined in this file. */static char *dwarf_tag_name PROTO((unsigned));static char *dwarf_attr_name PROTO((unsigned));static char *dwarf_stack_op_name PROTO((unsigned));static char *dwarf_typemod_name PROTO((unsigned));static char *dwarf_fmt_byte_name PROTO((unsigned));static char *dwarf_fund_type_name PROTO((unsigned));static tree decl_ultimate_origin PROTO((tree));static tree block_ultimate_origin PROTO((tree));static void output_unsigned_leb128 PROTO((unsigned long));static void output_signed_leb128 PROTO((long));static inline int is_body_block PROTO((tree));static int fundamental_type_code PROTO((tree));static tree root_type_1 PROTO((tree, int));static tree root_type PROTO((tree));static void write_modifier_bytes_1 PROTO((tree, int, int, int));static void write_modifier_bytes PROTO((tree, int, int));static inline int type_is_fundamental PROTO((tree));static void equate_decl_number_to_die_number PROTO((tree));static inline void equate_type_number_to_die_number PROTO((tree));static void output_reg_number PROTO((rtx));static void output_mem_loc_descriptor PROTO((rtx));static void output_loc_descriptor PROTO((rtx));static void output_bound_representation PROTO((tree, unsigned, int));static void output_enumeral_list PROTO((tree));static inline unsigned ceiling PROTO((unsigned, unsigned));static inline tree field_type PROTO((tree));static inline unsigned simple_type_align_in_bits PROTO((tree));static inline unsigned simple_type_size_in_bits PROTO((tree));static unsigned field_byte_offset PROTO((tree));static inline void sibling_attribute PROTO((void));static void location_attribute PROTO((rtx));static void data_member_location_attribute PROTO((tree));static void const_value_attribute PROTO((rtx));static void location_or_const_value_attribute PROTO((tree));static inline void name_attribute PROTO((char *));static inline void fund_type_attribute PROTO((unsigned));static void mod_fund_type_attribute PROTO((tree, int, int));static inline void user_def_type_attribute PROTO((tree));static void mod_u_d_type_attribute PROTO((tree, int, int));static inline void ordering_attribute PROTO((unsigned));static void subscript_data_attribute PROTO((tree));static void byte_size_attribute PROTO((tree));static inline void bit_offset_attribute PROTO((tree));static inline void bit_size_attribute PROTO((tree));static inline void element_list_attribute PROTO((tree));static inline void stmt_list_attribute PROTO((char *));static inline void low_pc_attribute PROTO((char *));static inline void high_pc_attribute PROTO((char *));static inline void body_begin_attribute PROTO((char *));static inline void body_end_attribute PROTO((char *));static inline void language_attribute PROTO((unsigned));static inline void member_attribute PROTO((tree));static inline void string_length_attribute PROTO((tree));static inline void comp_dir_attribute PROTO((char *));static inline void sf_names_attribute PROTO((char *));static inline void src_info_attribute PROTO((char *));static inline void mac_info_attribute PROTO((char *));static inline void prototyped_attribute PROTO((tree));static inline void producer_attribute PROTO((char *));static inline void inline_attribute PROTO((tree));static inline void containing_type_attribute PROTO((tree));static inline void abstract_origin_attribute PROTO((tree));static inline void src_coords_attribute PROTO((unsigned, unsigned));static inline void pure_or_virtual_attribute PROTO((tree));static void name_and_src_coords_attributes PROTO((tree));static void type_attribute PROTO((tree, int, int));static char *type_tag PROTO((tree));static inline void dienum_push PROTO((void));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -