dwarf2out.c revision 146895
1132718Skan/* Output Dwarf2 format symbol table information from GCC. 2132718Skan Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 3146895Skan 2003, 2004, 2005 Free Software Foundation, Inc. 450397Sobrien Contributed by Gary Funck (gary@intrepid.com). 550397Sobrien Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com). 650397Sobrien Extensively modified by Jason Merrill (jason@cygnus.com). 750397Sobrien 890075SobrienThis file is part of GCC. 950397Sobrien 1090075SobrienGCC is free software; you can redistribute it and/or modify it under 1190075Sobrienthe terms of the GNU General Public License as published by the Free 1290075SobrienSoftware Foundation; either version 2, or (at your option) any later 1390075Sobrienversion. 1450397Sobrien 1590075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1690075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1790075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1890075Sobrienfor more details. 1950397Sobrien 2050397SobrienYou should have received a copy of the GNU General Public License 2190075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 2290075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2390075Sobrien02111-1307, USA. */ 2450397Sobrien 2590075Sobrien/* TODO: Emit .debug_line header even when there are no functions, since 2690075Sobrien the file numbers are used by .debug_info. Alternately, leave 2790075Sobrien out locations for types and decls. 2890075Sobrien Avoid talking about ctors and op= for PODs. 2990075Sobrien Factor out common prologue sequences into multiple CIEs. */ 3090075Sobrien 3150397Sobrien/* The first part of this file deals with the DWARF 2 frame unwind 3250397Sobrien information, which is also used by the GCC efficient exception handling 3350397Sobrien mechanism. The second part, controlled only by an #ifdef 3450397Sobrien DWARF2_DEBUGGING_INFO, deals with the other DWARF 2 debugging 3550397Sobrien information. */ 3650397Sobrien 3750397Sobrien#include "config.h" 3850397Sobrien#include "system.h" 39132718Skan#include "coretypes.h" 40132718Skan#include "tm.h" 4150397Sobrien#include "tree.h" 4250397Sobrien#include "flags.h" 43117395Skan#include "real.h" 4450397Sobrien#include "rtl.h" 4550397Sobrien#include "hard-reg-set.h" 4650397Sobrien#include "regs.h" 4750397Sobrien#include "insn-config.h" 4850397Sobrien#include "reload.h" 4990075Sobrien#include "function.h" 5050397Sobrien#include "output.h" 5150397Sobrien#include "expr.h" 5290075Sobrien#include "libfuncs.h" 5350397Sobrien#include "except.h" 5450397Sobrien#include "dwarf2.h" 5550397Sobrien#include "dwarf2out.h" 5690075Sobrien#include "dwarf2asm.h" 5750397Sobrien#include "toplev.h" 5890075Sobrien#include "varray.h" 5990075Sobrien#include "ggc.h" 6090075Sobrien#include "md5.h" 6190075Sobrien#include "tm_p.h" 6290075Sobrien#include "diagnostic.h" 6390075Sobrien#include "debug.h" 6490075Sobrien#include "target.h" 6590075Sobrien#include "langhooks.h" 66117395Skan#include "hashtab.h" 67132718Skan#include "cgraph.h" 6850397Sobrien 6990075Sobrien#ifdef DWARF2_DEBUGGING_INFO 70132718Skanstatic void dwarf2out_source_line (unsigned int, const char *); 7150397Sobrien#endif 7250397Sobrien 7390075Sobrien/* DWARF2 Abbreviation Glossary: 7490075Sobrien CFA = Canonical Frame Address 7590075Sobrien a fixed address on the stack which identifies a call frame. 7690075Sobrien We define it to be the value of SP just before the call insn. 7790075Sobrien The CFA register and offset, which may change during the course 7890075Sobrien of the function, are used to calculate its value at runtime. 7990075Sobrien CFI = Call Frame Instruction 8090075Sobrien an instruction for the DWARF2 abstract machine 8190075Sobrien CIE = Common Information Entry 8290075Sobrien information describing information common to one or more FDEs 8390075Sobrien DIE = Debugging Information Entry 8490075Sobrien FDE = Frame Description Entry 8590075Sobrien information describing the stack call frame, in particular, 8690075Sobrien how to restore registers 8790075Sobrien 8890075Sobrien DW_CFA_... = DWARF2 CFA call frame instruction 8990075Sobrien DW_TAG_... = DWARF2 DIE tag */ 9090075Sobrien 9150397Sobrien/* Decide whether we want to emit frame unwind information for the current 9250397Sobrien translation unit. */ 9350397Sobrien 9450397Sobrienint 95132718Skandwarf2out_do_frame (void) 9650397Sobrien{ 9750397Sobrien return (write_symbols == DWARF2_DEBUG 9890075Sobrien || write_symbols == VMS_AND_DWARF2_DEBUG 9950397Sobrien#ifdef DWARF2_FRAME_INFO 10090075Sobrien || DWARF2_FRAME_INFO 10150397Sobrien#endif 10250397Sobrien#ifdef DWARF2_UNWIND_INFO 10390075Sobrien || flag_unwind_tables 10490075Sobrien || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS) 10550397Sobrien#endif 10650397Sobrien ); 10750397Sobrien} 10850397Sobrien 10990075Sobrien/* The size of the target's pointer type. */ 11090075Sobrien#ifndef PTR_SIZE 11190075Sobrien#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT) 11290075Sobrien#endif 11390075Sobrien 114132718Skan/* Various versions of targetm.eh_frame_section. Note these must appear 115132718Skan outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro guards. */ 11690075Sobrien 117132718Skan/* Version of targetm.eh_frame_section for systems with named sections. */ 11890075Sobrienvoid 119132718Skannamed_section_eh_frame_section (void) 12090075Sobrien{ 12190075Sobrien#ifdef EH_FRAME_SECTION_NAME 122117395Skan#ifdef HAVE_LD_RO_RW_SECTION_MIXING 123117395Skan int fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); 124117395Skan int per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); 125117395Skan int lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); 126117395Skan int flags; 127117395Skan 128117395Skan flags = (! flag_pic 129117395Skan || ((fde_encoding & 0x70) != DW_EH_PE_absptr 130117395Skan && (fde_encoding & 0x70) != DW_EH_PE_aligned 131117395Skan && (per_encoding & 0x70) != DW_EH_PE_absptr 132117395Skan && (per_encoding & 0x70) != DW_EH_PE_aligned 133117395Skan && (lsda_encoding & 0x70) != DW_EH_PE_absptr 134117395Skan && (lsda_encoding & 0x70) != DW_EH_PE_aligned)) 135117395Skan ? 0 : SECTION_WRITE; 136117395Skan named_section_flags (EH_FRAME_SECTION_NAME, flags); 137117395Skan#else 13890075Sobrien named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE); 139117395Skan#endif 140132718Skan#endif 141132718Skan} 142132718Skan 143132718Skan/* Version of targetm.eh_frame_section for systems using collect2. */ 144132718Skanvoid 145132718Skancollect2_eh_frame_section (void) 146132718Skan{ 14790075Sobrien tree label = get_file_function_name ('F'); 14890075Sobrien 14990075Sobrien data_section (); 15090075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); 151117395Skan (*targetm.asm_out.globalize_label) (asm_out_file, IDENTIFIER_POINTER (label)); 15290075Sobrien ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); 153132718Skan} 154132718Skan 155132718Skan/* Default version of targetm.eh_frame_section. */ 156132718Skanvoid 157132718Skandefault_eh_frame_section (void) 158132718Skan{ 159132718Skan#ifdef EH_FRAME_SECTION_NAME 160132718Skan named_section_eh_frame_section (); 161132718Skan#else 162132718Skan collect2_eh_frame_section (); 16390075Sobrien#endif 16490075Sobrien} 16590075Sobrien 166117395Skan/* Array of RTXes referenced by the debugging information, which therefore 167117395Skan must be kept around forever. */ 168117395Skanstatic GTY(()) varray_type used_rtx_varray; 169117395Skan 170117395Skan/* A pointer to the base of a list of incomplete types which might be 171117395Skan completed at some later time. incomplete_types_list needs to be a VARRAY 172117395Skan because we want to tell the garbage collector about it. */ 173117395Skanstatic GTY(()) varray_type incomplete_types; 174117395Skan 175117395Skan/* A pointer to the base of a table of references to declaration 176117395Skan scopes. This table is a display which tracks the nesting 177117395Skan of declaration scopes at the current scope and containing 178117395Skan scopes. This table is used to find the proper place to 179117395Skan define type declaration DIE's. */ 180117395Skanstatic GTY(()) varray_type decl_scope_table; 181117395Skan 18250397Sobrien/* How to start an assembler comment. */ 18350397Sobrien#ifndef ASM_COMMENT_START 18450397Sobrien#define ASM_COMMENT_START ";#" 18550397Sobrien#endif 18650397Sobrien 18750397Sobrientypedef struct dw_cfi_struct *dw_cfi_ref; 18850397Sobrientypedef struct dw_fde_struct *dw_fde_ref; 18950397Sobrientypedef union dw_cfi_oprnd_struct *dw_cfi_oprnd_ref; 19050397Sobrien 19150397Sobrien/* Call frames are described using a sequence of Call Frame 19250397Sobrien Information instructions. The register number, offset 19350397Sobrien and address fields are provided as possible operands; 19450397Sobrien their use is selected by the opcode field. */ 19550397Sobrien 196132718Skanenum dw_cfi_oprnd_type { 197132718Skan dw_cfi_oprnd_unused, 198132718Skan dw_cfi_oprnd_reg_num, 199132718Skan dw_cfi_oprnd_offset, 200132718Skan dw_cfi_oprnd_addr, 201132718Skan dw_cfi_oprnd_loc 202132718Skan}; 203132718Skan 204132718Skantypedef union dw_cfi_oprnd_struct GTY(()) 20550397Sobrien{ 206132718Skan unsigned long GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num; 207132718Skan HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset; 208132718Skan const char * GTY ((tag ("dw_cfi_oprnd_addr"))) dw_cfi_addr; 209132718Skan struct dw_loc_descr_struct * GTY ((tag ("dw_cfi_oprnd_loc"))) dw_cfi_loc; 21050397Sobrien} 21150397Sobriendw_cfi_oprnd; 21250397Sobrien 213132718Skantypedef struct dw_cfi_struct GTY(()) 21450397Sobrien{ 21550397Sobrien dw_cfi_ref dw_cfi_next; 21650397Sobrien enum dwarf_call_frame_info dw_cfi_opc; 217132718Skan dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)"))) 218132718Skan dw_cfi_oprnd1; 219132718Skan dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)"))) 220132718Skan dw_cfi_oprnd2; 22150397Sobrien} 22250397Sobriendw_cfi_node; 22350397Sobrien 22490075Sobrien/* This is how we define the location of the CFA. We use to handle it 22590075Sobrien as REG + OFFSET all the time, but now it can be more complex. 22690075Sobrien It can now be either REG + CFA_OFFSET or *(REG + BASE_OFFSET) + CFA_OFFSET. 22790075Sobrien Instead of passing around REG and OFFSET, we pass a copy 22890075Sobrien of this structure. */ 229132718Skantypedef struct cfa_loc GTY(()) 23090075Sobrien{ 23190075Sobrien unsigned long reg; 232132718Skan HOST_WIDE_INT offset; 233132718Skan HOST_WIDE_INT base_offset; 23490075Sobrien int indirect; /* 1 if CFA is accessed via a dereference. */ 23590075Sobrien} dw_cfa_location; 23690075Sobrien 23750397Sobrien/* All call frame descriptions (FDE's) in the GCC generated DWARF 23850397Sobrien refer to a single Common Information Entry (CIE), defined at 23990075Sobrien the beginning of the .debug_frame section. This use of a single 24050397Sobrien CIE obviates the need to keep track of multiple CIE's 24150397Sobrien in the DWARF generation routines below. */ 24250397Sobrien 243132718Skantypedef struct dw_fde_struct GTY(()) 24450397Sobrien{ 24590075Sobrien const char *dw_fde_begin; 24690075Sobrien const char *dw_fde_current_label; 24790075Sobrien const char *dw_fde_end; 24850397Sobrien dw_cfi_ref dw_fde_cfi; 24990075Sobrien unsigned funcdef_number; 250117395Skan unsigned all_throwers_are_sibcalls : 1; 25190075Sobrien unsigned nothrow : 1; 25290075Sobrien unsigned uses_eh_lsda : 1; 25350397Sobrien} 25450397Sobriendw_fde_node; 25550397Sobrien 25690075Sobrien/* Maximum size (in bytes) of an artificially generated label. */ 25750397Sobrien#define MAX_ARTIFICIAL_LABEL_BYTES 30 25850397Sobrien 25990075Sobrien/* The size of addresses as they appear in the Dwarf 2 data. 26090075Sobrien Some architectures use word addresses to refer to code locations, 26190075Sobrien but Dwarf 2 info always uses byte addresses. On such machines, 26290075Sobrien Dwarf 2 addresses need to be larger than the architecture's 26390075Sobrien pointers. */ 26490075Sobrien#ifndef DWARF2_ADDR_SIZE 26590075Sobrien#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT) 26650397Sobrien#endif 26750397Sobrien 26850397Sobrien/* The size in bytes of a DWARF field indicating an offset or length 26990075Sobrien relative to a debug info section, specified to be 4 bytes in the 27090075Sobrien DWARF-2 specification. The SGI/MIPS ABI defines it to be the same 27190075Sobrien as PTR_SIZE. */ 27250397Sobrien 27350397Sobrien#ifndef DWARF_OFFSET_SIZE 27450397Sobrien#define DWARF_OFFSET_SIZE 4 27550397Sobrien#endif 27650397Sobrien 277132718Skan/* According to the (draft) DWARF 3 specification, the initial length 278132718Skan should either be 4 or 12 bytes. When it's 12 bytes, the first 4 279132718Skan bytes are 0xffffffff, followed by the length stored in the next 8 280132718Skan bytes. 281132718Skan 282132718Skan However, the SGI/MIPS ABI uses an initial length which is equal to 283132718Skan DWARF_OFFSET_SIZE. It is defined (elsewhere) accordingly. */ 284132718Skan 285132718Skan#ifndef DWARF_INITIAL_LENGTH_SIZE 286132718Skan#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12) 287132718Skan#endif 288132718Skan 28950397Sobrien#define DWARF_VERSION 2 29050397Sobrien 29150397Sobrien/* Round SIZE up to the nearest BOUNDARY. */ 29250397Sobrien#define DWARF_ROUND(SIZE,BOUNDARY) \ 29390075Sobrien ((((SIZE) + (BOUNDARY) - 1) / (BOUNDARY)) * (BOUNDARY)) 29450397Sobrien 29550397Sobrien/* Offsets recorded in opcodes are a multiple of this alignment factor. */ 29690075Sobrien#ifndef DWARF_CIE_DATA_ALIGNMENT 29750397Sobrien#ifdef STACK_GROWS_DOWNWARD 29890075Sobrien#define DWARF_CIE_DATA_ALIGNMENT (-((int) UNITS_PER_WORD)) 29950397Sobrien#else 30090075Sobrien#define DWARF_CIE_DATA_ALIGNMENT ((int) UNITS_PER_WORD) 30150397Sobrien#endif 30290075Sobrien#endif 30350397Sobrien 30450397Sobrien/* A pointer to the base of a table that contains frame description 30550397Sobrien information for each routine. */ 306132718Skanstatic GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table; 30750397Sobrien 30850397Sobrien/* Number of elements currently allocated for fde_table. */ 309132718Skanstatic GTY(()) unsigned fde_table_allocated; 31050397Sobrien 31150397Sobrien/* Number of elements in fde_table currently in use. */ 312132718Skanstatic GTY(()) unsigned fde_table_in_use; 31350397Sobrien 31450397Sobrien/* Size (in elements) of increments by which we may expand the 31550397Sobrien fde_table. */ 31650397Sobrien#define FDE_TABLE_INCREMENT 256 31750397Sobrien 31850397Sobrien/* A list of call frame insns for the CIE. */ 319132718Skanstatic GTY(()) dw_cfi_ref cie_cfi_head; 32050397Sobrien 321132718Skan#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) 32250397Sobrien/* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram 32350397Sobrien attribute that accelerates the lookup of the FDE associated 32490075Sobrien with the subprogram. This variable holds the table index of the FDE 32550397Sobrien associated with the current function (body) definition. */ 32650397Sobrienstatic unsigned current_funcdef_fde; 327132718Skan#endif 32850397Sobrien 329132718Skanstruct indirect_string_node GTY(()) 33090075Sobrien{ 331132718Skan const char *str; 33290075Sobrien unsigned int refcount; 33390075Sobrien unsigned int form; 33490075Sobrien char *label; 33590075Sobrien}; 33690075Sobrien 337132718Skanstatic GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash; 338132718Skan 339132718Skanstatic GTY(()) int dw2_string_counter; 340132718Skanstatic GTY(()) unsigned long dwarf2out_cfi_label_num; 341132718Skan 342132718Skan#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) 343132718Skan 34450397Sobrien/* Forward declarations for functions defined in this file. */ 34550397Sobrien 346132718Skanstatic char *stripattributes (const char *); 347132718Skanstatic const char *dwarf_cfi_name (unsigned); 348132718Skanstatic dw_cfi_ref new_cfi (void); 349132718Skanstatic void add_cfi (dw_cfi_ref *, dw_cfi_ref); 350132718Skanstatic void add_fde_cfi (const char *, dw_cfi_ref); 351132718Skanstatic void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *); 352132718Skanstatic void lookup_cfa (dw_cfa_location *); 353132718Skanstatic void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT); 354132718Skanstatic void initial_return_save (rtx); 355132718Skanstatic HOST_WIDE_INT stack_adjust_offset (rtx); 356132718Skanstatic void output_cfi (dw_cfi_ref, dw_fde_ref, int); 357132718Skanstatic void output_call_frame_info (int); 358132718Skanstatic void dwarf2out_stack_adjust (rtx); 359132718Skanstatic void queue_reg_save (const char *, rtx, HOST_WIDE_INT); 360132718Skanstatic void flush_queued_reg_saves (void); 361132718Skanstatic bool clobbers_queued_reg_save (rtx); 362132718Skanstatic void dwarf2out_frame_debug_expr (rtx, const char *); 36350397Sobrien 36490075Sobrien/* Support for complex CFA locations. */ 365132718Skanstatic void output_cfa_loc (dw_cfi_ref); 366132718Skanstatic void get_cfa_from_loc_descr (dw_cfa_location *, 367132718Skan struct dw_loc_descr_struct *); 36890075Sobrienstatic struct dw_loc_descr_struct *build_cfa_loc 369132718Skan (dw_cfa_location *); 370132718Skanstatic void def_cfa_1 (const char *, dw_cfa_location *); 37150397Sobrien 37290075Sobrien/* How to start an assembler comment. */ 37390075Sobrien#ifndef ASM_COMMENT_START 37490075Sobrien#define ASM_COMMENT_START ";#" 37550397Sobrien#endif 37650397Sobrien 37750397Sobrien/* Data and reference forms for relocatable data. */ 37850397Sobrien#define DW_FORM_data (DWARF_OFFSET_SIZE == 8 ? DW_FORM_data8 : DW_FORM_data4) 37950397Sobrien#define DW_FORM_ref (DWARF_OFFSET_SIZE == 8 ? DW_FORM_ref8 : DW_FORM_ref4) 38050397Sobrien 38190075Sobrien#ifndef DEBUG_FRAME_SECTION 38290075Sobrien#define DEBUG_FRAME_SECTION ".debug_frame" 38350397Sobrien#endif 38450397Sobrien 38550397Sobrien#ifndef FUNC_BEGIN_LABEL 38650397Sobrien#define FUNC_BEGIN_LABEL "LFB" 38750397Sobrien#endif 38890075Sobrien 38950397Sobrien#ifndef FUNC_END_LABEL 39050397Sobrien#define FUNC_END_LABEL "LFE" 39150397Sobrien#endif 39290075Sobrien 39390075Sobrien#define FRAME_BEGIN_LABEL "Lframe" 39450397Sobrien#define CIE_AFTER_SIZE_LABEL "LSCIE" 39550397Sobrien#define CIE_END_LABEL "LECIE" 39690075Sobrien#define FDE_LABEL "LSFDE" 39790075Sobrien#define FDE_AFTER_SIZE_LABEL "LASFDE" 39850397Sobrien#define FDE_END_LABEL "LEFDE" 39990075Sobrien#define LINE_NUMBER_BEGIN_LABEL "LSLT" 40090075Sobrien#define LINE_NUMBER_END_LABEL "LELT" 40190075Sobrien#define LN_PROLOG_AS_LABEL "LASLTP" 40290075Sobrien#define LN_PROLOG_END_LABEL "LELTP" 40390075Sobrien#define DIE_LABEL_PREFIX "DW" 40450397Sobrien 40550397Sobrien/* The DWARF 2 CFA column which tracks the return address. Normally this 40650397Sobrien is the column for PC, or the first column after all of the hard 40750397Sobrien registers. */ 40850397Sobrien#ifndef DWARF_FRAME_RETURN_COLUMN 40950397Sobrien#ifdef PC_REGNUM 410132718Skan#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM) 41150397Sobrien#else 412132718Skan#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS 41350397Sobrien#endif 41450397Sobrien#endif 41550397Sobrien 41650397Sobrien/* The mapping from gcc register number to DWARF 2 CFA column number. By 41750397Sobrien default, we just provide columns for all registers. */ 41850397Sobrien#ifndef DWARF_FRAME_REGNUM 41950397Sobrien#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG) 42050397Sobrien#endif 42150397Sobrien 42290075Sobrien/* The offset from the incoming value of %sp to the top of the stack frame 42390075Sobrien for the current function. */ 42490075Sobrien#ifndef INCOMING_FRAME_SP_OFFSET 42590075Sobrien#define INCOMING_FRAME_SP_OFFSET 0 42690075Sobrien#endif 42790075Sobrien 42850397Sobrien/* Hook used by __throw. */ 42950397Sobrien 43050397Sobrienrtx 431132718Skanexpand_builtin_dwarf_sp_column (void) 43250397Sobrien{ 433117395Skan return GEN_INT (DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM)); 43450397Sobrien} 43550397Sobrien 43650397Sobrien/* Return a pointer to a copy of the section string name S with all 43750397Sobrien attributes stripped off, and an asterisk prepended (for assemble_name). */ 43850397Sobrien 43950397Sobrienstatic inline char * 440132718Skanstripattributes (const char *s) 44150397Sobrien{ 44250397Sobrien char *stripped = xmalloc (strlen (s) + 2); 44350397Sobrien char *p = stripped; 44450397Sobrien 44550397Sobrien *p++ = '*'; 44650397Sobrien 44750397Sobrien while (*s && *s != ',') 44850397Sobrien *p++ = *s++; 44950397Sobrien 45050397Sobrien *p = '\0'; 45150397Sobrien return stripped; 45250397Sobrien} 45350397Sobrien 45490075Sobrien/* Generate code to initialize the register size table. */ 45550397Sobrien 45690075Sobrienvoid 457132718Skanexpand_builtin_init_dwarf_reg_sizes (tree address) 45850397Sobrien{ 45990075Sobrien int i; 46090075Sobrien enum machine_mode mode = TYPE_MODE (char_type_node); 46190075Sobrien rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0); 46290075Sobrien rtx mem = gen_rtx_MEM (BLKmode, addr); 463132718Skan bool wrote_return_column = false; 46450397Sobrien 465102780Skan for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 466102780Skan if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS) 467102780Skan { 468102780Skan HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode); 469132718Skan enum machine_mode save_mode = reg_raw_mode[i]; 470132718Skan HOST_WIDE_INT size; 47150397Sobrien 472132718Skan if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode)) 473132718Skan save_mode = choose_hard_reg_mode (i, 1, true); 474132718Skan if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN) 475132718Skan { 476132718Skan if (save_mode == VOIDmode) 477132718Skan continue; 478132718Skan wrote_return_column = true; 479132718Skan } 480132718Skan size = GET_MODE_SIZE (save_mode); 481102780Skan if (offset < 0) 482102780Skan continue; 48350397Sobrien 484102780Skan emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size)); 485102780Skan } 486122180Skan 487122180Skan#ifdef DWARF_ALT_FRAME_RETURN_COLUMN 488132718Skan if (! wrote_return_column) 489132718Skan abort (); 490132718Skan i = DWARF_ALT_FRAME_RETURN_COLUMN; 491132718Skan wrote_return_column = false; 492132718Skan#else 493132718Skan i = DWARF_FRAME_RETURN_COLUMN; 494122180Skan#endif 495132718Skan 496132718Skan if (! wrote_return_column) 497132718Skan { 498132718Skan enum machine_mode save_mode = Pmode; 499132718Skan HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode); 500132718Skan HOST_WIDE_INT size = GET_MODE_SIZE (save_mode); 501132718Skan emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size)); 502132718Skan } 50350397Sobrien} 50450397Sobrien 50550397Sobrien/* Convert a DWARF call frame info. operation to its string name */ 50650397Sobrien 50790075Sobrienstatic const char * 508132718Skandwarf_cfi_name (unsigned int cfi_opc) 50950397Sobrien{ 51050397Sobrien switch (cfi_opc) 51150397Sobrien { 51250397Sobrien case DW_CFA_advance_loc: 51350397Sobrien return "DW_CFA_advance_loc"; 51450397Sobrien case DW_CFA_offset: 51550397Sobrien return "DW_CFA_offset"; 51650397Sobrien case DW_CFA_restore: 51750397Sobrien return "DW_CFA_restore"; 51850397Sobrien case DW_CFA_nop: 51950397Sobrien return "DW_CFA_nop"; 52050397Sobrien case DW_CFA_set_loc: 52150397Sobrien return "DW_CFA_set_loc"; 52250397Sobrien case DW_CFA_advance_loc1: 52350397Sobrien return "DW_CFA_advance_loc1"; 52450397Sobrien case DW_CFA_advance_loc2: 52550397Sobrien return "DW_CFA_advance_loc2"; 52650397Sobrien case DW_CFA_advance_loc4: 52750397Sobrien return "DW_CFA_advance_loc4"; 52850397Sobrien case DW_CFA_offset_extended: 52950397Sobrien return "DW_CFA_offset_extended"; 53050397Sobrien case DW_CFA_restore_extended: 53150397Sobrien return "DW_CFA_restore_extended"; 53250397Sobrien case DW_CFA_undefined: 53350397Sobrien return "DW_CFA_undefined"; 53450397Sobrien case DW_CFA_same_value: 53550397Sobrien return "DW_CFA_same_value"; 53650397Sobrien case DW_CFA_register: 53750397Sobrien return "DW_CFA_register"; 53850397Sobrien case DW_CFA_remember_state: 53950397Sobrien return "DW_CFA_remember_state"; 54050397Sobrien case DW_CFA_restore_state: 54150397Sobrien return "DW_CFA_restore_state"; 54250397Sobrien case DW_CFA_def_cfa: 54350397Sobrien return "DW_CFA_def_cfa"; 54450397Sobrien case DW_CFA_def_cfa_register: 54550397Sobrien return "DW_CFA_def_cfa_register"; 54650397Sobrien case DW_CFA_def_cfa_offset: 54750397Sobrien return "DW_CFA_def_cfa_offset"; 54850397Sobrien 54990075Sobrien /* DWARF 3 */ 55090075Sobrien case DW_CFA_def_cfa_expression: 55190075Sobrien return "DW_CFA_def_cfa_expression"; 55290075Sobrien case DW_CFA_expression: 55390075Sobrien return "DW_CFA_expression"; 55490075Sobrien case DW_CFA_offset_extended_sf: 55590075Sobrien return "DW_CFA_offset_extended_sf"; 55690075Sobrien case DW_CFA_def_cfa_sf: 55790075Sobrien return "DW_CFA_def_cfa_sf"; 55890075Sobrien case DW_CFA_def_cfa_offset_sf: 55990075Sobrien return "DW_CFA_def_cfa_offset_sf"; 56090075Sobrien 56150397Sobrien /* SGI/MIPS specific */ 56250397Sobrien case DW_CFA_MIPS_advance_loc8: 56350397Sobrien return "DW_CFA_MIPS_advance_loc8"; 56450397Sobrien 56550397Sobrien /* GNU extensions */ 56650397Sobrien case DW_CFA_GNU_window_save: 56750397Sobrien return "DW_CFA_GNU_window_save"; 56850397Sobrien case DW_CFA_GNU_args_size: 56950397Sobrien return "DW_CFA_GNU_args_size"; 57070635Sobrien case DW_CFA_GNU_negative_offset_extended: 57170635Sobrien return "DW_CFA_GNU_negative_offset_extended"; 57250397Sobrien 57350397Sobrien default: 57450397Sobrien return "DW_CFA_<unknown>"; 57550397Sobrien } 57650397Sobrien} 57750397Sobrien 57850397Sobrien/* Return a pointer to a newly allocated Call Frame Instruction. */ 57950397Sobrien 58050397Sobrienstatic inline dw_cfi_ref 581132718Skannew_cfi (void) 58250397Sobrien{ 583132718Skan dw_cfi_ref cfi = ggc_alloc (sizeof (dw_cfi_node)); 58450397Sobrien 58550397Sobrien cfi->dw_cfi_next = NULL; 58650397Sobrien cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0; 58750397Sobrien cfi->dw_cfi_oprnd2.dw_cfi_reg_num = 0; 58850397Sobrien 58950397Sobrien return cfi; 59050397Sobrien} 59150397Sobrien 59250397Sobrien/* Add a Call Frame Instruction to list of instructions. */ 59350397Sobrien 59450397Sobrienstatic inline void 595132718Skanadd_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi) 59650397Sobrien{ 59790075Sobrien dw_cfi_ref *p; 59850397Sobrien 59950397Sobrien /* Find the end of the chain. */ 60050397Sobrien for (p = list_head; (*p) != NULL; p = &(*p)->dw_cfi_next) 60150397Sobrien ; 60250397Sobrien 60350397Sobrien *p = cfi; 60450397Sobrien} 60550397Sobrien 60650397Sobrien/* Generate a new label for the CFI info to refer to. */ 60750397Sobrien 60850397Sobrienchar * 609132718Skandwarf2out_cfi_label (void) 61050397Sobrien{ 61150397Sobrien static char label[20]; 61290075Sobrien 613132718Skan ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", dwarf2out_cfi_label_num++); 61450397Sobrien ASM_OUTPUT_LABEL (asm_out_file, label); 61550397Sobrien return label; 61650397Sobrien} 61750397Sobrien 61850397Sobrien/* Add CFI to the current fde at the PC value indicated by LABEL if specified, 61950397Sobrien or to the CIE if LABEL is NULL. */ 62050397Sobrien 62150397Sobrienstatic void 622132718Skanadd_fde_cfi (const char *label, dw_cfi_ref cfi) 62350397Sobrien{ 62450397Sobrien if (label) 62550397Sobrien { 62690075Sobrien dw_fde_ref fde = &fde_table[fde_table_in_use - 1]; 62750397Sobrien 62850397Sobrien if (*label == 0) 62950397Sobrien label = dwarf2out_cfi_label (); 63050397Sobrien 63150397Sobrien if (fde->dw_fde_current_label == NULL 63250397Sobrien || strcmp (label, fde->dw_fde_current_label) != 0) 63350397Sobrien { 63490075Sobrien dw_cfi_ref xcfi; 63550397Sobrien 63650397Sobrien fde->dw_fde_current_label = label = xstrdup (label); 63750397Sobrien 63850397Sobrien /* Set the location counter to the new label. */ 63950397Sobrien xcfi = new_cfi (); 64050397Sobrien xcfi->dw_cfi_opc = DW_CFA_advance_loc4; 64150397Sobrien xcfi->dw_cfi_oprnd1.dw_cfi_addr = label; 64250397Sobrien add_cfi (&fde->dw_fde_cfi, xcfi); 64350397Sobrien } 64450397Sobrien 64550397Sobrien add_cfi (&fde->dw_fde_cfi, cfi); 64650397Sobrien } 64750397Sobrien 64850397Sobrien else 64950397Sobrien add_cfi (&cie_cfi_head, cfi); 65050397Sobrien} 65150397Sobrien 65250397Sobrien/* Subroutine of lookup_cfa. */ 65350397Sobrien 65450397Sobrienstatic inline void 655132718Skanlookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc) 65650397Sobrien{ 65750397Sobrien switch (cfi->dw_cfi_opc) 65850397Sobrien { 65950397Sobrien case DW_CFA_def_cfa_offset: 66090075Sobrien loc->offset = cfi->dw_cfi_oprnd1.dw_cfi_offset; 66150397Sobrien break; 66250397Sobrien case DW_CFA_def_cfa_register: 66390075Sobrien loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num; 66450397Sobrien break; 66550397Sobrien case DW_CFA_def_cfa: 66690075Sobrien loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num; 66790075Sobrien loc->offset = cfi->dw_cfi_oprnd2.dw_cfi_offset; 66850397Sobrien break; 66990075Sobrien case DW_CFA_def_cfa_expression: 67090075Sobrien get_cfa_from_loc_descr (loc, cfi->dw_cfi_oprnd1.dw_cfi_loc); 67190075Sobrien break; 67250397Sobrien default: 67350397Sobrien break; 67450397Sobrien } 67550397Sobrien} 67650397Sobrien 67750397Sobrien/* Find the previous value for the CFA. */ 67850397Sobrien 67950397Sobrienstatic void 680132718Skanlookup_cfa (dw_cfa_location *loc) 68150397Sobrien{ 68290075Sobrien dw_cfi_ref cfi; 68350397Sobrien 68490075Sobrien loc->reg = (unsigned long) -1; 68590075Sobrien loc->offset = 0; 68690075Sobrien loc->indirect = 0; 68790075Sobrien loc->base_offset = 0; 68850397Sobrien 68950397Sobrien for (cfi = cie_cfi_head; cfi; cfi = cfi->dw_cfi_next) 69090075Sobrien lookup_cfa_1 (cfi, loc); 69150397Sobrien 69250397Sobrien if (fde_table_in_use) 69350397Sobrien { 69490075Sobrien dw_fde_ref fde = &fde_table[fde_table_in_use - 1]; 69550397Sobrien for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next) 69690075Sobrien lookup_cfa_1 (cfi, loc); 69750397Sobrien } 69850397Sobrien} 69950397Sobrien 70050397Sobrien/* The current rule for calculating the DWARF2 canonical frame address. */ 70190075Sobrienstatic dw_cfa_location cfa; 70250397Sobrien 70350397Sobrien/* The register used for saving registers to the stack, and its offset 70450397Sobrien from the CFA. */ 70590075Sobrienstatic dw_cfa_location cfa_store; 70650397Sobrien 70750397Sobrien/* The running total of the size of arguments pushed onto the stack. */ 708132718Skanstatic HOST_WIDE_INT args_size; 70950397Sobrien 71050397Sobrien/* The last args_size we actually output. */ 711132718Skanstatic HOST_WIDE_INT old_args_size; 71250397Sobrien 71350397Sobrien/* Entry point to update the canonical frame address (CFA). 71450397Sobrien LABEL is passed to add_fde_cfi. The value of CFA is now to be 71550397Sobrien calculated from REG+OFFSET. */ 71650397Sobrien 71750397Sobrienvoid 718132718Skandwarf2out_def_cfa (const char *label, unsigned int reg, HOST_WIDE_INT offset) 71950397Sobrien{ 72090075Sobrien dw_cfa_location loc; 72190075Sobrien loc.indirect = 0; 72290075Sobrien loc.base_offset = 0; 72390075Sobrien loc.reg = reg; 72490075Sobrien loc.offset = offset; 72590075Sobrien def_cfa_1 (label, &loc); 72690075Sobrien} 72750397Sobrien 72890075Sobrien/* This routine does the actual work. The CFA is now calculated from 72990075Sobrien the dw_cfa_location structure. */ 73050397Sobrien 73190075Sobrienstatic void 732132718Skandef_cfa_1 (const char *label, dw_cfa_location *loc_p) 73390075Sobrien{ 73490075Sobrien dw_cfi_ref cfi; 73590075Sobrien dw_cfa_location old_cfa, loc; 73650397Sobrien 73790075Sobrien cfa = *loc_p; 73890075Sobrien loc = *loc_p; 73990075Sobrien 74090075Sobrien if (cfa_store.reg == loc.reg && loc.indirect == 0) 74190075Sobrien cfa_store.offset = loc.offset; 74290075Sobrien 74390075Sobrien loc.reg = DWARF_FRAME_REGNUM (loc.reg); 74490075Sobrien lookup_cfa (&old_cfa); 74590075Sobrien 74690075Sobrien /* If nothing changed, no need to issue any call frame instructions. */ 74790075Sobrien if (loc.reg == old_cfa.reg && loc.offset == old_cfa.offset 74890075Sobrien && loc.indirect == old_cfa.indirect 74990075Sobrien && (loc.indirect == 0 || loc.base_offset == old_cfa.base_offset)) 75050397Sobrien return; 75150397Sobrien 75250397Sobrien cfi = new_cfi (); 75350397Sobrien 75490075Sobrien if (loc.reg == old_cfa.reg && !loc.indirect) 75550397Sobrien { 75690075Sobrien /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, 75790075Sobrien indicating the CFA register did not change but the offset 75890075Sobrien did. */ 75950397Sobrien cfi->dw_cfi_opc = DW_CFA_def_cfa_offset; 76090075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_offset = loc.offset; 76150397Sobrien } 76250397Sobrien 76350397Sobrien#ifndef MIPS_DEBUGGING_INFO /* SGI dbx thinks this means no offset. */ 76490075Sobrien else if (loc.offset == old_cfa.offset && old_cfa.reg != (unsigned long) -1 76590075Sobrien && !loc.indirect) 76650397Sobrien { 76790075Sobrien /* Construct a "DW_CFA_def_cfa_register <register>" instruction, 76890075Sobrien indicating the CFA register has changed to <register> but the 76990075Sobrien offset has not changed. */ 77050397Sobrien cfi->dw_cfi_opc = DW_CFA_def_cfa_register; 77190075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg; 77250397Sobrien } 77350397Sobrien#endif 77450397Sobrien 77590075Sobrien else if (loc.indirect == 0) 77650397Sobrien { 77790075Sobrien /* Construct a "DW_CFA_def_cfa <register> <offset>" instruction, 77890075Sobrien indicating the CFA register has changed to <register> with 77990075Sobrien the specified offset. */ 78050397Sobrien cfi->dw_cfi_opc = DW_CFA_def_cfa; 78190075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg; 78290075Sobrien cfi->dw_cfi_oprnd2.dw_cfi_offset = loc.offset; 78350397Sobrien } 78490075Sobrien else 78590075Sobrien { 78690075Sobrien /* Construct a DW_CFA_def_cfa_expression instruction to 78790075Sobrien calculate the CFA using a full location expression since no 78890075Sobrien register-offset pair is available. */ 78990075Sobrien struct dw_loc_descr_struct *loc_list; 79050397Sobrien 79190075Sobrien cfi->dw_cfi_opc = DW_CFA_def_cfa_expression; 79290075Sobrien loc_list = build_cfa_loc (&loc); 79390075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_loc = loc_list; 79490075Sobrien } 79590075Sobrien 79650397Sobrien add_fde_cfi (label, cfi); 79750397Sobrien} 79850397Sobrien 79950397Sobrien/* Add the CFI for saving a register. REG is the CFA column number. 80050397Sobrien LABEL is passed to add_fde_cfi. 80150397Sobrien If SREG is -1, the register is saved at OFFSET from the CFA; 80250397Sobrien otherwise it is saved in SREG. */ 80350397Sobrien 80450397Sobrienstatic void 805132718Skanreg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset) 80650397Sobrien{ 80790075Sobrien dw_cfi_ref cfi = new_cfi (); 80850397Sobrien 80950397Sobrien cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg; 81050397Sobrien 81150397Sobrien /* The following comparison is correct. -1 is used to indicate that 81250397Sobrien the value isn't a register number. */ 81350397Sobrien if (sreg == (unsigned int) -1) 81450397Sobrien { 81550397Sobrien if (reg & ~0x3f) 81650397Sobrien /* The register number won't fit in 6 bits, so we have to use 81750397Sobrien the long form. */ 81850397Sobrien cfi->dw_cfi_opc = DW_CFA_offset_extended; 81950397Sobrien else 82050397Sobrien cfi->dw_cfi_opc = DW_CFA_offset; 82150397Sobrien 82290075Sobrien#ifdef ENABLE_CHECKING 82390075Sobrien { 82490075Sobrien /* If we get an offset that is not a multiple of 82590075Sobrien DWARF_CIE_DATA_ALIGNMENT, there is either a bug in the 82690075Sobrien definition of DWARF_CIE_DATA_ALIGNMENT, or a bug in the machine 82790075Sobrien description. */ 828132718Skan HOST_WIDE_INT check_offset = offset / DWARF_CIE_DATA_ALIGNMENT; 82990075Sobrien 83090075Sobrien if (check_offset * DWARF_CIE_DATA_ALIGNMENT != offset) 83190075Sobrien abort (); 83290075Sobrien } 83390075Sobrien#endif 83450397Sobrien offset /= DWARF_CIE_DATA_ALIGNMENT; 83550397Sobrien if (offset < 0) 83690075Sobrien cfi->dw_cfi_opc = DW_CFA_offset_extended_sf; 83790075Sobrien 83850397Sobrien cfi->dw_cfi_oprnd2.dw_cfi_offset = offset; 83950397Sobrien } 84090075Sobrien else if (sreg == reg) 84190075Sobrien /* We could emit a DW_CFA_same_value in this case, but don't bother. */ 84290075Sobrien return; 84350397Sobrien else 84450397Sobrien { 84550397Sobrien cfi->dw_cfi_opc = DW_CFA_register; 84650397Sobrien cfi->dw_cfi_oprnd2.dw_cfi_reg_num = sreg; 84750397Sobrien } 84850397Sobrien 84950397Sobrien add_fde_cfi (label, cfi); 85050397Sobrien} 85150397Sobrien 85250397Sobrien/* Add the CFI for saving a register window. LABEL is passed to reg_save. 85350397Sobrien This CFI tells the unwinder that it needs to restore the window registers 85450397Sobrien from the previous frame's window save area. 85590075Sobrien 85650397Sobrien ??? Perhaps we should note in the CIE where windows are saved (instead of 85750397Sobrien assuming 0(cfa)) and what registers are in the window. */ 85850397Sobrien 85950397Sobrienvoid 860132718Skandwarf2out_window_save (const char *label) 86150397Sobrien{ 86290075Sobrien dw_cfi_ref cfi = new_cfi (); 86390075Sobrien 86450397Sobrien cfi->dw_cfi_opc = DW_CFA_GNU_window_save; 86550397Sobrien add_fde_cfi (label, cfi); 86650397Sobrien} 86750397Sobrien 86850397Sobrien/* Add a CFI to update the running total of the size of arguments 86950397Sobrien pushed onto the stack. */ 87050397Sobrien 87150397Sobrienvoid 872132718Skandwarf2out_args_size (const char *label, HOST_WIDE_INT size) 87350397Sobrien{ 87490075Sobrien dw_cfi_ref cfi; 87550397Sobrien 87650397Sobrien if (size == old_args_size) 87750397Sobrien return; 87890075Sobrien 87950397Sobrien old_args_size = size; 88050397Sobrien 88150397Sobrien cfi = new_cfi (); 88250397Sobrien cfi->dw_cfi_opc = DW_CFA_GNU_args_size; 88350397Sobrien cfi->dw_cfi_oprnd1.dw_cfi_offset = size; 88450397Sobrien add_fde_cfi (label, cfi); 88550397Sobrien} 88650397Sobrien 88750397Sobrien/* Entry point for saving a register to the stack. REG is the GCC register 88850397Sobrien number. LABEL and OFFSET are passed to reg_save. */ 88950397Sobrien 89050397Sobrienvoid 891132718Skandwarf2out_reg_save (const char *label, unsigned int reg, HOST_WIDE_INT offset) 89250397Sobrien{ 89350397Sobrien reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset); 89450397Sobrien} 89550397Sobrien 89650397Sobrien/* Entry point for saving the return address in the stack. 89750397Sobrien LABEL and OFFSET are passed to reg_save. */ 89850397Sobrien 89950397Sobrienvoid 900132718Skandwarf2out_return_save (const char *label, HOST_WIDE_INT offset) 90150397Sobrien{ 90250397Sobrien reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset); 90350397Sobrien} 90450397Sobrien 90550397Sobrien/* Entry point for saving the return address in a register. 90650397Sobrien LABEL and SREG are passed to reg_save. */ 90750397Sobrien 90850397Sobrienvoid 909132718Skandwarf2out_return_reg (const char *label, unsigned int sreg) 91050397Sobrien{ 91150397Sobrien reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0); 91250397Sobrien} 91350397Sobrien 91450397Sobrien/* Record the initial position of the return address. RTL is 91550397Sobrien INCOMING_RETURN_ADDR_RTX. */ 91650397Sobrien 91750397Sobrienstatic void 918132718Skaninitial_return_save (rtx rtl) 91950397Sobrien{ 92052284Sobrien unsigned int reg = (unsigned int) -1; 92190075Sobrien HOST_WIDE_INT offset = 0; 92250397Sobrien 92350397Sobrien switch (GET_CODE (rtl)) 92450397Sobrien { 92550397Sobrien case REG: 92650397Sobrien /* RA is in a register. */ 92790075Sobrien reg = DWARF_FRAME_REGNUM (REGNO (rtl)); 92850397Sobrien break; 92990075Sobrien 93050397Sobrien case MEM: 93150397Sobrien /* RA is on the stack. */ 93250397Sobrien rtl = XEXP (rtl, 0); 93350397Sobrien switch (GET_CODE (rtl)) 93450397Sobrien { 93550397Sobrien case REG: 93650397Sobrien if (REGNO (rtl) != STACK_POINTER_REGNUM) 93750397Sobrien abort (); 93850397Sobrien offset = 0; 93950397Sobrien break; 94090075Sobrien 94150397Sobrien case PLUS: 94250397Sobrien if (REGNO (XEXP (rtl, 0)) != STACK_POINTER_REGNUM) 94350397Sobrien abort (); 94450397Sobrien offset = INTVAL (XEXP (rtl, 1)); 94550397Sobrien break; 94690075Sobrien 94750397Sobrien case MINUS: 94850397Sobrien if (REGNO (XEXP (rtl, 0)) != STACK_POINTER_REGNUM) 94950397Sobrien abort (); 95050397Sobrien offset = -INTVAL (XEXP (rtl, 1)); 95150397Sobrien break; 95290075Sobrien 95350397Sobrien default: 95450397Sobrien abort (); 95550397Sobrien } 95690075Sobrien 95750397Sobrien break; 95890075Sobrien 95950397Sobrien case PLUS: 96050397Sobrien /* The return address is at some offset from any value we can 96150397Sobrien actually load. For instance, on the SPARC it is in %i7+8. Just 96250397Sobrien ignore the offset for now; it doesn't matter for unwinding frames. */ 96350397Sobrien if (GET_CODE (XEXP (rtl, 1)) != CONST_INT) 96450397Sobrien abort (); 96550397Sobrien initial_return_save (XEXP (rtl, 0)); 96650397Sobrien return; 96790075Sobrien 96850397Sobrien default: 96950397Sobrien abort (); 97050397Sobrien } 97150397Sobrien 97290075Sobrien reg_save (NULL, DWARF_FRAME_RETURN_COLUMN, reg, offset - cfa.offset); 97350397Sobrien} 97450397Sobrien 97590075Sobrien/* Given a SET, calculate the amount of stack adjustment it 97690075Sobrien contains. */ 97790075Sobrien 978132718Skanstatic HOST_WIDE_INT 979132718Skanstack_adjust_offset (rtx pattern) 98090075Sobrien{ 98190075Sobrien rtx src = SET_SRC (pattern); 98290075Sobrien rtx dest = SET_DEST (pattern); 98390075Sobrien HOST_WIDE_INT offset = 0; 98490075Sobrien enum rtx_code code; 98590075Sobrien 98690075Sobrien if (dest == stack_pointer_rtx) 98790075Sobrien { 98890075Sobrien /* (set (reg sp) (plus (reg sp) (const_int))) */ 98990075Sobrien code = GET_CODE (src); 99090075Sobrien if (! (code == PLUS || code == MINUS) 99190075Sobrien || XEXP (src, 0) != stack_pointer_rtx 99290075Sobrien || GET_CODE (XEXP (src, 1)) != CONST_INT) 99390075Sobrien return 0; 99490075Sobrien 99590075Sobrien offset = INTVAL (XEXP (src, 1)); 996117395Skan if (code == PLUS) 997117395Skan offset = -offset; 99890075Sobrien } 99990075Sobrien else if (GET_CODE (dest) == MEM) 100090075Sobrien { 100190075Sobrien /* (set (mem (pre_dec (reg sp))) (foo)) */ 100290075Sobrien src = XEXP (dest, 0); 100390075Sobrien code = GET_CODE (src); 100490075Sobrien 1005117395Skan switch (code) 100690075Sobrien { 1007117395Skan case PRE_MODIFY: 1008117395Skan case POST_MODIFY: 1009117395Skan if (XEXP (src, 0) == stack_pointer_rtx) 1010117395Skan { 1011117395Skan rtx val = XEXP (XEXP (src, 1), 1); 1012117395Skan /* We handle only adjustments by constant amount. */ 1013117395Skan if (GET_CODE (XEXP (src, 1)) != PLUS || 1014117395Skan GET_CODE (val) != CONST_INT) 1015117395Skan abort (); 1016117395Skan offset = -INTVAL (val); 1017117395Skan break; 1018117395Skan } 1019117395Skan return 0; 102090075Sobrien 1021117395Skan case PRE_DEC: 1022117395Skan case POST_DEC: 1023117395Skan if (XEXP (src, 0) == stack_pointer_rtx) 1024117395Skan { 1025117395Skan offset = GET_MODE_SIZE (GET_MODE (dest)); 1026117395Skan break; 1027117395Skan } 1028117395Skan return 0; 102990075Sobrien 1030117395Skan case PRE_INC: 1031117395Skan case POST_INC: 1032117395Skan if (XEXP (src, 0) == stack_pointer_rtx) 1033117395Skan { 1034117395Skan offset = -GET_MODE_SIZE (GET_MODE (dest)); 1035117395Skan break; 1036117395Skan } 1037117395Skan return 0; 1038117395Skan 1039117395Skan default: 1040117395Skan return 0; 104190075Sobrien } 104290075Sobrien } 104390075Sobrien else 104490075Sobrien return 0; 104590075Sobrien 104690075Sobrien return offset; 104790075Sobrien} 104890075Sobrien 104950397Sobrien/* Check INSN to see if it looks like a push or a stack adjustment, and 105050397Sobrien make a note of it if it does. EH uses this information to find out how 105150397Sobrien much extra space it needs to pop off the stack. */ 105250397Sobrien 105350397Sobrienstatic void 1054132718Skandwarf2out_stack_adjust (rtx insn) 105550397Sobrien{ 105690075Sobrien HOST_WIDE_INT offset; 105790075Sobrien const char *label; 105890075Sobrien int i; 105950397Sobrien 1060132718Skan /* Don't handle epilogues at all. Certainly it would be wrong to do so 1061132718Skan with this function. Proper support would require all frame-related 1062132718Skan insns to be marked, and to be able to handle saving state around 1063132718Skan epilogues textually in the middle of the function. */ 1064132718Skan if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn)) 1065132718Skan return; 1066132718Skan 106790075Sobrien if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN) 106850397Sobrien { 106950397Sobrien /* Extract the size of the args from the CALL rtx itself. */ 107050397Sobrien insn = PATTERN (insn); 107150397Sobrien if (GET_CODE (insn) == PARALLEL) 107250397Sobrien insn = XVECEXP (insn, 0, 0); 107350397Sobrien if (GET_CODE (insn) == SET) 107450397Sobrien insn = SET_SRC (insn); 107590075Sobrien if (GET_CODE (insn) != CALL) 107690075Sobrien abort (); 107790075Sobrien 107850397Sobrien dwarf2out_args_size ("", INTVAL (XEXP (insn, 1))); 107950397Sobrien return; 108050397Sobrien } 108150397Sobrien 108250397Sobrien /* If only calls can throw, and we have a frame pointer, 108350397Sobrien save up adjustments until we see the CALL_INSN. */ 108490075Sobrien else if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM) 108550397Sobrien return; 108650397Sobrien 108750397Sobrien if (GET_CODE (insn) == BARRIER) 108850397Sobrien { 108950397Sobrien /* When we see a BARRIER, we know to reset args_size to 0. Usually 109050397Sobrien the compiler will have already emitted a stack adjustment, but 109150397Sobrien doesn't bother for calls to noreturn functions. */ 109250397Sobrien#ifdef STACK_GROWS_DOWNWARD 109350397Sobrien offset = -args_size; 109450397Sobrien#else 109550397Sobrien offset = args_size; 109650397Sobrien#endif 109750397Sobrien } 109850397Sobrien else if (GET_CODE (PATTERN (insn)) == SET) 109990075Sobrien offset = stack_adjust_offset (PATTERN (insn)); 110090075Sobrien else if (GET_CODE (PATTERN (insn)) == PARALLEL 110190075Sobrien || GET_CODE (PATTERN (insn)) == SEQUENCE) 110250397Sobrien { 110390075Sobrien /* There may be stack adjustments inside compound insns. Search 110490075Sobrien for them. */ 110590075Sobrien for (offset = 0, i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 110690075Sobrien if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) 110790075Sobrien offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i)); 110850397Sobrien } 110950397Sobrien else 111050397Sobrien return; 111150397Sobrien 111250397Sobrien if (offset == 0) 111350397Sobrien return; 111450397Sobrien 111590075Sobrien if (cfa.reg == STACK_POINTER_REGNUM) 111690075Sobrien cfa.offset += offset; 111750397Sobrien 111850397Sobrien#ifndef STACK_GROWS_DOWNWARD 111950397Sobrien offset = -offset; 112050397Sobrien#endif 112190075Sobrien 112250397Sobrien args_size += offset; 112350397Sobrien if (args_size < 0) 112450397Sobrien args_size = 0; 112550397Sobrien 112650397Sobrien label = dwarf2out_cfi_label (); 112790075Sobrien def_cfa_1 (label, &cfa); 112850397Sobrien dwarf2out_args_size (label, args_size); 112950397Sobrien} 113050397Sobrien 1131132718Skan#endif 1132132718Skan 113390075Sobrien/* We delay emitting a register save until either (a) we reach the end 113490075Sobrien of the prologue or (b) the register is clobbered. This clusters 113590075Sobrien register saves so that there are fewer pc advances. */ 113652284Sobrien 1137132718Skanstruct queued_reg_save GTY(()) 113890075Sobrien{ 113990075Sobrien struct queued_reg_save *next; 114090075Sobrien rtx reg; 1141132718Skan HOST_WIDE_INT cfa_offset; 114290075Sobrien}; 114352284Sobrien 1144132718Skanstatic GTY(()) struct queued_reg_save *queued_reg_saves; 1145132718Skan 1146132718Skan#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) 114790075Sobrienstatic const char *last_reg_save_label; 114850397Sobrien 114952284Sobrienstatic void 1150132718Skanqueue_reg_save (const char *label, rtx reg, HOST_WIDE_INT offset) 115190075Sobrien{ 1152132718Skan struct queued_reg_save *q = ggc_alloc (sizeof (*q)); 115390075Sobrien 115490075Sobrien q->next = queued_reg_saves; 115590075Sobrien q->reg = reg; 115690075Sobrien q->cfa_offset = offset; 115790075Sobrien queued_reg_saves = q; 115890075Sobrien 115990075Sobrien last_reg_save_label = label; 116090075Sobrien} 116190075Sobrien 116290075Sobrienstatic void 1163132718Skanflush_queued_reg_saves (void) 116490075Sobrien{ 116590075Sobrien struct queued_reg_save *q, *next; 116690075Sobrien 1167117395Skan for (q = queued_reg_saves; q; q = next) 116890075Sobrien { 116990075Sobrien dwarf2out_reg_save (last_reg_save_label, REGNO (q->reg), q->cfa_offset); 117090075Sobrien next = q->next; 117190075Sobrien } 117290075Sobrien 117390075Sobrien queued_reg_saves = NULL; 117490075Sobrien last_reg_save_label = NULL; 117590075Sobrien} 117690075Sobrien 117790075Sobrienstatic bool 1178132718Skanclobbers_queued_reg_save (rtx insn) 117990075Sobrien{ 118090075Sobrien struct queued_reg_save *q; 118190075Sobrien 1182117395Skan for (q = queued_reg_saves; q; q = q->next) 118390075Sobrien if (modified_in_p (q->reg, insn)) 118490075Sobrien return true; 118590075Sobrien 118690075Sobrien return false; 118790075Sobrien} 118890075Sobrien 1189117395Skan 119090075Sobrien/* A temporary register holding an integral value used in adjusting SP 119190075Sobrien or setting up the store_reg. The "offset" field holds the integer 119290075Sobrien value, not an offset. */ 119390075Sobrienstatic dw_cfa_location cfa_temp; 119490075Sobrien 119590075Sobrien/* Record call frame debugging information for an expression EXPR, 119690075Sobrien which either sets SP or FP (adjusting how we calculate the frame 119790075Sobrien address) or saves a register to the stack. LABEL indicates the 119890075Sobrien address of EXPR. 119990075Sobrien 120090075Sobrien This function encodes a state machine mapping rtxes to actions on 120190075Sobrien cfa, cfa_store, and cfa_temp.reg. We describe these rules so 120290075Sobrien users need not read the source code. 120390075Sobrien 120490075Sobrien The High-Level Picture 120590075Sobrien 120690075Sobrien Changes in the register we use to calculate the CFA: Currently we 120790075Sobrien assume that if you copy the CFA register into another register, we 120890075Sobrien should take the other one as the new CFA register; this seems to 120990075Sobrien work pretty well. If it's wrong for some target, it's simple 121090075Sobrien enough not to set RTX_FRAME_RELATED_P on the insn in question. 121190075Sobrien 121290075Sobrien Changes in the register we use for saving registers to the stack: 121390075Sobrien This is usually SP, but not always. Again, we deduce that if you 121490075Sobrien copy SP into another register (and SP is not the CFA register), 121590075Sobrien then the new register is the one we will be using for register 121690075Sobrien saves. This also seems to work. 121790075Sobrien 121890075Sobrien Register saves: There's not much guesswork about this one; if 121990075Sobrien RTX_FRAME_RELATED_P is set on an insn which modifies memory, it's a 122090075Sobrien register save, and the register used to calculate the destination 122190075Sobrien had better be the one we think we're using for this purpose. 122290075Sobrien 122390075Sobrien Except: If the register being saved is the CFA register, and the 1224117395Skan offset is nonzero, we are saving the CFA, so we assume we have to 122590075Sobrien use DW_CFA_def_cfa_expression. If the offset is 0, we assume that 122690075Sobrien the intent is to save the value of SP from the previous frame. 122790075Sobrien 122890075Sobrien Invariants / Summaries of Rules 122990075Sobrien 123090075Sobrien cfa current rule for calculating the CFA. It usually 123190075Sobrien consists of a register and an offset. 123290075Sobrien cfa_store register used by prologue code to save things to the stack 123390075Sobrien cfa_store.offset is the offset from the value of 123490075Sobrien cfa_store.reg to the actual CFA 123590075Sobrien cfa_temp register holding an integral value. cfa_temp.offset 123690075Sobrien stores the value, which will be used to adjust the 123790075Sobrien stack pointer. cfa_temp is also used like cfa_store, 123890075Sobrien to track stores to the stack via fp or a temp reg. 1239117395Skan 124090075Sobrien Rules 1- 4: Setting a register's value to cfa.reg or an expression 1241132718Skan with cfa.reg as the first operand changes the cfa.reg and its 124290075Sobrien cfa.offset. Rule 1 and 4 also set cfa_temp.reg and 124390075Sobrien cfa_temp.offset. 124490075Sobrien 124590075Sobrien Rules 6- 9: Set a non-cfa.reg register value to a constant or an 124690075Sobrien expression yielding a constant. This sets cfa_temp.reg 124790075Sobrien and cfa_temp.offset. 124890075Sobrien 124990075Sobrien Rule 5: Create a new register cfa_store used to save items to the 125090075Sobrien stack. 125190075Sobrien 125290075Sobrien Rules 10-14: Save a register to the stack. Define offset as the 125390075Sobrien difference of the original location and cfa_store's 125490075Sobrien location (or cfa_temp's location if cfa_temp is used). 125590075Sobrien 125690075Sobrien The Rules 125790075Sobrien 125890075Sobrien "{a,b}" indicates a choice of a xor b. 125990075Sobrien "<reg>:cfa.reg" indicates that <reg> must equal cfa.reg. 126090075Sobrien 126190075Sobrien Rule 1: 126290075Sobrien (set <reg1> <reg2>:cfa.reg) 126390075Sobrien effects: cfa.reg = <reg1> 1264132718Skan cfa.offset unchanged 126590075Sobrien cfa_temp.reg = <reg1> 126690075Sobrien cfa_temp.offset = cfa.offset 126790075Sobrien 126890075Sobrien Rule 2: 126990075Sobrien (set sp ({minus,plus,losum} {sp,fp}:cfa.reg 127090075Sobrien {<const_int>,<reg>:cfa_temp.reg})) 127190075Sobrien effects: cfa.reg = sp if fp used 1272132718Skan cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp 127390075Sobrien cfa_store.offset += {+/- <const_int>, cfa_temp.offset} 127490075Sobrien if cfa_store.reg==sp 127590075Sobrien 127690075Sobrien Rule 3: 127790075Sobrien (set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>)) 127890075Sobrien effects: cfa.reg = fp 1279132718Skan cfa_offset += +/- <const_int> 128090075Sobrien 128190075Sobrien Rule 4: 128290075Sobrien (set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>)) 128390075Sobrien constraints: <reg1> != fp 1284132718Skan <reg1> != sp 128590075Sobrien effects: cfa.reg = <reg1> 128690075Sobrien cfa_temp.reg = <reg1> 128790075Sobrien cfa_temp.offset = cfa.offset 128890075Sobrien 128990075Sobrien Rule 5: 129090075Sobrien (set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg)) 129190075Sobrien constraints: <reg1> != fp 1292132718Skan <reg1> != sp 129390075Sobrien effects: cfa_store.reg = <reg1> 1294132718Skan cfa_store.offset = cfa.offset - cfa_temp.offset 129590075Sobrien 129690075Sobrien Rule 6: 129790075Sobrien (set <reg> <const_int>) 129890075Sobrien effects: cfa_temp.reg = <reg> 1299132718Skan cfa_temp.offset = <const_int> 130090075Sobrien 130190075Sobrien Rule 7: 130290075Sobrien (set <reg1>:cfa_temp.reg (ior <reg2>:cfa_temp.reg <const_int>)) 130390075Sobrien effects: cfa_temp.reg = <reg1> 130490075Sobrien cfa_temp.offset |= <const_int> 130590075Sobrien 130690075Sobrien Rule 8: 130790075Sobrien (set <reg> (high <exp>)) 130890075Sobrien effects: none 130990075Sobrien 131090075Sobrien Rule 9: 131190075Sobrien (set <reg> (lo_sum <exp> <const_int>)) 131290075Sobrien effects: cfa_temp.reg = <reg> 1313132718Skan cfa_temp.offset = <const_int> 131490075Sobrien 131590075Sobrien Rule 10: 131690075Sobrien (set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>) 131790075Sobrien effects: cfa_store.offset -= <const_int> 131890075Sobrien cfa.offset = cfa_store.offset if cfa.reg == sp 131990075Sobrien cfa.reg = sp 132090075Sobrien cfa.base_offset = -cfa_store.offset 132190075Sobrien 132290075Sobrien Rule 11: 132390075Sobrien (set (mem ({pre_inc,pre_dec} sp:cfa_store.reg)) <reg>) 132490075Sobrien effects: cfa_store.offset += -/+ mode_size(mem) 132590075Sobrien cfa.offset = cfa_store.offset if cfa.reg == sp 132690075Sobrien cfa.reg = sp 132790075Sobrien cfa.base_offset = -cfa_store.offset 132890075Sobrien 132990075Sobrien Rule 12: 133090075Sobrien (set (mem ({minus,plus,losum} <reg1>:{cfa_store,cfa_temp} <const_int>)) 133190075Sobrien 133290075Sobrien <reg2>) 133390075Sobrien effects: cfa.reg = <reg1> 133490075Sobrien cfa.base_offset = -/+ <const_int> - {cfa_store,cfa_temp}.offset 133590075Sobrien 133690075Sobrien Rule 13: 133790075Sobrien (set (mem <reg1>:{cfa_store,cfa_temp}) <reg2>) 133890075Sobrien effects: cfa.reg = <reg1> 133990075Sobrien cfa.base_offset = -{cfa_store,cfa_temp}.offset 134090075Sobrien 134190075Sobrien Rule 14: 134290075Sobrien (set (mem (postinc <reg1>:cfa_temp <const_int>)) <reg2>) 134390075Sobrien effects: cfa.reg = <reg1> 134490075Sobrien cfa.base_offset = -cfa_temp.offset 134590075Sobrien cfa_temp.offset -= mode_size(mem) */ 134690075Sobrien 134790075Sobrienstatic void 1348132718Skandwarf2out_frame_debug_expr (rtx expr, const char *label) 134950397Sobrien{ 135050397Sobrien rtx src, dest; 135190075Sobrien HOST_WIDE_INT offset; 135250397Sobrien 135390075Sobrien /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of 135490075Sobrien the PARALLEL independently. The first element is always processed if 135590075Sobrien it is a SET. This is for backward compatibility. Other elements 135690075Sobrien are processed only if they are SETs and the RTX_FRAME_RELATED_P 135790075Sobrien flag is set in them. */ 135890075Sobrien if (GET_CODE (expr) == PARALLEL || GET_CODE (expr) == SEQUENCE) 135990075Sobrien { 136052284Sobrien int par_index; 136152284Sobrien int limit = XVECLEN (expr, 0); 136250397Sobrien 136352284Sobrien for (par_index = 0; par_index < limit; par_index++) 136490075Sobrien if (GET_CODE (XVECEXP (expr, 0, par_index)) == SET 136590075Sobrien && (RTX_FRAME_RELATED_P (XVECEXP (expr, 0, par_index)) 136690075Sobrien || par_index == 0)) 136790075Sobrien dwarf2out_frame_debug_expr (XVECEXP (expr, 0, par_index), label); 136890075Sobrien 136950397Sobrien return; 137050397Sobrien } 137190075Sobrien 137252284Sobrien if (GET_CODE (expr) != SET) 137350397Sobrien abort (); 137450397Sobrien 137552284Sobrien src = SET_SRC (expr); 137652284Sobrien dest = SET_DEST (expr); 137750397Sobrien 137850397Sobrien switch (GET_CODE (dest)) 137950397Sobrien { 138050397Sobrien case REG: 138190075Sobrien /* Rule 1 */ 138250397Sobrien /* Update the CFA rule wrt SP or FP. Make sure src is 1383132718Skan relative to the current CFA register. */ 138450397Sobrien switch (GET_CODE (src)) 138590075Sobrien { 138690075Sobrien /* Setting FP from SP. */ 138790075Sobrien case REG: 138890075Sobrien if (cfa.reg == (unsigned) REGNO (src)) 138990075Sobrien /* OK. */ 139090075Sobrien ; 139190075Sobrien else 139290075Sobrien abort (); 139350397Sobrien 139490075Sobrien /* We used to require that dest be either SP or FP, but the 139590075Sobrien ARM copies SP to a temporary register, and from there to 139690075Sobrien FP. So we just rely on the backends to only set 139790075Sobrien RTX_FRAME_RELATED_P on appropriate insns. */ 139890075Sobrien cfa.reg = REGNO (dest); 139990075Sobrien cfa_temp.reg = cfa.reg; 140090075Sobrien cfa_temp.offset = cfa.offset; 140190075Sobrien break; 140250397Sobrien 140390075Sobrien case PLUS: 140490075Sobrien case MINUS: 140590075Sobrien case LO_SUM: 140690075Sobrien if (dest == stack_pointer_rtx) 140790075Sobrien { 140890075Sobrien /* Rule 2 */ 140990075Sobrien /* Adjusting SP. */ 141090075Sobrien switch (GET_CODE (XEXP (src, 1))) 141190075Sobrien { 141290075Sobrien case CONST_INT: 141390075Sobrien offset = INTVAL (XEXP (src, 1)); 141490075Sobrien break; 141590075Sobrien case REG: 141690075Sobrien if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp.reg) 141790075Sobrien abort (); 141890075Sobrien offset = cfa_temp.offset; 141990075Sobrien break; 142090075Sobrien default: 142190075Sobrien abort (); 142290075Sobrien } 142350397Sobrien 142490075Sobrien if (XEXP (src, 0) == hard_frame_pointer_rtx) 142590075Sobrien { 142690075Sobrien /* Restoring SP from FP in the epilogue. */ 142790075Sobrien if (cfa.reg != (unsigned) HARD_FRAME_POINTER_REGNUM) 142890075Sobrien abort (); 142990075Sobrien cfa.reg = STACK_POINTER_REGNUM; 143090075Sobrien } 143190075Sobrien else if (GET_CODE (src) == LO_SUM) 143290075Sobrien /* Assume we've set the source reg of the LO_SUM from sp. */ 143390075Sobrien ; 143490075Sobrien else if (XEXP (src, 0) != stack_pointer_rtx) 143590075Sobrien abort (); 143650397Sobrien 143790075Sobrien if (GET_CODE (src) != MINUS) 143890075Sobrien offset = -offset; 143990075Sobrien if (cfa.reg == STACK_POINTER_REGNUM) 144090075Sobrien cfa.offset += offset; 144190075Sobrien if (cfa_store.reg == STACK_POINTER_REGNUM) 144290075Sobrien cfa_store.offset += offset; 144390075Sobrien } 144490075Sobrien else if (dest == hard_frame_pointer_rtx) 144590075Sobrien { 144690075Sobrien /* Rule 3 */ 144790075Sobrien /* Either setting the FP from an offset of the SP, 144890075Sobrien or adjusting the FP */ 144990075Sobrien if (! frame_pointer_needed) 145090075Sobrien abort (); 145150397Sobrien 145290075Sobrien if (GET_CODE (XEXP (src, 0)) == REG 145390075Sobrien && (unsigned) REGNO (XEXP (src, 0)) == cfa.reg 145490075Sobrien && GET_CODE (XEXP (src, 1)) == CONST_INT) 145590075Sobrien { 145690075Sobrien offset = INTVAL (XEXP (src, 1)); 145790075Sobrien if (GET_CODE (src) != MINUS) 145890075Sobrien offset = -offset; 145990075Sobrien cfa.offset += offset; 146090075Sobrien cfa.reg = HARD_FRAME_POINTER_REGNUM; 146190075Sobrien } 146290075Sobrien else 146390075Sobrien abort (); 146490075Sobrien } 146590075Sobrien else 146690075Sobrien { 146790075Sobrien if (GET_CODE (src) == MINUS) 146890075Sobrien abort (); 146950397Sobrien 147090075Sobrien /* Rule 4 */ 147190075Sobrien if (GET_CODE (XEXP (src, 0)) == REG 147290075Sobrien && REGNO (XEXP (src, 0)) == cfa.reg 147390075Sobrien && GET_CODE (XEXP (src, 1)) == CONST_INT) 147490075Sobrien { 147590075Sobrien /* Setting a temporary CFA register that will be copied 147690075Sobrien into the FP later on. */ 147790075Sobrien offset = - INTVAL (XEXP (src, 1)); 147890075Sobrien cfa.offset += offset; 147990075Sobrien cfa.reg = REGNO (dest); 148090075Sobrien /* Or used to save regs to the stack. */ 148190075Sobrien cfa_temp.reg = cfa.reg; 148290075Sobrien cfa_temp.offset = cfa.offset; 148390075Sobrien } 148450397Sobrien 148590075Sobrien /* Rule 5 */ 148690075Sobrien else if (GET_CODE (XEXP (src, 0)) == REG 148790075Sobrien && REGNO (XEXP (src, 0)) == cfa_temp.reg 148890075Sobrien && XEXP (src, 1) == stack_pointer_rtx) 148990075Sobrien { 149090075Sobrien /* Setting a scratch register that we will use instead 149190075Sobrien of SP for saving registers to the stack. */ 149290075Sobrien if (cfa.reg != STACK_POINTER_REGNUM) 149390075Sobrien abort (); 149490075Sobrien cfa_store.reg = REGNO (dest); 149590075Sobrien cfa_store.offset = cfa.offset - cfa_temp.offset; 149690075Sobrien } 149750397Sobrien 149890075Sobrien /* Rule 9 */ 149990075Sobrien else if (GET_CODE (src) == LO_SUM 150090075Sobrien && GET_CODE (XEXP (src, 1)) == CONST_INT) 150190075Sobrien { 150290075Sobrien cfa_temp.reg = REGNO (dest); 150390075Sobrien cfa_temp.offset = INTVAL (XEXP (src, 1)); 150490075Sobrien } 150590075Sobrien else 150690075Sobrien abort (); 150790075Sobrien } 150890075Sobrien break; 150950397Sobrien 151090075Sobrien /* Rule 6 */ 151190075Sobrien case CONST_INT: 151290075Sobrien cfa_temp.reg = REGNO (dest); 151390075Sobrien cfa_temp.offset = INTVAL (src); 151490075Sobrien break; 151550397Sobrien 151690075Sobrien /* Rule 7 */ 151790075Sobrien case IOR: 151890075Sobrien if (GET_CODE (XEXP (src, 0)) != REG 151990075Sobrien || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp.reg 152090075Sobrien || GET_CODE (XEXP (src, 1)) != CONST_INT) 152190075Sobrien abort (); 152250397Sobrien 152390075Sobrien if ((unsigned) REGNO (dest) != cfa_temp.reg) 152490075Sobrien cfa_temp.reg = REGNO (dest); 152590075Sobrien cfa_temp.offset |= INTVAL (XEXP (src, 1)); 152690075Sobrien break; 152750397Sobrien 152890075Sobrien /* Skip over HIGH, assuming it will be followed by a LO_SUM, 152990075Sobrien which will fill in all of the bits. */ 153090075Sobrien /* Rule 8 */ 153190075Sobrien case HIGH: 153290075Sobrien break; 153350397Sobrien 153490075Sobrien default: 153590075Sobrien abort (); 153690075Sobrien } 153750397Sobrien 153890075Sobrien def_cfa_1 (label, &cfa); 153990075Sobrien break; 154050397Sobrien 154190075Sobrien case MEM: 154290075Sobrien if (GET_CODE (src) != REG) 154390075Sobrien abort (); 154452284Sobrien 154590075Sobrien /* Saving a register to the stack. Make sure dest is relative to the 154690075Sobrien CFA register. */ 154790075Sobrien switch (GET_CODE (XEXP (dest, 0))) 154890075Sobrien { 154990075Sobrien /* Rule 10 */ 155090075Sobrien /* With a push. */ 155190075Sobrien case PRE_MODIFY: 155290075Sobrien /* We can't handle variable size modifications. */ 155390075Sobrien if (GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1)) != CONST_INT) 155490075Sobrien abort (); 155590075Sobrien offset = -INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1)); 155690075Sobrien 155790075Sobrien if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM 155890075Sobrien || cfa_store.reg != STACK_POINTER_REGNUM) 155990075Sobrien abort (); 156090075Sobrien 156190075Sobrien cfa_store.offset += offset; 156290075Sobrien if (cfa.reg == STACK_POINTER_REGNUM) 156390075Sobrien cfa.offset = cfa_store.offset; 156490075Sobrien 156590075Sobrien offset = -cfa_store.offset; 156690075Sobrien break; 156790075Sobrien 156890075Sobrien /* Rule 11 */ 156990075Sobrien case PRE_INC: 157090075Sobrien case PRE_DEC: 157190075Sobrien offset = GET_MODE_SIZE (GET_MODE (dest)); 157290075Sobrien if (GET_CODE (XEXP (dest, 0)) == PRE_INC) 157390075Sobrien offset = -offset; 157490075Sobrien 157590075Sobrien if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM 157690075Sobrien || cfa_store.reg != STACK_POINTER_REGNUM) 157790075Sobrien abort (); 157890075Sobrien 157990075Sobrien cfa_store.offset += offset; 158090075Sobrien if (cfa.reg == STACK_POINTER_REGNUM) 158190075Sobrien cfa.offset = cfa_store.offset; 158290075Sobrien 158390075Sobrien offset = -cfa_store.offset; 158490075Sobrien break; 158590075Sobrien 158690075Sobrien /* Rule 12 */ 158790075Sobrien /* With an offset. */ 158890075Sobrien case PLUS: 158990075Sobrien case MINUS: 159090075Sobrien case LO_SUM: 159190075Sobrien if (GET_CODE (XEXP (XEXP (dest, 0), 1)) != CONST_INT) 159290075Sobrien abort (); 159390075Sobrien offset = INTVAL (XEXP (XEXP (dest, 0), 1)); 159490075Sobrien if (GET_CODE (XEXP (dest, 0)) == MINUS) 159590075Sobrien offset = -offset; 159690075Sobrien 159790075Sobrien if (cfa_store.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) 159890075Sobrien offset -= cfa_store.offset; 159990075Sobrien else if (cfa_temp.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) 160090075Sobrien offset -= cfa_temp.offset; 160190075Sobrien else 160290075Sobrien abort (); 160390075Sobrien break; 160490075Sobrien 160590075Sobrien /* Rule 13 */ 160690075Sobrien /* Without an offset. */ 160790075Sobrien case REG: 160890075Sobrien if (cfa_store.reg == (unsigned) REGNO (XEXP (dest, 0))) 160990075Sobrien offset = -cfa_store.offset; 161090075Sobrien else if (cfa_temp.reg == (unsigned) REGNO (XEXP (dest, 0))) 161190075Sobrien offset = -cfa_temp.offset; 161290075Sobrien else 161390075Sobrien abort (); 161490075Sobrien break; 161590075Sobrien 161690075Sobrien /* Rule 14 */ 161790075Sobrien case POST_INC: 161890075Sobrien if (cfa_temp.reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) 161990075Sobrien abort (); 162090075Sobrien offset = -cfa_temp.offset; 162190075Sobrien cfa_temp.offset -= GET_MODE_SIZE (GET_MODE (dest)); 162290075Sobrien break; 162390075Sobrien 162490075Sobrien default: 162590075Sobrien abort (); 162690075Sobrien } 162790075Sobrien 162890075Sobrien if (REGNO (src) != STACK_POINTER_REGNUM 162990075Sobrien && REGNO (src) != HARD_FRAME_POINTER_REGNUM 163090075Sobrien && (unsigned) REGNO (src) == cfa.reg) 163190075Sobrien { 163290075Sobrien /* We're storing the current CFA reg into the stack. */ 163390075Sobrien 163490075Sobrien if (cfa.offset == 0) 163590075Sobrien { 163690075Sobrien /* If the source register is exactly the CFA, assume 163790075Sobrien we're saving SP like any other register; this happens 163890075Sobrien on the ARM. */ 163990075Sobrien def_cfa_1 (label, &cfa); 164090075Sobrien queue_reg_save (label, stack_pointer_rtx, offset); 164190075Sobrien break; 164290075Sobrien } 164390075Sobrien else 164490075Sobrien { 164590075Sobrien /* Otherwise, we'll need to look in the stack to 1646132718Skan calculate the CFA. */ 164790075Sobrien rtx x = XEXP (dest, 0); 164890075Sobrien 164990075Sobrien if (GET_CODE (x) != REG) 165090075Sobrien x = XEXP (x, 0); 165190075Sobrien if (GET_CODE (x) != REG) 165290075Sobrien abort (); 165390075Sobrien 165490075Sobrien cfa.reg = REGNO (x); 165590075Sobrien cfa.base_offset = offset; 165690075Sobrien cfa.indirect = 1; 165790075Sobrien def_cfa_1 (label, &cfa); 165890075Sobrien break; 165990075Sobrien } 166090075Sobrien } 166190075Sobrien 166290075Sobrien def_cfa_1 (label, &cfa); 166390075Sobrien queue_reg_save (label, src, offset); 166490075Sobrien break; 166590075Sobrien 166690075Sobrien default: 166790075Sobrien abort (); 166890075Sobrien } 166952284Sobrien} 167052284Sobrien 167152284Sobrien/* Record call frame debugging information for INSN, which either 167252284Sobrien sets SP or FP (adjusting how we calculate the frame address) or saves a 167352284Sobrien register to the stack. If INSN is NULL_RTX, initialize our state. */ 167452284Sobrien 167552284Sobrienvoid 1676132718Skandwarf2out_frame_debug (rtx insn) 167752284Sobrien{ 167890075Sobrien const char *label; 167952284Sobrien rtx src; 168052284Sobrien 168152284Sobrien if (insn == NULL_RTX) 168252284Sobrien { 168390075Sobrien /* Flush any queued register saves. */ 168490075Sobrien flush_queued_reg_saves (); 168590075Sobrien 168652284Sobrien /* Set up state for generating call frame debug info. */ 168790075Sobrien lookup_cfa (&cfa); 168890075Sobrien if (cfa.reg != (unsigned long) DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM)) 168952284Sobrien abort (); 169090075Sobrien 169190075Sobrien cfa.reg = STACK_POINTER_REGNUM; 169290075Sobrien cfa_store = cfa; 169390075Sobrien cfa_temp.reg = -1; 169490075Sobrien cfa_temp.offset = 0; 169552284Sobrien return; 169650397Sobrien } 169752284Sobrien 169890075Sobrien if (GET_CODE (insn) != INSN || clobbers_queued_reg_save (insn)) 169990075Sobrien flush_queued_reg_saves (); 170090075Sobrien 170152284Sobrien if (! RTX_FRAME_RELATED_P (insn)) 170252284Sobrien { 170390075Sobrien if (!ACCUMULATE_OUTGOING_ARGS) 1704117395Skan dwarf2out_stack_adjust (insn); 170590075Sobrien 170652284Sobrien return; 170752284Sobrien } 170852284Sobrien 170952284Sobrien label = dwarf2out_cfi_label (); 171052284Sobrien src = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); 171152284Sobrien if (src) 171252284Sobrien insn = XEXP (src, 0); 171390075Sobrien else 171452284Sobrien insn = PATTERN (insn); 171552284Sobrien 171652284Sobrien dwarf2out_frame_debug_expr (insn, label); 171750397Sobrien} 171850397Sobrien 1719132718Skan#endif 1720132718Skan 1721132718Skan/* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used. */ 1722132718Skanstatic enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc 1723132718Skan (enum dwarf_call_frame_info cfi); 1724132718Skan 1725132718Skanstatic enum dw_cfi_oprnd_type 1726132718Skandw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi) 1727132718Skan{ 1728132718Skan switch (cfi) 1729132718Skan { 1730132718Skan case DW_CFA_nop: 1731132718Skan case DW_CFA_GNU_window_save: 1732132718Skan return dw_cfi_oprnd_unused; 1733132718Skan 1734132718Skan case DW_CFA_set_loc: 1735132718Skan case DW_CFA_advance_loc1: 1736132718Skan case DW_CFA_advance_loc2: 1737132718Skan case DW_CFA_advance_loc4: 1738132718Skan case DW_CFA_MIPS_advance_loc8: 1739132718Skan return dw_cfi_oprnd_addr; 1740132718Skan 1741132718Skan case DW_CFA_offset: 1742132718Skan case DW_CFA_offset_extended: 1743132718Skan case DW_CFA_def_cfa: 1744132718Skan case DW_CFA_offset_extended_sf: 1745132718Skan case DW_CFA_def_cfa_sf: 1746132718Skan case DW_CFA_restore_extended: 1747132718Skan case DW_CFA_undefined: 1748132718Skan case DW_CFA_same_value: 1749132718Skan case DW_CFA_def_cfa_register: 1750132718Skan case DW_CFA_register: 1751132718Skan return dw_cfi_oprnd_reg_num; 1752132718Skan 1753132718Skan case DW_CFA_def_cfa_offset: 1754132718Skan case DW_CFA_GNU_args_size: 1755132718Skan case DW_CFA_def_cfa_offset_sf: 1756132718Skan return dw_cfi_oprnd_offset; 1757132718Skan 1758132718Skan case DW_CFA_def_cfa_expression: 1759132718Skan case DW_CFA_expression: 1760132718Skan return dw_cfi_oprnd_loc; 1761132718Skan 1762132718Skan default: 1763132718Skan abort (); 1764132718Skan } 1765132718Skan} 1766132718Skan 1767132718Skan/* Describe for the GTY machinery what parts of dw_cfi_oprnd2 are used. */ 1768132718Skanstatic enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc 1769132718Skan (enum dwarf_call_frame_info cfi); 1770132718Skan 1771132718Skanstatic enum dw_cfi_oprnd_type 1772132718Skandw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi) 1773132718Skan{ 1774132718Skan switch (cfi) 1775132718Skan { 1776132718Skan case DW_CFA_def_cfa: 1777132718Skan case DW_CFA_def_cfa_sf: 1778132718Skan case DW_CFA_offset: 1779132718Skan case DW_CFA_offset_extended_sf: 1780132718Skan case DW_CFA_offset_extended: 1781132718Skan return dw_cfi_oprnd_offset; 1782132718Skan 1783132718Skan case DW_CFA_register: 1784132718Skan return dw_cfi_oprnd_reg_num; 1785132718Skan 1786132718Skan default: 1787132718Skan return dw_cfi_oprnd_unused; 1788132718Skan } 1789132718Skan} 1790132718Skan 1791132718Skan#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) 1792132718Skan 1793132718Skan/* Map register numbers held in the call frame info that gcc has 1794132718Skan collected using DWARF_FRAME_REGNUM to those that should be output in 1795132718Skan .debug_frame and .eh_frame. */ 1796132718Skan#ifndef DWARF2_FRAME_REG_OUT 1797132718Skan#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO) 1798132718Skan#endif 1799132718Skan 180050397Sobrien/* Output a Call Frame Information opcode and its operand(s). */ 180150397Sobrien 180250397Sobrienstatic void 1803132718Skanoutput_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh) 180450397Sobrien{ 1805132718Skan unsigned long r; 180650397Sobrien if (cfi->dw_cfi_opc == DW_CFA_advance_loc) 180790075Sobrien dw2_asm_output_data (1, (cfi->dw_cfi_opc 180890075Sobrien | (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)), 1809132718Skan "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX, 181090075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_offset); 181150397Sobrien else if (cfi->dw_cfi_opc == DW_CFA_offset) 181250397Sobrien { 1813132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1814132718Skan dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)), 1815132718Skan "DW_CFA_offset, column 0x%lx", r); 181690075Sobrien dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); 181750397Sobrien } 181850397Sobrien else if (cfi->dw_cfi_opc == DW_CFA_restore) 1819132718Skan { 1820132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1821132718Skan dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)), 1822132718Skan "DW_CFA_restore, column 0x%lx", r); 1823132718Skan } 182450397Sobrien else 182550397Sobrien { 182690075Sobrien dw2_asm_output_data (1, cfi->dw_cfi_opc, 182790075Sobrien "%s", dwarf_cfi_name (cfi->dw_cfi_opc)); 182850397Sobrien 182950397Sobrien switch (cfi->dw_cfi_opc) 183050397Sobrien { 183150397Sobrien case DW_CFA_set_loc: 183290075Sobrien if (for_eh) 183390075Sobrien dw2_asm_output_encoded_addr_rtx ( 183490075Sobrien ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0), 183590075Sobrien gen_rtx_SYMBOL_REF (Pmode, cfi->dw_cfi_oprnd1.dw_cfi_addr), 183690075Sobrien NULL); 183790075Sobrien else 183890075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, 183990075Sobrien cfi->dw_cfi_oprnd1.dw_cfi_addr, NULL); 184050397Sobrien break; 184190075Sobrien 184250397Sobrien case DW_CFA_advance_loc1: 184390075Sobrien dw2_asm_output_delta (1, cfi->dw_cfi_oprnd1.dw_cfi_addr, 184490075Sobrien fde->dw_fde_current_label, NULL); 184550397Sobrien fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; 184650397Sobrien break; 184790075Sobrien 184850397Sobrien case DW_CFA_advance_loc2: 184990075Sobrien dw2_asm_output_delta (2, cfi->dw_cfi_oprnd1.dw_cfi_addr, 185090075Sobrien fde->dw_fde_current_label, NULL); 185150397Sobrien fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; 185250397Sobrien break; 185390075Sobrien 185450397Sobrien case DW_CFA_advance_loc4: 185590075Sobrien dw2_asm_output_delta (4, cfi->dw_cfi_oprnd1.dw_cfi_addr, 185690075Sobrien fde->dw_fde_current_label, NULL); 185750397Sobrien fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; 185850397Sobrien break; 185990075Sobrien 186050397Sobrien case DW_CFA_MIPS_advance_loc8: 186190075Sobrien dw2_asm_output_delta (8, cfi->dw_cfi_oprnd1.dw_cfi_addr, 186290075Sobrien fde->dw_fde_current_label, NULL); 186390075Sobrien fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; 186450397Sobrien break; 186590075Sobrien 186650397Sobrien case DW_CFA_offset_extended: 186750397Sobrien case DW_CFA_def_cfa: 1868132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1869132718Skan dw2_asm_output_data_uleb128 (r, NULL); 187090075Sobrien dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); 187150397Sobrien break; 187290075Sobrien 187390075Sobrien case DW_CFA_offset_extended_sf: 187490075Sobrien case DW_CFA_def_cfa_sf: 1875132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1876132718Skan dw2_asm_output_data_uleb128 (r, NULL); 187790075Sobrien dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); 187890075Sobrien break; 187990075Sobrien 188050397Sobrien case DW_CFA_restore_extended: 188150397Sobrien case DW_CFA_undefined: 188250397Sobrien case DW_CFA_same_value: 188350397Sobrien case DW_CFA_def_cfa_register: 1884132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1885132718Skan dw2_asm_output_data_uleb128 (r, NULL); 188650397Sobrien break; 188790075Sobrien 188850397Sobrien case DW_CFA_register: 1889132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 1890132718Skan dw2_asm_output_data_uleb128 (r, NULL); 1891132718Skan r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh); 1892132718Skan dw2_asm_output_data_uleb128 (r, NULL); 189350397Sobrien break; 189490075Sobrien 189550397Sobrien case DW_CFA_def_cfa_offset: 189690075Sobrien case DW_CFA_GNU_args_size: 189790075Sobrien dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL); 189850397Sobrien break; 189990075Sobrien 190090075Sobrien case DW_CFA_def_cfa_offset_sf: 190190075Sobrien dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL); 190290075Sobrien break; 190390075Sobrien 190450397Sobrien case DW_CFA_GNU_window_save: 190550397Sobrien break; 190690075Sobrien 190790075Sobrien case DW_CFA_def_cfa_expression: 190890075Sobrien case DW_CFA_expression: 190990075Sobrien output_cfa_loc (cfi); 191050397Sobrien break; 191190075Sobrien 191290075Sobrien case DW_CFA_GNU_negative_offset_extended: 191390075Sobrien /* Obsoleted by DW_CFA_offset_extended_sf. */ 191490075Sobrien abort (); 191590075Sobrien 191650397Sobrien default: 191750397Sobrien break; 191850397Sobrien } 191990075Sobrien } 192050397Sobrien} 192150397Sobrien 1922132718Skan/* Output the call frame information used to record information 192350397Sobrien that relates to calculating the frame pointer, and records the 192450397Sobrien location of saved registers. */ 192550397Sobrien 192650397Sobrienstatic void 1927132718Skanoutput_call_frame_info (int for_eh) 192850397Sobrien{ 192990075Sobrien unsigned int i; 193090075Sobrien dw_fde_ref fde; 193190075Sobrien dw_cfi_ref cfi; 193290075Sobrien char l1[20], l2[20], section_start_label[20]; 1933117395Skan bool any_lsda_needed = false; 193490075Sobrien char augmentation[6]; 193590075Sobrien int augmentation_size; 193690075Sobrien int fde_encoding = DW_EH_PE_absptr; 193790075Sobrien int per_encoding = DW_EH_PE_absptr; 193890075Sobrien int lsda_encoding = DW_EH_PE_absptr; 193950397Sobrien 1940117395Skan /* Don't emit a CIE if there won't be any FDEs. */ 1941117395Skan if (fde_table_in_use == 0) 1942117395Skan return; 1943117395Skan 1944117395Skan /* If we don't have any functions we'll want to unwind out of, don't 1945117395Skan emit any EH unwind information. Note that if exceptions aren't 1946117395Skan enabled, we won't have collected nothrow information, and if we 1947117395Skan asked for asynchronous tables, we always want this info. */ 194890075Sobrien if (for_eh) 194990075Sobrien { 1950117395Skan bool any_eh_needed = !flag_exceptions || flag_asynchronous_unwind_tables; 195150397Sobrien 195290075Sobrien for (i = 0; i < fde_table_in_use; i++) 195390075Sobrien if (fde_table[i].uses_eh_lsda) 1954117395Skan any_eh_needed = any_lsda_needed = true; 1955132718Skan else if (! fde_table[i].nothrow 1956132718Skan && ! fde_table[i].all_throwers_are_sibcalls) 1957117395Skan any_eh_needed = true; 195850397Sobrien 195990075Sobrien if (! any_eh_needed) 196090075Sobrien return; 196190075Sobrien } 196290075Sobrien 196350397Sobrien /* We're going to be generating comments, so turn on app. */ 196450397Sobrien if (flag_debug_asm) 196550397Sobrien app_enable (); 196650397Sobrien 196750397Sobrien if (for_eh) 196890075Sobrien (*targetm.asm_out.eh_frame_section) (); 196950397Sobrien else 197090075Sobrien named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG); 197150397Sobrien 197290075Sobrien ASM_GENERATE_INTERNAL_LABEL (section_start_label, FRAME_BEGIN_LABEL, for_eh); 197390075Sobrien ASM_OUTPUT_LABEL (asm_out_file, section_start_label); 197490075Sobrien 197590075Sobrien /* Output the CIE. */ 197650397Sobrien ASM_GENERATE_INTERNAL_LABEL (l1, CIE_AFTER_SIZE_LABEL, for_eh); 197750397Sobrien ASM_GENERATE_INTERNAL_LABEL (l2, CIE_END_LABEL, for_eh); 197890075Sobrien dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, 197990075Sobrien "Length of Common Information Entry"); 198050397Sobrien ASM_OUTPUT_LABEL (asm_out_file, l1); 198150397Sobrien 198290075Sobrien /* Now that the CIE pointer is PC-relative for EH, 198390075Sobrien use 0 to identify the CIE. */ 198490075Sobrien dw2_asm_output_data ((for_eh ? 4 : DWARF_OFFSET_SIZE), 198590075Sobrien (for_eh ? 0 : DW_CIE_ID), 198690075Sobrien "CIE Identifier Tag"); 198750397Sobrien 198890075Sobrien dw2_asm_output_data (1, DW_CIE_VERSION, "CIE Version"); 198950397Sobrien 199090075Sobrien augmentation[0] = 0; 199190075Sobrien augmentation_size = 0; 199290075Sobrien if (for_eh) 199350397Sobrien { 199490075Sobrien char *p; 199550397Sobrien 199690075Sobrien /* Augmentation: 199790075Sobrien z Indicates that a uleb128 is present to size the 1998132718Skan augmentation section. 199990075Sobrien L Indicates the encoding (and thus presence) of 200090075Sobrien an LSDA pointer in the FDE augmentation. 200190075Sobrien R Indicates a non-default pointer encoding for 200290075Sobrien FDE code pointers. 200390075Sobrien P Indicates the presence of an encoding + language 200490075Sobrien personality routine in the CIE augmentation. */ 200550397Sobrien 200690075Sobrien fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); 200790075Sobrien per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); 200890075Sobrien lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); 200990075Sobrien 201090075Sobrien p = augmentation + 1; 201190075Sobrien if (eh_personality_libfunc) 201250397Sobrien { 201390075Sobrien *p++ = 'P'; 201490075Sobrien augmentation_size += 1 + size_of_encoded_value (per_encoding); 201550397Sobrien } 201690075Sobrien if (any_lsda_needed) 201750397Sobrien { 201890075Sobrien *p++ = 'L'; 201990075Sobrien augmentation_size += 1; 202050397Sobrien } 202190075Sobrien if (fde_encoding != DW_EH_PE_absptr) 202290075Sobrien { 202390075Sobrien *p++ = 'R'; 202490075Sobrien augmentation_size += 1; 202590075Sobrien } 202690075Sobrien if (p > augmentation + 1) 202790075Sobrien { 202890075Sobrien augmentation[0] = 'z'; 2029117395Skan *p = '\0'; 203090075Sobrien } 203150397Sobrien 203290075Sobrien /* Ug. Some platforms can't do unaligned dynamic relocations at all. */ 203390075Sobrien if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned) 203490075Sobrien { 203590075Sobrien int offset = ( 4 /* Length */ 203690075Sobrien + 4 /* CIE Id */ 203790075Sobrien + 1 /* CIE version */ 203890075Sobrien + strlen (augmentation) + 1 /* Augmentation */ 203990075Sobrien + size_of_uleb128 (1) /* Code alignment */ 204090075Sobrien + size_of_sleb128 (DWARF_CIE_DATA_ALIGNMENT) 204190075Sobrien + 1 /* RA column */ 204290075Sobrien + 1 /* Augmentation size */ 204390075Sobrien + 1 /* Personality encoding */ ); 204490075Sobrien int pad = -offset & (PTR_SIZE - 1); 204590075Sobrien 204690075Sobrien augmentation_size += pad; 204790075Sobrien 204890075Sobrien /* Augmentations should be small, so there's scarce need to 204990075Sobrien iterate for a solution. Die if we exceed one uleb128 byte. */ 205090075Sobrien if (size_of_uleb128 (augmentation_size) != 1) 205190075Sobrien abort (); 205290075Sobrien } 205350397Sobrien } 205450397Sobrien 205590075Sobrien dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation"); 205690075Sobrien dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor"); 205790075Sobrien dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT, 205890075Sobrien "CIE Data Alignment Factor"); 205990075Sobrien dw2_asm_output_data (1, DWARF_FRAME_RETURN_COLUMN, "CIE RA Column"); 206050397Sobrien 206190075Sobrien if (augmentation[0]) 206290075Sobrien { 206390075Sobrien dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size"); 206490075Sobrien if (eh_personality_libfunc) 206590075Sobrien { 206690075Sobrien dw2_asm_output_data (1, per_encoding, "Personality (%s)", 206790075Sobrien eh_data_format_name (per_encoding)); 206890075Sobrien dw2_asm_output_encoded_addr_rtx (per_encoding, 206990075Sobrien eh_personality_libfunc, NULL); 207090075Sobrien } 207150397Sobrien 207290075Sobrien if (any_lsda_needed) 207390075Sobrien dw2_asm_output_data (1, lsda_encoding, "LSDA Encoding (%s)", 207490075Sobrien eh_data_format_name (lsda_encoding)); 207550397Sobrien 207690075Sobrien if (fde_encoding != DW_EH_PE_absptr) 207790075Sobrien dw2_asm_output_data (1, fde_encoding, "FDE Encoding (%s)", 207890075Sobrien eh_data_format_name (fde_encoding)); 207990075Sobrien } 208050397Sobrien 208150397Sobrien for (cfi = cie_cfi_head; cfi != NULL; cfi = cfi->dw_cfi_next) 208290075Sobrien output_cfi (cfi, NULL, for_eh); 208350397Sobrien 208450397Sobrien /* Pad the CIE out to an address sized boundary. */ 2085117395Skan ASM_OUTPUT_ALIGN (asm_out_file, 208690075Sobrien floor_log2 (for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)); 208750397Sobrien ASM_OUTPUT_LABEL (asm_out_file, l2); 208850397Sobrien 208950397Sobrien /* Loop through all of the FDE's. */ 209090075Sobrien for (i = 0; i < fde_table_in_use; i++) 209150397Sobrien { 209250397Sobrien fde = &fde_table[i]; 209350397Sobrien 209490075Sobrien /* Don't emit EH unwind info for leaf functions that don't need it. */ 2095117395Skan if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions 2096117395Skan && (fde->nothrow || fde->all_throwers_are_sibcalls) 2097117395Skan && !fde->uses_eh_lsda) 209890075Sobrien continue; 209990075Sobrien 2100132718Skan (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2); 210190075Sobrien ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2); 210290075Sobrien ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2); 210390075Sobrien dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, 210490075Sobrien "FDE Length"); 210590075Sobrien ASM_OUTPUT_LABEL (asm_out_file, l1); 210690075Sobrien 210750397Sobrien if (for_eh) 210890075Sobrien dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset"); 210950397Sobrien else 211090075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label, 211190075Sobrien "FDE CIE offset"); 211250397Sobrien 211350397Sobrien if (for_eh) 211490075Sobrien { 211590075Sobrien dw2_asm_output_encoded_addr_rtx (fde_encoding, 211690075Sobrien gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin), 211790075Sobrien "FDE initial location"); 211890075Sobrien dw2_asm_output_delta (size_of_encoded_value (fde_encoding), 2119117395Skan fde->dw_fde_end, fde->dw_fde_begin, 212090075Sobrien "FDE address range"); 212190075Sobrien } 212250397Sobrien else 212390075Sobrien { 212490075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin, 212590075Sobrien "FDE initial location"); 2126117395Skan dw2_asm_output_delta (DWARF2_ADDR_SIZE, 2127117395Skan fde->dw_fde_end, fde->dw_fde_begin, 212890075Sobrien "FDE address range"); 212990075Sobrien } 213050397Sobrien 213190075Sobrien if (augmentation[0]) 213290075Sobrien { 213390075Sobrien if (any_lsda_needed) 213490075Sobrien { 213590075Sobrien int size = size_of_encoded_value (lsda_encoding); 213650397Sobrien 213790075Sobrien if (lsda_encoding == DW_EH_PE_aligned) 213890075Sobrien { 213990075Sobrien int offset = ( 4 /* Length */ 214090075Sobrien + 4 /* CIE offset */ 214190075Sobrien + 2 * size_of_encoded_value (fde_encoding) 214290075Sobrien + 1 /* Augmentation size */ ); 214390075Sobrien int pad = -offset & (PTR_SIZE - 1); 214450397Sobrien 214590075Sobrien size += pad; 214690075Sobrien if (size_of_uleb128 (size) != 1) 214790075Sobrien abort (); 214890075Sobrien } 214950397Sobrien 215090075Sobrien dw2_asm_output_data_uleb128 (size, "Augmentation size"); 215190075Sobrien 215290075Sobrien if (fde->uses_eh_lsda) 2153132718Skan { 2154132718Skan ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", 215590075Sobrien fde->funcdef_number); 2156132718Skan dw2_asm_output_encoded_addr_rtx ( 215790075Sobrien lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1), 2158132718Skan "Language Specific Data Area"); 2159132718Skan } 216090075Sobrien else 216190075Sobrien { 216290075Sobrien if (lsda_encoding == DW_EH_PE_aligned) 216390075Sobrien ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); 216490075Sobrien dw2_asm_output_data 216590075Sobrien (size_of_encoded_value (lsda_encoding), 0, 216690075Sobrien "Language Specific Data Area (none)"); 216790075Sobrien } 216890075Sobrien } 216990075Sobrien else 217090075Sobrien dw2_asm_output_data_uleb128 (0, "Augmentation size"); 217190075Sobrien } 217290075Sobrien 217350397Sobrien /* Loop through the Call Frame Instructions associated with 217450397Sobrien this FDE. */ 217550397Sobrien fde->dw_fde_current_label = fde->dw_fde_begin; 217650397Sobrien for (cfi = fde->dw_fde_cfi; cfi != NULL; cfi = cfi->dw_cfi_next) 217790075Sobrien output_cfi (cfi, fde, for_eh); 217850397Sobrien 217950397Sobrien /* Pad the FDE out to an address sized boundary. */ 2180117395Skan ASM_OUTPUT_ALIGN (asm_out_file, 2181132718Skan floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE))); 218250397Sobrien ASM_OUTPUT_LABEL (asm_out_file, l2); 218350397Sobrien } 218490075Sobrien 2185117395Skan if (for_eh && targetm.terminate_dw2_eh_frame_info) 218690075Sobrien dw2_asm_output_data (4, 0, "End of Table"); 218750397Sobrien#ifdef MIPS_DEBUGGING_INFO 218850397Sobrien /* Work around Irix 6 assembler bug whereby labels at the end of a section 218950397Sobrien get a value of 0. Putting .align 0 after the label fixes it. */ 219050397Sobrien ASM_OUTPUT_ALIGN (asm_out_file, 0); 219150397Sobrien#endif 219250397Sobrien 219350397Sobrien /* Turn off app to make assembly quicker. */ 219450397Sobrien if (flag_debug_asm) 219550397Sobrien app_disable (); 219650397Sobrien} 219750397Sobrien 219850397Sobrien/* Output a marker (i.e. a label) for the beginning of a function, before 219950397Sobrien the prologue. */ 220050397Sobrien 220150397Sobrienvoid 2202132718Skandwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, 2203132718Skan const char *file ATTRIBUTE_UNUSED) 220450397Sobrien{ 220550397Sobrien char label[MAX_ARTIFICIAL_LABEL_BYTES]; 220690075Sobrien dw_fde_ref fde; 220750397Sobrien 220890075Sobrien current_function_func_begin_label = 0; 220950397Sobrien 221090075Sobrien#ifdef IA64_UNWIND_INFO 221190075Sobrien /* ??? current_function_func_begin_label is also used by except.c 221290075Sobrien for call-site information. We must emit this label if it might 221390075Sobrien be used. */ 221490075Sobrien if ((! flag_exceptions || USING_SJLJ_EXCEPTIONS) 221590075Sobrien && ! dwarf2out_do_frame ()) 221690075Sobrien return; 221790075Sobrien#else 221890075Sobrien if (! dwarf2out_do_frame ()) 221990075Sobrien return; 222090075Sobrien#endif 222190075Sobrien 222250397Sobrien function_section (current_function_decl); 222350397Sobrien ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL, 2224117395Skan current_function_funcdef_no); 222590075Sobrien ASM_OUTPUT_DEBUG_LABEL (asm_out_file, FUNC_BEGIN_LABEL, 2226117395Skan current_function_funcdef_no); 222790075Sobrien current_function_func_begin_label = get_identifier (label); 222850397Sobrien 222990075Sobrien#ifdef IA64_UNWIND_INFO 223090075Sobrien /* We can elide the fde allocation if we're not emitting debug info. */ 223190075Sobrien if (! dwarf2out_do_frame ()) 223290075Sobrien return; 223390075Sobrien#endif 223490075Sobrien 223550397Sobrien /* Expand the fde table if necessary. */ 223650397Sobrien if (fde_table_in_use == fde_table_allocated) 223750397Sobrien { 223850397Sobrien fde_table_allocated += FDE_TABLE_INCREMENT; 2239132718Skan fde_table = ggc_realloc (fde_table, 2240132718Skan fde_table_allocated * sizeof (dw_fde_node)); 2241132718Skan memset (fde_table + fde_table_in_use, 0, 2242132718Skan FDE_TABLE_INCREMENT * sizeof (dw_fde_node)); 224350397Sobrien } 224450397Sobrien 224550397Sobrien /* Record the FDE associated with this function. */ 224650397Sobrien current_funcdef_fde = fde_table_in_use; 224750397Sobrien 224850397Sobrien /* Add the new FDE at the end of the fde_table. */ 224950397Sobrien fde = &fde_table[fde_table_in_use++]; 225050397Sobrien fde->dw_fde_begin = xstrdup (label); 225150397Sobrien fde->dw_fde_current_label = NULL; 225250397Sobrien fde->dw_fde_end = NULL; 225350397Sobrien fde->dw_fde_cfi = NULL; 2254117395Skan fde->funcdef_number = current_function_funcdef_no; 225590075Sobrien fde->nothrow = current_function_nothrow; 225690075Sobrien fde->uses_eh_lsda = cfun->uses_eh_lsda; 2257117395Skan fde->all_throwers_are_sibcalls = cfun->all_throwers_are_sibcalls; 225850397Sobrien 225950397Sobrien args_size = old_args_size = 0; 226090075Sobrien 226190075Sobrien /* We only want to output line number information for the genuine dwarf2 226290075Sobrien prologue case, not the eh frame case. */ 226390075Sobrien#ifdef DWARF2_DEBUGGING_INFO 226490075Sobrien if (file) 226590075Sobrien dwarf2out_source_line (line, file); 226690075Sobrien#endif 226750397Sobrien} 226850397Sobrien 226950397Sobrien/* Output a marker (i.e. a label) for the absolute end of the generated code 227050397Sobrien for a function definition. This gets called *after* the epilogue code has 227150397Sobrien been generated. */ 227250397Sobrien 227350397Sobrienvoid 2274132718Skandwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, 2275132718Skan const char *file ATTRIBUTE_UNUSED) 227650397Sobrien{ 227750397Sobrien dw_fde_ref fde; 227850397Sobrien char label[MAX_ARTIFICIAL_LABEL_BYTES]; 227950397Sobrien 228050397Sobrien /* Output a label to mark the endpoint of the code generated for this 228190075Sobrien function. */ 2282117395Skan ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL, 2283117395Skan current_function_funcdef_no); 228450397Sobrien ASM_OUTPUT_LABEL (asm_out_file, label); 228550397Sobrien fde = &fde_table[fde_table_in_use - 1]; 228650397Sobrien fde->dw_fde_end = xstrdup (label); 228750397Sobrien} 228850397Sobrien 228950397Sobrienvoid 2290132718Skandwarf2out_frame_init (void) 229150397Sobrien{ 229250397Sobrien /* Allocate the initial hunk of the fde_table. */ 2293132718Skan fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node)); 229450397Sobrien fde_table_allocated = FDE_TABLE_INCREMENT; 229550397Sobrien fde_table_in_use = 0; 229650397Sobrien 229750397Sobrien /* Generate the CFA instructions common to all FDE's. Do it now for the 229850397Sobrien sake of lookup_cfa. */ 229950397Sobrien 230050397Sobrien#ifdef DWARF2_UNWIND_INFO 230150397Sobrien /* On entry, the Canonical Frame Address is at SP. */ 230250397Sobrien dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET); 230350397Sobrien initial_return_save (INCOMING_RETURN_ADDR_RTX); 230450397Sobrien#endif 230550397Sobrien} 230650397Sobrien 230750397Sobrienvoid 2308132718Skandwarf2out_frame_finish (void) 230950397Sobrien{ 231050397Sobrien /* Output call frame information. */ 231190075Sobrien if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) 231250397Sobrien output_call_frame_info (0); 231390075Sobrien 231490075Sobrien if (! USING_SJLJ_EXCEPTIONS && (flag_unwind_tables || flag_exceptions)) 231550397Sobrien output_call_frame_info (1); 231690075Sobrien} 2317132718Skan#endif 231890075Sobrien 231990075Sobrien/* And now, the subset of the debugging information support code necessary 232090075Sobrien for emitting location expressions. */ 232150397Sobrien 2322117395Skan/* We need some way to distinguish DW_OP_addr with a direct symbol 2323117395Skan relocation from DW_OP_addr with a dtp-relative symbol relocation. */ 2324117395Skan#define INTERNAL_DW_OP_tls_addr (0x100 + DW_OP_addr) 2325117395Skan 2326117395Skan 232790075Sobrientypedef struct dw_val_struct *dw_val_ref; 232890075Sobrientypedef struct die_struct *dw_die_ref; 232990075Sobrientypedef struct dw_loc_descr_struct *dw_loc_descr_ref; 233090075Sobrientypedef struct dw_loc_list_struct *dw_loc_list_ref; 233150397Sobrien 233250397Sobrien/* Each DIE may have a series of attribute/value pairs. Values 233350397Sobrien can take on several forms. The forms that are used in this 233450397Sobrien implementation are listed below. */ 233550397Sobrien 2336132718Skanenum dw_val_class 233750397Sobrien{ 233850397Sobrien dw_val_class_addr, 233990075Sobrien dw_val_class_offset, 234050397Sobrien dw_val_class_loc, 234190075Sobrien dw_val_class_loc_list, 234290075Sobrien dw_val_class_range_list, 234350397Sobrien dw_val_class_const, 234450397Sobrien dw_val_class_unsigned_const, 234550397Sobrien dw_val_class_long_long, 2346132718Skan dw_val_class_vec, 234750397Sobrien dw_val_class_flag, 234850397Sobrien dw_val_class_die_ref, 234950397Sobrien dw_val_class_fde_ref, 235050397Sobrien dw_val_class_lbl_id, 235152284Sobrien dw_val_class_lbl_offset, 235250397Sobrien dw_val_class_str 2353132718Skan}; 235450397Sobrien 235550397Sobrien/* Describe a double word constant value. */ 235690075Sobrien/* ??? Every instance of long_long in the code really means CONST_DOUBLE. */ 235750397Sobrien 2358132718Skantypedef struct dw_long_long_struct GTY(()) 235950397Sobrien{ 236050397Sobrien unsigned long hi; 236150397Sobrien unsigned long low; 236250397Sobrien} 236350397Sobriendw_long_long_const; 236450397Sobrien 2365132718Skan/* Describe a floating point constant value, or a vector constant value. */ 236650397Sobrien 2367132718Skantypedef struct dw_vec_struct GTY(()) 236850397Sobrien{ 2369132718Skan unsigned char * GTY((length ("%h.length"))) array; 237050397Sobrien unsigned length; 2371132718Skan unsigned elt_size; 237250397Sobrien} 2373132718Skandw_vec_const; 237450397Sobrien 237550397Sobrien/* The dw_val_node describes an attribute's value, as it is 237650397Sobrien represented internally. */ 237750397Sobrien 2378132718Skantypedef struct dw_val_struct GTY(()) 237950397Sobrien{ 2380132718Skan enum dw_val_class val_class; 2381132718Skan union dw_val_struct_union 238250397Sobrien { 2383132718Skan rtx GTY ((tag ("dw_val_class_addr"))) val_addr; 2384132718Skan unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset; 2385132718Skan dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list; 2386132718Skan dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc; 2387132718Skan HOST_WIDE_INT GTY ((default (""))) val_int; 2388132718Skan unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned; 2389132718Skan dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long; 2390132718Skan dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec; 2391132718Skan struct dw_val_die_union 239290075Sobrien { 239390075Sobrien dw_die_ref die; 239490075Sobrien int external; 2395132718Skan } GTY ((tag ("dw_val_class_die_ref"))) val_die_ref; 2396132718Skan unsigned GTY ((tag ("dw_val_class_fde_ref"))) val_fde_index; 2397132718Skan struct indirect_string_node * GTY ((tag ("dw_val_class_str"))) val_str; 2398132718Skan char * GTY ((tag ("dw_val_class_lbl_id"))) val_lbl_id; 2399132718Skan unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag; 240050397Sobrien } 2401132718Skan GTY ((desc ("%1.val_class"))) v; 240250397Sobrien} 240350397Sobriendw_val_node; 240450397Sobrien 240550397Sobrien/* Locations in memory are described using a sequence of stack machine 240650397Sobrien operations. */ 240750397Sobrien 2408132718Skantypedef struct dw_loc_descr_struct GTY(()) 240950397Sobrien{ 241050397Sobrien dw_loc_descr_ref dw_loc_next; 241150397Sobrien enum dwarf_location_atom dw_loc_opc; 241250397Sobrien dw_val_node dw_loc_oprnd1; 241350397Sobrien dw_val_node dw_loc_oprnd2; 241490075Sobrien int dw_loc_addr; 241550397Sobrien} 241650397Sobriendw_loc_descr_node; 241750397Sobrien 241890075Sobrien/* Location lists are ranges + location descriptions for that range, 241990075Sobrien so you can track variables that are in different places over 242090075Sobrien their entire life. */ 2421132718Skantypedef struct dw_loc_list_struct GTY(()) 242290075Sobrien{ 242390075Sobrien dw_loc_list_ref dw_loc_next; 242490075Sobrien const char *begin; /* Label for begin address of range */ 242590075Sobrien const char *end; /* Label for end address of range */ 242690075Sobrien char *ll_symbol; /* Label for beginning of location list. 242790075Sobrien Only on head of list */ 242890075Sobrien const char *section; /* Section this loclist is relative to */ 242990075Sobrien dw_loc_descr_ref expr; 243090075Sobrien} dw_loc_list_node; 243190075Sobrien 2432132718Skan#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) 243390075Sobrien 2434132718Skanstatic const char *dwarf_stack_op_name (unsigned); 2435132718Skanstatic dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom, 2436132718Skan unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT); 2437132718Skanstatic void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref); 2438132718Skanstatic unsigned long size_of_loc_descr (dw_loc_descr_ref); 2439132718Skanstatic unsigned long size_of_locs (dw_loc_descr_ref); 2440132718Skanstatic void output_loc_operands (dw_loc_descr_ref); 2441132718Skanstatic void output_loc_sequence (dw_loc_descr_ref); 2442132718Skan 244390075Sobrien/* Convert a DWARF stack opcode into its string name. */ 244490075Sobrien 244590075Sobrienstatic const char * 2446132718Skandwarf_stack_op_name (unsigned int op) 244790075Sobrien{ 244890075Sobrien switch (op) 244990075Sobrien { 245090075Sobrien case DW_OP_addr: 2451117395Skan case INTERNAL_DW_OP_tls_addr: 245290075Sobrien return "DW_OP_addr"; 245390075Sobrien case DW_OP_deref: 245490075Sobrien return "DW_OP_deref"; 245590075Sobrien case DW_OP_const1u: 245690075Sobrien return "DW_OP_const1u"; 245790075Sobrien case DW_OP_const1s: 245890075Sobrien return "DW_OP_const1s"; 245990075Sobrien case DW_OP_const2u: 246090075Sobrien return "DW_OP_const2u"; 246190075Sobrien case DW_OP_const2s: 246290075Sobrien return "DW_OP_const2s"; 246390075Sobrien case DW_OP_const4u: 246490075Sobrien return "DW_OP_const4u"; 246590075Sobrien case DW_OP_const4s: 246690075Sobrien return "DW_OP_const4s"; 246790075Sobrien case DW_OP_const8u: 246890075Sobrien return "DW_OP_const8u"; 246990075Sobrien case DW_OP_const8s: 247090075Sobrien return "DW_OP_const8s"; 247190075Sobrien case DW_OP_constu: 247290075Sobrien return "DW_OP_constu"; 247390075Sobrien case DW_OP_consts: 247490075Sobrien return "DW_OP_consts"; 247590075Sobrien case DW_OP_dup: 247690075Sobrien return "DW_OP_dup"; 247790075Sobrien case DW_OP_drop: 247890075Sobrien return "DW_OP_drop"; 247990075Sobrien case DW_OP_over: 248090075Sobrien return "DW_OP_over"; 248190075Sobrien case DW_OP_pick: 248290075Sobrien return "DW_OP_pick"; 248390075Sobrien case DW_OP_swap: 248490075Sobrien return "DW_OP_swap"; 248590075Sobrien case DW_OP_rot: 248690075Sobrien return "DW_OP_rot"; 248790075Sobrien case DW_OP_xderef: 248890075Sobrien return "DW_OP_xderef"; 248990075Sobrien case DW_OP_abs: 249090075Sobrien return "DW_OP_abs"; 249190075Sobrien case DW_OP_and: 249290075Sobrien return "DW_OP_and"; 249390075Sobrien case DW_OP_div: 249490075Sobrien return "DW_OP_div"; 249590075Sobrien case DW_OP_minus: 249690075Sobrien return "DW_OP_minus"; 249790075Sobrien case DW_OP_mod: 249890075Sobrien return "DW_OP_mod"; 249990075Sobrien case DW_OP_mul: 250090075Sobrien return "DW_OP_mul"; 250190075Sobrien case DW_OP_neg: 250290075Sobrien return "DW_OP_neg"; 250390075Sobrien case DW_OP_not: 250490075Sobrien return "DW_OP_not"; 250590075Sobrien case DW_OP_or: 250690075Sobrien return "DW_OP_or"; 250790075Sobrien case DW_OP_plus: 250890075Sobrien return "DW_OP_plus"; 250990075Sobrien case DW_OP_plus_uconst: 251090075Sobrien return "DW_OP_plus_uconst"; 251190075Sobrien case DW_OP_shl: 251290075Sobrien return "DW_OP_shl"; 251390075Sobrien case DW_OP_shr: 251490075Sobrien return "DW_OP_shr"; 251590075Sobrien case DW_OP_shra: 251690075Sobrien return "DW_OP_shra"; 251790075Sobrien case DW_OP_xor: 251890075Sobrien return "DW_OP_xor"; 251990075Sobrien case DW_OP_bra: 252090075Sobrien return "DW_OP_bra"; 252190075Sobrien case DW_OP_eq: 252290075Sobrien return "DW_OP_eq"; 252390075Sobrien case DW_OP_ge: 252490075Sobrien return "DW_OP_ge"; 252590075Sobrien case DW_OP_gt: 252690075Sobrien return "DW_OP_gt"; 252790075Sobrien case DW_OP_le: 252890075Sobrien return "DW_OP_le"; 252990075Sobrien case DW_OP_lt: 253090075Sobrien return "DW_OP_lt"; 253190075Sobrien case DW_OP_ne: 253290075Sobrien return "DW_OP_ne"; 253390075Sobrien case DW_OP_skip: 253490075Sobrien return "DW_OP_skip"; 253590075Sobrien case DW_OP_lit0: 253690075Sobrien return "DW_OP_lit0"; 253790075Sobrien case DW_OP_lit1: 253890075Sobrien return "DW_OP_lit1"; 253990075Sobrien case DW_OP_lit2: 254090075Sobrien return "DW_OP_lit2"; 254190075Sobrien case DW_OP_lit3: 254290075Sobrien return "DW_OP_lit3"; 254390075Sobrien case DW_OP_lit4: 254490075Sobrien return "DW_OP_lit4"; 254590075Sobrien case DW_OP_lit5: 254690075Sobrien return "DW_OP_lit5"; 254790075Sobrien case DW_OP_lit6: 254890075Sobrien return "DW_OP_lit6"; 254990075Sobrien case DW_OP_lit7: 255090075Sobrien return "DW_OP_lit7"; 255190075Sobrien case DW_OP_lit8: 255290075Sobrien return "DW_OP_lit8"; 255390075Sobrien case DW_OP_lit9: 255490075Sobrien return "DW_OP_lit9"; 255590075Sobrien case DW_OP_lit10: 255690075Sobrien return "DW_OP_lit10"; 255790075Sobrien case DW_OP_lit11: 255890075Sobrien return "DW_OP_lit11"; 255990075Sobrien case DW_OP_lit12: 256090075Sobrien return "DW_OP_lit12"; 256190075Sobrien case DW_OP_lit13: 256290075Sobrien return "DW_OP_lit13"; 256390075Sobrien case DW_OP_lit14: 256490075Sobrien return "DW_OP_lit14"; 256590075Sobrien case DW_OP_lit15: 256690075Sobrien return "DW_OP_lit15"; 256790075Sobrien case DW_OP_lit16: 256890075Sobrien return "DW_OP_lit16"; 256990075Sobrien case DW_OP_lit17: 257090075Sobrien return "DW_OP_lit17"; 257190075Sobrien case DW_OP_lit18: 257290075Sobrien return "DW_OP_lit18"; 257390075Sobrien case DW_OP_lit19: 257490075Sobrien return "DW_OP_lit19"; 257590075Sobrien case DW_OP_lit20: 257690075Sobrien return "DW_OP_lit20"; 257790075Sobrien case DW_OP_lit21: 257890075Sobrien return "DW_OP_lit21"; 257990075Sobrien case DW_OP_lit22: 258090075Sobrien return "DW_OP_lit22"; 258190075Sobrien case DW_OP_lit23: 258290075Sobrien return "DW_OP_lit23"; 258390075Sobrien case DW_OP_lit24: 258490075Sobrien return "DW_OP_lit24"; 258590075Sobrien case DW_OP_lit25: 258690075Sobrien return "DW_OP_lit25"; 258790075Sobrien case DW_OP_lit26: 258890075Sobrien return "DW_OP_lit26"; 258990075Sobrien case DW_OP_lit27: 259090075Sobrien return "DW_OP_lit27"; 259190075Sobrien case DW_OP_lit28: 259290075Sobrien return "DW_OP_lit28"; 259390075Sobrien case DW_OP_lit29: 259490075Sobrien return "DW_OP_lit29"; 259590075Sobrien case DW_OP_lit30: 259690075Sobrien return "DW_OP_lit30"; 259790075Sobrien case DW_OP_lit31: 259890075Sobrien return "DW_OP_lit31"; 259990075Sobrien case DW_OP_reg0: 260090075Sobrien return "DW_OP_reg0"; 260190075Sobrien case DW_OP_reg1: 260290075Sobrien return "DW_OP_reg1"; 260390075Sobrien case DW_OP_reg2: 260490075Sobrien return "DW_OP_reg2"; 260590075Sobrien case DW_OP_reg3: 260690075Sobrien return "DW_OP_reg3"; 260790075Sobrien case DW_OP_reg4: 260890075Sobrien return "DW_OP_reg4"; 260990075Sobrien case DW_OP_reg5: 261090075Sobrien return "DW_OP_reg5"; 261190075Sobrien case DW_OP_reg6: 261290075Sobrien return "DW_OP_reg6"; 261390075Sobrien case DW_OP_reg7: 261490075Sobrien return "DW_OP_reg7"; 261590075Sobrien case DW_OP_reg8: 261690075Sobrien return "DW_OP_reg8"; 261790075Sobrien case DW_OP_reg9: 261890075Sobrien return "DW_OP_reg9"; 261990075Sobrien case DW_OP_reg10: 262090075Sobrien return "DW_OP_reg10"; 262190075Sobrien case DW_OP_reg11: 262290075Sobrien return "DW_OP_reg11"; 262390075Sobrien case DW_OP_reg12: 262490075Sobrien return "DW_OP_reg12"; 262590075Sobrien case DW_OP_reg13: 262690075Sobrien return "DW_OP_reg13"; 262790075Sobrien case DW_OP_reg14: 262890075Sobrien return "DW_OP_reg14"; 262990075Sobrien case DW_OP_reg15: 263090075Sobrien return "DW_OP_reg15"; 263190075Sobrien case DW_OP_reg16: 263290075Sobrien return "DW_OP_reg16"; 263390075Sobrien case DW_OP_reg17: 263490075Sobrien return "DW_OP_reg17"; 263590075Sobrien case DW_OP_reg18: 263690075Sobrien return "DW_OP_reg18"; 263790075Sobrien case DW_OP_reg19: 263890075Sobrien return "DW_OP_reg19"; 263990075Sobrien case DW_OP_reg20: 264090075Sobrien return "DW_OP_reg20"; 264190075Sobrien case DW_OP_reg21: 264290075Sobrien return "DW_OP_reg21"; 264390075Sobrien case DW_OP_reg22: 264490075Sobrien return "DW_OP_reg22"; 264590075Sobrien case DW_OP_reg23: 264690075Sobrien return "DW_OP_reg23"; 264790075Sobrien case DW_OP_reg24: 264890075Sobrien return "DW_OP_reg24"; 264990075Sobrien case DW_OP_reg25: 265090075Sobrien return "DW_OP_reg25"; 265190075Sobrien case DW_OP_reg26: 265290075Sobrien return "DW_OP_reg26"; 265390075Sobrien case DW_OP_reg27: 265490075Sobrien return "DW_OP_reg27"; 265590075Sobrien case DW_OP_reg28: 265690075Sobrien return "DW_OP_reg28"; 265790075Sobrien case DW_OP_reg29: 265890075Sobrien return "DW_OP_reg29"; 265990075Sobrien case DW_OP_reg30: 266090075Sobrien return "DW_OP_reg30"; 266190075Sobrien case DW_OP_reg31: 266290075Sobrien return "DW_OP_reg31"; 266390075Sobrien case DW_OP_breg0: 266490075Sobrien return "DW_OP_breg0"; 266590075Sobrien case DW_OP_breg1: 266690075Sobrien return "DW_OP_breg1"; 266790075Sobrien case DW_OP_breg2: 266890075Sobrien return "DW_OP_breg2"; 266990075Sobrien case DW_OP_breg3: 267090075Sobrien return "DW_OP_breg3"; 267190075Sobrien case DW_OP_breg4: 267290075Sobrien return "DW_OP_breg4"; 267390075Sobrien case DW_OP_breg5: 267490075Sobrien return "DW_OP_breg5"; 267590075Sobrien case DW_OP_breg6: 267690075Sobrien return "DW_OP_breg6"; 267790075Sobrien case DW_OP_breg7: 267890075Sobrien return "DW_OP_breg7"; 267990075Sobrien case DW_OP_breg8: 268090075Sobrien return "DW_OP_breg8"; 268190075Sobrien case DW_OP_breg9: 268290075Sobrien return "DW_OP_breg9"; 268390075Sobrien case DW_OP_breg10: 268490075Sobrien return "DW_OP_breg10"; 268590075Sobrien case DW_OP_breg11: 268690075Sobrien return "DW_OP_breg11"; 268790075Sobrien case DW_OP_breg12: 268890075Sobrien return "DW_OP_breg12"; 268990075Sobrien case DW_OP_breg13: 269090075Sobrien return "DW_OP_breg13"; 269190075Sobrien case DW_OP_breg14: 269290075Sobrien return "DW_OP_breg14"; 269390075Sobrien case DW_OP_breg15: 269490075Sobrien return "DW_OP_breg15"; 269590075Sobrien case DW_OP_breg16: 269690075Sobrien return "DW_OP_breg16"; 269790075Sobrien case DW_OP_breg17: 269890075Sobrien return "DW_OP_breg17"; 269990075Sobrien case DW_OP_breg18: 270090075Sobrien return "DW_OP_breg18"; 270190075Sobrien case DW_OP_breg19: 270290075Sobrien return "DW_OP_breg19"; 270390075Sobrien case DW_OP_breg20: 270490075Sobrien return "DW_OP_breg20"; 270590075Sobrien case DW_OP_breg21: 270690075Sobrien return "DW_OP_breg21"; 270790075Sobrien case DW_OP_breg22: 270890075Sobrien return "DW_OP_breg22"; 270990075Sobrien case DW_OP_breg23: 271090075Sobrien return "DW_OP_breg23"; 271190075Sobrien case DW_OP_breg24: 271290075Sobrien return "DW_OP_breg24"; 271390075Sobrien case DW_OP_breg25: 271490075Sobrien return "DW_OP_breg25"; 271590075Sobrien case DW_OP_breg26: 271690075Sobrien return "DW_OP_breg26"; 271790075Sobrien case DW_OP_breg27: 271890075Sobrien return "DW_OP_breg27"; 271990075Sobrien case DW_OP_breg28: 272090075Sobrien return "DW_OP_breg28"; 272190075Sobrien case DW_OP_breg29: 272290075Sobrien return "DW_OP_breg29"; 272390075Sobrien case DW_OP_breg30: 272490075Sobrien return "DW_OP_breg30"; 272590075Sobrien case DW_OP_breg31: 272690075Sobrien return "DW_OP_breg31"; 272790075Sobrien case DW_OP_regx: 272890075Sobrien return "DW_OP_regx"; 272990075Sobrien case DW_OP_fbreg: 273090075Sobrien return "DW_OP_fbreg"; 273190075Sobrien case DW_OP_bregx: 273290075Sobrien return "DW_OP_bregx"; 273390075Sobrien case DW_OP_piece: 273490075Sobrien return "DW_OP_piece"; 273590075Sobrien case DW_OP_deref_size: 273690075Sobrien return "DW_OP_deref_size"; 273790075Sobrien case DW_OP_xderef_size: 273890075Sobrien return "DW_OP_xderef_size"; 273990075Sobrien case DW_OP_nop: 274090075Sobrien return "DW_OP_nop"; 2741117395Skan case DW_OP_push_object_address: 2742117395Skan return "DW_OP_push_object_address"; 2743117395Skan case DW_OP_call2: 2744117395Skan return "DW_OP_call2"; 2745117395Skan case DW_OP_call4: 2746117395Skan return "DW_OP_call4"; 2747117395Skan case DW_OP_call_ref: 2748117395Skan return "DW_OP_call_ref"; 2749117395Skan case DW_OP_GNU_push_tls_address: 2750117395Skan return "DW_OP_GNU_push_tls_address"; 275190075Sobrien default: 275290075Sobrien return "OP_<unknown>"; 275390075Sobrien } 275490075Sobrien} 275590075Sobrien 275690075Sobrien/* Return a pointer to a newly allocated location description. Location 275790075Sobrien descriptions are simple expression terms that can be strung 275890075Sobrien together to form more complicated location (address) descriptions. */ 275990075Sobrien 276090075Sobrienstatic inline dw_loc_descr_ref 2761132718Skannew_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1, 2762132718Skan unsigned HOST_WIDE_INT oprnd2) 276390075Sobrien{ 2764132718Skan dw_loc_descr_ref descr = ggc_alloc_cleared (sizeof (dw_loc_descr_node)); 276590075Sobrien 276690075Sobrien descr->dw_loc_opc = op; 276790075Sobrien descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const; 276890075Sobrien descr->dw_loc_oprnd1.v.val_unsigned = oprnd1; 276990075Sobrien descr->dw_loc_oprnd2.val_class = dw_val_class_unsigned_const; 277090075Sobrien descr->dw_loc_oprnd2.v.val_unsigned = oprnd2; 277190075Sobrien 277290075Sobrien return descr; 277390075Sobrien} 277490075Sobrien 277590075Sobrien 277690075Sobrien/* Add a location description term to a location description expression. */ 277790075Sobrien 277890075Sobrienstatic inline void 2779132718Skanadd_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr) 278090075Sobrien{ 278190075Sobrien dw_loc_descr_ref *d; 278290075Sobrien 278390075Sobrien /* Find the end of the chain. */ 278490075Sobrien for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next) 278590075Sobrien ; 278690075Sobrien 278790075Sobrien *d = descr; 278890075Sobrien} 278990075Sobrien 279090075Sobrien/* Return the size of a location descriptor. */ 279190075Sobrien 279290075Sobrienstatic unsigned long 2793132718Skansize_of_loc_descr (dw_loc_descr_ref loc) 279490075Sobrien{ 279590075Sobrien unsigned long size = 1; 279690075Sobrien 279790075Sobrien switch (loc->dw_loc_opc) 279890075Sobrien { 279990075Sobrien case DW_OP_addr: 2800117395Skan case INTERNAL_DW_OP_tls_addr: 280190075Sobrien size += DWARF2_ADDR_SIZE; 280290075Sobrien break; 280390075Sobrien case DW_OP_const1u: 280490075Sobrien case DW_OP_const1s: 280590075Sobrien size += 1; 280690075Sobrien break; 280790075Sobrien case DW_OP_const2u: 280890075Sobrien case DW_OP_const2s: 280990075Sobrien size += 2; 281090075Sobrien break; 281190075Sobrien case DW_OP_const4u: 281290075Sobrien case DW_OP_const4s: 281390075Sobrien size += 4; 281490075Sobrien break; 281590075Sobrien case DW_OP_const8u: 281690075Sobrien case DW_OP_const8s: 281790075Sobrien size += 8; 281890075Sobrien break; 281990075Sobrien case DW_OP_constu: 282090075Sobrien size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); 282190075Sobrien break; 282290075Sobrien case DW_OP_consts: 282390075Sobrien size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int); 282490075Sobrien break; 282590075Sobrien case DW_OP_pick: 282690075Sobrien size += 1; 282790075Sobrien break; 282890075Sobrien case DW_OP_plus_uconst: 282990075Sobrien size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); 283090075Sobrien break; 283190075Sobrien case DW_OP_skip: 283290075Sobrien case DW_OP_bra: 283390075Sobrien size += 2; 283490075Sobrien break; 283590075Sobrien case DW_OP_breg0: 283690075Sobrien case DW_OP_breg1: 283790075Sobrien case DW_OP_breg2: 283890075Sobrien case DW_OP_breg3: 283990075Sobrien case DW_OP_breg4: 284090075Sobrien case DW_OP_breg5: 284190075Sobrien case DW_OP_breg6: 284290075Sobrien case DW_OP_breg7: 284390075Sobrien case DW_OP_breg8: 284490075Sobrien case DW_OP_breg9: 284590075Sobrien case DW_OP_breg10: 284690075Sobrien case DW_OP_breg11: 284790075Sobrien case DW_OP_breg12: 284890075Sobrien case DW_OP_breg13: 284990075Sobrien case DW_OP_breg14: 285090075Sobrien case DW_OP_breg15: 285190075Sobrien case DW_OP_breg16: 285290075Sobrien case DW_OP_breg17: 285390075Sobrien case DW_OP_breg18: 285490075Sobrien case DW_OP_breg19: 285590075Sobrien case DW_OP_breg20: 285690075Sobrien case DW_OP_breg21: 285790075Sobrien case DW_OP_breg22: 285890075Sobrien case DW_OP_breg23: 285990075Sobrien case DW_OP_breg24: 286090075Sobrien case DW_OP_breg25: 286190075Sobrien case DW_OP_breg26: 286290075Sobrien case DW_OP_breg27: 286390075Sobrien case DW_OP_breg28: 286490075Sobrien case DW_OP_breg29: 286590075Sobrien case DW_OP_breg30: 286690075Sobrien case DW_OP_breg31: 286790075Sobrien size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int); 286890075Sobrien break; 286990075Sobrien case DW_OP_regx: 287090075Sobrien size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); 287190075Sobrien break; 287290075Sobrien case DW_OP_fbreg: 287390075Sobrien size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int); 287490075Sobrien break; 287590075Sobrien case DW_OP_bregx: 287690075Sobrien size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); 287790075Sobrien size += size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int); 287890075Sobrien break; 287990075Sobrien case DW_OP_piece: 288090075Sobrien size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); 288190075Sobrien break; 288290075Sobrien case DW_OP_deref_size: 288390075Sobrien case DW_OP_xderef_size: 288490075Sobrien size += 1; 288590075Sobrien break; 2886117395Skan case DW_OP_call2: 2887117395Skan size += 2; 2888117395Skan break; 2889117395Skan case DW_OP_call4: 2890117395Skan size += 4; 2891117395Skan break; 2892117395Skan case DW_OP_call_ref: 2893117395Skan size += DWARF2_ADDR_SIZE; 2894117395Skan break; 289590075Sobrien default: 289690075Sobrien break; 289790075Sobrien } 289890075Sobrien 289990075Sobrien return size; 290090075Sobrien} 290190075Sobrien 290290075Sobrien/* Return the size of a series of location descriptors. */ 290390075Sobrien 290490075Sobrienstatic unsigned long 2905132718Skansize_of_locs (dw_loc_descr_ref loc) 290690075Sobrien{ 290790075Sobrien unsigned long size; 290890075Sobrien 290990075Sobrien for (size = 0; loc != NULL; loc = loc->dw_loc_next) 291090075Sobrien { 291190075Sobrien loc->dw_loc_addr = size; 291290075Sobrien size += size_of_loc_descr (loc); 291390075Sobrien } 291490075Sobrien 291590075Sobrien return size; 291690075Sobrien} 291790075Sobrien 291890075Sobrien/* Output location description stack opcode's operands (if any). */ 291990075Sobrien 292090075Sobrienstatic void 2921132718Skanoutput_loc_operands (dw_loc_descr_ref loc) 292290075Sobrien{ 292390075Sobrien dw_val_ref val1 = &loc->dw_loc_oprnd1; 292490075Sobrien dw_val_ref val2 = &loc->dw_loc_oprnd2; 292590075Sobrien 292690075Sobrien switch (loc->dw_loc_opc) 292790075Sobrien { 292890075Sobrien#ifdef DWARF2_DEBUGGING_INFO 292990075Sobrien case DW_OP_addr: 293090075Sobrien dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val1->v.val_addr, NULL); 293190075Sobrien break; 293290075Sobrien case DW_OP_const2u: 293390075Sobrien case DW_OP_const2s: 293490075Sobrien dw2_asm_output_data (2, val1->v.val_int, NULL); 293590075Sobrien break; 293690075Sobrien case DW_OP_const4u: 293790075Sobrien case DW_OP_const4s: 293890075Sobrien dw2_asm_output_data (4, val1->v.val_int, NULL); 293990075Sobrien break; 294090075Sobrien case DW_OP_const8u: 294190075Sobrien case DW_OP_const8s: 294290075Sobrien if (HOST_BITS_PER_LONG < 64) 294390075Sobrien abort (); 294490075Sobrien dw2_asm_output_data (8, val1->v.val_int, NULL); 294590075Sobrien break; 294690075Sobrien case DW_OP_skip: 294790075Sobrien case DW_OP_bra: 294890075Sobrien { 294990075Sobrien int offset; 295090075Sobrien 295190075Sobrien if (val1->val_class == dw_val_class_loc) 295290075Sobrien offset = val1->v.val_loc->dw_loc_addr - (loc->dw_loc_addr + 3); 295390075Sobrien else 295490075Sobrien abort (); 295590075Sobrien 295690075Sobrien dw2_asm_output_data (2, offset, NULL); 295790075Sobrien } 295890075Sobrien break; 295990075Sobrien#else 296090075Sobrien case DW_OP_addr: 296190075Sobrien case DW_OP_const2u: 296290075Sobrien case DW_OP_const2s: 296390075Sobrien case DW_OP_const4u: 296490075Sobrien case DW_OP_const4s: 296590075Sobrien case DW_OP_const8u: 296690075Sobrien case DW_OP_const8s: 296790075Sobrien case DW_OP_skip: 296890075Sobrien case DW_OP_bra: 296990075Sobrien /* We currently don't make any attempt to make sure these are 2970132718Skan aligned properly like we do for the main unwind info, so 2971132718Skan don't support emitting things larger than a byte if we're 2972132718Skan only doing unwinding. */ 297390075Sobrien abort (); 297490075Sobrien#endif 297590075Sobrien case DW_OP_const1u: 297690075Sobrien case DW_OP_const1s: 297790075Sobrien dw2_asm_output_data (1, val1->v.val_int, NULL); 297890075Sobrien break; 297990075Sobrien case DW_OP_constu: 298090075Sobrien dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); 298190075Sobrien break; 298290075Sobrien case DW_OP_consts: 298390075Sobrien dw2_asm_output_data_sleb128 (val1->v.val_int, NULL); 298490075Sobrien break; 298590075Sobrien case DW_OP_pick: 298690075Sobrien dw2_asm_output_data (1, val1->v.val_int, NULL); 298790075Sobrien break; 298890075Sobrien case DW_OP_plus_uconst: 298990075Sobrien dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); 299090075Sobrien break; 299190075Sobrien case DW_OP_breg0: 299290075Sobrien case DW_OP_breg1: 299390075Sobrien case DW_OP_breg2: 299490075Sobrien case DW_OP_breg3: 299590075Sobrien case DW_OP_breg4: 299690075Sobrien case DW_OP_breg5: 299790075Sobrien case DW_OP_breg6: 299890075Sobrien case DW_OP_breg7: 299990075Sobrien case DW_OP_breg8: 300090075Sobrien case DW_OP_breg9: 300190075Sobrien case DW_OP_breg10: 300290075Sobrien case DW_OP_breg11: 300390075Sobrien case DW_OP_breg12: 300490075Sobrien case DW_OP_breg13: 300590075Sobrien case DW_OP_breg14: 300690075Sobrien case DW_OP_breg15: 300790075Sobrien case DW_OP_breg16: 300890075Sobrien case DW_OP_breg17: 300990075Sobrien case DW_OP_breg18: 301090075Sobrien case DW_OP_breg19: 301190075Sobrien case DW_OP_breg20: 301290075Sobrien case DW_OP_breg21: 301390075Sobrien case DW_OP_breg22: 301490075Sobrien case DW_OP_breg23: 301590075Sobrien case DW_OP_breg24: 301690075Sobrien case DW_OP_breg25: 301790075Sobrien case DW_OP_breg26: 301890075Sobrien case DW_OP_breg27: 301990075Sobrien case DW_OP_breg28: 302090075Sobrien case DW_OP_breg29: 302190075Sobrien case DW_OP_breg30: 302290075Sobrien case DW_OP_breg31: 302390075Sobrien dw2_asm_output_data_sleb128 (val1->v.val_int, NULL); 302490075Sobrien break; 302590075Sobrien case DW_OP_regx: 302690075Sobrien dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); 302790075Sobrien break; 302890075Sobrien case DW_OP_fbreg: 302990075Sobrien dw2_asm_output_data_sleb128 (val1->v.val_int, NULL); 303090075Sobrien break; 303190075Sobrien case DW_OP_bregx: 303290075Sobrien dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); 303390075Sobrien dw2_asm_output_data_sleb128 (val2->v.val_int, NULL); 303490075Sobrien break; 303590075Sobrien case DW_OP_piece: 303690075Sobrien dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); 303790075Sobrien break; 303890075Sobrien case DW_OP_deref_size: 303990075Sobrien case DW_OP_xderef_size: 304090075Sobrien dw2_asm_output_data (1, val1->v.val_int, NULL); 304190075Sobrien break; 3042117395Skan 3043117395Skan case INTERNAL_DW_OP_tls_addr: 3044117395Skan#ifdef ASM_OUTPUT_DWARF_DTPREL 3045117395Skan ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE, 3046117395Skan val1->v.val_addr); 3047117395Skan fputc ('\n', asm_out_file); 3048117395Skan#else 3049117395Skan abort (); 3050117395Skan#endif 3051117395Skan break; 3052117395Skan 305390075Sobrien default: 305490075Sobrien /* Other codes have no operands. */ 305590075Sobrien break; 305690075Sobrien } 305790075Sobrien} 305890075Sobrien 305990075Sobrien/* Output a sequence of location operations. */ 306090075Sobrien 306190075Sobrienstatic void 3062132718Skanoutput_loc_sequence (dw_loc_descr_ref loc) 306390075Sobrien{ 306490075Sobrien for (; loc != NULL; loc = loc->dw_loc_next) 306590075Sobrien { 306690075Sobrien /* Output the opcode. */ 306790075Sobrien dw2_asm_output_data (1, loc->dw_loc_opc, 306890075Sobrien "%s", dwarf_stack_op_name (loc->dw_loc_opc)); 306990075Sobrien 307090075Sobrien /* Output the operand(s) (if any). */ 307190075Sobrien output_loc_operands (loc); 307290075Sobrien } 307390075Sobrien} 307490075Sobrien 307590075Sobrien/* This routine will generate the correct assembly data for a location 307690075Sobrien description based on a cfi entry with a complex address. */ 307790075Sobrien 307890075Sobrienstatic void 3079132718Skanoutput_cfa_loc (dw_cfi_ref cfi) 308090075Sobrien{ 308190075Sobrien dw_loc_descr_ref loc; 308290075Sobrien unsigned long size; 308390075Sobrien 308490075Sobrien /* Output the size of the block. */ 308590075Sobrien loc = cfi->dw_cfi_oprnd1.dw_cfi_loc; 308690075Sobrien size = size_of_locs (loc); 308790075Sobrien dw2_asm_output_data_uleb128 (size, NULL); 308890075Sobrien 308990075Sobrien /* Now output the operations themselves. */ 309090075Sobrien output_loc_sequence (loc); 309190075Sobrien} 309290075Sobrien 309390075Sobrien/* This function builds a dwarf location descriptor sequence from 309490075Sobrien a dw_cfa_location. */ 309590075Sobrien 309690075Sobrienstatic struct dw_loc_descr_struct * 3097132718Skanbuild_cfa_loc (dw_cfa_location *cfa) 309890075Sobrien{ 309990075Sobrien struct dw_loc_descr_struct *head, *tmp; 310090075Sobrien 310190075Sobrien if (cfa->indirect == 0) 310290075Sobrien abort (); 310390075Sobrien 310490075Sobrien if (cfa->base_offset) 310590075Sobrien { 310690075Sobrien if (cfa->reg <= 31) 310790075Sobrien head = new_loc_descr (DW_OP_breg0 + cfa->reg, cfa->base_offset, 0); 310890075Sobrien else 310990075Sobrien head = new_loc_descr (DW_OP_bregx, cfa->reg, cfa->base_offset); 311090075Sobrien } 311190075Sobrien else if (cfa->reg <= 31) 311290075Sobrien head = new_loc_descr (DW_OP_reg0 + cfa->reg, 0, 0); 311390075Sobrien else 311490075Sobrien head = new_loc_descr (DW_OP_regx, cfa->reg, 0); 311590075Sobrien 311690075Sobrien head->dw_loc_oprnd1.val_class = dw_val_class_const; 311790075Sobrien tmp = new_loc_descr (DW_OP_deref, 0, 0); 311890075Sobrien add_loc_descr (&head, tmp); 311990075Sobrien if (cfa->offset != 0) 312090075Sobrien { 312190075Sobrien tmp = new_loc_descr (DW_OP_plus_uconst, cfa->offset, 0); 312290075Sobrien add_loc_descr (&head, tmp); 312390075Sobrien } 312490075Sobrien 312590075Sobrien return head; 312690075Sobrien} 312790075Sobrien 312890075Sobrien/* This function fills in aa dw_cfa_location structure from a dwarf location 312990075Sobrien descriptor sequence. */ 313090075Sobrien 313190075Sobrienstatic void 3132132718Skanget_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc) 313390075Sobrien{ 313490075Sobrien struct dw_loc_descr_struct *ptr; 313590075Sobrien cfa->offset = 0; 313690075Sobrien cfa->base_offset = 0; 313790075Sobrien cfa->indirect = 0; 313890075Sobrien cfa->reg = -1; 313990075Sobrien 314090075Sobrien for (ptr = loc; ptr != NULL; ptr = ptr->dw_loc_next) 314190075Sobrien { 314290075Sobrien enum dwarf_location_atom op = ptr->dw_loc_opc; 314390075Sobrien 314490075Sobrien switch (op) 314590075Sobrien { 314690075Sobrien case DW_OP_reg0: 314790075Sobrien case DW_OP_reg1: 314890075Sobrien case DW_OP_reg2: 314990075Sobrien case DW_OP_reg3: 315090075Sobrien case DW_OP_reg4: 315190075Sobrien case DW_OP_reg5: 315290075Sobrien case DW_OP_reg6: 315390075Sobrien case DW_OP_reg7: 315490075Sobrien case DW_OP_reg8: 315590075Sobrien case DW_OP_reg9: 315690075Sobrien case DW_OP_reg10: 315790075Sobrien case DW_OP_reg11: 315890075Sobrien case DW_OP_reg12: 315990075Sobrien case DW_OP_reg13: 316090075Sobrien case DW_OP_reg14: 316190075Sobrien case DW_OP_reg15: 316290075Sobrien case DW_OP_reg16: 316390075Sobrien case DW_OP_reg17: 316490075Sobrien case DW_OP_reg18: 316590075Sobrien case DW_OP_reg19: 316690075Sobrien case DW_OP_reg20: 316790075Sobrien case DW_OP_reg21: 316890075Sobrien case DW_OP_reg22: 316990075Sobrien case DW_OP_reg23: 317090075Sobrien case DW_OP_reg24: 317190075Sobrien case DW_OP_reg25: 317290075Sobrien case DW_OP_reg26: 317390075Sobrien case DW_OP_reg27: 317490075Sobrien case DW_OP_reg28: 317590075Sobrien case DW_OP_reg29: 317690075Sobrien case DW_OP_reg30: 317790075Sobrien case DW_OP_reg31: 317890075Sobrien cfa->reg = op - DW_OP_reg0; 317990075Sobrien break; 318090075Sobrien case DW_OP_regx: 318190075Sobrien cfa->reg = ptr->dw_loc_oprnd1.v.val_int; 318290075Sobrien break; 318390075Sobrien case DW_OP_breg0: 318490075Sobrien case DW_OP_breg1: 318590075Sobrien case DW_OP_breg2: 318690075Sobrien case DW_OP_breg3: 318790075Sobrien case DW_OP_breg4: 318890075Sobrien case DW_OP_breg5: 318990075Sobrien case DW_OP_breg6: 319090075Sobrien case DW_OP_breg7: 319190075Sobrien case DW_OP_breg8: 319290075Sobrien case DW_OP_breg9: 319390075Sobrien case DW_OP_breg10: 319490075Sobrien case DW_OP_breg11: 319590075Sobrien case DW_OP_breg12: 319690075Sobrien case DW_OP_breg13: 319790075Sobrien case DW_OP_breg14: 319890075Sobrien case DW_OP_breg15: 319990075Sobrien case DW_OP_breg16: 320090075Sobrien case DW_OP_breg17: 320190075Sobrien case DW_OP_breg18: 320290075Sobrien case DW_OP_breg19: 320390075Sobrien case DW_OP_breg20: 320490075Sobrien case DW_OP_breg21: 320590075Sobrien case DW_OP_breg22: 320690075Sobrien case DW_OP_breg23: 320790075Sobrien case DW_OP_breg24: 320890075Sobrien case DW_OP_breg25: 320990075Sobrien case DW_OP_breg26: 321090075Sobrien case DW_OP_breg27: 321190075Sobrien case DW_OP_breg28: 321290075Sobrien case DW_OP_breg29: 321390075Sobrien case DW_OP_breg30: 321490075Sobrien case DW_OP_breg31: 321590075Sobrien cfa->reg = op - DW_OP_breg0; 321690075Sobrien cfa->base_offset = ptr->dw_loc_oprnd1.v.val_int; 321790075Sobrien break; 321890075Sobrien case DW_OP_bregx: 321990075Sobrien cfa->reg = ptr->dw_loc_oprnd1.v.val_int; 322090075Sobrien cfa->base_offset = ptr->dw_loc_oprnd2.v.val_int; 322190075Sobrien break; 322290075Sobrien case DW_OP_deref: 322390075Sobrien cfa->indirect = 1; 322490075Sobrien break; 322590075Sobrien case DW_OP_plus_uconst: 322690075Sobrien cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned; 322790075Sobrien break; 322890075Sobrien default: 322990075Sobrien internal_error ("DW_LOC_OP %s not implemented\n", 323090075Sobrien dwarf_stack_op_name (ptr->dw_loc_opc)); 323190075Sobrien } 323290075Sobrien } 323390075Sobrien} 323490075Sobrien#endif /* .debug_frame support */ 323590075Sobrien 323690075Sobrien/* And now, the support for symbolic debugging information. */ 323790075Sobrien#ifdef DWARF2_DEBUGGING_INFO 323890075Sobrien 323990075Sobrien/* .debug_str support. */ 3240132718Skanstatic int output_indirect_string (void **, void *); 324190075Sobrien 3242132718Skanstatic void dwarf2out_init (const char *); 3243132718Skanstatic void dwarf2out_finish (const char *); 3244132718Skanstatic void dwarf2out_define (unsigned int, const char *); 3245132718Skanstatic void dwarf2out_undef (unsigned int, const char *); 3246132718Skanstatic void dwarf2out_start_source_file (unsigned, const char *); 3247132718Skanstatic void dwarf2out_end_source_file (unsigned); 3248132718Skanstatic void dwarf2out_begin_block (unsigned, unsigned); 3249132718Skanstatic void dwarf2out_end_block (unsigned, unsigned); 3250132718Skanstatic bool dwarf2out_ignore_block (tree); 3251132718Skanstatic void dwarf2out_global_decl (tree); 3252132718Skanstatic void dwarf2out_abstract_function (tree); 325390075Sobrien 325490075Sobrien/* The debug hooks structure. */ 325590075Sobrien 3256117395Skanconst struct gcc_debug_hooks dwarf2_debug_hooks = 325790075Sobrien{ 325890075Sobrien dwarf2out_init, 325990075Sobrien dwarf2out_finish, 326090075Sobrien dwarf2out_define, 326190075Sobrien dwarf2out_undef, 326290075Sobrien dwarf2out_start_source_file, 326390075Sobrien dwarf2out_end_source_file, 326490075Sobrien dwarf2out_begin_block, 326590075Sobrien dwarf2out_end_block, 326690075Sobrien dwarf2out_ignore_block, 326790075Sobrien dwarf2out_source_line, 326890075Sobrien dwarf2out_begin_prologue, 3269117395Skan debug_nothing_int_charstar, /* end_prologue */ 327090075Sobrien dwarf2out_end_epilogue, 327190075Sobrien debug_nothing_tree, /* begin_function */ 327290075Sobrien debug_nothing_int, /* end_function */ 327390075Sobrien dwarf2out_decl, /* function_decl */ 327490075Sobrien dwarf2out_global_decl, 327590075Sobrien debug_nothing_tree, /* deferred_inline_function */ 327690075Sobrien /* The DWARF 2 backend tries to reduce debugging bloat by not 327790075Sobrien emitting the abstract description of inline functions until 327890075Sobrien something tries to reference them. */ 327990075Sobrien dwarf2out_abstract_function, /* outlining_inline_function */ 3280132718Skan debug_nothing_rtx, /* label */ 3281132718Skan debug_nothing_int /* handle_pch */ 328290075Sobrien}; 3283132718Skan#endif 328490075Sobrien 328590075Sobrien/* NOTE: In the comments in this file, many references are made to 328690075Sobrien "Debugging Information Entries". This term is abbreviated as `DIE' 328790075Sobrien throughout the remainder of this file. */ 328890075Sobrien 328990075Sobrien/* An internal representation of the DWARF output is built, and then 329090075Sobrien walked to generate the DWARF debugging info. The walk of the internal 329190075Sobrien representation is done after the entire program has been compiled. 329290075Sobrien The types below are used to describe the internal representation. */ 329390075Sobrien 329490075Sobrien/* Various DIE's use offsets relative to the beginning of the 329590075Sobrien .debug_info section to refer to each other. */ 329690075Sobrien 329790075Sobrientypedef long int dw_offset; 329890075Sobrien 329990075Sobrien/* Define typedefs here to avoid circular dependencies. */ 330090075Sobrien 330190075Sobrientypedef struct dw_attr_struct *dw_attr_ref; 330290075Sobrientypedef struct dw_line_info_struct *dw_line_info_ref; 330390075Sobrientypedef struct dw_separate_line_info_struct *dw_separate_line_info_ref; 330490075Sobrientypedef struct pubname_struct *pubname_ref; 330590075Sobrientypedef struct dw_ranges_struct *dw_ranges_ref; 330690075Sobrien 330790075Sobrien/* Each entry in the line_info_table maintains the file and 330890075Sobrien line number associated with the label generated for that 330990075Sobrien entry. The label gives the PC value associated with 331090075Sobrien the line number entry. */ 331190075Sobrien 3312132718Skantypedef struct dw_line_info_struct GTY(()) 331390075Sobrien{ 331490075Sobrien unsigned long dw_file_num; 331590075Sobrien unsigned long dw_line_num; 331690075Sobrien} 331790075Sobriendw_line_info_entry; 331890075Sobrien 331990075Sobrien/* Line information for functions in separate sections; each one gets its 332090075Sobrien own sequence. */ 3321132718Skantypedef struct dw_separate_line_info_struct GTY(()) 332290075Sobrien{ 332390075Sobrien unsigned long dw_file_num; 332490075Sobrien unsigned long dw_line_num; 332590075Sobrien unsigned long function; 332690075Sobrien} 332790075Sobriendw_separate_line_info_entry; 332890075Sobrien 332950397Sobrien/* Each DIE attribute has a field specifying the attribute kind, 333050397Sobrien a link to the next attribute in the chain, and an attribute value. 333150397Sobrien Attributes are typically linked below the DIE they modify. */ 333250397Sobrien 3333132718Skantypedef struct dw_attr_struct GTY(()) 333450397Sobrien{ 333550397Sobrien enum dwarf_attribute dw_attr; 333650397Sobrien dw_attr_ref dw_attr_next; 333750397Sobrien dw_val_node dw_attr_val; 333850397Sobrien} 333950397Sobriendw_attr_node; 334050397Sobrien 334150397Sobrien/* The Debugging Information Entry (DIE) structure */ 334250397Sobrien 3343132718Skantypedef struct die_struct GTY(()) 334450397Sobrien{ 334550397Sobrien enum dwarf_tag die_tag; 334690075Sobrien char *die_symbol; 334750397Sobrien dw_attr_ref die_attr; 334850397Sobrien dw_die_ref die_parent; 334950397Sobrien dw_die_ref die_child; 335050397Sobrien dw_die_ref die_sib; 3351132718Skan dw_die_ref die_definition; /* ref from a specification to its definition */ 335250397Sobrien dw_offset die_offset; 335350397Sobrien unsigned long die_abbrev; 335490075Sobrien int die_mark; 335550397Sobrien} 335650397Sobriendie_node; 335750397Sobrien 335850397Sobrien/* The pubname structure */ 335950397Sobrien 3360132718Skantypedef struct pubname_struct GTY(()) 336150397Sobrien{ 336250397Sobrien dw_die_ref die; 336390075Sobrien char *name; 336450397Sobrien} 336550397Sobrienpubname_entry; 336650397Sobrien 3367132718Skanstruct dw_ranges_struct GTY(()) 336890075Sobrien{ 336990075Sobrien int block_num; 337090075Sobrien}; 337190075Sobrien 337250397Sobrien/* The limbo die list structure. */ 3373132718Skantypedef struct limbo_die_struct GTY(()) 337450397Sobrien{ 337550397Sobrien dw_die_ref die; 337690075Sobrien tree created_for; 337750397Sobrien struct limbo_die_struct *next; 337850397Sobrien} 337950397Sobrienlimbo_die_node; 338050397Sobrien 338150397Sobrien/* How to start an assembler comment. */ 338250397Sobrien#ifndef ASM_COMMENT_START 338350397Sobrien#define ASM_COMMENT_START ";#" 338450397Sobrien#endif 338550397Sobrien 3386117395Skan/* Define a macro which returns nonzero for a TYPE_DECL which was 338750397Sobrien implicitly generated for a tagged type. 338850397Sobrien 338950397Sobrien Note that unlike the gcc front end (which generates a NULL named 339050397Sobrien TYPE_DECL node for each complete tagged type, each array type, and 339150397Sobrien each function type node created) the g++ front end generates a 339250397Sobrien _named_ TYPE_DECL node for each tagged type node created. 339350397Sobrien These TYPE_DECLs have DECL_ARTIFICIAL set, so we know not to 339450397Sobrien generate a DW_TAG_typedef DIE for them. */ 339550397Sobrien 339650397Sobrien#define TYPE_DECL_IS_STUB(decl) \ 339750397Sobrien (DECL_NAME (decl) == NULL_TREE \ 339850397Sobrien || (DECL_ARTIFICIAL (decl) \ 339950397Sobrien && is_tagged_type (TREE_TYPE (decl)) \ 340050397Sobrien && ((decl == TYPE_STUB_DECL (TREE_TYPE (decl))) \ 340150397Sobrien /* This is necessary for stub decls that \ 340250397Sobrien appear in nested inline functions. */ \ 340350397Sobrien || (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE \ 340450397Sobrien && (decl_ultimate_origin (decl) \ 340550397Sobrien == TYPE_STUB_DECL (TREE_TYPE (decl))))))) 340650397Sobrien 340750397Sobrien/* Information concerning the compilation unit's programming 340850397Sobrien language, and compiler version. */ 340950397Sobrien 341050397Sobrien/* Fixed size portion of the DWARF compilation unit header. */ 3411132718Skan#define DWARF_COMPILE_UNIT_HEADER_SIZE \ 3412132718Skan (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 3) 341350397Sobrien 341450397Sobrien/* Fixed size portion of public names info. */ 341550397Sobrien#define DWARF_PUBNAMES_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 2) 341650397Sobrien 341750397Sobrien/* Fixed size portion of the address range info. */ 341890075Sobrien#define DWARF_ARANGES_HEADER_SIZE \ 3419132718Skan (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \ 3420132718Skan DWARF2_ADDR_SIZE * 2) \ 3421132718Skan - DWARF_INITIAL_LENGTH_SIZE) 342250397Sobrien 342390075Sobrien/* Size of padding portion in the address range info. It must be 342490075Sobrien aligned to twice the pointer size. */ 342590075Sobrien#define DWARF_ARANGES_PAD_SIZE \ 3426132718Skan (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \ 3427132718Skan DWARF2_ADDR_SIZE * 2) \ 3428132718Skan - (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4)) 342990075Sobrien 343090075Sobrien/* Use assembler line directives if available. */ 343190075Sobrien#ifndef DWARF2_ASM_LINE_DEBUG_INFO 343290075Sobrien#ifdef HAVE_AS_DWARF2_DEBUG_LINE 343390075Sobrien#define DWARF2_ASM_LINE_DEBUG_INFO 1 343490075Sobrien#else 343590075Sobrien#define DWARF2_ASM_LINE_DEBUG_INFO 0 343690075Sobrien#endif 343790075Sobrien#endif 343890075Sobrien 343950397Sobrien/* Minimum line offset in a special line info. opcode. 344050397Sobrien This value was chosen to give a reasonable range of values. */ 344150397Sobrien#define DWARF_LINE_BASE -10 344250397Sobrien 344390075Sobrien/* First special line opcode - leave room for the standard opcodes. */ 344450397Sobrien#define DWARF_LINE_OPCODE_BASE 10 344550397Sobrien 344650397Sobrien/* Range of line offsets in a special line info. opcode. */ 344750397Sobrien#define DWARF_LINE_RANGE (254-DWARF_LINE_OPCODE_BASE+1) 344850397Sobrien 344950397Sobrien/* Flag that indicates the initial value of the is_stmt_start flag. 345050397Sobrien In the present implementation, we do not mark any lines as 345150397Sobrien the beginning of a source statement, because that information 345250397Sobrien is not made available by the GCC front-end. */ 345350397Sobrien#define DWARF_LINE_DEFAULT_IS_STMT_START 1 345450397Sobrien 3455132718Skan#ifdef DWARF2_DEBUGGING_INFO 345650397Sobrien/* This location is used by calc_die_sizes() to keep track 345750397Sobrien the offset of each DIE within the .debug_info section. */ 345850397Sobrienstatic unsigned long next_die_offset; 3459132718Skan#endif 346050397Sobrien 346150397Sobrien/* Record the root of the DIE's built for the current compilation unit. */ 3462132718Skanstatic GTY(()) dw_die_ref comp_unit_die; 346350397Sobrien 346450397Sobrien/* A list of DIEs with a NULL parent waiting to be relocated. */ 3465132718Skanstatic GTY(()) limbo_die_node *limbo_die_list; 346650397Sobrien 346790075Sobrien/* Filenames referenced by this compilation unit. */ 3468132718Skanstatic GTY(()) varray_type file_table; 3469132718Skanstatic GTY(()) varray_type file_table_emitted; 3470132718Skanstatic GTY(()) size_t file_table_last_lookup_index; 347190075Sobrien 347250397Sobrien/* A pointer to the base of a table of references to DIE's that describe 347350397Sobrien declarations. The table is indexed by DECL_UID() which is a unique 347450397Sobrien number identifying each decl. */ 3475132718Skanstatic GTY((length ("decl_die_table_allocated"))) dw_die_ref *decl_die_table; 347650397Sobrien 347750397Sobrien/* Number of elements currently allocated for the decl_die_table. */ 3478132718Skanstatic GTY(()) unsigned decl_die_table_allocated; 347950397Sobrien 348050397Sobrien/* Number of elements in decl_die_table currently in use. */ 3481132718Skanstatic GTY(()) unsigned decl_die_table_in_use; 348250397Sobrien 348350397Sobrien/* Size (in elements) of increments by which we may expand the 348450397Sobrien decl_die_table. */ 348550397Sobrien#define DECL_DIE_TABLE_INCREMENT 256 348650397Sobrien 348750397Sobrien/* A pointer to the base of a list of references to DIE's that 348850397Sobrien are uniquely identified by their tag, presence/absence of 348950397Sobrien children DIE's, and list of attribute/value pairs. */ 3490132718Skanstatic GTY((length ("abbrev_die_table_allocated"))) 3491132718Skan dw_die_ref *abbrev_die_table; 349250397Sobrien 349350397Sobrien/* Number of elements currently allocated for abbrev_die_table. */ 3494132718Skanstatic GTY(()) unsigned abbrev_die_table_allocated; 349550397Sobrien 349650397Sobrien/* Number of elements in type_die_table currently in use. */ 3497132718Skanstatic GTY(()) unsigned abbrev_die_table_in_use; 349850397Sobrien 349950397Sobrien/* Size (in elements) of increments by which we may expand the 350050397Sobrien abbrev_die_table. */ 350150397Sobrien#define ABBREV_DIE_TABLE_INCREMENT 256 350250397Sobrien 350350397Sobrien/* A pointer to the base of a table that contains line information 350450397Sobrien for each source code line in .text in the compilation unit. */ 3505132718Skanstatic GTY((length ("line_info_table_allocated"))) 3506132718Skan dw_line_info_ref line_info_table; 350750397Sobrien 350850397Sobrien/* Number of elements currently allocated for line_info_table. */ 3509132718Skanstatic GTY(()) unsigned line_info_table_allocated; 351050397Sobrien 3511132718Skan/* Number of elements in line_info_table currently in use. */ 3512132718Skanstatic GTY(()) unsigned line_info_table_in_use; 351350397Sobrien 351450397Sobrien/* A pointer to the base of a table that contains line information 351550397Sobrien for each source code line outside of .text in the compilation unit. */ 3516132718Skanstatic GTY ((length ("separate_line_info_table_allocated"))) 3517132718Skan dw_separate_line_info_ref separate_line_info_table; 351850397Sobrien 351950397Sobrien/* Number of elements currently allocated for separate_line_info_table. */ 3520132718Skanstatic GTY(()) unsigned separate_line_info_table_allocated; 352150397Sobrien 3522132718Skan/* Number of elements in separate_line_info_table currently in use. */ 3523132718Skanstatic GTY(()) unsigned separate_line_info_table_in_use; 352450397Sobrien 352550397Sobrien/* Size (in elements) of increments by which we may expand the 352650397Sobrien line_info_table. */ 352750397Sobrien#define LINE_INFO_TABLE_INCREMENT 1024 352850397Sobrien 352950397Sobrien/* A pointer to the base of a table that contains a list of publicly 353050397Sobrien accessible names. */ 3531132718Skanstatic GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table; 353250397Sobrien 353350397Sobrien/* Number of elements currently allocated for pubname_table. */ 3534132718Skanstatic GTY(()) unsigned pubname_table_allocated; 353550397Sobrien 353650397Sobrien/* Number of elements in pubname_table currently in use. */ 3537132718Skanstatic GTY(()) unsigned pubname_table_in_use; 353850397Sobrien 353950397Sobrien/* Size (in elements) of increments by which we may expand the 354050397Sobrien pubname_table. */ 354150397Sobrien#define PUBNAME_TABLE_INCREMENT 64 354250397Sobrien 354390075Sobrien/* Array of dies for which we should generate .debug_arange info. */ 3544132718Skanstatic GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table; 354550397Sobrien 354650397Sobrien/* Number of elements currently allocated for arange_table. */ 3547132718Skanstatic GTY(()) unsigned arange_table_allocated; 354850397Sobrien 354950397Sobrien/* Number of elements in arange_table currently in use. */ 3550132718Skanstatic GTY(()) unsigned arange_table_in_use; 355150397Sobrien 355250397Sobrien/* Size (in elements) of increments by which we may expand the 355350397Sobrien arange_table. */ 355450397Sobrien#define ARANGE_TABLE_INCREMENT 64 355550397Sobrien 355690075Sobrien/* Array of dies for which we should generate .debug_ranges info. */ 3557132718Skanstatic GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table; 355850397Sobrien 355990075Sobrien/* Number of elements currently allocated for ranges_table. */ 3560132718Skanstatic GTY(()) unsigned ranges_table_allocated; 356150397Sobrien 356290075Sobrien/* Number of elements in ranges_table currently in use. */ 3563132718Skanstatic GTY(()) unsigned ranges_table_in_use; 356450397Sobrien 356590075Sobrien/* Size (in elements) of increments by which we may expand the 356690075Sobrien ranges_table. */ 356790075Sobrien#define RANGES_TABLE_INCREMENT 64 356850397Sobrien 356990075Sobrien/* Whether we have location lists that need outputting */ 3570132718Skanstatic GTY(()) unsigned have_location_lists; 357150397Sobrien 3572132718Skan#ifdef DWARF2_DEBUGGING_INFO 357350397Sobrien/* Record whether the function being analyzed contains inlined functions. */ 357450397Sobrienstatic int current_function_has_inlines; 3575132718Skan#endif 357650397Sobrien#if 0 && defined (MIPS_DEBUGGING_INFO) 357750397Sobrienstatic int comp_unit_has_inlines; 357850397Sobrien#endif 357950397Sobrien 3580132718Skan/* Number of file tables emitted in maybe_emit_file(). */ 3581132718Skanstatic GTY(()) int emitcount = 0; 3582132718Skan 3583132718Skan/* Number of internal labels generated by gen_internal_sym(). */ 3584132718Skanstatic GTY(()) int label_num; 3585132718Skan 3586132718Skan#ifdef DWARF2_DEBUGGING_INFO 3587132718Skan 358850397Sobrien/* Forward declarations for functions defined in this file. */ 358950397Sobrien 3590132718Skanstatic int is_pseudo_reg (rtx); 3591132718Skanstatic tree type_main_variant (tree); 3592132718Skanstatic int is_tagged_type (tree); 3593132718Skanstatic const char *dwarf_tag_name (unsigned); 3594132718Skanstatic const char *dwarf_attr_name (unsigned); 3595132718Skanstatic const char *dwarf_form_name (unsigned); 359650397Sobrien#if 0 3597132718Skanstatic const char *dwarf_type_encoding_name (unsigned); 359850397Sobrien#endif 3599132718Skanstatic tree decl_ultimate_origin (tree); 3600132718Skanstatic tree block_ultimate_origin (tree); 3601132718Skanstatic tree decl_class_context (tree); 3602132718Skanstatic void add_dwarf_attr (dw_die_ref, dw_attr_ref); 3603132718Skanstatic inline enum dw_val_class AT_class (dw_attr_ref); 3604132718Skanstatic void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned); 3605132718Skanstatic inline unsigned AT_flag (dw_attr_ref); 3606132718Skanstatic void add_AT_int (dw_die_ref, enum dwarf_attribute, HOST_WIDE_INT); 3607132718Skanstatic inline HOST_WIDE_INT AT_int (dw_attr_ref); 3608132718Skanstatic void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT); 3609132718Skanstatic inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref); 3610132718Skanstatic void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long, 3611132718Skan unsigned long); 3612132718Skanstatic inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int, 3613132718Skan unsigned int, unsigned char *); 3614132718Skanstatic hashval_t debug_str_do_hash (const void *); 3615132718Skanstatic int debug_str_eq (const void *, const void *); 3616132718Skanstatic void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *); 3617132718Skanstatic inline const char *AT_string (dw_attr_ref); 3618132718Skanstatic int AT_string_form (dw_attr_ref); 3619132718Skanstatic void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref); 3620132718Skanstatic void add_AT_specification (dw_die_ref, dw_die_ref); 3621132718Skanstatic inline dw_die_ref AT_ref (dw_attr_ref); 3622132718Skanstatic inline int AT_ref_external (dw_attr_ref); 3623132718Skanstatic inline void set_AT_ref_external (dw_attr_ref, int); 3624132718Skanstatic void add_AT_fde_ref (dw_die_ref, enum dwarf_attribute, unsigned); 3625132718Skanstatic void add_AT_loc (dw_die_ref, enum dwarf_attribute, dw_loc_descr_ref); 3626132718Skanstatic inline dw_loc_descr_ref AT_loc (dw_attr_ref); 3627132718Skanstatic void add_AT_loc_list (dw_die_ref, enum dwarf_attribute, 3628132718Skan dw_loc_list_ref); 3629132718Skanstatic inline dw_loc_list_ref AT_loc_list (dw_attr_ref); 3630132718Skanstatic void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx); 3631132718Skanstatic inline rtx AT_addr (dw_attr_ref); 3632132718Skanstatic void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); 3633132718Skanstatic void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *); 3634132718Skanstatic void add_AT_offset (dw_die_ref, enum dwarf_attribute, 3635132718Skan unsigned HOST_WIDE_INT); 3636132718Skanstatic void add_AT_range_list (dw_die_ref, enum dwarf_attribute, 3637132718Skan unsigned long); 3638132718Skanstatic inline const char *AT_lbl (dw_attr_ref); 3639132718Skanstatic dw_attr_ref get_AT (dw_die_ref, enum dwarf_attribute); 3640132718Skanstatic const char *get_AT_low_pc (dw_die_ref); 3641132718Skanstatic const char *get_AT_hi_pc (dw_die_ref); 3642132718Skanstatic const char *get_AT_string (dw_die_ref, enum dwarf_attribute); 3643132718Skanstatic int get_AT_flag (dw_die_ref, enum dwarf_attribute); 3644132718Skanstatic unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute); 3645132718Skanstatic inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute); 3646132718Skanstatic bool is_c_family (void); 3647132718Skanstatic bool is_cxx (void); 3648132718Skanstatic bool is_java (void); 3649132718Skanstatic bool is_fortran (void); 3650132718Skanstatic bool is_ada (void); 3651132718Skanstatic void remove_AT (dw_die_ref, enum dwarf_attribute); 3652146895Skanstatic void remove_child_TAG (dw_die_ref, enum dwarf_tag); 3653132718Skanstatic inline void free_die (dw_die_ref); 3654132718Skanstatic void remove_children (dw_die_ref); 3655132718Skanstatic void add_child_die (dw_die_ref, dw_die_ref); 3656132718Skanstatic dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree); 3657132718Skanstatic dw_die_ref lookup_type_die (tree); 3658132718Skanstatic void equate_type_number_to_die (tree, dw_die_ref); 3659132718Skanstatic dw_die_ref lookup_decl_die (tree); 3660132718Skanstatic void equate_decl_number_to_die (tree, dw_die_ref); 3661132718Skanstatic void print_spaces (FILE *); 3662132718Skanstatic void print_die (dw_die_ref, FILE *); 3663132718Skanstatic void print_dwarf_line_table (FILE *); 3664132718Skanstatic void reverse_die_lists (dw_die_ref); 3665132718Skanstatic void reverse_all_dies (dw_die_ref); 3666132718Skanstatic dw_die_ref push_new_compile_unit (dw_die_ref, dw_die_ref); 3667132718Skanstatic dw_die_ref pop_compile_unit (dw_die_ref); 3668132718Skanstatic void loc_checksum (dw_loc_descr_ref, struct md5_ctx *); 3669132718Skanstatic void attr_checksum (dw_attr_ref, struct md5_ctx *, int *); 3670132718Skanstatic void die_checksum (dw_die_ref, struct md5_ctx *, int *); 3671132718Skanstatic int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *); 3672132718Skanstatic int same_dw_val_p (dw_val_node *, dw_val_node *, int *); 3673132718Skanstatic int same_attr_p (dw_attr_ref, dw_attr_ref, int *); 3674132718Skanstatic int same_die_p (dw_die_ref, dw_die_ref, int *); 3675132718Skanstatic int same_die_p_wrap (dw_die_ref, dw_die_ref); 3676132718Skanstatic void compute_section_prefix (dw_die_ref); 3677132718Skanstatic int is_type_die (dw_die_ref); 3678132718Skanstatic int is_comdat_die (dw_die_ref); 3679132718Skanstatic int is_symbol_die (dw_die_ref); 3680132718Skanstatic void assign_symbol_names (dw_die_ref); 3681132718Skanstatic void break_out_includes (dw_die_ref); 3682132718Skanstatic hashval_t htab_cu_hash (const void *); 3683132718Skanstatic int htab_cu_eq (const void *, const void *); 3684132718Skanstatic void htab_cu_del (void *); 3685132718Skanstatic int check_duplicate_cu (dw_die_ref, htab_t, unsigned *); 3686132718Skanstatic void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned); 3687132718Skanstatic void add_sibling_attributes (dw_die_ref); 3688132718Skanstatic void build_abbrev_table (dw_die_ref); 3689132718Skanstatic void output_location_lists (dw_die_ref); 3690132718Skanstatic int constant_size (long unsigned); 3691132718Skanstatic unsigned long size_of_die (dw_die_ref); 3692132718Skanstatic void calc_die_sizes (dw_die_ref); 3693132718Skanstatic void mark_dies (dw_die_ref); 3694132718Skanstatic void unmark_dies (dw_die_ref); 3695132718Skanstatic void unmark_all_dies (dw_die_ref); 3696132718Skanstatic unsigned long size_of_pubnames (void); 3697132718Skanstatic unsigned long size_of_aranges (void); 3698132718Skanstatic enum dwarf_form value_format (dw_attr_ref); 3699132718Skanstatic void output_value_format (dw_attr_ref); 3700132718Skanstatic void output_abbrev_section (void); 3701132718Skanstatic void output_die_symbol (dw_die_ref); 3702132718Skanstatic void output_die (dw_die_ref); 3703132718Skanstatic void output_compilation_unit_header (void); 3704132718Skanstatic void output_comp_unit (dw_die_ref, int); 3705132718Skanstatic const char *dwarf2_name (tree, int); 3706132718Skanstatic void add_pubname (tree, dw_die_ref); 3707132718Skanstatic void output_pubnames (void); 3708132718Skanstatic void add_arange (tree, dw_die_ref); 3709132718Skanstatic void output_aranges (void); 3710132718Skanstatic unsigned int add_ranges (tree); 3711132718Skanstatic void output_ranges (void); 3712132718Skanstatic void output_line_info (void); 3713132718Skanstatic void output_file_names (void); 3714132718Skanstatic dw_die_ref base_type_die (tree); 3715132718Skanstatic tree root_type (tree); 3716132718Skanstatic int is_base_type (tree); 3717132718Skanstatic bool is_subrange_type (tree); 3718132718Skanstatic dw_die_ref subrange_type_die (tree, dw_die_ref); 3719132718Skanstatic dw_die_ref modified_type_die (tree, int, int, dw_die_ref); 3720132718Skanstatic int type_is_enum (tree); 3721132718Skanstatic unsigned int dbx_reg_number (rtx); 3722132718Skanstatic dw_loc_descr_ref reg_loc_descriptor (rtx); 3723132718Skanstatic dw_loc_descr_ref one_reg_loc_descriptor (unsigned int); 3724132718Skanstatic dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx); 3725132718Skanstatic dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT); 3726132718Skanstatic dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT); 3727132718Skanstatic int is_based_loc (rtx); 3728132718Skanstatic dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode); 3729132718Skanstatic dw_loc_descr_ref concat_loc_descriptor (rtx, rtx); 3730132718Skanstatic dw_loc_descr_ref loc_descriptor (rtx); 3731132718Skanstatic dw_loc_descr_ref loc_descriptor_from_tree (tree, int); 3732132718Skanstatic HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int); 3733132718Skanstatic tree field_type (tree); 3734132718Skanstatic unsigned int simple_type_align_in_bits (tree); 3735132718Skanstatic unsigned int simple_decl_align_in_bits (tree); 3736132718Skanstatic unsigned HOST_WIDE_INT simple_type_size_in_bits (tree); 3737132718Skanstatic HOST_WIDE_INT field_byte_offset (tree); 3738132718Skanstatic void add_AT_location_description (dw_die_ref, enum dwarf_attribute, 3739132718Skan dw_loc_descr_ref); 3740132718Skanstatic void add_data_member_location_attribute (dw_die_ref, tree); 3741132718Skanstatic void add_const_value_attribute (dw_die_ref, rtx); 3742132718Skanstatic void insert_int (HOST_WIDE_INT, unsigned, unsigned char *); 3743132718Skanstatic HOST_WIDE_INT extract_int (const unsigned char *, unsigned); 3744132718Skanstatic void insert_float (rtx, unsigned char *); 3745132718Skanstatic rtx rtl_for_decl_location (tree); 3746132718Skanstatic void add_location_or_const_value_attribute (dw_die_ref, tree); 3747132718Skanstatic void tree_add_const_value_attribute (dw_die_ref, tree); 3748132718Skanstatic void add_name_attribute (dw_die_ref, const char *); 3749132718Skanstatic void add_comp_dir_attribute (dw_die_ref); 3750132718Skanstatic void add_bound_info (dw_die_ref, enum dwarf_attribute, tree); 3751132718Skanstatic void add_subscript_info (dw_die_ref, tree); 3752132718Skanstatic void add_byte_size_attribute (dw_die_ref, tree); 3753132718Skanstatic void add_bit_offset_attribute (dw_die_ref, tree); 3754132718Skanstatic void add_bit_size_attribute (dw_die_ref, tree); 3755132718Skanstatic void add_prototyped_attribute (dw_die_ref, tree); 3756132718Skanstatic void add_abstract_origin_attribute (dw_die_ref, tree); 3757132718Skanstatic void add_pure_or_virtual_attribute (dw_die_ref, tree); 3758132718Skanstatic void add_src_coords_attributes (dw_die_ref, tree); 3759132718Skanstatic void add_name_and_src_coords_attributes (dw_die_ref, tree); 3760132718Skanstatic void push_decl_scope (tree); 3761132718Skanstatic void pop_decl_scope (void); 3762132718Skanstatic dw_die_ref scope_die_for (tree, dw_die_ref); 3763132718Skanstatic inline int local_scope_p (dw_die_ref); 3764132718Skanstatic inline int class_or_namespace_scope_p (dw_die_ref); 3765132718Skanstatic void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref); 3766132718Skanstatic const char *type_tag (tree); 3767132718Skanstatic tree member_declared_type (tree); 376850397Sobrien#if 0 3769132718Skanstatic const char *decl_start_label (tree); 377050397Sobrien#endif 3771132718Skanstatic void gen_array_type_die (tree, dw_die_ref); 3772132718Skanstatic void gen_set_type_die (tree, dw_die_ref); 377350397Sobrien#if 0 3774132718Skanstatic void gen_entry_point_die (tree, dw_die_ref); 377550397Sobrien#endif 3776132718Skanstatic void gen_inlined_enumeration_type_die (tree, dw_die_ref); 3777132718Skanstatic void gen_inlined_structure_type_die (tree, dw_die_ref); 3778132718Skanstatic void gen_inlined_union_type_die (tree, dw_die_ref); 3779132718Skanstatic dw_die_ref gen_enumeration_type_die (tree, dw_die_ref); 3780132718Skanstatic dw_die_ref gen_formal_parameter_die (tree, dw_die_ref); 3781132718Skanstatic void gen_unspecified_parameters_die (tree, dw_die_ref); 3782132718Skanstatic void gen_formal_types_die (tree, dw_die_ref); 3783132718Skanstatic void gen_subprogram_die (tree, dw_die_ref); 3784132718Skanstatic void gen_variable_die (tree, dw_die_ref); 3785132718Skanstatic void gen_label_die (tree, dw_die_ref); 3786132718Skanstatic void gen_lexical_block_die (tree, dw_die_ref, int); 3787132718Skanstatic void gen_inlined_subroutine_die (tree, dw_die_ref, int); 3788132718Skanstatic void gen_field_die (tree, dw_die_ref); 3789132718Skanstatic void gen_ptr_to_mbr_type_die (tree, dw_die_ref); 3790132718Skanstatic dw_die_ref gen_compile_unit_die (const char *); 3791132718Skanstatic void gen_string_type_die (tree, dw_die_ref); 3792132718Skanstatic void gen_inheritance_die (tree, tree, dw_die_ref); 3793132718Skanstatic void gen_member_die (tree, dw_die_ref); 3794132718Skanstatic void gen_struct_or_union_type_die (tree, dw_die_ref); 3795132718Skanstatic void gen_subroutine_type_die (tree, dw_die_ref); 3796132718Skanstatic void gen_typedef_die (tree, dw_die_ref); 3797132718Skanstatic void gen_type_die (tree, dw_die_ref); 3798132718Skanstatic void gen_tagged_type_instantiation_die (tree, dw_die_ref); 3799132718Skanstatic void gen_block_die (tree, dw_die_ref, int); 3800132718Skanstatic void decls_for_scope (tree, dw_die_ref, int); 3801132718Skanstatic int is_redundant_typedef (tree); 3802132718Skanstatic void gen_namespace_die (tree); 3803132718Skanstatic void gen_decl_die (tree, dw_die_ref); 3804132718Skanstatic dw_die_ref force_namespace_die (tree); 3805132718Skanstatic dw_die_ref setup_namespace_context (tree, dw_die_ref); 3806132718Skanstatic void declare_in_namespace (tree, dw_die_ref); 3807132718Skanstatic unsigned lookup_filename (const char *); 3808132718Skanstatic void init_file_table (void); 3809132718Skanstatic void retry_incomplete_types (void); 3810132718Skanstatic void gen_type_die_for_member (tree, tree, dw_die_ref); 3811132718Skanstatic void splice_child_die (dw_die_ref, dw_die_ref); 3812132718Skanstatic int file_info_cmp (const void *, const void *); 3813132718Skanstatic dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, 3814132718Skan const char *, const char *, unsigned); 3815132718Skanstatic void add_loc_descr_to_loc_list (dw_loc_list_ref *, dw_loc_descr_ref, 3816132718Skan const char *, const char *, 3817132718Skan const char *); 3818132718Skanstatic void output_loc_list (dw_loc_list_ref); 3819132718Skanstatic char *gen_internal_sym (const char *); 382050397Sobrien 3821132718Skanstatic void prune_unmark_dies (dw_die_ref); 3822132718Skanstatic void prune_unused_types_mark (dw_die_ref, int); 3823132718Skanstatic void prune_unused_types_walk (dw_die_ref); 3824132718Skanstatic void prune_unused_types_walk_attribs (dw_die_ref); 3825132718Skanstatic void prune_unused_types_prune (dw_die_ref); 3826132718Skanstatic void prune_unused_types (void); 3827132718Skanstatic int maybe_emit_file (int); 3828132718Skan 382950397Sobrien/* Section names used to hold DWARF debugging information. */ 383050397Sobrien#ifndef DEBUG_INFO_SECTION 383150397Sobrien#define DEBUG_INFO_SECTION ".debug_info" 383250397Sobrien#endif 383390075Sobrien#ifndef DEBUG_ABBREV_SECTION 383490075Sobrien#define DEBUG_ABBREV_SECTION ".debug_abbrev" 383550397Sobrien#endif 383690075Sobrien#ifndef DEBUG_ARANGES_SECTION 383790075Sobrien#define DEBUG_ARANGES_SECTION ".debug_aranges" 383850397Sobrien#endif 383990075Sobrien#ifndef DEBUG_MACINFO_SECTION 384090075Sobrien#define DEBUG_MACINFO_SECTION ".debug_macinfo" 384150397Sobrien#endif 384250397Sobrien#ifndef DEBUG_LINE_SECTION 384350397Sobrien#define DEBUG_LINE_SECTION ".debug_line" 384450397Sobrien#endif 384590075Sobrien#ifndef DEBUG_LOC_SECTION 384690075Sobrien#define DEBUG_LOC_SECTION ".debug_loc" 384750397Sobrien#endif 384890075Sobrien#ifndef DEBUG_PUBNAMES_SECTION 384990075Sobrien#define DEBUG_PUBNAMES_SECTION ".debug_pubnames" 385050397Sobrien#endif 385190075Sobrien#ifndef DEBUG_STR_SECTION 385290075Sobrien#define DEBUG_STR_SECTION ".debug_str" 385350397Sobrien#endif 385490075Sobrien#ifndef DEBUG_RANGES_SECTION 385590075Sobrien#define DEBUG_RANGES_SECTION ".debug_ranges" 385690075Sobrien#endif 385750397Sobrien 385850397Sobrien/* Standard ELF section names for compiled code and data. */ 385990075Sobrien#ifndef TEXT_SECTION_NAME 386090075Sobrien#define TEXT_SECTION_NAME ".text" 386150397Sobrien#endif 386290075Sobrien 386390075Sobrien/* Section flags for .debug_str section. */ 386490075Sobrien#define DEBUG_STR_SECTION_FLAGS \ 3865132718Skan (HAVE_GAS_SHF_MERGE && flag_merge_constants \ 3866132718Skan ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \ 3867132718Skan : SECTION_DEBUG) 386850397Sobrien 386952284Sobrien/* Labels we insert at beginning sections we can reference instead of 387090075Sobrien the section names themselves. */ 387150397Sobrien 387252284Sobrien#ifndef TEXT_SECTION_LABEL 387390075Sobrien#define TEXT_SECTION_LABEL "Ltext" 387452284Sobrien#endif 387552284Sobrien#ifndef DEBUG_LINE_SECTION_LABEL 387690075Sobrien#define DEBUG_LINE_SECTION_LABEL "Ldebug_line" 387752284Sobrien#endif 387852284Sobrien#ifndef DEBUG_INFO_SECTION_LABEL 387990075Sobrien#define DEBUG_INFO_SECTION_LABEL "Ldebug_info" 388052284Sobrien#endif 388190075Sobrien#ifndef DEBUG_ABBREV_SECTION_LABEL 388290075Sobrien#define DEBUG_ABBREV_SECTION_LABEL "Ldebug_abbrev" 388352284Sobrien#endif 388490075Sobrien#ifndef DEBUG_LOC_SECTION_LABEL 388590075Sobrien#define DEBUG_LOC_SECTION_LABEL "Ldebug_loc" 388690075Sobrien#endif 388790075Sobrien#ifndef DEBUG_RANGES_SECTION_LABEL 388890075Sobrien#define DEBUG_RANGES_SECTION_LABEL "Ldebug_ranges" 388990075Sobrien#endif 389090075Sobrien#ifndef DEBUG_MACINFO_SECTION_LABEL 389190075Sobrien#define DEBUG_MACINFO_SECTION_LABEL "Ldebug_macinfo" 389290075Sobrien#endif 389352284Sobrien 389450397Sobrien/* Definitions of defaults for formats and names of various special 389550397Sobrien (artificial) labels which may be generated within this file (when the -g 3896132718Skan options is used and DWARF2_DEBUGGING_INFO is in effect. 389750397Sobrien If necessary, these may be overridden from within the tm.h file, but 389850397Sobrien typically, overriding these defaults is unnecessary. */ 389950397Sobrien 390050397Sobrienstatic char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390152284Sobrienstatic char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390252284Sobrienstatic char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390352284Sobrienstatic char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390452284Sobrienstatic char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390590075Sobrienstatic char macinfo_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390690075Sobrienstatic char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; 390790075Sobrienstatic char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES]; 390850397Sobrien 390950397Sobrien#ifndef TEXT_END_LABEL 391050397Sobrien#define TEXT_END_LABEL "Letext" 391150397Sobrien#endif 391250397Sobrien#ifndef BLOCK_BEGIN_LABEL 391350397Sobrien#define BLOCK_BEGIN_LABEL "LBB" 391450397Sobrien#endif 391550397Sobrien#ifndef BLOCK_END_LABEL 391650397Sobrien#define BLOCK_END_LABEL "LBE" 391750397Sobrien#endif 391850397Sobrien#ifndef LINE_CODE_LABEL 391950397Sobrien#define LINE_CODE_LABEL "LM" 392050397Sobrien#endif 392150397Sobrien#ifndef SEPARATE_LINE_CODE_LABEL 392250397Sobrien#define SEPARATE_LINE_CODE_LABEL "LSM" 392350397Sobrien#endif 392450397Sobrien 392590075Sobrien/* We allow a language front-end to designate a function that is to be 392690075Sobrien called to "demangle" any name before it it put into a DIE. */ 392750397Sobrien 3928132718Skanstatic const char *(*demangle_name_func) (const char *); 392950397Sobrien 393090075Sobrienvoid 3931132718Skandwarf2out_set_demangle_name_func (const char *(*func) (const char *)) 393250397Sobrien{ 393390075Sobrien demangle_name_func = func; 393450397Sobrien} 393550397Sobrien 393650397Sobrien/* Test if rtl node points to a pseudo register. */ 393750397Sobrien 393850397Sobrienstatic inline int 3939132718Skanis_pseudo_reg (rtx rtl) 394050397Sobrien{ 394190075Sobrien return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER) 394290075Sobrien || (GET_CODE (rtl) == SUBREG 394390075Sobrien && REGNO (SUBREG_REG (rtl)) >= FIRST_PSEUDO_REGISTER)); 394450397Sobrien} 394550397Sobrien 394650397Sobrien/* Return a reference to a type, with its const and volatile qualifiers 394750397Sobrien removed. */ 394850397Sobrien 394950397Sobrienstatic inline tree 3950132718Skantype_main_variant (tree type) 395150397Sobrien{ 395250397Sobrien type = TYPE_MAIN_VARIANT (type); 395350397Sobrien 395490075Sobrien /* ??? There really should be only one main variant among any group of 395590075Sobrien variants of a given type (and all of the MAIN_VARIANT values for all 395690075Sobrien members of the group should point to that one type) but sometimes the C 395790075Sobrien front-end messes this up for array types, so we work around that bug 395890075Sobrien here. */ 395950397Sobrien if (TREE_CODE (type) == ARRAY_TYPE) 396050397Sobrien while (type != TYPE_MAIN_VARIANT (type)) 396150397Sobrien type = TYPE_MAIN_VARIANT (type); 396250397Sobrien 396350397Sobrien return type; 396450397Sobrien} 396550397Sobrien 3966117395Skan/* Return nonzero if the given type node represents a tagged type. */ 396750397Sobrien 396850397Sobrienstatic inline int 3969132718Skanis_tagged_type (tree type) 397050397Sobrien{ 397190075Sobrien enum tree_code code = TREE_CODE (type); 397250397Sobrien 397350397Sobrien return (code == RECORD_TYPE || code == UNION_TYPE 397450397Sobrien || code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE); 397550397Sobrien} 397650397Sobrien 397750397Sobrien/* Convert a DIE tag into its string name. */ 397850397Sobrien 397990075Sobrienstatic const char * 3980132718Skandwarf_tag_name (unsigned int tag) 398150397Sobrien{ 398250397Sobrien switch (tag) 398350397Sobrien { 398450397Sobrien case DW_TAG_padding: 398550397Sobrien return "DW_TAG_padding"; 398650397Sobrien case DW_TAG_array_type: 398750397Sobrien return "DW_TAG_array_type"; 398850397Sobrien case DW_TAG_class_type: 398950397Sobrien return "DW_TAG_class_type"; 399050397Sobrien case DW_TAG_entry_point: 399150397Sobrien return "DW_TAG_entry_point"; 399250397Sobrien case DW_TAG_enumeration_type: 399350397Sobrien return "DW_TAG_enumeration_type"; 399450397Sobrien case DW_TAG_formal_parameter: 399550397Sobrien return "DW_TAG_formal_parameter"; 399650397Sobrien case DW_TAG_imported_declaration: 399750397Sobrien return "DW_TAG_imported_declaration"; 399850397Sobrien case DW_TAG_label: 399950397Sobrien return "DW_TAG_label"; 400050397Sobrien case DW_TAG_lexical_block: 400150397Sobrien return "DW_TAG_lexical_block"; 400250397Sobrien case DW_TAG_member: 400350397Sobrien return "DW_TAG_member"; 400450397Sobrien case DW_TAG_pointer_type: 400550397Sobrien return "DW_TAG_pointer_type"; 400650397Sobrien case DW_TAG_reference_type: 400750397Sobrien return "DW_TAG_reference_type"; 400850397Sobrien case DW_TAG_compile_unit: 400950397Sobrien return "DW_TAG_compile_unit"; 401050397Sobrien case DW_TAG_string_type: 401150397Sobrien return "DW_TAG_string_type"; 401250397Sobrien case DW_TAG_structure_type: 401350397Sobrien return "DW_TAG_structure_type"; 401450397Sobrien case DW_TAG_subroutine_type: 401550397Sobrien return "DW_TAG_subroutine_type"; 401650397Sobrien case DW_TAG_typedef: 401750397Sobrien return "DW_TAG_typedef"; 401850397Sobrien case DW_TAG_union_type: 401950397Sobrien return "DW_TAG_union_type"; 402050397Sobrien case DW_TAG_unspecified_parameters: 402150397Sobrien return "DW_TAG_unspecified_parameters"; 402250397Sobrien case DW_TAG_variant: 402350397Sobrien return "DW_TAG_variant"; 402450397Sobrien case DW_TAG_common_block: 402550397Sobrien return "DW_TAG_common_block"; 402650397Sobrien case DW_TAG_common_inclusion: 402750397Sobrien return "DW_TAG_common_inclusion"; 402850397Sobrien case DW_TAG_inheritance: 402950397Sobrien return "DW_TAG_inheritance"; 403050397Sobrien case DW_TAG_inlined_subroutine: 403150397Sobrien return "DW_TAG_inlined_subroutine"; 403250397Sobrien case DW_TAG_module: 403350397Sobrien return "DW_TAG_module"; 403450397Sobrien case DW_TAG_ptr_to_member_type: 403550397Sobrien return "DW_TAG_ptr_to_member_type"; 403650397Sobrien case DW_TAG_set_type: 403750397Sobrien return "DW_TAG_set_type"; 403850397Sobrien case DW_TAG_subrange_type: 403950397Sobrien return "DW_TAG_subrange_type"; 404050397Sobrien case DW_TAG_with_stmt: 404150397Sobrien return "DW_TAG_with_stmt"; 404250397Sobrien case DW_TAG_access_declaration: 404350397Sobrien return "DW_TAG_access_declaration"; 404450397Sobrien case DW_TAG_base_type: 404550397Sobrien return "DW_TAG_base_type"; 404650397Sobrien case DW_TAG_catch_block: 404750397Sobrien return "DW_TAG_catch_block"; 404850397Sobrien case DW_TAG_const_type: 404950397Sobrien return "DW_TAG_const_type"; 405050397Sobrien case DW_TAG_constant: 405150397Sobrien return "DW_TAG_constant"; 405250397Sobrien case DW_TAG_enumerator: 405350397Sobrien return "DW_TAG_enumerator"; 405450397Sobrien case DW_TAG_file_type: 405550397Sobrien return "DW_TAG_file_type"; 405650397Sobrien case DW_TAG_friend: 405750397Sobrien return "DW_TAG_friend"; 405850397Sobrien case DW_TAG_namelist: 405950397Sobrien return "DW_TAG_namelist"; 406050397Sobrien case DW_TAG_namelist_item: 406150397Sobrien return "DW_TAG_namelist_item"; 4062132718Skan case DW_TAG_namespace: 4063132718Skan return "DW_TAG_namespace"; 406450397Sobrien case DW_TAG_packed_type: 406550397Sobrien return "DW_TAG_packed_type"; 406650397Sobrien case DW_TAG_subprogram: 406750397Sobrien return "DW_TAG_subprogram"; 406850397Sobrien case DW_TAG_template_type_param: 406950397Sobrien return "DW_TAG_template_type_param"; 407050397Sobrien case DW_TAG_template_value_param: 407150397Sobrien return "DW_TAG_template_value_param"; 407250397Sobrien case DW_TAG_thrown_type: 407350397Sobrien return "DW_TAG_thrown_type"; 407450397Sobrien case DW_TAG_try_block: 407550397Sobrien return "DW_TAG_try_block"; 407650397Sobrien case DW_TAG_variant_part: 407750397Sobrien return "DW_TAG_variant_part"; 407850397Sobrien case DW_TAG_variable: 407950397Sobrien return "DW_TAG_variable"; 408050397Sobrien case DW_TAG_volatile_type: 408150397Sobrien return "DW_TAG_volatile_type"; 408250397Sobrien case DW_TAG_MIPS_loop: 408350397Sobrien return "DW_TAG_MIPS_loop"; 408450397Sobrien case DW_TAG_format_label: 408550397Sobrien return "DW_TAG_format_label"; 408650397Sobrien case DW_TAG_function_template: 408750397Sobrien return "DW_TAG_function_template"; 408850397Sobrien case DW_TAG_class_template: 408950397Sobrien return "DW_TAG_class_template"; 409090075Sobrien case DW_TAG_GNU_BINCL: 409190075Sobrien return "DW_TAG_GNU_BINCL"; 409290075Sobrien case DW_TAG_GNU_EINCL: 409390075Sobrien return "DW_TAG_GNU_EINCL"; 409450397Sobrien default: 409550397Sobrien return "DW_TAG_<unknown>"; 409650397Sobrien } 409750397Sobrien} 409850397Sobrien 409950397Sobrien/* Convert a DWARF attribute code into its string name. */ 410050397Sobrien 410190075Sobrienstatic const char * 4102132718Skandwarf_attr_name (unsigned int attr) 410350397Sobrien{ 410450397Sobrien switch (attr) 410550397Sobrien { 410650397Sobrien case DW_AT_sibling: 410750397Sobrien return "DW_AT_sibling"; 410850397Sobrien case DW_AT_location: 410950397Sobrien return "DW_AT_location"; 411050397Sobrien case DW_AT_name: 411150397Sobrien return "DW_AT_name"; 411250397Sobrien case DW_AT_ordering: 411350397Sobrien return "DW_AT_ordering"; 411450397Sobrien case DW_AT_subscr_data: 411550397Sobrien return "DW_AT_subscr_data"; 411650397Sobrien case DW_AT_byte_size: 411750397Sobrien return "DW_AT_byte_size"; 411850397Sobrien case DW_AT_bit_offset: 411950397Sobrien return "DW_AT_bit_offset"; 412050397Sobrien case DW_AT_bit_size: 412150397Sobrien return "DW_AT_bit_size"; 412250397Sobrien case DW_AT_element_list: 412350397Sobrien return "DW_AT_element_list"; 412450397Sobrien case DW_AT_stmt_list: 412550397Sobrien return "DW_AT_stmt_list"; 412650397Sobrien case DW_AT_low_pc: 412750397Sobrien return "DW_AT_low_pc"; 412850397Sobrien case DW_AT_high_pc: 412950397Sobrien return "DW_AT_high_pc"; 413050397Sobrien case DW_AT_language: 413150397Sobrien return "DW_AT_language"; 413250397Sobrien case DW_AT_member: 413350397Sobrien return "DW_AT_member"; 413450397Sobrien case DW_AT_discr: 413550397Sobrien return "DW_AT_discr"; 413650397Sobrien case DW_AT_discr_value: 413750397Sobrien return "DW_AT_discr_value"; 413850397Sobrien case DW_AT_visibility: 413950397Sobrien return "DW_AT_visibility"; 414050397Sobrien case DW_AT_import: 414150397Sobrien return "DW_AT_import"; 414250397Sobrien case DW_AT_string_length: 414350397Sobrien return "DW_AT_string_length"; 414450397Sobrien case DW_AT_common_reference: 414550397Sobrien return "DW_AT_common_reference"; 414650397Sobrien case DW_AT_comp_dir: 414750397Sobrien return "DW_AT_comp_dir"; 414850397Sobrien case DW_AT_const_value: 414950397Sobrien return "DW_AT_const_value"; 415050397Sobrien case DW_AT_containing_type: 415150397Sobrien return "DW_AT_containing_type"; 415250397Sobrien case DW_AT_default_value: 415350397Sobrien return "DW_AT_default_value"; 415450397Sobrien case DW_AT_inline: 415550397Sobrien return "DW_AT_inline"; 415650397Sobrien case DW_AT_is_optional: 415750397Sobrien return "DW_AT_is_optional"; 415850397Sobrien case DW_AT_lower_bound: 415950397Sobrien return "DW_AT_lower_bound"; 416050397Sobrien case DW_AT_producer: 416150397Sobrien return "DW_AT_producer"; 416250397Sobrien case DW_AT_prototyped: 416350397Sobrien return "DW_AT_prototyped"; 416450397Sobrien case DW_AT_return_addr: 416550397Sobrien return "DW_AT_return_addr"; 416650397Sobrien case DW_AT_start_scope: 416750397Sobrien return "DW_AT_start_scope"; 416850397Sobrien case DW_AT_stride_size: 416950397Sobrien return "DW_AT_stride_size"; 417050397Sobrien case DW_AT_upper_bound: 417150397Sobrien return "DW_AT_upper_bound"; 417250397Sobrien case DW_AT_abstract_origin: 417350397Sobrien return "DW_AT_abstract_origin"; 417450397Sobrien case DW_AT_accessibility: 417550397Sobrien return "DW_AT_accessibility"; 417650397Sobrien case DW_AT_address_class: 417750397Sobrien return "DW_AT_address_class"; 417850397Sobrien case DW_AT_artificial: 417950397Sobrien return "DW_AT_artificial"; 418050397Sobrien case DW_AT_base_types: 418150397Sobrien return "DW_AT_base_types"; 418250397Sobrien case DW_AT_calling_convention: 418350397Sobrien return "DW_AT_calling_convention"; 418450397Sobrien case DW_AT_count: 418550397Sobrien return "DW_AT_count"; 418650397Sobrien case DW_AT_data_member_location: 418750397Sobrien return "DW_AT_data_member_location"; 418850397Sobrien case DW_AT_decl_column: 418950397Sobrien return "DW_AT_decl_column"; 419050397Sobrien case DW_AT_decl_file: 419150397Sobrien return "DW_AT_decl_file"; 419250397Sobrien case DW_AT_decl_line: 419350397Sobrien return "DW_AT_decl_line"; 419450397Sobrien case DW_AT_declaration: 419550397Sobrien return "DW_AT_declaration"; 419650397Sobrien case DW_AT_discr_list: 419750397Sobrien return "DW_AT_discr_list"; 419850397Sobrien case DW_AT_encoding: 419950397Sobrien return "DW_AT_encoding"; 420050397Sobrien case DW_AT_external: 420150397Sobrien return "DW_AT_external"; 420250397Sobrien case DW_AT_frame_base: 420350397Sobrien return "DW_AT_frame_base"; 420450397Sobrien case DW_AT_friend: 420550397Sobrien return "DW_AT_friend"; 420650397Sobrien case DW_AT_identifier_case: 420750397Sobrien return "DW_AT_identifier_case"; 420850397Sobrien case DW_AT_macro_info: 420950397Sobrien return "DW_AT_macro_info"; 421050397Sobrien case DW_AT_namelist_items: 421150397Sobrien return "DW_AT_namelist_items"; 421250397Sobrien case DW_AT_priority: 421350397Sobrien return "DW_AT_priority"; 421450397Sobrien case DW_AT_segment: 421550397Sobrien return "DW_AT_segment"; 421650397Sobrien case DW_AT_specification: 421750397Sobrien return "DW_AT_specification"; 421850397Sobrien case DW_AT_static_link: 421950397Sobrien return "DW_AT_static_link"; 422050397Sobrien case DW_AT_type: 422150397Sobrien return "DW_AT_type"; 422250397Sobrien case DW_AT_use_location: 422350397Sobrien return "DW_AT_use_location"; 422450397Sobrien case DW_AT_variable_parameter: 422550397Sobrien return "DW_AT_variable_parameter"; 422650397Sobrien case DW_AT_virtuality: 422750397Sobrien return "DW_AT_virtuality"; 422850397Sobrien case DW_AT_vtable_elem_location: 422950397Sobrien return "DW_AT_vtable_elem_location"; 423050397Sobrien 423190075Sobrien case DW_AT_allocated: 423290075Sobrien return "DW_AT_allocated"; 423390075Sobrien case DW_AT_associated: 423490075Sobrien return "DW_AT_associated"; 423590075Sobrien case DW_AT_data_location: 423690075Sobrien return "DW_AT_data_location"; 423790075Sobrien case DW_AT_stride: 423890075Sobrien return "DW_AT_stride"; 423990075Sobrien case DW_AT_entry_pc: 424090075Sobrien return "DW_AT_entry_pc"; 424190075Sobrien case DW_AT_use_UTF8: 424290075Sobrien return "DW_AT_use_UTF8"; 424390075Sobrien case DW_AT_extension: 424490075Sobrien return "DW_AT_extension"; 424590075Sobrien case DW_AT_ranges: 424690075Sobrien return "DW_AT_ranges"; 424790075Sobrien case DW_AT_trampoline: 424890075Sobrien return "DW_AT_trampoline"; 424990075Sobrien case DW_AT_call_column: 425090075Sobrien return "DW_AT_call_column"; 425190075Sobrien case DW_AT_call_file: 425290075Sobrien return "DW_AT_call_file"; 425390075Sobrien case DW_AT_call_line: 425490075Sobrien return "DW_AT_call_line"; 425590075Sobrien 425650397Sobrien case DW_AT_MIPS_fde: 425750397Sobrien return "DW_AT_MIPS_fde"; 425850397Sobrien case DW_AT_MIPS_loop_begin: 425950397Sobrien return "DW_AT_MIPS_loop_begin"; 426050397Sobrien case DW_AT_MIPS_tail_loop_begin: 426150397Sobrien return "DW_AT_MIPS_tail_loop_begin"; 426250397Sobrien case DW_AT_MIPS_epilog_begin: 426350397Sobrien return "DW_AT_MIPS_epilog_begin"; 426450397Sobrien case DW_AT_MIPS_loop_unroll_factor: 426550397Sobrien return "DW_AT_MIPS_loop_unroll_factor"; 426650397Sobrien case DW_AT_MIPS_software_pipeline_depth: 426750397Sobrien return "DW_AT_MIPS_software_pipeline_depth"; 426850397Sobrien case DW_AT_MIPS_linkage_name: 426950397Sobrien return "DW_AT_MIPS_linkage_name"; 427050397Sobrien case DW_AT_MIPS_stride: 427150397Sobrien return "DW_AT_MIPS_stride"; 427250397Sobrien case DW_AT_MIPS_abstract_name: 427350397Sobrien return "DW_AT_MIPS_abstract_name"; 427450397Sobrien case DW_AT_MIPS_clone_origin: 427550397Sobrien return "DW_AT_MIPS_clone_origin"; 427650397Sobrien case DW_AT_MIPS_has_inlines: 427750397Sobrien return "DW_AT_MIPS_has_inlines"; 427850397Sobrien 427950397Sobrien case DW_AT_sf_names: 428050397Sobrien return "DW_AT_sf_names"; 428150397Sobrien case DW_AT_src_info: 428250397Sobrien return "DW_AT_src_info"; 428350397Sobrien case DW_AT_mac_info: 428450397Sobrien return "DW_AT_mac_info"; 428550397Sobrien case DW_AT_src_coords: 428650397Sobrien return "DW_AT_src_coords"; 428750397Sobrien case DW_AT_body_begin: 428850397Sobrien return "DW_AT_body_begin"; 428950397Sobrien case DW_AT_body_end: 429050397Sobrien return "DW_AT_body_end"; 429196263Sobrien case DW_AT_GNU_vector: 429296263Sobrien return "DW_AT_GNU_vector"; 429396263Sobrien 429490075Sobrien case DW_AT_VMS_rtnbeg_pd_address: 429590075Sobrien return "DW_AT_VMS_rtnbeg_pd_address"; 429690075Sobrien 429750397Sobrien default: 429850397Sobrien return "DW_AT_<unknown>"; 429950397Sobrien } 430050397Sobrien} 430150397Sobrien 430250397Sobrien/* Convert a DWARF value form code into its string name. */ 430350397Sobrien 430490075Sobrienstatic const char * 4305132718Skandwarf_form_name (unsigned int form) 430650397Sobrien{ 430750397Sobrien switch (form) 430850397Sobrien { 430950397Sobrien case DW_FORM_addr: 431050397Sobrien return "DW_FORM_addr"; 431150397Sobrien case DW_FORM_block2: 431250397Sobrien return "DW_FORM_block2"; 431350397Sobrien case DW_FORM_block4: 431450397Sobrien return "DW_FORM_block4"; 431550397Sobrien case DW_FORM_data2: 431650397Sobrien return "DW_FORM_data2"; 431750397Sobrien case DW_FORM_data4: 431850397Sobrien return "DW_FORM_data4"; 431950397Sobrien case DW_FORM_data8: 432050397Sobrien return "DW_FORM_data8"; 432150397Sobrien case DW_FORM_string: 432250397Sobrien return "DW_FORM_string"; 432350397Sobrien case DW_FORM_block: 432450397Sobrien return "DW_FORM_block"; 432550397Sobrien case DW_FORM_block1: 432650397Sobrien return "DW_FORM_block1"; 432750397Sobrien case DW_FORM_data1: 432850397Sobrien return "DW_FORM_data1"; 432950397Sobrien case DW_FORM_flag: 433050397Sobrien return "DW_FORM_flag"; 433150397Sobrien case DW_FORM_sdata: 433250397Sobrien return "DW_FORM_sdata"; 433350397Sobrien case DW_FORM_strp: 433450397Sobrien return "DW_FORM_strp"; 433550397Sobrien case DW_FORM_udata: 433650397Sobrien return "DW_FORM_udata"; 433750397Sobrien case DW_FORM_ref_addr: 433850397Sobrien return "DW_FORM_ref_addr"; 433950397Sobrien case DW_FORM_ref1: 434050397Sobrien return "DW_FORM_ref1"; 434150397Sobrien case DW_FORM_ref2: 434250397Sobrien return "DW_FORM_ref2"; 434350397Sobrien case DW_FORM_ref4: 434450397Sobrien return "DW_FORM_ref4"; 434550397Sobrien case DW_FORM_ref8: 434650397Sobrien return "DW_FORM_ref8"; 434750397Sobrien case DW_FORM_ref_udata: 434850397Sobrien return "DW_FORM_ref_udata"; 434950397Sobrien case DW_FORM_indirect: 435050397Sobrien return "DW_FORM_indirect"; 435150397Sobrien default: 435250397Sobrien return "DW_FORM_<unknown>"; 435350397Sobrien } 435450397Sobrien} 435550397Sobrien 435650397Sobrien/* Convert a DWARF type code into its string name. */ 435750397Sobrien 435850397Sobrien#if 0 435990075Sobrienstatic const char * 4360132718Skandwarf_type_encoding_name (unsigned enc) 436150397Sobrien{ 436250397Sobrien switch (enc) 436350397Sobrien { 436450397Sobrien case DW_ATE_address: 436550397Sobrien return "DW_ATE_address"; 436650397Sobrien case DW_ATE_boolean: 436750397Sobrien return "DW_ATE_boolean"; 436850397Sobrien case DW_ATE_complex_float: 436950397Sobrien return "DW_ATE_complex_float"; 437050397Sobrien case DW_ATE_float: 437150397Sobrien return "DW_ATE_float"; 437250397Sobrien case DW_ATE_signed: 437350397Sobrien return "DW_ATE_signed"; 437450397Sobrien case DW_ATE_signed_char: 437550397Sobrien return "DW_ATE_signed_char"; 437650397Sobrien case DW_ATE_unsigned: 437750397Sobrien return "DW_ATE_unsigned"; 437850397Sobrien case DW_ATE_unsigned_char: 437950397Sobrien return "DW_ATE_unsigned_char"; 438050397Sobrien default: 438150397Sobrien return "DW_ATE_<unknown>"; 438250397Sobrien } 438350397Sobrien} 438450397Sobrien#endif 438550397Sobrien 438650397Sobrien/* Determine the "ultimate origin" of a decl. The decl may be an inlined 438750397Sobrien instance of an inlined instance of a decl which is local to an inline 438850397Sobrien function, so we have to trace all of the way back through the origin chain 438950397Sobrien to find out what sort of node actually served as the original seed for the 439050397Sobrien given block. */ 439150397Sobrien 439250397Sobrienstatic tree 4393132718Skandecl_ultimate_origin (tree decl) 439450397Sobrien{ 439590075Sobrien /* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the 439690075Sobrien nodes in the function to point to themselves; ignore that if 439790075Sobrien we're trying to output the abstract instance of this function. */ 439890075Sobrien if (DECL_ABSTRACT (decl) && DECL_ABSTRACT_ORIGIN (decl) == decl) 439990075Sobrien return NULL_TREE; 440090075Sobrien 440190075Sobrien#ifdef ENABLE_CHECKING 440252284Sobrien if (DECL_FROM_INLINE (DECL_ORIGIN (decl))) 440352284Sobrien /* Since the DECL_ABSTRACT_ORIGIN for a DECL is supposed to be the 440452284Sobrien most distant ancestor, this should never happen. */ 440552284Sobrien abort (); 440652284Sobrien#endif 440750397Sobrien 440852284Sobrien return DECL_ABSTRACT_ORIGIN (decl); 440950397Sobrien} 441050397Sobrien 441150397Sobrien/* Determine the "ultimate origin" of a block. The block may be an inlined 441250397Sobrien instance of an inlined instance of a block which is local to an inline 441350397Sobrien function, so we have to trace all of the way back through the origin chain 441450397Sobrien to find out what sort of node actually served as the original seed for the 441550397Sobrien given block. */ 441650397Sobrien 441750397Sobrienstatic tree 4418132718Skanblock_ultimate_origin (tree block) 441950397Sobrien{ 442090075Sobrien tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block); 442150397Sobrien 442290075Sobrien /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the 442390075Sobrien nodes in the function to point to themselves; ignore that if 442490075Sobrien we're trying to output the abstract instance of this function. */ 442590075Sobrien if (BLOCK_ABSTRACT (block) && immediate_origin == block) 442690075Sobrien return NULL_TREE; 442790075Sobrien 442850397Sobrien if (immediate_origin == NULL_TREE) 442950397Sobrien return NULL_TREE; 443050397Sobrien else 443150397Sobrien { 443290075Sobrien tree ret_val; 443390075Sobrien tree lookahead = immediate_origin; 443450397Sobrien 443550397Sobrien do 443650397Sobrien { 443750397Sobrien ret_val = lookahead; 443890075Sobrien lookahead = (TREE_CODE (ret_val) == BLOCK 443990075Sobrien ? BLOCK_ABSTRACT_ORIGIN (ret_val) : NULL); 444050397Sobrien } 444150397Sobrien while (lookahead != NULL && lookahead != ret_val); 444250397Sobrien 444350397Sobrien return ret_val; 444450397Sobrien } 444550397Sobrien} 444650397Sobrien 444750397Sobrien/* Get the class to which DECL belongs, if any. In g++, the DECL_CONTEXT 444850397Sobrien of a virtual function may refer to a base class, so we check the 'this' 444950397Sobrien parameter. */ 445050397Sobrien 445150397Sobrienstatic tree 4452132718Skandecl_class_context (tree decl) 445350397Sobrien{ 445450397Sobrien tree context = NULL_TREE; 445550397Sobrien 445650397Sobrien if (TREE_CODE (decl) != FUNCTION_DECL || ! DECL_VINDEX (decl)) 445750397Sobrien context = DECL_CONTEXT (decl); 445850397Sobrien else 445950397Sobrien context = TYPE_MAIN_VARIANT 446050397Sobrien (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); 446150397Sobrien 446290075Sobrien if (context && !TYPE_P (context)) 446350397Sobrien context = NULL_TREE; 446450397Sobrien 446550397Sobrien return context; 446650397Sobrien} 446750397Sobrien 446890075Sobrien/* Add an attribute/value pair to a DIE. We build the lists up in reverse 446990075Sobrien addition order, and correct that in reverse_all_dies. */ 447050397Sobrien 447150397Sobrienstatic inline void 4472132718Skanadd_dwarf_attr (dw_die_ref die, dw_attr_ref attr) 447350397Sobrien{ 447450397Sobrien if (die != NULL && attr != NULL) 447550397Sobrien { 447690075Sobrien attr->dw_attr_next = die->die_attr; 447790075Sobrien die->die_attr = attr; 447850397Sobrien } 447950397Sobrien} 448050397Sobrien 4481132718Skanstatic inline enum dw_val_class 4482132718SkanAT_class (dw_attr_ref a) 448390075Sobrien{ 448490075Sobrien return a->dw_attr_val.val_class; 448590075Sobrien} 448690075Sobrien 448750397Sobrien/* Add a flag value attribute to a DIE. */ 448850397Sobrien 448950397Sobrienstatic inline void 4490132718Skanadd_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int flag) 449150397Sobrien{ 4492132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 449350397Sobrien 449450397Sobrien attr->dw_attr_next = NULL; 449550397Sobrien attr->dw_attr = attr_kind; 449650397Sobrien attr->dw_attr_val.val_class = dw_val_class_flag; 449750397Sobrien attr->dw_attr_val.v.val_flag = flag; 449850397Sobrien add_dwarf_attr (die, attr); 449950397Sobrien} 450050397Sobrien 450190075Sobrienstatic inline unsigned 4502132718SkanAT_flag (dw_attr_ref a) 450390075Sobrien{ 450490075Sobrien if (a && AT_class (a) == dw_val_class_flag) 450590075Sobrien return a->dw_attr_val.v.val_flag; 450690075Sobrien 450790075Sobrien abort (); 450890075Sobrien} 450990075Sobrien 451050397Sobrien/* Add a signed integer attribute value to a DIE. */ 451150397Sobrien 451250397Sobrienstatic inline void 4513132718Skanadd_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, HOST_WIDE_INT int_val) 451450397Sobrien{ 4515132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 451650397Sobrien 451750397Sobrien attr->dw_attr_next = NULL; 451850397Sobrien attr->dw_attr = attr_kind; 451950397Sobrien attr->dw_attr_val.val_class = dw_val_class_const; 452050397Sobrien attr->dw_attr_val.v.val_int = int_val; 452150397Sobrien add_dwarf_attr (die, attr); 452250397Sobrien} 452350397Sobrien 4524132718Skanstatic inline HOST_WIDE_INT 4525132718SkanAT_int (dw_attr_ref a) 452690075Sobrien{ 452790075Sobrien if (a && AT_class (a) == dw_val_class_const) 452890075Sobrien return a->dw_attr_val.v.val_int; 452990075Sobrien 453090075Sobrien abort (); 453190075Sobrien} 453290075Sobrien 453350397Sobrien/* Add an unsigned integer attribute value to a DIE. */ 453450397Sobrien 453550397Sobrienstatic inline void 4536132718Skanadd_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind, 4537132718Skan unsigned HOST_WIDE_INT unsigned_val) 453850397Sobrien{ 4539132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 454050397Sobrien 454150397Sobrien attr->dw_attr_next = NULL; 454250397Sobrien attr->dw_attr = attr_kind; 454350397Sobrien attr->dw_attr_val.val_class = dw_val_class_unsigned_const; 454450397Sobrien attr->dw_attr_val.v.val_unsigned = unsigned_val; 454550397Sobrien add_dwarf_attr (die, attr); 454650397Sobrien} 454750397Sobrien 4548132718Skanstatic inline unsigned HOST_WIDE_INT 4549132718SkanAT_unsigned (dw_attr_ref a) 455090075Sobrien{ 455190075Sobrien if (a && AT_class (a) == dw_val_class_unsigned_const) 455290075Sobrien return a->dw_attr_val.v.val_unsigned; 455390075Sobrien 455490075Sobrien abort (); 455590075Sobrien} 455690075Sobrien 455750397Sobrien/* Add an unsigned double integer attribute value to a DIE. */ 455850397Sobrien 455950397Sobrienstatic inline void 4560132718Skanadd_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind, 4561132718Skan long unsigned int val_hi, long unsigned int val_low) 456250397Sobrien{ 4563132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 456450397Sobrien 456550397Sobrien attr->dw_attr_next = NULL; 456650397Sobrien attr->dw_attr = attr_kind; 456750397Sobrien attr->dw_attr_val.val_class = dw_val_class_long_long; 456850397Sobrien attr->dw_attr_val.v.val_long_long.hi = val_hi; 456950397Sobrien attr->dw_attr_val.v.val_long_long.low = val_low; 457050397Sobrien add_dwarf_attr (die, attr); 457150397Sobrien} 457250397Sobrien 457350397Sobrien/* Add a floating point attribute value to a DIE and return it. */ 457450397Sobrien 457550397Sobrienstatic inline void 4576132718Skanadd_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind, 4577132718Skan unsigned int length, unsigned int elt_size, unsigned char *array) 457850397Sobrien{ 4579132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 458050397Sobrien 458150397Sobrien attr->dw_attr_next = NULL; 458250397Sobrien attr->dw_attr = attr_kind; 4583132718Skan attr->dw_attr_val.val_class = dw_val_class_vec; 4584132718Skan attr->dw_attr_val.v.val_vec.length = length; 4585132718Skan attr->dw_attr_val.v.val_vec.elt_size = elt_size; 4586132718Skan attr->dw_attr_val.v.val_vec.array = array; 458750397Sobrien add_dwarf_attr (die, attr); 458850397Sobrien} 458950397Sobrien 4590132718Skan/* Hash and equality functions for debug_str_hash. */ 4591132718Skan 4592132718Skanstatic hashval_t 4593132718Skandebug_str_do_hash (const void *x) 4594132718Skan{ 4595132718Skan return htab_hash_string (((const struct indirect_string_node *)x)->str); 4596132718Skan} 4597132718Skan 4598132718Skanstatic int 4599132718Skandebug_str_eq (const void *x1, const void *x2) 4600132718Skan{ 4601132718Skan return strcmp ((((const struct indirect_string_node *)x1)->str), 4602132718Skan (const char *)x2) == 0; 4603132718Skan} 4604132718Skan 460550397Sobrien/* Add a string attribute value to a DIE. */ 460650397Sobrien 460750397Sobrienstatic inline void 4608132718Skanadd_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str) 460950397Sobrien{ 4610132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 461190075Sobrien struct indirect_string_node *node; 4612132718Skan void **slot; 4613117395Skan 461490075Sobrien if (! debug_str_hash) 4615132718Skan debug_str_hash = htab_create_ggc (10, debug_str_do_hash, 4616132718Skan debug_str_eq, NULL); 461750397Sobrien 4618132718Skan slot = htab_find_slot_with_hash (debug_str_hash, str, 4619132718Skan htab_hash_string (str), INSERT); 4620132718Skan if (*slot == NULL) 4621132718Skan *slot = ggc_alloc_cleared (sizeof (struct indirect_string_node)); 4622132718Skan node = (struct indirect_string_node *) *slot; 4623132718Skan node->str = ggc_strdup (str); 462490075Sobrien node->refcount++; 462590075Sobrien 462650397Sobrien attr->dw_attr_next = NULL; 462750397Sobrien attr->dw_attr = attr_kind; 462850397Sobrien attr->dw_attr_val.val_class = dw_val_class_str; 462990075Sobrien attr->dw_attr_val.v.val_str = node; 463050397Sobrien add_dwarf_attr (die, attr); 463150397Sobrien} 463250397Sobrien 463390075Sobrienstatic inline const char * 4634132718SkanAT_string (dw_attr_ref a) 463590075Sobrien{ 463690075Sobrien if (a && AT_class (a) == dw_val_class_str) 4637132718Skan return a->dw_attr_val.v.val_str->str; 463890075Sobrien 463990075Sobrien abort (); 464090075Sobrien} 464190075Sobrien 464290075Sobrien/* Find out whether a string should be output inline in DIE 464390075Sobrien or out-of-line in .debug_str section. */ 464490075Sobrien 464590075Sobrienstatic int 4646132718SkanAT_string_form (dw_attr_ref a) 464790075Sobrien{ 464890075Sobrien if (a && AT_class (a) == dw_val_class_str) 464990075Sobrien { 465090075Sobrien struct indirect_string_node *node; 465190075Sobrien unsigned int len; 465290075Sobrien char label[32]; 465390075Sobrien 465490075Sobrien node = a->dw_attr_val.v.val_str; 465590075Sobrien if (node->form) 465690075Sobrien return node->form; 465790075Sobrien 4658132718Skan len = strlen (node->str) + 1; 465990075Sobrien 466090075Sobrien /* If the string is shorter or equal to the size of the reference, it is 466190075Sobrien always better to put it inline. */ 466290075Sobrien if (len <= DWARF_OFFSET_SIZE || node->refcount == 0) 466390075Sobrien return node->form = DW_FORM_string; 466490075Sobrien 466590075Sobrien /* If we cannot expect the linker to merge strings in .debug_str 466690075Sobrien section, only put it into .debug_str if it is worth even in this 466790075Sobrien single module. */ 466890075Sobrien if ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) == 0 466990075Sobrien && (len - DWARF_OFFSET_SIZE) * node->refcount <= len) 467090075Sobrien return node->form = DW_FORM_string; 467190075Sobrien 4672132718Skan ASM_GENERATE_INTERNAL_LABEL (label, "LASF", dw2_string_counter); 4673132718Skan ++dw2_string_counter; 467490075Sobrien node->label = xstrdup (label); 467590075Sobrien 467690075Sobrien return node->form = DW_FORM_strp; 467790075Sobrien } 467890075Sobrien 467990075Sobrien abort (); 468090075Sobrien} 468190075Sobrien 468250397Sobrien/* Add a DIE reference attribute value to a DIE. */ 468350397Sobrien 468450397Sobrienstatic inline void 4685132718Skanadd_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_die) 468650397Sobrien{ 4687132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 468850397Sobrien 468950397Sobrien attr->dw_attr_next = NULL; 469050397Sobrien attr->dw_attr = attr_kind; 469150397Sobrien attr->dw_attr_val.val_class = dw_val_class_die_ref; 469290075Sobrien attr->dw_attr_val.v.val_die_ref.die = targ_die; 469390075Sobrien attr->dw_attr_val.v.val_die_ref.external = 0; 469450397Sobrien add_dwarf_attr (die, attr); 469550397Sobrien} 469650397Sobrien 4697132718Skan/* Add an AT_specification attribute to a DIE, and also make the back 4698132718Skan pointer from the specification to the definition. */ 4699132718Skan 4700132718Skanstatic inline void 4701132718Skanadd_AT_specification (dw_die_ref die, dw_die_ref targ_die) 4702132718Skan{ 4703132718Skan add_AT_die_ref (die, DW_AT_specification, targ_die); 4704132718Skan if (targ_die->die_definition) 4705132718Skan abort (); 4706132718Skan targ_die->die_definition = die; 4707132718Skan} 4708132718Skan 470990075Sobrienstatic inline dw_die_ref 4710132718SkanAT_ref (dw_attr_ref a) 471190075Sobrien{ 471290075Sobrien if (a && AT_class (a) == dw_val_class_die_ref) 471390075Sobrien return a->dw_attr_val.v.val_die_ref.die; 471490075Sobrien 471590075Sobrien abort (); 471690075Sobrien} 471790075Sobrien 471890075Sobrienstatic inline int 4719132718SkanAT_ref_external (dw_attr_ref a) 472090075Sobrien{ 472190075Sobrien if (a && AT_class (a) == dw_val_class_die_ref) 472290075Sobrien return a->dw_attr_val.v.val_die_ref.external; 472390075Sobrien 472490075Sobrien return 0; 472590075Sobrien} 472690075Sobrien 472790075Sobrienstatic inline void 4728132718Skanset_AT_ref_external (dw_attr_ref a, int i) 472990075Sobrien{ 473090075Sobrien if (a && AT_class (a) == dw_val_class_die_ref) 473190075Sobrien a->dw_attr_val.v.val_die_ref.external = i; 473290075Sobrien else 473390075Sobrien abort (); 473490075Sobrien} 473590075Sobrien 473650397Sobrien/* Add an FDE reference attribute value to a DIE. */ 473750397Sobrien 473850397Sobrienstatic inline void 4739132718Skanadd_AT_fde_ref (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int targ_fde) 474050397Sobrien{ 4741132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 474250397Sobrien 474350397Sobrien attr->dw_attr_next = NULL; 474450397Sobrien attr->dw_attr = attr_kind; 474550397Sobrien attr->dw_attr_val.val_class = dw_val_class_fde_ref; 474650397Sobrien attr->dw_attr_val.v.val_fde_index = targ_fde; 474750397Sobrien add_dwarf_attr (die, attr); 474850397Sobrien} 474950397Sobrien 475050397Sobrien/* Add a location description attribute value to a DIE. */ 475150397Sobrien 475250397Sobrienstatic inline void 4753132718Skanadd_AT_loc (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_descr_ref loc) 475450397Sobrien{ 4755132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 475650397Sobrien 475750397Sobrien attr->dw_attr_next = NULL; 475850397Sobrien attr->dw_attr = attr_kind; 475950397Sobrien attr->dw_attr_val.val_class = dw_val_class_loc; 476050397Sobrien attr->dw_attr_val.v.val_loc = loc; 476150397Sobrien add_dwarf_attr (die, attr); 476250397Sobrien} 476350397Sobrien 476490075Sobrienstatic inline dw_loc_descr_ref 4765132718SkanAT_loc (dw_attr_ref a) 476690075Sobrien{ 476790075Sobrien if (a && AT_class (a) == dw_val_class_loc) 476890075Sobrien return a->dw_attr_val.v.val_loc; 476990075Sobrien 477090075Sobrien abort (); 477190075Sobrien} 477290075Sobrien 477390075Sobrienstatic inline void 4774132718Skanadd_AT_loc_list (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref loc_list) 477590075Sobrien{ 4776132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 477790075Sobrien 477890075Sobrien attr->dw_attr_next = NULL; 477990075Sobrien attr->dw_attr = attr_kind; 478090075Sobrien attr->dw_attr_val.val_class = dw_val_class_loc_list; 478190075Sobrien attr->dw_attr_val.v.val_loc_list = loc_list; 478290075Sobrien add_dwarf_attr (die, attr); 478390075Sobrien have_location_lists = 1; 478490075Sobrien} 478590075Sobrien 478690075Sobrienstatic inline dw_loc_list_ref 4787132718SkanAT_loc_list (dw_attr_ref a) 478890075Sobrien{ 478990075Sobrien if (a && AT_class (a) == dw_val_class_loc_list) 479090075Sobrien return a->dw_attr_val.v.val_loc_list; 479190075Sobrien 479290075Sobrien abort (); 479390075Sobrien} 479490075Sobrien 479550397Sobrien/* Add an address constant attribute value to a DIE. */ 479650397Sobrien 479750397Sobrienstatic inline void 4798132718Skanadd_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr) 479950397Sobrien{ 4800132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 480150397Sobrien 480250397Sobrien attr->dw_attr_next = NULL; 480350397Sobrien attr->dw_attr = attr_kind; 480450397Sobrien attr->dw_attr_val.val_class = dw_val_class_addr; 480550397Sobrien attr->dw_attr_val.v.val_addr = addr; 480650397Sobrien add_dwarf_attr (die, attr); 480750397Sobrien} 480850397Sobrien 480990075Sobrienstatic inline rtx 4810132718SkanAT_addr (dw_attr_ref a) 481190075Sobrien{ 481290075Sobrien if (a && AT_class (a) == dw_val_class_addr) 481390075Sobrien return a->dw_attr_val.v.val_addr; 481490075Sobrien 481590075Sobrien abort (); 481690075Sobrien} 481790075Sobrien 481850397Sobrien/* Add a label identifier attribute value to a DIE. */ 481950397Sobrien 482050397Sobrienstatic inline void 4821132718Skanadd_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, const char *lbl_id) 482250397Sobrien{ 4823132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 482450397Sobrien 482550397Sobrien attr->dw_attr_next = NULL; 482650397Sobrien attr->dw_attr = attr_kind; 482750397Sobrien attr->dw_attr_val.val_class = dw_val_class_lbl_id; 482850397Sobrien attr->dw_attr_val.v.val_lbl_id = xstrdup (lbl_id); 482950397Sobrien add_dwarf_attr (die, attr); 483050397Sobrien} 483150397Sobrien 483250397Sobrien/* Add a section offset attribute value to a DIE. */ 483350397Sobrien 483450397Sobrienstatic inline void 4835132718Skanadd_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *label) 483650397Sobrien{ 4837132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 483850397Sobrien 483950397Sobrien attr->dw_attr_next = NULL; 484050397Sobrien attr->dw_attr = attr_kind; 484152284Sobrien attr->dw_attr_val.val_class = dw_val_class_lbl_offset; 484290075Sobrien attr->dw_attr_val.v.val_lbl_id = xstrdup (label); 484350397Sobrien add_dwarf_attr (die, attr); 484450397Sobrien} 484550397Sobrien 484690075Sobrien/* Add an offset attribute value to a DIE. */ 484750397Sobrien 484890075Sobrienstatic inline void 4849132718Skanadd_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind, 4850132718Skan unsigned HOST_WIDE_INT offset) 485150397Sobrien{ 4852132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 485350397Sobrien 485490075Sobrien attr->dw_attr_next = NULL; 485590075Sobrien attr->dw_attr = attr_kind; 485690075Sobrien attr->dw_attr_val.val_class = dw_val_class_offset; 485790075Sobrien attr->dw_attr_val.v.val_offset = offset; 485890075Sobrien add_dwarf_attr (die, attr); 485990075Sobrien} 486050397Sobrien 486190075Sobrien/* Add an range_list attribute value to a DIE. */ 486290075Sobrien 486390075Sobrienstatic void 4864132718Skanadd_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind, 4865132718Skan long unsigned int offset) 486690075Sobrien{ 4867132718Skan dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); 486890075Sobrien 486990075Sobrien attr->dw_attr_next = NULL; 487090075Sobrien attr->dw_attr = attr_kind; 487190075Sobrien attr->dw_attr_val.val_class = dw_val_class_range_list; 487290075Sobrien attr->dw_attr_val.v.val_offset = offset; 487390075Sobrien add_dwarf_attr (die, attr); 487450397Sobrien} 487550397Sobrien 487690075Sobrienstatic inline const char * 4877132718SkanAT_lbl (dw_attr_ref a) 487890075Sobrien{ 487990075Sobrien if (a && (AT_class (a) == dw_val_class_lbl_id 488090075Sobrien || AT_class (a) == dw_val_class_lbl_offset)) 488190075Sobrien return a->dw_attr_val.v.val_lbl_id; 488290075Sobrien 488390075Sobrien abort (); 488490075Sobrien} 488590075Sobrien 488650397Sobrien/* Get the attribute of type attr_kind. */ 488750397Sobrien 4888132718Skanstatic dw_attr_ref 4889132718Skanget_AT (dw_die_ref die, enum dwarf_attribute attr_kind) 489050397Sobrien{ 489190075Sobrien dw_attr_ref a; 489290075Sobrien dw_die_ref spec = NULL; 489390075Sobrien 489450397Sobrien if (die != NULL) 489550397Sobrien { 489650397Sobrien for (a = die->die_attr; a != NULL; a = a->dw_attr_next) 489790075Sobrien if (a->dw_attr == attr_kind) 489890075Sobrien return a; 489990075Sobrien else if (a->dw_attr == DW_AT_specification 490090075Sobrien || a->dw_attr == DW_AT_abstract_origin) 490190075Sobrien spec = AT_ref (a); 490250397Sobrien 490350397Sobrien if (spec) 490450397Sobrien return get_AT (spec, attr_kind); 490550397Sobrien } 490650397Sobrien 490750397Sobrien return NULL; 490850397Sobrien} 490950397Sobrien 491090075Sobrien/* Return the "low pc" attribute value, typically associated with a subprogram 491190075Sobrien DIE. Return null if the "low pc" attribute is either not present, or if it 491290075Sobrien cannot be represented as an assembler label identifier. */ 491350397Sobrien 491490075Sobrienstatic inline const char * 4915132718Skanget_AT_low_pc (dw_die_ref die) 491650397Sobrien{ 491790075Sobrien dw_attr_ref a = get_AT (die, DW_AT_low_pc); 491850397Sobrien 491990075Sobrien return a ? AT_lbl (a) : NULL; 492050397Sobrien} 492150397Sobrien 492290075Sobrien/* Return the "high pc" attribute value, typically associated with a subprogram 492390075Sobrien DIE. Return null if the "high pc" attribute is either not present, or if it 492490075Sobrien cannot be represented as an assembler label identifier. */ 492550397Sobrien 492690075Sobrienstatic inline const char * 4927132718Skanget_AT_hi_pc (dw_die_ref die) 492850397Sobrien{ 492990075Sobrien dw_attr_ref a = get_AT (die, DW_AT_high_pc); 493050397Sobrien 493190075Sobrien return a ? AT_lbl (a) : NULL; 493250397Sobrien} 493350397Sobrien 493450397Sobrien/* Return the value of the string attribute designated by ATTR_KIND, or 493550397Sobrien NULL if it is not present. */ 493650397Sobrien 493790075Sobrienstatic inline const char * 4938132718Skanget_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind) 493950397Sobrien{ 494090075Sobrien dw_attr_ref a = get_AT (die, attr_kind); 494150397Sobrien 494290075Sobrien return a ? AT_string (a) : NULL; 494350397Sobrien} 494450397Sobrien 494550397Sobrien/* Return the value of the flag attribute designated by ATTR_KIND, or -1 494650397Sobrien if it is not present. */ 494750397Sobrien 494850397Sobrienstatic inline int 4949132718Skanget_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind) 495050397Sobrien{ 495190075Sobrien dw_attr_ref a = get_AT (die, attr_kind); 495250397Sobrien 495390075Sobrien return a ? AT_flag (a) : 0; 495450397Sobrien} 495550397Sobrien 495650397Sobrien/* Return the value of the unsigned attribute designated by ATTR_KIND, or 0 495750397Sobrien if it is not present. */ 495850397Sobrien 495950397Sobrienstatic inline unsigned 4960132718Skanget_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind) 496150397Sobrien{ 496290075Sobrien dw_attr_ref a = get_AT (die, attr_kind); 496350397Sobrien 496490075Sobrien return a ? AT_unsigned (a) : 0; 496590075Sobrien} 496650397Sobrien 496790075Sobrienstatic inline dw_die_ref 4968132718Skanget_AT_ref (dw_die_ref die, enum dwarf_attribute attr_kind) 496990075Sobrien{ 497090075Sobrien dw_attr_ref a = get_AT (die, attr_kind); 497190075Sobrien 497290075Sobrien return a ? AT_ref (a) : NULL; 497350397Sobrien} 497450397Sobrien 4975132718Skan/* Return TRUE if the language is C or C++. */ 4976132718Skan 4977132718Skanstatic inline bool 4978132718Skanis_c_family (void) 497950397Sobrien{ 4980132718Skan unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language); 498150397Sobrien 498250397Sobrien return (lang == DW_LANG_C || lang == DW_LANG_C89 498350397Sobrien || lang == DW_LANG_C_plus_plus); 498490075Sobrien} 498550397Sobrien 4986132718Skan/* Return TRUE if the language is C++. */ 4987132718Skan 4988132718Skanstatic inline bool 4989132718Skanis_cxx (void) 499090075Sobrien{ 499190075Sobrien return (get_AT_unsigned (comp_unit_die, DW_AT_language) 499290075Sobrien == DW_LANG_C_plus_plus); 4993117395Skan} 499490075Sobrien 4995132718Skan/* Return TRUE if the language is Fortran. */ 4996132718Skan 4997132718Skanstatic inline bool 4998132718Skanis_fortran (void) 499950397Sobrien{ 5000132718Skan unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language); 500150397Sobrien 5002132718Skan return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90; 500390075Sobrien} 500450397Sobrien 5005132718Skan/* Return TRUE if the language is Java. */ 5006132718Skan 5007132718Skanstatic inline bool 5008132718Skanis_java (void) 500990075Sobrien{ 5010132718Skan unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language); 501190075Sobrien 5012132718Skan return lang == DW_LANG_Java; 501390075Sobrien} 501490075Sobrien 5015132718Skan/* Return TRUE if the language is Ada. */ 501690075Sobrien 5017132718Skanstatic inline bool 5018132718Skanis_ada (void) 501990075Sobrien{ 5020132718Skan unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language); 502190075Sobrien 5022132718Skan return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83; 5023132718Skan} 502490075Sobrien 5025132718Skan/* Free up the memory used by A. */ 502690075Sobrien 5027132718Skanstatic inline void free_AT (dw_attr_ref); 5028132718Skanstatic inline void 5029132718Skanfree_AT (dw_attr_ref a) 5030132718Skan{ 5031132718Skan if (AT_class (a) == dw_val_class_str) 5032132718Skan if (a->dw_attr_val.v.val_str->refcount) 5033132718Skan a->dw_attr_val.v.val_str->refcount--; 503490075Sobrien} 503590075Sobrien 503650397Sobrien/* Remove the specified attribute if present. */ 503750397Sobrien 503890075Sobrienstatic void 5039132718Skanremove_AT (dw_die_ref die, enum dwarf_attribute attr_kind) 504050397Sobrien{ 504190075Sobrien dw_attr_ref *p; 504290075Sobrien dw_attr_ref removed = NULL; 504350397Sobrien 504450397Sobrien if (die != NULL) 504550397Sobrien { 504690075Sobrien for (p = &(die->die_attr); *p; p = &((*p)->dw_attr_next)) 504790075Sobrien if ((*p)->dw_attr == attr_kind) 504890075Sobrien { 504990075Sobrien removed = *p; 505090075Sobrien *p = (*p)->dw_attr_next; 505190075Sobrien break; 505290075Sobrien } 505350397Sobrien 505450397Sobrien if (removed != 0) 505590075Sobrien free_AT (removed); 505650397Sobrien } 505750397Sobrien} 505850397Sobrien 5059146895Skan/* Remove child die whose die_tag is specified tag. */ 5060146895Skan 5061146895Skanstatic void 5062146895Skanremove_child_TAG (dw_die_ref die, enum dwarf_tag tag) 5063146895Skan{ 5064146895Skan dw_die_ref current, prev, next; 5065146895Skan current = die->die_child; 5066146895Skan prev = NULL; 5067146895Skan while (current != NULL) 5068146895Skan { 5069146895Skan if (current->die_tag == tag) 5070146895Skan { 5071146895Skan next = current->die_sib; 5072146895Skan if (prev == NULL) 5073146895Skan die->die_child = next; 5074146895Skan else 5075146895Skan prev->die_sib = next; 5076146895Skan free_die (current); 5077146895Skan current = next; 5078146895Skan } 5079146895Skan else 5080146895Skan { 5081146895Skan prev = current; 5082146895Skan current = current->die_sib; 5083146895Skan } 5084146895Skan } 5085146895Skan} 5086146895Skan 508790075Sobrien/* Free up the memory used by DIE. */ 508890075Sobrien 508990075Sobrienstatic inline void 5090132718Skanfree_die (dw_die_ref die) 509190075Sobrien{ 509290075Sobrien remove_children (die); 509390075Sobrien} 509490075Sobrien 509550397Sobrien/* Discard the children of this DIE. */ 509650397Sobrien 509790075Sobrienstatic void 5098132718Skanremove_children (dw_die_ref die) 509950397Sobrien{ 510090075Sobrien dw_die_ref child_die = die->die_child; 510150397Sobrien 510250397Sobrien die->die_child = NULL; 510350397Sobrien 510450397Sobrien while (child_die != NULL) 510550397Sobrien { 510690075Sobrien dw_die_ref tmp_die = child_die; 510790075Sobrien dw_attr_ref a; 510850397Sobrien 510950397Sobrien child_die = child_die->die_sib; 511090075Sobrien 511190075Sobrien for (a = tmp_die->die_attr; a != NULL;) 511250397Sobrien { 511390075Sobrien dw_attr_ref tmp_a = a; 511450397Sobrien 511550397Sobrien a = a->dw_attr_next; 511690075Sobrien free_AT (tmp_a); 511750397Sobrien } 511850397Sobrien 511990075Sobrien free_die (tmp_die); 512050397Sobrien } 512150397Sobrien} 512250397Sobrien 512390075Sobrien/* Add a child DIE below its parent. We build the lists up in reverse 512490075Sobrien addition order, and correct that in reverse_all_dies. */ 512550397Sobrien 512650397Sobrienstatic inline void 5127132718Skanadd_child_die (dw_die_ref die, dw_die_ref child_die) 512850397Sobrien{ 512950397Sobrien if (die != NULL && child_die != NULL) 513050397Sobrien { 513150397Sobrien if (die == child_die) 513250397Sobrien abort (); 513390075Sobrien 513450397Sobrien child_die->die_parent = die; 513590075Sobrien child_die->die_sib = die->die_child; 513690075Sobrien die->die_child = child_die; 513790075Sobrien } 513890075Sobrien} 513950397Sobrien 514090075Sobrien/* Move CHILD, which must be a child of PARENT or the DIE for which PARENT 514190075Sobrien is the specification, to the front of PARENT's list of children. */ 514290075Sobrien 514390075Sobrienstatic void 5144132718Skansplice_child_die (dw_die_ref parent, dw_die_ref child) 514590075Sobrien{ 514690075Sobrien dw_die_ref *p; 514790075Sobrien 514890075Sobrien /* We want the declaration DIE from inside the class, not the 514990075Sobrien specification DIE at toplevel. */ 515090075Sobrien if (child->die_parent != parent) 515190075Sobrien { 515290075Sobrien dw_die_ref tmp = get_AT_ref (child, DW_AT_specification); 515390075Sobrien 515490075Sobrien if (tmp) 515590075Sobrien child = tmp; 515650397Sobrien } 515790075Sobrien 515890075Sobrien if (child->die_parent != parent 515990075Sobrien && child->die_parent != get_AT_ref (parent, DW_AT_specification)) 516090075Sobrien abort (); 516190075Sobrien 516290075Sobrien for (p = &(child->die_parent->die_child); *p; p = &((*p)->die_sib)) 516390075Sobrien if (*p == child) 516490075Sobrien { 516590075Sobrien *p = child->die_sib; 516690075Sobrien break; 516790075Sobrien } 516890075Sobrien 5169132718Skan child->die_parent = parent; 517090075Sobrien child->die_sib = parent->die_child; 517190075Sobrien parent->die_child = child; 517250397Sobrien} 517350397Sobrien 517450397Sobrien/* Return a pointer to a newly created DIE node. */ 517550397Sobrien 517650397Sobrienstatic inline dw_die_ref 5177132718Skannew_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t) 517850397Sobrien{ 5179132718Skan dw_die_ref die = ggc_alloc_cleared (sizeof (die_node)); 518050397Sobrien 518150397Sobrien die->die_tag = tag_value; 518250397Sobrien 518350397Sobrien if (parent_die != NULL) 518450397Sobrien add_child_die (parent_die, die); 518550397Sobrien else 518650397Sobrien { 518750397Sobrien limbo_die_node *limbo_node; 518850397Sobrien 5189132718Skan limbo_node = ggc_alloc_cleared (sizeof (limbo_die_node)); 519050397Sobrien limbo_node->die = die; 519190075Sobrien limbo_node->created_for = t; 519250397Sobrien limbo_node->next = limbo_die_list; 519350397Sobrien limbo_die_list = limbo_node; 519450397Sobrien } 519550397Sobrien 519650397Sobrien return die; 519750397Sobrien} 519850397Sobrien 519950397Sobrien/* Return the DIE associated with the given type specifier. */ 520050397Sobrien 520150397Sobrienstatic inline dw_die_ref 5202132718Skanlookup_type_die (tree type) 520350397Sobrien{ 5204117395Skan return TYPE_SYMTAB_DIE (type); 520550397Sobrien} 520650397Sobrien 520750397Sobrien/* Equate a DIE to a given type specifier. */ 520850397Sobrien 520990075Sobrienstatic inline void 5210132718Skanequate_type_number_to_die (tree type, dw_die_ref type_die) 521150397Sobrien{ 5212117395Skan TYPE_SYMTAB_DIE (type) = type_die; 521350397Sobrien} 521450397Sobrien 521550397Sobrien/* Return the DIE associated with a given declaration. */ 521650397Sobrien 521750397Sobrienstatic inline dw_die_ref 5218132718Skanlookup_decl_die (tree decl) 521950397Sobrien{ 522090075Sobrien unsigned decl_id = DECL_UID (decl); 522150397Sobrien 522290075Sobrien return (decl_id < decl_die_table_in_use ? decl_die_table[decl_id] : NULL); 522350397Sobrien} 522450397Sobrien 522550397Sobrien/* Equate a DIE to a particular declaration. */ 522650397Sobrien 522750397Sobrienstatic void 5228132718Skanequate_decl_number_to_die (tree decl, dw_die_ref decl_die) 522950397Sobrien{ 523090075Sobrien unsigned int decl_id = DECL_UID (decl); 523190075Sobrien unsigned int num_allocated; 523250397Sobrien 523350397Sobrien if (decl_id >= decl_die_table_allocated) 523450397Sobrien { 523550397Sobrien num_allocated 523650397Sobrien = ((decl_id + 1 + DECL_DIE_TABLE_INCREMENT - 1) 523750397Sobrien / DECL_DIE_TABLE_INCREMENT) 523850397Sobrien * DECL_DIE_TABLE_INCREMENT; 523950397Sobrien 5240132718Skan decl_die_table = ggc_realloc (decl_die_table, 5241132718Skan sizeof (dw_die_ref) * num_allocated); 524250397Sobrien 5243132718Skan memset (&decl_die_table[decl_die_table_allocated], 0, 524450397Sobrien (num_allocated - decl_die_table_allocated) * sizeof (dw_die_ref)); 524550397Sobrien decl_die_table_allocated = num_allocated; 524650397Sobrien } 524750397Sobrien 524850397Sobrien if (decl_id >= decl_die_table_in_use) 524950397Sobrien decl_die_table_in_use = (decl_id + 1); 525050397Sobrien 525150397Sobrien decl_die_table[decl_id] = decl_die; 525250397Sobrien} 525350397Sobrien 525450397Sobrien/* Keep track of the number of spaces used to indent the 525550397Sobrien output of the debugging routines that print the structure of 525650397Sobrien the DIE internal representation. */ 525750397Sobrienstatic int print_indent; 525850397Sobrien 525950397Sobrien/* Indent the line the number of spaces given by print_indent. */ 526050397Sobrien 526150397Sobrienstatic inline void 5262132718Skanprint_spaces (FILE *outfile) 526350397Sobrien{ 526450397Sobrien fprintf (outfile, "%*s", print_indent, ""); 526550397Sobrien} 526650397Sobrien 526750397Sobrien/* Print the information associated with a given DIE, and its children. 526850397Sobrien This routine is a debugging aid only. */ 526950397Sobrien 527050397Sobrienstatic void 5271132718Skanprint_die (dw_die_ref die, FILE *outfile) 527250397Sobrien{ 527390075Sobrien dw_attr_ref a; 527490075Sobrien dw_die_ref c; 527550397Sobrien 527650397Sobrien print_spaces (outfile); 527750397Sobrien fprintf (outfile, "DIE %4lu: %s\n", 527850397Sobrien die->die_offset, dwarf_tag_name (die->die_tag)); 527950397Sobrien print_spaces (outfile); 528050397Sobrien fprintf (outfile, " abbrev id: %lu", die->die_abbrev); 528150397Sobrien fprintf (outfile, " offset: %lu\n", die->die_offset); 528250397Sobrien 528350397Sobrien for (a = die->die_attr; a != NULL; a = a->dw_attr_next) 528450397Sobrien { 528550397Sobrien print_spaces (outfile); 528650397Sobrien fprintf (outfile, " %s: ", dwarf_attr_name (a->dw_attr)); 528750397Sobrien 528890075Sobrien switch (AT_class (a)) 528950397Sobrien { 529050397Sobrien case dw_val_class_addr: 529150397Sobrien fprintf (outfile, "address"); 529250397Sobrien break; 529390075Sobrien case dw_val_class_offset: 529490075Sobrien fprintf (outfile, "offset"); 529590075Sobrien break; 529650397Sobrien case dw_val_class_loc: 529750397Sobrien fprintf (outfile, "location descriptor"); 529850397Sobrien break; 529990075Sobrien case dw_val_class_loc_list: 530090075Sobrien fprintf (outfile, "location list -> label:%s", 530190075Sobrien AT_loc_list (a)->ll_symbol); 530290075Sobrien break; 530390075Sobrien case dw_val_class_range_list: 530490075Sobrien fprintf (outfile, "range list"); 530590075Sobrien break; 530650397Sobrien case dw_val_class_const: 5307132718Skan fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a)); 530850397Sobrien break; 530950397Sobrien case dw_val_class_unsigned_const: 5310132718Skan fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a)); 531150397Sobrien break; 531250397Sobrien case dw_val_class_long_long: 531350397Sobrien fprintf (outfile, "constant (%lu,%lu)", 531490075Sobrien a->dw_attr_val.v.val_long_long.hi, 531590075Sobrien a->dw_attr_val.v.val_long_long.low); 531650397Sobrien break; 5317132718Skan case dw_val_class_vec: 5318132718Skan fprintf (outfile, "floating-point or vector constant"); 531950397Sobrien break; 532050397Sobrien case dw_val_class_flag: 532190075Sobrien fprintf (outfile, "%u", AT_flag (a)); 532250397Sobrien break; 532350397Sobrien case dw_val_class_die_ref: 532490075Sobrien if (AT_ref (a) != NULL) 532590075Sobrien { 532690075Sobrien if (AT_ref (a)->die_symbol) 532790075Sobrien fprintf (outfile, "die -> label: %s", AT_ref (a)->die_symbol); 532890075Sobrien else 532990075Sobrien fprintf (outfile, "die -> %lu", AT_ref (a)->die_offset); 533090075Sobrien } 533150397Sobrien else 533250397Sobrien fprintf (outfile, "die -> <null>"); 533350397Sobrien break; 533450397Sobrien case dw_val_class_lbl_id: 533552284Sobrien case dw_val_class_lbl_offset: 533690075Sobrien fprintf (outfile, "label: %s", AT_lbl (a)); 533750397Sobrien break; 533850397Sobrien case dw_val_class_str: 533990075Sobrien if (AT_string (a) != NULL) 534090075Sobrien fprintf (outfile, "\"%s\"", AT_string (a)); 534150397Sobrien else 534250397Sobrien fprintf (outfile, "<null>"); 534350397Sobrien break; 534450397Sobrien default: 534550397Sobrien break; 534650397Sobrien } 534750397Sobrien 534850397Sobrien fprintf (outfile, "\n"); 534950397Sobrien } 535050397Sobrien 535150397Sobrien if (die->die_child != NULL) 535250397Sobrien { 535350397Sobrien print_indent += 4; 535450397Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 535550397Sobrien print_die (c, outfile); 535650397Sobrien 535750397Sobrien print_indent -= 4; 535850397Sobrien } 535990075Sobrien if (print_indent == 0) 536090075Sobrien fprintf (outfile, "\n"); 536150397Sobrien} 536250397Sobrien 536350397Sobrien/* Print the contents of the source code line number correspondence table. 536450397Sobrien This routine is a debugging aid only. */ 536550397Sobrien 536650397Sobrienstatic void 5367132718Skanprint_dwarf_line_table (FILE *outfile) 536850397Sobrien{ 536990075Sobrien unsigned i; 537090075Sobrien dw_line_info_ref line_info; 537150397Sobrien 537250397Sobrien fprintf (outfile, "\n\nDWARF source line information\n"); 537390075Sobrien for (i = 1; i < line_info_table_in_use; i++) 537450397Sobrien { 537550397Sobrien line_info = &line_info_table[i]; 537650397Sobrien fprintf (outfile, "%5d: ", i); 5377132718Skan fprintf (outfile, "%-20s", 5378132718Skan VARRAY_CHAR_PTR (file_table, line_info->dw_file_num)); 537950397Sobrien fprintf (outfile, "%6ld", line_info->dw_line_num); 538050397Sobrien fprintf (outfile, "\n"); 538150397Sobrien } 538250397Sobrien 538350397Sobrien fprintf (outfile, "\n\n"); 538450397Sobrien} 538550397Sobrien 538650397Sobrien/* Print the information collected for a given DIE. */ 538750397Sobrien 538850397Sobrienvoid 5389132718Skandebug_dwarf_die (dw_die_ref die) 539050397Sobrien{ 539150397Sobrien print_die (die, stderr); 539250397Sobrien} 539350397Sobrien 539450397Sobrien/* Print all DWARF information collected for the compilation unit. 539550397Sobrien This routine is a debugging aid only. */ 539650397Sobrien 539750397Sobrienvoid 5398132718Skandebug_dwarf (void) 539950397Sobrien{ 540050397Sobrien print_indent = 0; 540150397Sobrien print_die (comp_unit_die, stderr); 540290075Sobrien if (! DWARF2_ASM_LINE_DEBUG_INFO) 540390075Sobrien print_dwarf_line_table (stderr); 540450397Sobrien} 540550397Sobrien 540690075Sobrien/* We build up the lists of children and attributes by pushing new ones 540790075Sobrien onto the beginning of the list. Reverse the lists for DIE so that 540890075Sobrien they are in order of addition. */ 540950397Sobrien 541050397Sobrienstatic void 5411132718Skanreverse_die_lists (dw_die_ref die) 541250397Sobrien{ 541390075Sobrien dw_die_ref c, cp, cn; 541490075Sobrien dw_attr_ref a, ap, an; 541590075Sobrien 541690075Sobrien for (a = die->die_attr, ap = 0; a; a = an) 541750397Sobrien { 541890075Sobrien an = a->dw_attr_next; 541990075Sobrien a->dw_attr_next = ap; 542090075Sobrien ap = a; 542190075Sobrien } 542250397Sobrien 542390075Sobrien die->die_attr = ap; 542450397Sobrien 542590075Sobrien for (c = die->die_child, cp = 0; c; c = cn) 542690075Sobrien { 542790075Sobrien cn = c->die_sib; 542890075Sobrien c->die_sib = cp; 542990075Sobrien cp = c; 543050397Sobrien } 543150397Sobrien 543290075Sobrien die->die_child = cp; 543390075Sobrien} 543490075Sobrien 543590075Sobrien/* reverse_die_lists only reverses the single die you pass it. Since we used to 543690075Sobrien reverse all dies in add_sibling_attributes, which runs through all the dies, 543790075Sobrien it would reverse all the dies. Now, however, since we don't call 543890075Sobrien reverse_die_lists in add_sibling_attributes, we need a routine to 543990075Sobrien recursively reverse all the dies. This is that routine. */ 544090075Sobrien 544190075Sobrienstatic void 5442132718Skanreverse_all_dies (dw_die_ref die) 544390075Sobrien{ 544490075Sobrien dw_die_ref c; 544590075Sobrien 544690075Sobrien reverse_die_lists (die); 544790075Sobrien 544890075Sobrien for (c = die->die_child; c; c = c->die_sib) 544990075Sobrien reverse_all_dies (c); 545090075Sobrien} 545190075Sobrien 545290075Sobrien/* Start a new compilation unit DIE for an include file. OLD_UNIT is the CU 545390075Sobrien for the enclosing include file, if any. BINCL_DIE is the DW_TAG_GNU_BINCL 545490075Sobrien DIE that marks the start of the DIEs for this include file. */ 545590075Sobrien 545690075Sobrienstatic dw_die_ref 5457132718Skanpush_new_compile_unit (dw_die_ref old_unit, dw_die_ref bincl_die) 545890075Sobrien{ 545990075Sobrien const char *filename = get_AT_string (bincl_die, DW_AT_name); 546090075Sobrien dw_die_ref new_unit = gen_compile_unit_die (filename); 546190075Sobrien 546290075Sobrien new_unit->die_sib = old_unit; 546390075Sobrien return new_unit; 546490075Sobrien} 546590075Sobrien 546690075Sobrien/* Close an include-file CU and reopen the enclosing one. */ 546790075Sobrien 546890075Sobrienstatic dw_die_ref 5469132718Skanpop_compile_unit (dw_die_ref old_unit) 547090075Sobrien{ 547190075Sobrien dw_die_ref new_unit = old_unit->die_sib; 547290075Sobrien 547390075Sobrien old_unit->die_sib = NULL; 547490075Sobrien return new_unit; 547590075Sobrien} 547690075Sobrien 547790075Sobrien#define CHECKSUM(FOO) md5_process_bytes (&(FOO), sizeof (FOO), ctx) 547890075Sobrien#define CHECKSUM_STRING(FOO) md5_process_bytes ((FOO), strlen (FOO), ctx) 547990075Sobrien 548090075Sobrien/* Calculate the checksum of a location expression. */ 548190075Sobrien 548290075Sobrienstatic inline void 5483132718Skanloc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx) 548490075Sobrien{ 548590075Sobrien CHECKSUM (loc->dw_loc_opc); 548690075Sobrien CHECKSUM (loc->dw_loc_oprnd1); 548790075Sobrien CHECKSUM (loc->dw_loc_oprnd2); 548890075Sobrien} 548990075Sobrien 549090075Sobrien/* Calculate the checksum of an attribute. */ 549190075Sobrien 549290075Sobrienstatic void 5493132718Skanattr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark) 549490075Sobrien{ 549590075Sobrien dw_loc_descr_ref loc; 549690075Sobrien rtx r; 549790075Sobrien 549890075Sobrien CHECKSUM (at->dw_attr); 549990075Sobrien 550090075Sobrien /* We don't care about differences in file numbering. */ 550190075Sobrien if (at->dw_attr == DW_AT_decl_file 550290075Sobrien /* Or that this was compiled with a different compiler snapshot; if 550390075Sobrien the output is the same, that's what matters. */ 550490075Sobrien || at->dw_attr == DW_AT_producer) 550590075Sobrien return; 550690075Sobrien 550790075Sobrien switch (AT_class (at)) 550890075Sobrien { 550990075Sobrien case dw_val_class_const: 551090075Sobrien CHECKSUM (at->dw_attr_val.v.val_int); 551190075Sobrien break; 551290075Sobrien case dw_val_class_unsigned_const: 551390075Sobrien CHECKSUM (at->dw_attr_val.v.val_unsigned); 551490075Sobrien break; 551590075Sobrien case dw_val_class_long_long: 551690075Sobrien CHECKSUM (at->dw_attr_val.v.val_long_long); 551790075Sobrien break; 5518132718Skan case dw_val_class_vec: 5519132718Skan CHECKSUM (at->dw_attr_val.v.val_vec); 552090075Sobrien break; 552190075Sobrien case dw_val_class_flag: 552290075Sobrien CHECKSUM (at->dw_attr_val.v.val_flag); 552390075Sobrien break; 552490075Sobrien case dw_val_class_str: 552590075Sobrien CHECKSUM_STRING (AT_string (at)); 552690075Sobrien break; 552790075Sobrien 552890075Sobrien case dw_val_class_addr: 552990075Sobrien r = AT_addr (at); 553090075Sobrien switch (GET_CODE (r)) 553190075Sobrien { 553290075Sobrien case SYMBOL_REF: 553390075Sobrien CHECKSUM_STRING (XSTR (r, 0)); 553490075Sobrien break; 553590075Sobrien 553690075Sobrien default: 553790075Sobrien abort (); 553890075Sobrien } 553990075Sobrien break; 554090075Sobrien 554190075Sobrien case dw_val_class_offset: 554290075Sobrien CHECKSUM (at->dw_attr_val.v.val_offset); 554390075Sobrien break; 554490075Sobrien 554590075Sobrien case dw_val_class_loc: 554690075Sobrien for (loc = AT_loc (at); loc; loc = loc->dw_loc_next) 554790075Sobrien loc_checksum (loc, ctx); 554890075Sobrien break; 554990075Sobrien 555090075Sobrien case dw_val_class_die_ref: 5551117395Skan die_checksum (AT_ref (at), ctx, mark); 5552117395Skan break; 555390075Sobrien 555490075Sobrien case dw_val_class_fde_ref: 555590075Sobrien case dw_val_class_lbl_id: 555690075Sobrien case dw_val_class_lbl_offset: 555790075Sobrien break; 555890075Sobrien 555990075Sobrien default: 556090075Sobrien break; 556190075Sobrien } 556290075Sobrien} 556390075Sobrien 556490075Sobrien/* Calculate the checksum of a DIE. */ 556590075Sobrien 556690075Sobrienstatic void 5567132718Skandie_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark) 556890075Sobrien{ 556990075Sobrien dw_die_ref c; 557090075Sobrien dw_attr_ref a; 557190075Sobrien 5572117395Skan /* To avoid infinite recursion. */ 5573117395Skan if (die->die_mark) 5574117395Skan { 5575117395Skan CHECKSUM (die->die_mark); 5576117395Skan return; 5577117395Skan } 5578117395Skan die->die_mark = ++(*mark); 5579117395Skan 558090075Sobrien CHECKSUM (die->die_tag); 558190075Sobrien 558290075Sobrien for (a = die->die_attr; a; a = a->dw_attr_next) 5583117395Skan attr_checksum (a, ctx, mark); 558490075Sobrien 558590075Sobrien for (c = die->die_child; c; c = c->die_sib) 5586117395Skan die_checksum (c, ctx, mark); 558790075Sobrien} 558890075Sobrien 558990075Sobrien#undef CHECKSUM 559090075Sobrien#undef CHECKSUM_STRING 559190075Sobrien 5592117395Skan/* Do the location expressions look same? */ 5593117395Skanstatic inline int 5594132718Skansame_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark) 5595117395Skan{ 5596117395Skan return loc1->dw_loc_opc == loc2->dw_loc_opc 5597117395Skan && same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark) 5598117395Skan && same_dw_val_p (&loc1->dw_loc_oprnd2, &loc2->dw_loc_oprnd2, mark); 5599117395Skan} 5600117395Skan 5601117395Skan/* Do the values look the same? */ 5602117395Skanstatic int 5603132718Skansame_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark) 5604117395Skan{ 5605117395Skan dw_loc_descr_ref loc1, loc2; 5606117395Skan rtx r1, r2; 5607117395Skan 5608117395Skan if (v1->val_class != v2->val_class) 5609117395Skan return 0; 5610117395Skan 5611117395Skan switch (v1->val_class) 5612117395Skan { 5613117395Skan case dw_val_class_const: 5614117395Skan return v1->v.val_int == v2->v.val_int; 5615117395Skan case dw_val_class_unsigned_const: 5616117395Skan return v1->v.val_unsigned == v2->v.val_unsigned; 5617117395Skan case dw_val_class_long_long: 5618117395Skan return v1->v.val_long_long.hi == v2->v.val_long_long.hi 5619132718Skan && v1->v.val_long_long.low == v2->v.val_long_long.low; 5620132718Skan case dw_val_class_vec: 5621132718Skan if (v1->v.val_vec.length != v2->v.val_vec.length 5622132718Skan || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size) 5623117395Skan return 0; 5624132718Skan if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array, 5625132718Skan v1->v.val_vec.length * v1->v.val_vec.elt_size)) 5626132718Skan return 0; 5627117395Skan return 1; 5628117395Skan case dw_val_class_flag: 5629117395Skan return v1->v.val_flag == v2->v.val_flag; 5630117395Skan case dw_val_class_str: 5631132718Skan return !strcmp(v1->v.val_str->str, v2->v.val_str->str); 5632117395Skan 5633117395Skan case dw_val_class_addr: 5634117395Skan r1 = v1->v.val_addr; 5635117395Skan r2 = v2->v.val_addr; 5636117395Skan if (GET_CODE (r1) != GET_CODE (r2)) 5637117395Skan return 0; 5638117395Skan switch (GET_CODE (r1)) 5639117395Skan { 5640117395Skan case SYMBOL_REF: 5641117395Skan return !strcmp (XSTR (r1, 0), XSTR (r2, 0)); 5642117395Skan 5643117395Skan default: 5644117395Skan abort (); 5645117395Skan } 5646117395Skan 5647117395Skan case dw_val_class_offset: 5648117395Skan return v1->v.val_offset == v2->v.val_offset; 5649117395Skan 5650117395Skan case dw_val_class_loc: 5651117395Skan for (loc1 = v1->v.val_loc, loc2 = v2->v.val_loc; 5652117395Skan loc1 && loc2; 5653117395Skan loc1 = loc1->dw_loc_next, loc2 = loc2->dw_loc_next) 5654117395Skan if (!same_loc_p (loc1, loc2, mark)) 5655117395Skan return 0; 5656117395Skan return !loc1 && !loc2; 5657117395Skan 5658117395Skan case dw_val_class_die_ref: 5659117395Skan return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark); 5660117395Skan 5661117395Skan case dw_val_class_fde_ref: 5662117395Skan case dw_val_class_lbl_id: 5663117395Skan case dw_val_class_lbl_offset: 5664117395Skan return 1; 5665117395Skan 5666117395Skan default: 5667117395Skan return 1; 5668117395Skan } 5669117395Skan} 5670117395Skan 5671117395Skan/* Do the attributes look the same? */ 5672117395Skan 5673117395Skanstatic int 5674132718Skansame_attr_p (dw_attr_ref at1, dw_attr_ref at2, int *mark) 5675117395Skan{ 5676117395Skan if (at1->dw_attr != at2->dw_attr) 5677117395Skan return 0; 5678117395Skan 5679117395Skan /* We don't care about differences in file numbering. */ 5680117395Skan if (at1->dw_attr == DW_AT_decl_file 5681117395Skan /* Or that this was compiled with a different compiler snapshot; if 5682117395Skan the output is the same, that's what matters. */ 5683117395Skan || at1->dw_attr == DW_AT_producer) 5684117395Skan return 1; 5685117395Skan 5686117395Skan return same_dw_val_p (&at1->dw_attr_val, &at2->dw_attr_val, mark); 5687117395Skan} 5688117395Skan 5689117395Skan/* Do the dies look the same? */ 5690117395Skan 5691117395Skanstatic int 5692132718Skansame_die_p (dw_die_ref die1, dw_die_ref die2, int *mark) 5693117395Skan{ 5694117395Skan dw_die_ref c1, c2; 5695117395Skan dw_attr_ref a1, a2; 5696117395Skan 5697117395Skan /* To avoid infinite recursion. */ 5698117395Skan if (die1->die_mark) 5699117395Skan return die1->die_mark == die2->die_mark; 5700117395Skan die1->die_mark = die2->die_mark = ++(*mark); 5701117395Skan 5702117395Skan if (die1->die_tag != die2->die_tag) 5703117395Skan return 0; 5704117395Skan 5705117395Skan for (a1 = die1->die_attr, a2 = die2->die_attr; 5706117395Skan a1 && a2; 5707117395Skan a1 = a1->dw_attr_next, a2 = a2->dw_attr_next) 5708117395Skan if (!same_attr_p (a1, a2, mark)) 5709117395Skan return 0; 5710117395Skan if (a1 || a2) 5711117395Skan return 0; 5712117395Skan 5713117395Skan for (c1 = die1->die_child, c2 = die2->die_child; 5714117395Skan c1 && c2; 5715117395Skan c1 = c1->die_sib, c2 = c2->die_sib) 5716117395Skan if (!same_die_p (c1, c2, mark)) 5717117395Skan return 0; 5718117395Skan if (c1 || c2) 5719117395Skan return 0; 5720117395Skan 5721117395Skan return 1; 5722117395Skan} 5723117395Skan 5724117395Skan/* Do the dies look the same? Wrapper around same_die_p. */ 5725117395Skan 5726117395Skanstatic int 5727132718Skansame_die_p_wrap (dw_die_ref die1, dw_die_ref die2) 5728117395Skan{ 5729117395Skan int mark = 0; 5730117395Skan int ret = same_die_p (die1, die2, &mark); 5731117395Skan 5732117395Skan unmark_all_dies (die1); 5733117395Skan unmark_all_dies (die2); 5734117395Skan 5735117395Skan return ret; 5736117395Skan} 5737117395Skan 573890075Sobrien/* The prefix to attach to symbols on DIEs in the current comdat debug 573990075Sobrien info section. */ 574090075Sobrienstatic char *comdat_symbol_id; 574190075Sobrien 574290075Sobrien/* The index of the current symbol within the current comdat CU. */ 574390075Sobrienstatic unsigned int comdat_symbol_number; 574490075Sobrien 574590075Sobrien/* Calculate the MD5 checksum of the compilation unit DIE UNIT_DIE and its 574690075Sobrien children, and set comdat_symbol_id accordingly. */ 574790075Sobrien 574890075Sobrienstatic void 5749132718Skancompute_section_prefix (dw_die_ref unit_die) 575090075Sobrien{ 5751117395Skan const char *die_name = get_AT_string (unit_die, DW_AT_name); 5752117395Skan const char *base = die_name ? lbasename (die_name) : "anonymous"; 5753132718Skan char *name = alloca (strlen (base) + 64); 575490075Sobrien char *p; 5755117395Skan int i, mark; 575690075Sobrien unsigned char checksum[16]; 575790075Sobrien struct md5_ctx ctx; 575890075Sobrien 575990075Sobrien /* Compute the checksum of the DIE, then append part of it as hex digits to 576090075Sobrien the name filename of the unit. */ 576190075Sobrien 576290075Sobrien md5_init_ctx (&ctx); 5763117395Skan mark = 0; 5764117395Skan die_checksum (unit_die, &ctx, &mark); 5765117395Skan unmark_all_dies (unit_die); 576690075Sobrien md5_finish_ctx (&ctx, checksum); 576790075Sobrien 576890075Sobrien sprintf (name, "%s.", base); 576990075Sobrien clean_symbol_name (name); 577090075Sobrien 577190075Sobrien p = name + strlen (name); 577290075Sobrien for (i = 0; i < 4; i++) 577390075Sobrien { 577490075Sobrien sprintf (p, "%.2x", checksum[i]); 577590075Sobrien p += 2; 577690075Sobrien } 577790075Sobrien 577890075Sobrien comdat_symbol_id = unit_die->die_symbol = xstrdup (name); 577990075Sobrien comdat_symbol_number = 0; 578090075Sobrien} 578190075Sobrien 578290075Sobrien/* Returns nonzero if DIE represents a type, in the sense of TYPE_P. */ 578390075Sobrien 578490075Sobrienstatic int 5785132718Skanis_type_die (dw_die_ref die) 578690075Sobrien{ 578790075Sobrien switch (die->die_tag) 578890075Sobrien { 578990075Sobrien case DW_TAG_array_type: 579090075Sobrien case DW_TAG_class_type: 579190075Sobrien case DW_TAG_enumeration_type: 579290075Sobrien case DW_TAG_pointer_type: 579390075Sobrien case DW_TAG_reference_type: 579490075Sobrien case DW_TAG_string_type: 579590075Sobrien case DW_TAG_structure_type: 579690075Sobrien case DW_TAG_subroutine_type: 579790075Sobrien case DW_TAG_union_type: 579890075Sobrien case DW_TAG_ptr_to_member_type: 579990075Sobrien case DW_TAG_set_type: 580090075Sobrien case DW_TAG_subrange_type: 580190075Sobrien case DW_TAG_base_type: 580290075Sobrien case DW_TAG_const_type: 580390075Sobrien case DW_TAG_file_type: 580490075Sobrien case DW_TAG_packed_type: 580590075Sobrien case DW_TAG_volatile_type: 5806117395Skan case DW_TAG_typedef: 580790075Sobrien return 1; 580890075Sobrien default: 580990075Sobrien return 0; 581090075Sobrien } 581190075Sobrien} 581290075Sobrien 581390075Sobrien/* Returns 1 iff C is the sort of DIE that should go into a COMDAT CU. 581490075Sobrien Basically, we want to choose the bits that are likely to be shared between 581590075Sobrien compilations (types) and leave out the bits that are specific to individual 581690075Sobrien compilations (functions). */ 581790075Sobrien 581890075Sobrienstatic int 5819132718Skanis_comdat_die (dw_die_ref c) 582090075Sobrien{ 582190075Sobrien /* I think we want to leave base types and __vtbl_ptr_type in the main CU, as 582290075Sobrien we do for stabs. The advantage is a greater likelihood of sharing between 582390075Sobrien objects that don't include headers in the same order (and therefore would 582490075Sobrien put the base types in a different comdat). jason 8/28/00 */ 582590075Sobrien 582690075Sobrien if (c->die_tag == DW_TAG_base_type) 582790075Sobrien return 0; 582890075Sobrien 582990075Sobrien if (c->die_tag == DW_TAG_pointer_type 583090075Sobrien || c->die_tag == DW_TAG_reference_type 583190075Sobrien || c->die_tag == DW_TAG_const_type 583290075Sobrien || c->die_tag == DW_TAG_volatile_type) 583390075Sobrien { 583490075Sobrien dw_die_ref t = get_AT_ref (c, DW_AT_type); 583590075Sobrien 583690075Sobrien return t ? is_comdat_die (t) : 0; 583790075Sobrien } 583890075Sobrien 583990075Sobrien return is_type_die (c); 584090075Sobrien} 584190075Sobrien 584290075Sobrien/* Returns 1 iff C is the sort of DIE that might be referred to from another 584390075Sobrien compilation unit. */ 584490075Sobrien 584590075Sobrienstatic int 5846132718Skanis_symbol_die (dw_die_ref c) 584790075Sobrien{ 584890075Sobrien return (is_type_die (c) 5849117395Skan || (get_AT (c, DW_AT_declaration) 585090075Sobrien && !get_AT (c, DW_AT_specification))); 585190075Sobrien} 585290075Sobrien 585390075Sobrienstatic char * 5854132718Skangen_internal_sym (const char *prefix) 585590075Sobrien{ 585690075Sobrien char buf[256]; 585790075Sobrien 585890075Sobrien ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++); 585990075Sobrien return xstrdup (buf); 586090075Sobrien} 586190075Sobrien 586290075Sobrien/* Assign symbols to all worthy DIEs under DIE. */ 586390075Sobrien 586490075Sobrienstatic void 5865132718Skanassign_symbol_names (dw_die_ref die) 586690075Sobrien{ 586790075Sobrien dw_die_ref c; 586890075Sobrien 586990075Sobrien if (is_symbol_die (die)) 587090075Sobrien { 587190075Sobrien if (comdat_symbol_id) 587290075Sobrien { 587390075Sobrien char *p = alloca (strlen (comdat_symbol_id) + 64); 587490075Sobrien 587590075Sobrien sprintf (p, "%s.%s.%x", DIE_LABEL_PREFIX, 587690075Sobrien comdat_symbol_id, comdat_symbol_number++); 587790075Sobrien die->die_symbol = xstrdup (p); 587890075Sobrien } 587990075Sobrien else 588090075Sobrien die->die_symbol = gen_internal_sym ("LDIE"); 588190075Sobrien } 588290075Sobrien 588350397Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 588490075Sobrien assign_symbol_names (c); 588590075Sobrien} 588690075Sobrien 5887117395Skanstruct cu_hash_table_entry 5888117395Skan{ 5889117395Skan dw_die_ref cu; 5890117395Skan unsigned min_comdat_num, max_comdat_num; 5891117395Skan struct cu_hash_table_entry *next; 5892117395Skan}; 5893117395Skan 5894117395Skan/* Routines to manipulate hash table of CUs. */ 5895117395Skanstatic hashval_t 5896132718Skanhtab_cu_hash (const void *of) 5897117395Skan{ 5898117395Skan const struct cu_hash_table_entry *entry = of; 5899117395Skan 5900117395Skan return htab_hash_string (entry->cu->die_symbol); 5901117395Skan} 5902117395Skan 5903117395Skanstatic int 5904132718Skanhtab_cu_eq (const void *of1, const void *of2) 5905117395Skan{ 5906117395Skan const struct cu_hash_table_entry *entry1 = of1; 5907117395Skan const struct die_struct *entry2 = of2; 5908117395Skan 5909117395Skan return !strcmp (entry1->cu->die_symbol, entry2->die_symbol); 5910117395Skan} 5911117395Skan 5912117395Skanstatic void 5913132718Skanhtab_cu_del (void *what) 5914117395Skan{ 5915117395Skan struct cu_hash_table_entry *next, *entry = what; 5916117395Skan 5917117395Skan while (entry) 5918117395Skan { 5919117395Skan next = entry->next; 5920117395Skan free (entry); 5921117395Skan entry = next; 5922117395Skan } 5923117395Skan} 5924117395Skan 5925117395Skan/* Check whether we have already seen this CU and set up SYM_NUM 5926117395Skan accordingly. */ 5927117395Skanstatic int 5928132718Skancheck_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num) 5929117395Skan{ 5930117395Skan struct cu_hash_table_entry dummy; 5931117395Skan struct cu_hash_table_entry **slot, *entry, *last = &dummy; 5932117395Skan 5933117395Skan dummy.max_comdat_num = 0; 5934117395Skan 5935117395Skan slot = (struct cu_hash_table_entry **) 5936117395Skan htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol), 5937117395Skan INSERT); 5938117395Skan entry = *slot; 5939117395Skan 5940117395Skan for (; entry; last = entry, entry = entry->next) 5941117395Skan { 5942117395Skan if (same_die_p_wrap (cu, entry->cu)) 5943117395Skan break; 5944117395Skan } 5945117395Skan 5946117395Skan if (entry) 5947117395Skan { 5948117395Skan *sym_num = entry->min_comdat_num; 5949117395Skan return 1; 5950117395Skan } 5951117395Skan 5952117395Skan entry = xcalloc (1, sizeof (struct cu_hash_table_entry)); 5953117395Skan entry->cu = cu; 5954117395Skan entry->min_comdat_num = *sym_num = last->max_comdat_num; 5955117395Skan entry->next = *slot; 5956117395Skan *slot = entry; 5957117395Skan 5958117395Skan return 0; 5959117395Skan} 5960117395Skan 5961117395Skan/* Record SYM_NUM to record of CU in HTABLE. */ 5962117395Skanstatic void 5963132718Skanrecord_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num) 5964117395Skan{ 5965117395Skan struct cu_hash_table_entry **slot, *entry; 5966117395Skan 5967117395Skan slot = (struct cu_hash_table_entry **) 5968117395Skan htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_symbol), 5969117395Skan NO_INSERT); 5970117395Skan entry = *slot; 5971117395Skan 5972117395Skan entry->max_comdat_num = sym_num; 5973117395Skan} 5974117395Skan 597590075Sobrien/* Traverse the DIE (which is always comp_unit_die), and set up 597690075Sobrien additional compilation units for each of the include files we see 597790075Sobrien bracketed by BINCL/EINCL. */ 597890075Sobrien 597990075Sobrienstatic void 5980132718Skanbreak_out_includes (dw_die_ref die) 598190075Sobrien{ 598290075Sobrien dw_die_ref *ptr; 598390075Sobrien dw_die_ref unit = NULL; 5984117395Skan limbo_die_node *node, **pnode; 5985117395Skan htab_t cu_hash_table; 598690075Sobrien 5987117395Skan for (ptr = &(die->die_child); *ptr;) 598890075Sobrien { 598990075Sobrien dw_die_ref c = *ptr; 599090075Sobrien 599190075Sobrien if (c->die_tag == DW_TAG_GNU_BINCL || c->die_tag == DW_TAG_GNU_EINCL 599290075Sobrien || (unit && is_comdat_die (c))) 599390075Sobrien { 599490075Sobrien /* This DIE is for a secondary CU; remove it from the main one. */ 599590075Sobrien *ptr = c->die_sib; 599690075Sobrien 599790075Sobrien if (c->die_tag == DW_TAG_GNU_BINCL) 599890075Sobrien { 599990075Sobrien unit = push_new_compile_unit (unit, c); 600090075Sobrien free_die (c); 600190075Sobrien } 600290075Sobrien else if (c->die_tag == DW_TAG_GNU_EINCL) 600390075Sobrien { 600490075Sobrien unit = pop_compile_unit (unit); 600590075Sobrien free_die (c); 600690075Sobrien } 600790075Sobrien else 600890075Sobrien add_child_die (unit, c); 600990075Sobrien } 601090075Sobrien else 601190075Sobrien { 601290075Sobrien /* Leave this DIE in the main CU. */ 601390075Sobrien ptr = &(c->die_sib); 601490075Sobrien continue; 601590075Sobrien } 601690075Sobrien } 601790075Sobrien 601890075Sobrien#if 0 601990075Sobrien /* We can only use this in debugging, since the frontend doesn't check 602090075Sobrien to make sure that we leave every include file we enter. */ 602190075Sobrien if (unit != NULL) 602290075Sobrien abort (); 602390075Sobrien#endif 602490075Sobrien 602590075Sobrien assign_symbol_names (die); 6026117395Skan cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del); 6027117395Skan for (node = limbo_die_list, pnode = &limbo_die_list; 6028117395Skan node; 6029117395Skan node = node->next) 603090075Sobrien { 6031117395Skan int is_dupl; 6032117395Skan 603390075Sobrien compute_section_prefix (node->die); 6034117395Skan is_dupl = check_duplicate_cu (node->die, cu_hash_table, 6035117395Skan &comdat_symbol_number); 603690075Sobrien assign_symbol_names (node->die); 6037117395Skan if (is_dupl) 6038117395Skan *pnode = node->next; 6039117395Skan else 6040132718Skan { 6041117395Skan pnode = &node->next; 6042117395Skan record_comdat_symbol_number (node->die, cu_hash_table, 6043117395Skan comdat_symbol_number); 6044117395Skan } 604590075Sobrien } 6046117395Skan htab_delete (cu_hash_table); 604790075Sobrien} 604890075Sobrien 604990075Sobrien/* Traverse the DIE and add a sibling attribute if it may have the 605090075Sobrien effect of speeding up access to siblings. To save some space, 605190075Sobrien avoid generating sibling attributes for DIE's without children. */ 605290075Sobrien 605390075Sobrienstatic void 6054132718Skanadd_sibling_attributes (dw_die_ref die) 605590075Sobrien{ 605690075Sobrien dw_die_ref c; 605790075Sobrien 605890075Sobrien if (die->die_tag != DW_TAG_compile_unit 605990075Sobrien && die->die_sib && die->die_child != NULL) 606090075Sobrien /* Add the sibling link to the front of the attribute list. */ 606190075Sobrien add_AT_die_ref (die, DW_AT_sibling, die->die_sib); 606290075Sobrien 606390075Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 606450397Sobrien add_sibling_attributes (c); 606550397Sobrien} 606650397Sobrien 606790075Sobrien/* Output all location lists for the DIE and its children. */ 606850397Sobrien 606950397Sobrienstatic void 6070132718Skanoutput_location_lists (dw_die_ref die) 607190075Sobrien{ 607290075Sobrien dw_die_ref c; 607390075Sobrien dw_attr_ref d_attr; 607490075Sobrien 607590075Sobrien for (d_attr = die->die_attr; d_attr; d_attr = d_attr->dw_attr_next) 607690075Sobrien if (AT_class (d_attr) == dw_val_class_loc_list) 607790075Sobrien output_loc_list (AT_loc_list (d_attr)); 607890075Sobrien 607990075Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 608090075Sobrien output_location_lists (c); 608190075Sobrien 608290075Sobrien} 6083117395Skan 608490075Sobrien/* The format of each DIE (and its attribute value pairs) is encoded in an 608590075Sobrien abbreviation table. This routine builds the abbreviation table and assigns 608690075Sobrien a unique abbreviation id for each abbreviation entry. The children of each 608790075Sobrien die are visited recursively. */ 608890075Sobrien 608990075Sobrienstatic void 6090132718Skanbuild_abbrev_table (dw_die_ref die) 609150397Sobrien{ 609290075Sobrien unsigned long abbrev_id; 609390075Sobrien unsigned int n_alloc; 609490075Sobrien dw_die_ref c; 609590075Sobrien dw_attr_ref d_attr, a_attr; 609690075Sobrien 609790075Sobrien /* Scan the DIE references, and mark as external any that refer to 609890075Sobrien DIEs from other CUs (i.e. those which are not marked). */ 609990075Sobrien for (d_attr = die->die_attr; d_attr; d_attr = d_attr->dw_attr_next) 610090075Sobrien if (AT_class (d_attr) == dw_val_class_die_ref 610190075Sobrien && AT_ref (d_attr)->die_mark == 0) 610290075Sobrien { 610390075Sobrien if (AT_ref (d_attr)->die_symbol == 0) 610490075Sobrien abort (); 610590075Sobrien 610690075Sobrien set_AT_ref_external (d_attr, 1); 610790075Sobrien } 610890075Sobrien 610950397Sobrien for (abbrev_id = 1; abbrev_id < abbrev_die_table_in_use; ++abbrev_id) 611050397Sobrien { 611190075Sobrien dw_die_ref abbrev = abbrev_die_table[abbrev_id]; 611250397Sobrien 611350397Sobrien if (abbrev->die_tag == die->die_tag) 611450397Sobrien { 611550397Sobrien if ((abbrev->die_child != NULL) == (die->die_child != NULL)) 611650397Sobrien { 611750397Sobrien a_attr = abbrev->die_attr; 611850397Sobrien d_attr = die->die_attr; 611950397Sobrien 612050397Sobrien while (a_attr != NULL && d_attr != NULL) 612150397Sobrien { 612250397Sobrien if ((a_attr->dw_attr != d_attr->dw_attr) 612390075Sobrien || (value_format (a_attr) != value_format (d_attr))) 612450397Sobrien break; 612550397Sobrien 612650397Sobrien a_attr = a_attr->dw_attr_next; 612750397Sobrien d_attr = d_attr->dw_attr_next; 612850397Sobrien } 612950397Sobrien 613050397Sobrien if (a_attr == NULL && d_attr == NULL) 613150397Sobrien break; 613250397Sobrien } 613350397Sobrien } 613450397Sobrien } 613550397Sobrien 613650397Sobrien if (abbrev_id >= abbrev_die_table_in_use) 613750397Sobrien { 613850397Sobrien if (abbrev_die_table_in_use >= abbrev_die_table_allocated) 613950397Sobrien { 614050397Sobrien n_alloc = abbrev_die_table_allocated + ABBREV_DIE_TABLE_INCREMENT; 6141132718Skan abbrev_die_table = ggc_realloc (abbrev_die_table, 6142132718Skan sizeof (dw_die_ref) * n_alloc); 614350397Sobrien 6144132718Skan memset (&abbrev_die_table[abbrev_die_table_allocated], 0, 614550397Sobrien (n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref)); 614650397Sobrien abbrev_die_table_allocated = n_alloc; 614750397Sobrien } 614850397Sobrien 614950397Sobrien ++abbrev_die_table_in_use; 615050397Sobrien abbrev_die_table[abbrev_id] = die; 615150397Sobrien } 615250397Sobrien 615350397Sobrien die->die_abbrev = abbrev_id; 615450397Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 615550397Sobrien build_abbrev_table (c); 615650397Sobrien} 615750397Sobrien 615850397Sobrien/* Return the power-of-two number of bytes necessary to represent VALUE. */ 615950397Sobrien 616050397Sobrienstatic int 6161132718Skanconstant_size (long unsigned int value) 616250397Sobrien{ 616350397Sobrien int log; 616450397Sobrien 616550397Sobrien if (value == 0) 616650397Sobrien log = 0; 616750397Sobrien else 616850397Sobrien log = floor_log2 (value); 616950397Sobrien 617050397Sobrien log = log / 8; 617150397Sobrien log = 1 << (floor_log2 (log) + 1); 617250397Sobrien 617350397Sobrien return log; 617450397Sobrien} 617550397Sobrien 617690075Sobrien/* Return the size of a DIE as it is represented in the 617750397Sobrien .debug_info section. */ 617850397Sobrien 617950397Sobrienstatic unsigned long 6180132718Skansize_of_die (dw_die_ref die) 618150397Sobrien{ 618290075Sobrien unsigned long size = 0; 618390075Sobrien dw_attr_ref a; 618450397Sobrien 618550397Sobrien size += size_of_uleb128 (die->die_abbrev); 618650397Sobrien for (a = die->die_attr; a != NULL; a = a->dw_attr_next) 618750397Sobrien { 618890075Sobrien switch (AT_class (a)) 618950397Sobrien { 619050397Sobrien case dw_val_class_addr: 619190075Sobrien size += DWARF2_ADDR_SIZE; 619250397Sobrien break; 619390075Sobrien case dw_val_class_offset: 619490075Sobrien size += DWARF_OFFSET_SIZE; 619590075Sobrien break; 619650397Sobrien case dw_val_class_loc: 619750397Sobrien { 619890075Sobrien unsigned long lsize = size_of_locs (AT_loc (a)); 619950397Sobrien 620050397Sobrien /* Block length. */ 620150397Sobrien size += constant_size (lsize); 620250397Sobrien size += lsize; 620350397Sobrien } 620450397Sobrien break; 620590075Sobrien case dw_val_class_loc_list: 620690075Sobrien size += DWARF_OFFSET_SIZE; 620790075Sobrien break; 620890075Sobrien case dw_val_class_range_list: 620990075Sobrien size += DWARF_OFFSET_SIZE; 621090075Sobrien break; 621150397Sobrien case dw_val_class_const: 621290075Sobrien size += size_of_sleb128 (AT_int (a)); 621350397Sobrien break; 621450397Sobrien case dw_val_class_unsigned_const: 621590075Sobrien size += constant_size (AT_unsigned (a)); 621650397Sobrien break; 621750397Sobrien case dw_val_class_long_long: 621890075Sobrien size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */ 621950397Sobrien break; 6220132718Skan case dw_val_class_vec: 6221132718Skan size += 1 + (a->dw_attr_val.v.val_vec.length 6222132718Skan * a->dw_attr_val.v.val_vec.elt_size); /* block */ 622350397Sobrien break; 622450397Sobrien case dw_val_class_flag: 622550397Sobrien size += 1; 622650397Sobrien break; 622750397Sobrien case dw_val_class_die_ref: 6228132718Skan if (AT_ref_external (a)) 6229132718Skan size += DWARF2_ADDR_SIZE; 6230132718Skan else 6231132718Skan size += DWARF_OFFSET_SIZE; 623250397Sobrien break; 623350397Sobrien case dw_val_class_fde_ref: 623450397Sobrien size += DWARF_OFFSET_SIZE; 623550397Sobrien break; 623650397Sobrien case dw_val_class_lbl_id: 623790075Sobrien size += DWARF2_ADDR_SIZE; 623850397Sobrien break; 623952284Sobrien case dw_val_class_lbl_offset: 624050397Sobrien size += DWARF_OFFSET_SIZE; 624150397Sobrien break; 624250397Sobrien case dw_val_class_str: 624390075Sobrien if (AT_string_form (a) == DW_FORM_strp) 624490075Sobrien size += DWARF_OFFSET_SIZE; 624590075Sobrien else 6246132718Skan size += strlen (a->dw_attr_val.v.val_str->str) + 1; 624750397Sobrien break; 624850397Sobrien default: 624950397Sobrien abort (); 625050397Sobrien } 625150397Sobrien } 625250397Sobrien 625350397Sobrien return size; 625450397Sobrien} 625550397Sobrien 625690075Sobrien/* Size the debugging information associated with a given DIE. Visits the 625790075Sobrien DIE's children recursively. Updates the global variable next_die_offset, on 625890075Sobrien each time through. Uses the current value of next_die_offset to update the 625990075Sobrien die_offset field in each DIE. */ 626050397Sobrien 626150397Sobrienstatic void 6262132718Skancalc_die_sizes (dw_die_ref die) 626350397Sobrien{ 626490075Sobrien dw_die_ref c; 626590075Sobrien 626650397Sobrien die->die_offset = next_die_offset; 626750397Sobrien next_die_offset += size_of_die (die); 626850397Sobrien 626950397Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 627050397Sobrien calc_die_sizes (c); 627150397Sobrien 627250397Sobrien if (die->die_child != NULL) 627350397Sobrien /* Count the null byte used to terminate sibling lists. */ 627450397Sobrien next_die_offset += 1; 627550397Sobrien} 627650397Sobrien 627790075Sobrien/* Set the marks for a die and its children. We do this so 627890075Sobrien that we know whether or not a reference needs to use FORM_ref_addr; only 627990075Sobrien DIEs in the same CU will be marked. We used to clear out the offset 628090075Sobrien and use that as the flag, but ran into ordering problems. */ 628150397Sobrien 628290075Sobrienstatic void 6283132718Skanmark_dies (dw_die_ref die) 628450397Sobrien{ 628590075Sobrien dw_die_ref c; 628650397Sobrien 6287117395Skan if (die->die_mark) 6288117395Skan abort (); 6289132718Skan 629090075Sobrien die->die_mark = 1; 629190075Sobrien for (c = die->die_child; c; c = c->die_sib) 629290075Sobrien mark_dies (c); 629350397Sobrien} 629450397Sobrien 629590075Sobrien/* Clear the marks for a die and its children. */ 629650397Sobrien 629790075Sobrienstatic void 6298132718Skanunmark_dies (dw_die_ref die) 629950397Sobrien{ 630090075Sobrien dw_die_ref c; 630150397Sobrien 6302117395Skan if (!die->die_mark) 6303117395Skan abort (); 6304132718Skan 630590075Sobrien die->die_mark = 0; 630690075Sobrien for (c = die->die_child; c; c = c->die_sib) 630790075Sobrien unmark_dies (c); 630850397Sobrien} 630950397Sobrien 6310117395Skan/* Clear the marks for a die, its children and referred dies. */ 6311117395Skan 6312117395Skanstatic void 6313132718Skanunmark_all_dies (dw_die_ref die) 6314117395Skan{ 6315117395Skan dw_die_ref c; 6316117395Skan dw_attr_ref a; 6317117395Skan 6318117395Skan if (!die->die_mark) 6319117395Skan return; 6320117395Skan die->die_mark = 0; 6321117395Skan 6322117395Skan for (c = die->die_child; c; c = c->die_sib) 6323117395Skan unmark_all_dies (c); 6324117395Skan 6325117395Skan for (a = die->die_attr; a; a = a->dw_attr_next) 6326117395Skan if (AT_class (a) == dw_val_class_die_ref) 6327117395Skan unmark_all_dies (AT_ref (a)); 6328117395Skan} 6329117395Skan 633050397Sobrien/* Return the size of the .debug_pubnames table generated for the 633150397Sobrien compilation unit. */ 633250397Sobrien 633350397Sobrienstatic unsigned long 6334132718Skansize_of_pubnames (void) 633550397Sobrien{ 633690075Sobrien unsigned long size; 633790075Sobrien unsigned i; 633850397Sobrien 633950397Sobrien size = DWARF_PUBNAMES_HEADER_SIZE; 634090075Sobrien for (i = 0; i < pubname_table_in_use; i++) 634150397Sobrien { 634290075Sobrien pubname_ref p = &pubname_table[i]; 634390075Sobrien size += DWARF_OFFSET_SIZE + strlen (p->name) + 1; 634450397Sobrien } 634550397Sobrien 634650397Sobrien size += DWARF_OFFSET_SIZE; 634750397Sobrien return size; 634850397Sobrien} 634950397Sobrien 635050397Sobrien/* Return the size of the information in the .debug_aranges section. */ 635150397Sobrien 635250397Sobrienstatic unsigned long 6353132718Skansize_of_aranges (void) 635450397Sobrien{ 635590075Sobrien unsigned long size; 635650397Sobrien 635750397Sobrien size = DWARF_ARANGES_HEADER_SIZE; 635850397Sobrien 635950397Sobrien /* Count the address/length pair for this compilation unit. */ 636090075Sobrien size += 2 * DWARF2_ADDR_SIZE; 636190075Sobrien size += 2 * DWARF2_ADDR_SIZE * arange_table_in_use; 636250397Sobrien 636350397Sobrien /* Count the two zero words used to terminated the address range table. */ 636490075Sobrien size += 2 * DWARF2_ADDR_SIZE; 636550397Sobrien return size; 636650397Sobrien} 636750397Sobrien 636850397Sobrien/* Select the encoding of an attribute value. */ 636950397Sobrien 637050397Sobrienstatic enum dwarf_form 6371132718Skanvalue_format (dw_attr_ref a) 637250397Sobrien{ 637390075Sobrien switch (a->dw_attr_val.val_class) 637450397Sobrien { 637550397Sobrien case dw_val_class_addr: 637650397Sobrien return DW_FORM_addr; 637790075Sobrien case dw_val_class_range_list: 637890075Sobrien case dw_val_class_offset: 637990075Sobrien if (DWARF_OFFSET_SIZE == 4) 638090075Sobrien return DW_FORM_data4; 638190075Sobrien if (DWARF_OFFSET_SIZE == 8) 638290075Sobrien return DW_FORM_data8; 638390075Sobrien abort (); 638490075Sobrien case dw_val_class_loc_list: 638590075Sobrien /* FIXME: Could be DW_FORM_data8, with a > 32 bit size 638690075Sobrien .debug_loc section */ 638790075Sobrien return DW_FORM_data4; 638850397Sobrien case dw_val_class_loc: 638990075Sobrien switch (constant_size (size_of_locs (AT_loc (a)))) 639050397Sobrien { 639150397Sobrien case 1: 639250397Sobrien return DW_FORM_block1; 639350397Sobrien case 2: 639450397Sobrien return DW_FORM_block2; 639550397Sobrien default: 639650397Sobrien abort (); 639750397Sobrien } 639850397Sobrien case dw_val_class_const: 639990075Sobrien return DW_FORM_sdata; 640050397Sobrien case dw_val_class_unsigned_const: 640190075Sobrien switch (constant_size (AT_unsigned (a))) 640250397Sobrien { 640350397Sobrien case 1: 640450397Sobrien return DW_FORM_data1; 640550397Sobrien case 2: 640650397Sobrien return DW_FORM_data2; 640750397Sobrien case 4: 640850397Sobrien return DW_FORM_data4; 640950397Sobrien case 8: 641050397Sobrien return DW_FORM_data8; 641150397Sobrien default: 641250397Sobrien abort (); 641350397Sobrien } 641450397Sobrien case dw_val_class_long_long: 641550397Sobrien return DW_FORM_block1; 6416132718Skan case dw_val_class_vec: 641750397Sobrien return DW_FORM_block1; 641850397Sobrien case dw_val_class_flag: 641950397Sobrien return DW_FORM_flag; 642050397Sobrien case dw_val_class_die_ref: 642190075Sobrien if (AT_ref_external (a)) 642290075Sobrien return DW_FORM_ref_addr; 642390075Sobrien else 642490075Sobrien return DW_FORM_ref; 642550397Sobrien case dw_val_class_fde_ref: 642650397Sobrien return DW_FORM_data; 642750397Sobrien case dw_val_class_lbl_id: 642850397Sobrien return DW_FORM_addr; 642952284Sobrien case dw_val_class_lbl_offset: 643050397Sobrien return DW_FORM_data; 643150397Sobrien case dw_val_class_str: 643290075Sobrien return AT_string_form (a); 643390075Sobrien 643450397Sobrien default: 643550397Sobrien abort (); 643650397Sobrien } 643750397Sobrien} 643850397Sobrien 643950397Sobrien/* Output the encoding of an attribute value. */ 644050397Sobrien 644150397Sobrienstatic void 6442132718Skanoutput_value_format (dw_attr_ref a) 644350397Sobrien{ 644490075Sobrien enum dwarf_form form = value_format (a); 644550397Sobrien 644690075Sobrien dw2_asm_output_data_uleb128 (form, "(%s)", dwarf_form_name (form)); 644750397Sobrien} 644850397Sobrien 644950397Sobrien/* Output the .debug_abbrev section which defines the DIE abbreviation 645050397Sobrien table. */ 645150397Sobrien 645250397Sobrienstatic void 6453132718Skanoutput_abbrev_section (void) 645450397Sobrien{ 645550397Sobrien unsigned long abbrev_id; 645650397Sobrien 645750397Sobrien dw_attr_ref a_attr; 645890075Sobrien 645950397Sobrien for (abbrev_id = 1; abbrev_id < abbrev_die_table_in_use; ++abbrev_id) 646050397Sobrien { 646190075Sobrien dw_die_ref abbrev = abbrev_die_table[abbrev_id]; 646250397Sobrien 646390075Sobrien dw2_asm_output_data_uleb128 (abbrev_id, "(abbrev code)"); 646490075Sobrien dw2_asm_output_data_uleb128 (abbrev->die_tag, "(TAG: %s)", 646590075Sobrien dwarf_tag_name (abbrev->die_tag)); 646650397Sobrien 646790075Sobrien if (abbrev->die_child != NULL) 646890075Sobrien dw2_asm_output_data (1, DW_children_yes, "DW_children_yes"); 646990075Sobrien else 647090075Sobrien dw2_asm_output_data (1, DW_children_no, "DW_children_no"); 647150397Sobrien 647250397Sobrien for (a_attr = abbrev->die_attr; a_attr != NULL; 647350397Sobrien a_attr = a_attr->dw_attr_next) 647450397Sobrien { 647590075Sobrien dw2_asm_output_data_uleb128 (a_attr->dw_attr, "(%s)", 647690075Sobrien dwarf_attr_name (a_attr->dw_attr)); 647790075Sobrien output_value_format (a_attr); 647850397Sobrien } 647950397Sobrien 648090075Sobrien dw2_asm_output_data (1, 0, NULL); 648190075Sobrien dw2_asm_output_data (1, 0, NULL); 648250397Sobrien } 648352284Sobrien 648490075Sobrien /* Terminate the table. */ 648590075Sobrien dw2_asm_output_data (1, 0, NULL); 648650397Sobrien} 648750397Sobrien 648890075Sobrien/* Output a symbol we can use to refer to this DIE from another CU. */ 648950397Sobrien 649090075Sobrienstatic inline void 6491132718Skanoutput_die_symbol (dw_die_ref die) 649290075Sobrien{ 649390075Sobrien char *sym = die->die_symbol; 649490075Sobrien 649590075Sobrien if (sym == 0) 649690075Sobrien return; 649790075Sobrien 649890075Sobrien if (strncmp (sym, DIE_LABEL_PREFIX, sizeof (DIE_LABEL_PREFIX) - 1) == 0) 649990075Sobrien /* We make these global, not weak; if the target doesn't support 650090075Sobrien .linkonce, it doesn't support combining the sections, so debugging 650190075Sobrien will break. */ 6502117395Skan (*targetm.asm_out.globalize_label) (asm_out_file, sym); 650390075Sobrien 650490075Sobrien ASM_OUTPUT_LABEL (asm_out_file, sym); 650590075Sobrien} 650690075Sobrien 650790075Sobrien/* Return a new location list, given the begin and end range, and the 650890075Sobrien expression. gensym tells us whether to generate a new internal symbol for 650990075Sobrien this location list node, which is done for the head of the list only. */ 651090075Sobrien 651190075Sobrienstatic inline dw_loc_list_ref 6512132718Skannew_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end, 6513132718Skan const char *section, unsigned int gensym) 651490075Sobrien{ 6515132718Skan dw_loc_list_ref retlist = ggc_alloc_cleared (sizeof (dw_loc_list_node)); 651690075Sobrien 651790075Sobrien retlist->begin = begin; 651890075Sobrien retlist->end = end; 651990075Sobrien retlist->expr = expr; 652090075Sobrien retlist->section = section; 6521117395Skan if (gensym) 652290075Sobrien retlist->ll_symbol = gen_internal_sym ("LLST"); 652390075Sobrien 652490075Sobrien return retlist; 652590075Sobrien} 652690075Sobrien 6527132718Skan/* Add a location description expression to a location list. */ 652890075Sobrien 652990075Sobrienstatic inline void 6530132718Skanadd_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr, 6531132718Skan const char *begin, const char *end, 6532132718Skan const char *section) 653390075Sobrien{ 653490075Sobrien dw_loc_list_ref *d; 6535117395Skan 653690075Sobrien /* Find the end of the chain. */ 653790075Sobrien for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next) 653890075Sobrien ; 653990075Sobrien 6540132718Skan /* Add a new location list node to the list. */ 654190075Sobrien *d = new_loc_list (descr, begin, end, section, 0); 654290075Sobrien} 654390075Sobrien 6544132718Skan/* Output the location list given to us. */ 654590075Sobrien 654650397Sobrienstatic void 6547132718Skanoutput_loc_list (dw_loc_list_ref list_head) 654850397Sobrien{ 654990075Sobrien dw_loc_list_ref curr = list_head; 655050397Sobrien 655190075Sobrien ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol); 655290075Sobrien 655390075Sobrien /* ??? This shouldn't be needed now that we've forced the 655490075Sobrien compilation unit base address to zero when there is code 655590075Sobrien in more than one section. */ 655690075Sobrien if (strcmp (curr->section, ".text") == 0) 655750397Sobrien { 655890075Sobrien /* dw2_asm_output_data will mask off any extra bits in the ~0. */ 655990075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, ~(unsigned HOST_WIDE_INT) 0, 656090075Sobrien "Location list base address specifier fake entry"); 656190075Sobrien dw2_asm_output_offset (DWARF2_ADDR_SIZE, curr->section, 656290075Sobrien "Location list base address specifier base"); 656350397Sobrien } 656450397Sobrien 6565117395Skan for (curr = list_head; curr != NULL; curr = curr->dw_loc_next) 656690075Sobrien { 656790075Sobrien unsigned long size; 656850397Sobrien 656990075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section, 657090075Sobrien "Location list begin address (%s)", 657190075Sobrien list_head->ll_symbol); 657290075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section, 657390075Sobrien "Location list end address (%s)", 657490075Sobrien list_head->ll_symbol); 657590075Sobrien size = size_of_locs (curr->expr); 6576117395Skan 657790075Sobrien /* Output the block length for this list of location operations. */ 657890075Sobrien if (size > 0xffff) 657990075Sobrien abort (); 658090075Sobrien dw2_asm_output_data (2, size, "%s", "Location expression size"); 658150397Sobrien 658290075Sobrien output_loc_sequence (curr->expr); 658390075Sobrien } 658450397Sobrien 658590075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, 658690075Sobrien "Location list terminator begin (%s)", 658790075Sobrien list_head->ll_symbol); 658890075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, 658990075Sobrien "Location list terminator end (%s)", 659090075Sobrien list_head->ll_symbol); 659150397Sobrien} 659250397Sobrien 659350397Sobrien/* Output the DIE and its attributes. Called recursively to generate 659450397Sobrien the definitions of each child DIE. */ 659550397Sobrien 659650397Sobrienstatic void 6597132718Skanoutput_die (dw_die_ref die) 659850397Sobrien{ 659990075Sobrien dw_attr_ref a; 660090075Sobrien dw_die_ref c; 660190075Sobrien unsigned long size; 660250397Sobrien 660390075Sobrien /* If someone in another CU might refer to us, set up a symbol for 660490075Sobrien them to point to. */ 660590075Sobrien if (die->die_symbol) 660690075Sobrien output_die_symbol (die); 660750397Sobrien 660890075Sobrien dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (0x%lx) %s)", 660990075Sobrien die->die_offset, dwarf_tag_name (die->die_tag)); 661050397Sobrien 661150397Sobrien for (a = die->die_attr; a != NULL; a = a->dw_attr_next) 661250397Sobrien { 661390075Sobrien const char *name = dwarf_attr_name (a->dw_attr); 661490075Sobrien 661590075Sobrien switch (AT_class (a)) 661650397Sobrien { 661750397Sobrien case dw_val_class_addr: 661890075Sobrien dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, AT_addr (a), "%s", name); 661950397Sobrien break; 662050397Sobrien 662190075Sobrien case dw_val_class_offset: 662290075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, a->dw_attr_val.v.val_offset, 662390075Sobrien "%s", name); 662490075Sobrien break; 662550397Sobrien 662690075Sobrien case dw_val_class_range_list: 662790075Sobrien { 662890075Sobrien char *p = strchr (ranges_section_label, '\0'); 662950397Sobrien 6630132718Skan sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX, 6631132718Skan a->dw_attr_val.v.val_offset); 663290075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label, 663390075Sobrien "%s", name); 663490075Sobrien *p = '\0'; 663590075Sobrien } 663690075Sobrien break; 663750397Sobrien 663890075Sobrien case dw_val_class_loc: 663990075Sobrien size = size_of_locs (AT_loc (a)); 664050397Sobrien 664190075Sobrien /* Output the block length for this list of location operations. */ 664290075Sobrien dw2_asm_output_data (constant_size (size), size, "%s", name); 664350397Sobrien 664490075Sobrien output_loc_sequence (AT_loc (a)); 664550397Sobrien break; 664650397Sobrien 664750397Sobrien case dw_val_class_const: 664890075Sobrien /* ??? It would be slightly more efficient to use a scheme like is 664990075Sobrien used for unsigned constants below, but gdb 4.x does not sign 665090075Sobrien extend. Gdb 5.x does sign extend. */ 665190075Sobrien dw2_asm_output_data_sleb128 (AT_int (a), "%s", name); 665250397Sobrien break; 665350397Sobrien 665450397Sobrien case dw_val_class_unsigned_const: 665590075Sobrien dw2_asm_output_data (constant_size (AT_unsigned (a)), 665690075Sobrien AT_unsigned (a), "%s", name); 665750397Sobrien break; 665850397Sobrien 665950397Sobrien case dw_val_class_long_long: 666090075Sobrien { 666190075Sobrien unsigned HOST_WIDE_INT first, second; 666250397Sobrien 666390075Sobrien dw2_asm_output_data (1, 666490075Sobrien 2 * HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR, 6665117395Skan "%s", name); 666650397Sobrien 666790075Sobrien if (WORDS_BIG_ENDIAN) 666890075Sobrien { 666990075Sobrien first = a->dw_attr_val.v.val_long_long.hi; 667090075Sobrien second = a->dw_attr_val.v.val_long_long.low; 667190075Sobrien } 667290075Sobrien else 667390075Sobrien { 667490075Sobrien first = a->dw_attr_val.v.val_long_long.low; 667590075Sobrien second = a->dw_attr_val.v.val_long_long.hi; 667690075Sobrien } 667790075Sobrien 667890075Sobrien dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR, 667990075Sobrien first, "long long constant"); 668090075Sobrien dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR, 668190075Sobrien second, NULL); 668290075Sobrien } 668350397Sobrien break; 668450397Sobrien 6685132718Skan case dw_val_class_vec: 668652284Sobrien { 6687132718Skan unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size; 6688132718Skan unsigned int len = a->dw_attr_val.v.val_vec.length; 668990075Sobrien unsigned int i; 6690132718Skan unsigned char *p; 669150397Sobrien 6692132718Skan dw2_asm_output_data (1, len * elt_size, "%s", name); 6693132718Skan if (elt_size > sizeof (HOST_WIDE_INT)) 6694132718Skan { 6695132718Skan elt_size /= 2; 6696132718Skan len *= 2; 6697132718Skan } 6698132718Skan for (i = 0, p = a->dw_attr_val.v.val_vec.array; 6699132718Skan i < len; 6700132718Skan i++, p += elt_size) 6701132718Skan dw2_asm_output_data (elt_size, extract_int (p, elt_size), 6702132718Skan "fp or vector constant word %u", i); 670390075Sobrien break; 670452284Sobrien } 670550397Sobrien 670650397Sobrien case dw_val_class_flag: 670790075Sobrien dw2_asm_output_data (1, AT_flag (a), "%s", name); 670850397Sobrien break; 670950397Sobrien 6710117395Skan case dw_val_class_loc_list: 671190075Sobrien { 671290075Sobrien char *sym = AT_loc_list (a)->ll_symbol; 671390075Sobrien 671490075Sobrien if (sym == 0) 671590075Sobrien abort (); 671690075Sobrien dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, 671790075Sobrien loc_section_label, "%s", name); 671890075Sobrien } 671990075Sobrien break; 672090075Sobrien 672150397Sobrien case dw_val_class_die_ref: 672290075Sobrien if (AT_ref_external (a)) 672390075Sobrien { 672490075Sobrien char *sym = AT_ref (a)->die_symbol; 672590075Sobrien 672690075Sobrien if (sym == 0) 672790075Sobrien abort (); 672890075Sobrien dw2_asm_output_offset (DWARF2_ADDR_SIZE, sym, "%s", name); 672990075Sobrien } 673090075Sobrien else if (AT_ref (a)->die_offset == 0) 673190075Sobrien abort (); 673250397Sobrien else 673390075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, AT_ref (a)->die_offset, 673490075Sobrien "%s", name); 673550397Sobrien break; 673650397Sobrien 673750397Sobrien case dw_val_class_fde_ref: 673850397Sobrien { 673950397Sobrien char l1[20]; 674090075Sobrien 674190075Sobrien ASM_GENERATE_INTERNAL_LABEL (l1, FDE_LABEL, 674290075Sobrien a->dw_attr_val.v.val_fde_index * 2); 674390075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, l1, "%s", name); 674450397Sobrien } 674550397Sobrien break; 674650397Sobrien 674750397Sobrien case dw_val_class_lbl_id: 674890075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name); 674950397Sobrien break; 675050397Sobrien 675152284Sobrien case dw_val_class_lbl_offset: 675290075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, AT_lbl (a), "%s", name); 675350397Sobrien break; 675450397Sobrien 675550397Sobrien case dw_val_class_str: 675690075Sobrien if (AT_string_form (a) == DW_FORM_strp) 675790075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, 675890075Sobrien a->dw_attr_val.v.val_str->label, 675990075Sobrien "%s: \"%s\"", name, AT_string (a)); 676050397Sobrien else 676190075Sobrien dw2_asm_output_nstring (AT_string (a), -1, "%s", name); 676250397Sobrien break; 676350397Sobrien 676450397Sobrien default: 676550397Sobrien abort (); 676650397Sobrien } 676750397Sobrien } 676850397Sobrien 676950397Sobrien for (c = die->die_child; c != NULL; c = c->die_sib) 677050397Sobrien output_die (c); 677150397Sobrien 677290075Sobrien /* Add null byte to terminate sibling list. */ 677350397Sobrien if (die->die_child != NULL) 677490075Sobrien dw2_asm_output_data (1, 0, "end of children of DIE 0x%lx", 677590075Sobrien die->die_offset); 677650397Sobrien} 677750397Sobrien 677850397Sobrien/* Output the compilation unit that appears at the beginning of the 677950397Sobrien .debug_info section, and precedes the DIE descriptions. */ 678050397Sobrien 678150397Sobrienstatic void 6782132718Skanoutput_compilation_unit_header (void) 678350397Sobrien{ 6784132718Skan if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) 6785132718Skan dw2_asm_output_data (4, 0xffffffff, 6786132718Skan "Initial length escape value indicating 64-bit DWARF extension"); 6787132718Skan dw2_asm_output_data (DWARF_OFFSET_SIZE, 6788132718Skan next_die_offset - DWARF_INITIAL_LENGTH_SIZE, 678990075Sobrien "Length of Compilation Unit Info"); 679090075Sobrien dw2_asm_output_data (2, DWARF_VERSION, "DWARF version number"); 679190075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label, 679290075Sobrien "Offset Into Abbrev. Section"); 679390075Sobrien dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)"); 679490075Sobrien} 679550397Sobrien 679690075Sobrien/* Output the compilation unit DIE and its children. */ 679750397Sobrien 679890075Sobrienstatic void 6799132718Skanoutput_comp_unit (dw_die_ref die, int output_if_empty) 680090075Sobrien{ 680190075Sobrien const char *secname; 6802117395Skan char *oldsym, *tmp; 680350397Sobrien 6804117395Skan /* Unless we are outputting main CU, we may throw away empty ones. */ 6805117395Skan if (!output_if_empty && die->die_child == NULL) 6806117395Skan return; 6807117395Skan 680890075Sobrien /* Even if there are no children of this DIE, we must output the information 680990075Sobrien about the compilation unit. Otherwise, on an empty translation unit, we 681090075Sobrien will generate a present, but empty, .debug_info section. IRIX 6.5 `nm' 681190075Sobrien will then complain when examining the file. First mark all the DIEs in 681290075Sobrien this CU so we know which get local refs. */ 681390075Sobrien mark_dies (die); 681450397Sobrien 681590075Sobrien build_abbrev_table (die); 681690075Sobrien 681790075Sobrien /* Initialize the beginning DIE offset - and calculate sizes/offsets. */ 681890075Sobrien next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE; 681990075Sobrien calc_die_sizes (die); 682090075Sobrien 6821117395Skan oldsym = die->die_symbol; 6822117395Skan if (oldsym) 682390075Sobrien { 6824132718Skan tmp = alloca (strlen (oldsym) + 24); 682590075Sobrien 6826117395Skan sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym); 682790075Sobrien secname = tmp; 682890075Sobrien die->die_symbol = NULL; 682990075Sobrien } 683090075Sobrien else 683190075Sobrien secname = (const char *) DEBUG_INFO_SECTION; 683290075Sobrien 683390075Sobrien /* Output debugging information. */ 683490075Sobrien named_section_flags (secname, SECTION_DEBUG); 683590075Sobrien output_compilation_unit_header (); 683690075Sobrien output_die (die); 683790075Sobrien 683890075Sobrien /* Leave the marks on the main CU, so we can check them in 683990075Sobrien output_pubnames. */ 6840117395Skan if (oldsym) 6841117395Skan { 6842117395Skan unmark_dies (die); 6843117395Skan die->die_symbol = oldsym; 6844117395Skan } 684550397Sobrien} 684650397Sobrien 6847117395Skan/* The DWARF2 pubname for a nested thingy looks like "A::f". The 6848117395Skan output of lang_hooks.decl_printable_name for C++ looks like 6849117395Skan "A::f(int)". Let's drop the argument list, and maybe the scope. */ 685050397Sobrien 685190075Sobrienstatic const char * 6852132718Skandwarf2_name (tree decl, int scope) 685350397Sobrien{ 6854117395Skan return (*lang_hooks.decl_printable_name) (decl, scope ? 1 : 0); 685550397Sobrien} 685650397Sobrien 685750397Sobrien/* Add a new entry to .debug_pubnames if appropriate. */ 685850397Sobrien 685950397Sobrienstatic void 6860132718Skanadd_pubname (tree decl, dw_die_ref die) 686150397Sobrien{ 686250397Sobrien pubname_ref p; 686350397Sobrien 686450397Sobrien if (! TREE_PUBLIC (decl)) 686550397Sobrien return; 686650397Sobrien 686750397Sobrien if (pubname_table_in_use == pubname_table_allocated) 686850397Sobrien { 686950397Sobrien pubname_table_allocated += PUBNAME_TABLE_INCREMENT; 687090075Sobrien pubname_table 6871132718Skan = ggc_realloc (pubname_table, 6872132718Skan (pubname_table_allocated * sizeof (pubname_entry))); 6873132718Skan memset (pubname_table + pubname_table_in_use, 0, 6874132718Skan PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry)); 687550397Sobrien } 687650397Sobrien 687750397Sobrien p = &pubname_table[pubname_table_in_use++]; 687850397Sobrien p->die = die; 687950397Sobrien p->name = xstrdup (dwarf2_name (decl, 1)); 688050397Sobrien} 688150397Sobrien 688250397Sobrien/* Output the public names table used to speed up access to externally 688350397Sobrien visible names. For now, only generate entries for externally 688450397Sobrien visible procedures. */ 688550397Sobrien 688650397Sobrienstatic void 6887132718Skanoutput_pubnames (void) 688850397Sobrien{ 688990075Sobrien unsigned i; 689090075Sobrien unsigned long pubnames_length = size_of_pubnames (); 689150397Sobrien 6892132718Skan if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) 6893132718Skan dw2_asm_output_data (4, 0xffffffff, 6894132718Skan "Initial length escape value indicating 64-bit DWARF extension"); 689590075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length, 689690075Sobrien "Length of Public Names Info"); 689790075Sobrien dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version"); 689890075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label, 689990075Sobrien "Offset of Compilation Unit Info"); 690090075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset, 690190075Sobrien "Compilation Unit Length"); 690250397Sobrien 690390075Sobrien for (i = 0; i < pubname_table_in_use; i++) 690450397Sobrien { 690590075Sobrien pubname_ref pub = &pubname_table[i]; 690650397Sobrien 690790075Sobrien /* We shouldn't see pubnames for DIEs outside of the main CU. */ 690890075Sobrien if (pub->die->die_mark == 0) 690990075Sobrien abort (); 691050397Sobrien 691190075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset, 691290075Sobrien "DIE offset"); 691350397Sobrien 691490075Sobrien dw2_asm_output_nstring (pub->name, -1, "external name"); 691550397Sobrien } 691650397Sobrien 691790075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL); 691850397Sobrien} 691950397Sobrien 692050397Sobrien/* Add a new entry to .debug_aranges if appropriate. */ 692150397Sobrien 692250397Sobrienstatic void 6923132718Skanadd_arange (tree decl, dw_die_ref die) 692450397Sobrien{ 692550397Sobrien if (! DECL_SECTION_NAME (decl)) 692650397Sobrien return; 692750397Sobrien 692850397Sobrien if (arange_table_in_use == arange_table_allocated) 692950397Sobrien { 693050397Sobrien arange_table_allocated += ARANGE_TABLE_INCREMENT; 6931132718Skan arange_table = ggc_realloc (arange_table, 6932132718Skan (arange_table_allocated 6933132718Skan * sizeof (dw_die_ref))); 6934132718Skan memset (arange_table + arange_table_in_use, 0, 6935132718Skan ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref)); 693650397Sobrien } 693750397Sobrien 693850397Sobrien arange_table[arange_table_in_use++] = die; 693950397Sobrien} 694050397Sobrien 694150397Sobrien/* Output the information that goes into the .debug_aranges table. 694250397Sobrien Namely, define the beginning and ending address range of the 694350397Sobrien text section generated for this compilation unit. */ 694450397Sobrien 694550397Sobrienstatic void 6946132718Skanoutput_aranges (void) 694750397Sobrien{ 694890075Sobrien unsigned i; 694990075Sobrien unsigned long aranges_length = size_of_aranges (); 695050397Sobrien 6951132718Skan if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) 6952132718Skan dw2_asm_output_data (4, 0xffffffff, 6953132718Skan "Initial length escape value indicating 64-bit DWARF extension"); 695490075Sobrien dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length, 695590075Sobrien "Length of Address Ranges Info"); 695690075Sobrien dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version"); 695790075Sobrien dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label, 695890075Sobrien "Offset of Compilation Unit Info"); 695990075Sobrien dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address"); 696090075Sobrien dw2_asm_output_data (1, 0, "Size of Segment Descriptor"); 696150397Sobrien 696290075Sobrien /* We need to align to twice the pointer size here. */ 696390075Sobrien if (DWARF_ARANGES_PAD_SIZE) 696490075Sobrien { 696590075Sobrien /* Pad using a 2 byte words so that padding is correct for any 6966132718Skan pointer size. */ 696790075Sobrien dw2_asm_output_data (2, 0, "Pad to %d byte boundary", 696890075Sobrien 2 * DWARF2_ADDR_SIZE); 696990075Sobrien for (i = 2; i < (unsigned) DWARF_ARANGES_PAD_SIZE; i += 2) 697090075Sobrien dw2_asm_output_data (2, 0, NULL); 697190075Sobrien } 697250397Sobrien 697390075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address"); 697490075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label, 697590075Sobrien text_section_label, "Length"); 697650397Sobrien 697790075Sobrien for (i = 0; i < arange_table_in_use; i++) 697890075Sobrien { 697990075Sobrien dw_die_ref die = arange_table[i]; 698050397Sobrien 698190075Sobrien /* We shouldn't see aranges for DIEs outside of the main CU. */ 698290075Sobrien if (die->die_mark == 0) 698390075Sobrien abort (); 698450397Sobrien 698590075Sobrien if (die->die_tag == DW_TAG_subprogram) 698690075Sobrien { 698790075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, get_AT_low_pc (die), 698890075Sobrien "Address"); 698990075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, get_AT_hi_pc (die), 699090075Sobrien get_AT_low_pc (die), "Length"); 699190075Sobrien } 699290075Sobrien else 699390075Sobrien { 699490075Sobrien /* A static variable; extract the symbol from DW_AT_location. 699590075Sobrien Note that this code isn't currently hit, as we only emit 699690075Sobrien aranges for functions (jason 9/23/99). */ 699790075Sobrien dw_attr_ref a = get_AT (die, DW_AT_location); 699890075Sobrien dw_loc_descr_ref loc; 699950397Sobrien 700090075Sobrien if (! a || AT_class (a) != dw_val_class_loc) 700190075Sobrien abort (); 700250397Sobrien 700390075Sobrien loc = AT_loc (a); 700490075Sobrien if (loc->dw_loc_opc != DW_OP_addr) 700590075Sobrien abort (); 700650397Sobrien 700790075Sobrien dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, 700890075Sobrien loc->dw_loc_oprnd1.v.val_addr, "Address"); 700990075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, 701090075Sobrien get_AT_unsigned (die, DW_AT_byte_size), 701190075Sobrien "Length"); 701290075Sobrien } 701390075Sobrien } 701450397Sobrien 701590075Sobrien /* Output the terminator words. */ 701690075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL); 701790075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL); 701890075Sobrien} 701990075Sobrien 702090075Sobrien/* Add a new entry to .debug_ranges. Return the offset at which it 702190075Sobrien was placed. */ 702290075Sobrien 702390075Sobrienstatic unsigned int 7024132718Skanadd_ranges (tree block) 702590075Sobrien{ 702690075Sobrien unsigned int in_use = ranges_table_in_use; 702790075Sobrien 702890075Sobrien if (in_use == ranges_table_allocated) 702950397Sobrien { 703090075Sobrien ranges_table_allocated += RANGES_TABLE_INCREMENT; 7031132718Skan ranges_table 7032132718Skan = ggc_realloc (ranges_table, (ranges_table_allocated 7033132718Skan * sizeof (struct dw_ranges_struct))); 7034132718Skan memset (ranges_table + ranges_table_in_use, 0, 7035132718Skan RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct)); 703690075Sobrien } 703750397Sobrien 703890075Sobrien ranges_table[in_use].block_num = (block ? BLOCK_NUMBER (block) : 0); 703990075Sobrien ranges_table_in_use = in_use + 1; 704090075Sobrien 704190075Sobrien return in_use * 2 * DWARF2_ADDR_SIZE; 704290075Sobrien} 704390075Sobrien 704490075Sobrienstatic void 7045132718Skanoutput_ranges (void) 704690075Sobrien{ 704790075Sobrien unsigned i; 704890075Sobrien static const char *const start_fmt = "Offset 0x%x"; 704990075Sobrien const char *fmt = start_fmt; 705090075Sobrien 705190075Sobrien for (i = 0; i < ranges_table_in_use; i++) 705290075Sobrien { 705390075Sobrien int block_num = ranges_table[i].block_num; 705490075Sobrien 705590075Sobrien if (block_num) 705690075Sobrien { 705790075Sobrien char blabel[MAX_ARTIFICIAL_LABEL_BYTES]; 705890075Sobrien char elabel[MAX_ARTIFICIAL_LABEL_BYTES]; 705990075Sobrien 706090075Sobrien ASM_GENERATE_INTERNAL_LABEL (blabel, BLOCK_BEGIN_LABEL, block_num); 706190075Sobrien ASM_GENERATE_INTERNAL_LABEL (elabel, BLOCK_END_LABEL, block_num); 706290075Sobrien 706390075Sobrien /* If all code is in the text section, then the compilation 706490075Sobrien unit base address defaults to DW_AT_low_pc, which is the 706590075Sobrien base of the text section. */ 706690075Sobrien if (separate_line_info_table_in_use == 0) 706790075Sobrien { 706890075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel, 706990075Sobrien text_section_label, 707090075Sobrien fmt, i * 2 * DWARF2_ADDR_SIZE); 707190075Sobrien dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel, 707290075Sobrien text_section_label, NULL); 707390075Sobrien } 707490075Sobrien 707590075Sobrien /* Otherwise, we add a DW_AT_entry_pc attribute to force the 707690075Sobrien compilation unit base address to zero, which allows us to 707790075Sobrien use absolute addresses, and not worry about whether the 707890075Sobrien target supports cross-section arithmetic. */ 707990075Sobrien else 708090075Sobrien { 708190075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel, 708290075Sobrien fmt, i * 2 * DWARF2_ADDR_SIZE); 708390075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, elabel, NULL); 708490075Sobrien } 708590075Sobrien 708690075Sobrien fmt = NULL; 708790075Sobrien } 708850397Sobrien else 708950397Sobrien { 709090075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL); 709190075Sobrien dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL); 709290075Sobrien fmt = start_fmt; 709390075Sobrien } 709490075Sobrien } 709590075Sobrien} 709650397Sobrien 709790075Sobrien/* Data structure containing information about input files. */ 709890075Sobrienstruct file_info 709990075Sobrien{ 710090075Sobrien char *path; /* Complete file name. */ 710190075Sobrien char *fname; /* File name part. */ 710290075Sobrien int length; /* Length of entire string. */ 710390075Sobrien int file_idx; /* Index in input file table. */ 710490075Sobrien int dir_idx; /* Index in directory table. */ 710590075Sobrien}; 710690075Sobrien 710790075Sobrien/* Data structure containing information about directories with source 710890075Sobrien files. */ 710990075Sobrienstruct dir_info 711090075Sobrien{ 711190075Sobrien char *path; /* Path including directory name. */ 711290075Sobrien int length; /* Path length. */ 711390075Sobrien int prefix; /* Index of directory entry which is a prefix. */ 711490075Sobrien int count; /* Number of files in this directory. */ 711590075Sobrien int dir_idx; /* Index of directory used as base. */ 711690075Sobrien int used; /* Used in the end? */ 711790075Sobrien}; 711890075Sobrien 711990075Sobrien/* Callback function for file_info comparison. We sort by looking at 712090075Sobrien the directories in the path. */ 712190075Sobrien 712290075Sobrienstatic int 7123132718Skanfile_info_cmp (const void *p1, const void *p2) 712490075Sobrien{ 712590075Sobrien const struct file_info *s1 = p1; 712690075Sobrien const struct file_info *s2 = p2; 712790075Sobrien unsigned char *cp1; 712890075Sobrien unsigned char *cp2; 712990075Sobrien 713090075Sobrien /* Take care of file names without directories. We need to make sure that 713190075Sobrien we return consistent values to qsort since some will get confused if 713290075Sobrien we return the same value when identical operands are passed in opposite 713390075Sobrien orders. So if neither has a directory, return 0 and otherwise return 713490075Sobrien 1 or -1 depending on which one has the directory. */ 713590075Sobrien if ((s1->path == s1->fname || s2->path == s2->fname)) 713690075Sobrien return (s2->path == s2->fname) - (s1->path == s1->fname); 713790075Sobrien 713890075Sobrien cp1 = (unsigned char *) s1->path; 713990075Sobrien cp2 = (unsigned char *) s2->path; 714090075Sobrien 714190075Sobrien while (1) 714290075Sobrien { 714390075Sobrien ++cp1; 714490075Sobrien ++cp2; 714590075Sobrien /* Reached the end of the first path? If so, handle like above. */ 714690075Sobrien if ((cp1 == (unsigned char *) s1->fname) 714790075Sobrien || (cp2 == (unsigned char *) s2->fname)) 714890075Sobrien return ((cp2 == (unsigned char *) s2->fname) 714990075Sobrien - (cp1 == (unsigned char *) s1->fname)); 715090075Sobrien 715190075Sobrien /* Character of current path component the same? */ 715290075Sobrien else if (*cp1 != *cp2) 715390075Sobrien return *cp1 - *cp2; 715490075Sobrien } 715590075Sobrien} 715690075Sobrien 715790075Sobrien/* Output the directory table and the file name table. We try to minimize 715890075Sobrien the total amount of memory needed. A heuristic is used to avoid large 715990075Sobrien slowdowns with many input files. */ 716090075Sobrien 716190075Sobrienstatic void 7162132718Skanoutput_file_names (void) 716390075Sobrien{ 716490075Sobrien struct file_info *files; 716590075Sobrien struct dir_info *dirs; 716690075Sobrien int *saved; 716790075Sobrien int *savehere; 716890075Sobrien int *backmap; 7169132718Skan size_t ndirs; 717090075Sobrien int idx_offset; 7171132718Skan size_t i; 717290075Sobrien int idx; 717390075Sobrien 7174132718Skan /* Handle the case where file_table is empty. */ 7175132718Skan if (VARRAY_ACTIVE_SIZE (file_table) <= 1) 7176132718Skan { 7177132718Skan dw2_asm_output_data (1, 0, "End directory table"); 7178132718Skan dw2_asm_output_data (1, 0, "End file name table"); 7179132718Skan return; 7180132718Skan } 7181132718Skan 718290075Sobrien /* Allocate the various arrays we need. */ 7183132718Skan files = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct file_info)); 7184132718Skan dirs = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct dir_info)); 718590075Sobrien 718690075Sobrien /* Sort the file names. */ 7187132718Skan for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++) 718890075Sobrien { 718990075Sobrien char *f; 719090075Sobrien 719190075Sobrien /* Skip all leading "./". */ 7192132718Skan f = VARRAY_CHAR_PTR (file_table, i); 719390075Sobrien while (f[0] == '.' && f[1] == '/') 719490075Sobrien f += 2; 719590075Sobrien 719690075Sobrien /* Create a new array entry. */ 719790075Sobrien files[i].path = f; 719890075Sobrien files[i].length = strlen (f); 719990075Sobrien files[i].file_idx = i; 720090075Sobrien 720190075Sobrien /* Search for the file name part. */ 720290075Sobrien f = strrchr (f, '/'); 720390075Sobrien files[i].fname = f == NULL ? files[i].path : f + 1; 720490075Sobrien } 720590075Sobrien 7206132718Skan qsort (files + 1, VARRAY_ACTIVE_SIZE (file_table) - 1, 7207132718Skan sizeof (files[0]), file_info_cmp); 720890075Sobrien 720990075Sobrien /* Find all the different directories used. */ 721090075Sobrien dirs[0].path = files[1].path; 721190075Sobrien dirs[0].length = files[1].fname - files[1].path; 721290075Sobrien dirs[0].prefix = -1; 721390075Sobrien dirs[0].count = 1; 721490075Sobrien dirs[0].dir_idx = 0; 721590075Sobrien dirs[0].used = 0; 721690075Sobrien files[1].dir_idx = 0; 721790075Sobrien ndirs = 1; 721890075Sobrien 7219132718Skan for (i = 2; i < VARRAY_ACTIVE_SIZE (file_table); i++) 722090075Sobrien if (files[i].fname - files[i].path == dirs[ndirs - 1].length 722190075Sobrien && memcmp (dirs[ndirs - 1].path, files[i].path, 722290075Sobrien dirs[ndirs - 1].length) == 0) 722390075Sobrien { 722490075Sobrien /* Same directory as last entry. */ 722590075Sobrien files[i].dir_idx = ndirs - 1; 722690075Sobrien ++dirs[ndirs - 1].count; 722790075Sobrien } 722890075Sobrien else 722990075Sobrien { 7230132718Skan size_t j; 723190075Sobrien 723290075Sobrien /* This is a new directory. */ 723390075Sobrien dirs[ndirs].path = files[i].path; 723490075Sobrien dirs[ndirs].length = files[i].fname - files[i].path; 723590075Sobrien dirs[ndirs].count = 1; 723690075Sobrien dirs[ndirs].dir_idx = ndirs; 723790075Sobrien dirs[ndirs].used = 0; 723890075Sobrien files[i].dir_idx = ndirs; 723990075Sobrien 724090075Sobrien /* Search for a prefix. */ 724190075Sobrien dirs[ndirs].prefix = -1; 724290075Sobrien for (j = 0; j < ndirs; j++) 724390075Sobrien if (dirs[j].length < dirs[ndirs].length 724490075Sobrien && dirs[j].length > 1 724590075Sobrien && (dirs[ndirs].prefix == -1 724690075Sobrien || dirs[j].length > dirs[dirs[ndirs].prefix].length) 724790075Sobrien && memcmp (dirs[j].path, dirs[ndirs].path, dirs[j].length) == 0) 724890075Sobrien dirs[ndirs].prefix = j; 724990075Sobrien 725090075Sobrien ++ndirs; 725190075Sobrien } 725290075Sobrien 725390075Sobrien /* Now to the actual work. We have to find a subset of the directories which 725490075Sobrien allow expressing the file name using references to the directory table 725590075Sobrien with the least amount of characters. We do not do an exhaustive search 725690075Sobrien where we would have to check out every combination of every single 725790075Sobrien possible prefix. Instead we use a heuristic which provides nearly optimal 725890075Sobrien results in most cases and never is much off. */ 7259132718Skan saved = alloca (ndirs * sizeof (int)); 7260132718Skan savehere = alloca (ndirs * sizeof (int)); 726190075Sobrien 726290075Sobrien memset (saved, '\0', ndirs * sizeof (saved[0])); 726390075Sobrien for (i = 0; i < ndirs; i++) 726490075Sobrien { 7265132718Skan size_t j; 726690075Sobrien int total; 726790075Sobrien 726890075Sobrien /* We can always save some space for the current directory. But this 726990075Sobrien does not mean it will be enough to justify adding the directory. */ 727090075Sobrien savehere[i] = dirs[i].length; 727190075Sobrien total = (savehere[i] - saved[i]) * dirs[i].count; 727290075Sobrien 727390075Sobrien for (j = i + 1; j < ndirs; j++) 727490075Sobrien { 727590075Sobrien savehere[j] = 0; 727690075Sobrien if (saved[j] < dirs[i].length) 727790075Sobrien { 727890075Sobrien /* Determine whether the dirs[i] path is a prefix of the 727990075Sobrien dirs[j] path. */ 728090075Sobrien int k; 728190075Sobrien 728290075Sobrien k = dirs[j].prefix; 7283132718Skan while (k != -1 && k != (int) i) 728490075Sobrien k = dirs[k].prefix; 728590075Sobrien 7286132718Skan if (k == (int) i) 728790075Sobrien { 728890075Sobrien /* Yes it is. We can possibly safe some memory but 728990075Sobrien writing the filenames in dirs[j] relative to 729090075Sobrien dirs[i]. */ 729190075Sobrien savehere[j] = dirs[i].length; 729290075Sobrien total += (savehere[j] - saved[j]) * dirs[j].count; 729390075Sobrien } 729490075Sobrien } 729550397Sobrien } 729650397Sobrien 729790075Sobrien /* Check whether we can safe enough to justify adding the dirs[i] 729890075Sobrien directory. */ 729990075Sobrien if (total > dirs[i].length + 1) 730090075Sobrien { 730190075Sobrien /* It's worthwhile adding. */ 7302117395Skan for (j = i; j < ndirs; j++) 730390075Sobrien if (savehere[j] > 0) 730490075Sobrien { 730590075Sobrien /* Remember how much we saved for this directory so far. */ 730690075Sobrien saved[j] = savehere[j]; 730750397Sobrien 730890075Sobrien /* Remember the prefix directory. */ 730990075Sobrien dirs[j].dir_idx = i; 731090075Sobrien } 731190075Sobrien } 731290075Sobrien } 731350397Sobrien 731490075Sobrien /* We have to emit them in the order they appear in the file_table array 731590075Sobrien since the index is used in the debug info generation. To do this 731690075Sobrien efficiently we generate a back-mapping of the indices first. */ 7317132718Skan backmap = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (int)); 7318132718Skan for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++) 731990075Sobrien { 732090075Sobrien backmap[files[i].file_idx] = i; 732150397Sobrien 732290075Sobrien /* Mark this directory as used. */ 732390075Sobrien dirs[dirs[files[i].dir_idx].dir_idx].used = 1; 732450397Sobrien } 732550397Sobrien 732690075Sobrien /* That was it. We are ready to emit the information. First emit the 732790075Sobrien directory name table. We have to make sure the first actually emitted 732890075Sobrien directory name has index one; zero is reserved for the current working 732990075Sobrien directory. Make sure we do not confuse these indices with the one for the 733090075Sobrien constructed table (even though most of the time they are identical). */ 733190075Sobrien idx = 1; 733290075Sobrien idx_offset = dirs[0].length > 0 ? 1 : 0; 733390075Sobrien for (i = 1 - idx_offset; i < ndirs; i++) 733490075Sobrien if (dirs[i].used != 0) 733590075Sobrien { 733690075Sobrien dirs[i].used = idx++; 733790075Sobrien dw2_asm_output_nstring (dirs[i].path, dirs[i].length - 1, 733890075Sobrien "Directory Entry: 0x%x", dirs[i].used); 733990075Sobrien } 734090075Sobrien 734190075Sobrien dw2_asm_output_data (1, 0, "End directory table"); 734290075Sobrien 734390075Sobrien /* Correct the index for the current working directory entry if it 734490075Sobrien exists. */ 734590075Sobrien if (idx_offset == 0) 734690075Sobrien dirs[0].used = 0; 734790075Sobrien 734890075Sobrien /* Now write all the file names. */ 7349132718Skan for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++) 735090075Sobrien { 735190075Sobrien int file_idx = backmap[i]; 735290075Sobrien int dir_idx = dirs[files[file_idx].dir_idx].dir_idx; 735390075Sobrien 735490075Sobrien dw2_asm_output_nstring (files[file_idx].path + dirs[dir_idx].length, -1, 7355132718Skan "File Entry: 0x%lx", (unsigned long) i); 735690075Sobrien 735790075Sobrien /* Include directory index. */ 735890075Sobrien dw2_asm_output_data_uleb128 (dirs[dir_idx].used, NULL); 735990075Sobrien 736090075Sobrien /* Modification time. */ 736190075Sobrien dw2_asm_output_data_uleb128 (0, NULL); 736290075Sobrien 736390075Sobrien /* File length in bytes. */ 736490075Sobrien dw2_asm_output_data_uleb128 (0, NULL); 736590075Sobrien } 736690075Sobrien 736790075Sobrien dw2_asm_output_data (1, 0, "End file name table"); 736850397Sobrien} 736950397Sobrien 737090075Sobrien 737150397Sobrien/* Output the source line number correspondence information. This 737290075Sobrien information goes into the .debug_line section. */ 737350397Sobrien 737450397Sobrienstatic void 7375132718Skanoutput_line_info (void) 737650397Sobrien{ 737790075Sobrien char l1[20], l2[20], p1[20], p2[20]; 737850397Sobrien char line_label[MAX_ARTIFICIAL_LABEL_BYTES]; 737950397Sobrien char prev_line_label[MAX_ARTIFICIAL_LABEL_BYTES]; 738090075Sobrien unsigned opc; 738190075Sobrien unsigned n_op_args; 738290075Sobrien unsigned long lt_index; 738390075Sobrien unsigned long current_line; 738490075Sobrien long line_offset; 738590075Sobrien long line_delta; 738690075Sobrien unsigned long current_file; 738790075Sobrien unsigned long function; 738850397Sobrien 738990075Sobrien ASM_GENERATE_INTERNAL_LABEL (l1, LINE_NUMBER_BEGIN_LABEL, 0); 739090075Sobrien ASM_GENERATE_INTERNAL_LABEL (l2, LINE_NUMBER_END_LABEL, 0); 739190075Sobrien ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL, 0); 739290075Sobrien ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL, 0); 739350397Sobrien 7394132718Skan if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) 7395132718Skan dw2_asm_output_data (4, 0xffffffff, 7396132718Skan "Initial length escape value indicating 64-bit DWARF extension"); 739790075Sobrien dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1, 739890075Sobrien "Length of Source Line Info"); 739990075Sobrien ASM_OUTPUT_LABEL (asm_out_file, l1); 740050397Sobrien 740190075Sobrien dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version"); 740290075Sobrien dw2_asm_output_delta (DWARF_OFFSET_SIZE, p2, p1, "Prolog Length"); 740390075Sobrien ASM_OUTPUT_LABEL (asm_out_file, p1); 740450397Sobrien 740596263Sobrien /* Define the architecture-dependent minimum instruction length (in 740696263Sobrien bytes). In this implementation of DWARF, this field is used for 740796263Sobrien information purposes only. Since GCC generates assembly language, 740896263Sobrien we have no a priori knowledge of how many instruction bytes are 740996263Sobrien generated for each source line, and therefore can use only the 741096263Sobrien DW_LNE_set_address and DW_LNS_fixed_advance_pc line information 741196263Sobrien commands. Accordingly, we fix this as `1', which is "correct 741296263Sobrien enough" for all architectures, and don't let the target override. */ 741396263Sobrien dw2_asm_output_data (1, 1, 741490075Sobrien "Minimum Instruction Length"); 741596263Sobrien 741690075Sobrien dw2_asm_output_data (1, DWARF_LINE_DEFAULT_IS_STMT_START, 741790075Sobrien "Default is_stmt_start flag"); 741890075Sobrien dw2_asm_output_data (1, DWARF_LINE_BASE, 741990075Sobrien "Line Base Value (Special Opcodes)"); 742090075Sobrien dw2_asm_output_data (1, DWARF_LINE_RANGE, 742190075Sobrien "Line Range Value (Special Opcodes)"); 742290075Sobrien dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE, 742390075Sobrien "Special Opcode Base"); 742450397Sobrien 742590075Sobrien for (opc = 1; opc < DWARF_LINE_OPCODE_BASE; opc++) 742650397Sobrien { 742750397Sobrien switch (opc) 742850397Sobrien { 742950397Sobrien case DW_LNS_advance_pc: 743050397Sobrien case DW_LNS_advance_line: 743150397Sobrien case DW_LNS_set_file: 743250397Sobrien case DW_LNS_set_column: 743350397Sobrien case DW_LNS_fixed_advance_pc: 743450397Sobrien n_op_args = 1; 743550397Sobrien break; 743650397Sobrien default: 743750397Sobrien n_op_args = 0; 743850397Sobrien break; 743950397Sobrien } 744050397Sobrien 744190075Sobrien dw2_asm_output_data (1, n_op_args, "opcode: 0x%x has %d args", 744290075Sobrien opc, n_op_args); 744350397Sobrien } 744450397Sobrien 744590075Sobrien /* Write out the information about the files we use. */ 744690075Sobrien output_file_names (); 744790075Sobrien ASM_OUTPUT_LABEL (asm_out_file, p2); 744850397Sobrien 744952284Sobrien /* We used to set the address register to the first location in the text 745052284Sobrien section here, but that didn't accomplish anything since we already 745152284Sobrien have a line note for the opening brace of the first function. */ 745250397Sobrien 745350397Sobrien /* Generate the line number to PC correspondence table, encoded as 745450397Sobrien a series of state machine operations. */ 745550397Sobrien current_file = 1; 745650397Sobrien current_line = 1; 745752284Sobrien strcpy (prev_line_label, text_section_label); 745850397Sobrien for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) 745950397Sobrien { 746090075Sobrien dw_line_info_ref line_info = &line_info_table[lt_index]; 746150397Sobrien 746290075Sobrien#if 0 746390075Sobrien /* Disable this optimization for now; GDB wants to see two line notes 746490075Sobrien at the beginning of a function so it can find the end of the 746590075Sobrien prologue. */ 746690075Sobrien 746752284Sobrien /* Don't emit anything for redundant notes. Just updating the 7468132718Skan address doesn't accomplish anything, because we already assume 7469132718Skan that anything after the last address is this line. */ 747052284Sobrien if (line_info->dw_line_num == current_line 747152284Sobrien && line_info->dw_file_num == current_file) 747252284Sobrien continue; 747390075Sobrien#endif 747452284Sobrien 747590075Sobrien /* Emit debug info for the address of the current line. 747690075Sobrien 747790075Sobrien Unfortunately, we have little choice here currently, and must always 747890075Sobrien use the most general form. GCC does not know the address delta 747990075Sobrien itself, so we can't use DW_LNS_advance_pc. Many ports do have length 748090075Sobrien attributes which will give an upper bound on the address range. We 748190075Sobrien could perhaps use length attributes to determine when it is safe to 748290075Sobrien use DW_LNS_fixed_advance_pc. */ 748390075Sobrien 748450397Sobrien ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, lt_index); 748550397Sobrien if (0) 748650397Sobrien { 748750397Sobrien /* This can handle deltas up to 0xffff. This takes 3 bytes. */ 748890075Sobrien dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, 748990075Sobrien "DW_LNS_fixed_advance_pc"); 749090075Sobrien dw2_asm_output_delta (2, line_label, prev_line_label, NULL); 749150397Sobrien } 749250397Sobrien else 749350397Sobrien { 749490075Sobrien /* This can handle any delta. This takes 7495132718Skan 4+DWARF2_ADDR_SIZE bytes. */ 749690075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_set_address"); 749790075Sobrien dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); 749890075Sobrien dw2_asm_output_data (1, DW_LNE_set_address, NULL); 749990075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL); 750050397Sobrien } 750190075Sobrien 750250397Sobrien strcpy (prev_line_label, line_label); 750350397Sobrien 750450397Sobrien /* Emit debug info for the source file of the current line, if 750550397Sobrien different from the previous line. */ 750650397Sobrien if (line_info->dw_file_num != current_file) 750750397Sobrien { 750850397Sobrien current_file = line_info->dw_file_num; 750990075Sobrien dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file"); 751090075Sobrien dw2_asm_output_data_uleb128 (current_file, "(\"%s\")", 7511132718Skan VARRAY_CHAR_PTR (file_table, 7512132718Skan current_file)); 751350397Sobrien } 751450397Sobrien 751550397Sobrien /* Emit debug info for the current line number, choosing the encoding 751650397Sobrien that uses the least amount of space. */ 751752284Sobrien if (line_info->dw_line_num != current_line) 751850397Sobrien { 751952284Sobrien line_offset = line_info->dw_line_num - current_line; 752052284Sobrien line_delta = line_offset - DWARF_LINE_BASE; 752152284Sobrien current_line = line_info->dw_line_num; 752252284Sobrien if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1)) 752390075Sobrien /* This can handle deltas from -10 to 234, using the current 752490075Sobrien definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE. This 752590075Sobrien takes 1 byte. */ 752690075Sobrien dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE + line_delta, 752790075Sobrien "line %lu", current_line); 752852284Sobrien else 752952284Sobrien { 753052284Sobrien /* This can handle any delta. This takes at least 4 bytes, 753152284Sobrien depending on the value being encoded. */ 753290075Sobrien dw2_asm_output_data (1, DW_LNS_advance_line, 753390075Sobrien "advance to line %lu", current_line); 753490075Sobrien dw2_asm_output_data_sleb128 (line_offset, NULL); 753590075Sobrien dw2_asm_output_data (1, DW_LNS_copy, "DW_LNS_copy"); 753652284Sobrien } 753750397Sobrien } 753850397Sobrien else 753990075Sobrien /* We still need to start a new row, so output a copy insn. */ 754090075Sobrien dw2_asm_output_data (1, DW_LNS_copy, "DW_LNS_copy"); 754150397Sobrien } 754250397Sobrien 754350397Sobrien /* Emit debug info for the address of the end of the function. */ 754450397Sobrien if (0) 754550397Sobrien { 754690075Sobrien dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, 754790075Sobrien "DW_LNS_fixed_advance_pc"); 754890075Sobrien dw2_asm_output_delta (2, text_end_label, prev_line_label, NULL); 754950397Sobrien } 755050397Sobrien else 755150397Sobrien { 755290075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_set_address"); 755390075Sobrien dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); 755490075Sobrien dw2_asm_output_data (1, DW_LNE_set_address, NULL); 755590075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_end_label, NULL); 755650397Sobrien } 755750397Sobrien 755890075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_end_sequence"); 755990075Sobrien dw2_asm_output_data_uleb128 (1, NULL); 756090075Sobrien dw2_asm_output_data (1, DW_LNE_end_sequence, NULL); 756150397Sobrien 756250397Sobrien function = 0; 756350397Sobrien current_file = 1; 756450397Sobrien current_line = 1; 756590075Sobrien for (lt_index = 0; lt_index < separate_line_info_table_in_use;) 756650397Sobrien { 756790075Sobrien dw_separate_line_info_ref line_info 756850397Sobrien = &separate_line_info_table[lt_index]; 756950397Sobrien 757090075Sobrien#if 0 757152284Sobrien /* Don't emit anything for redundant notes. */ 757252284Sobrien if (line_info->dw_line_num == current_line 757352284Sobrien && line_info->dw_file_num == current_file 757452284Sobrien && line_info->function == function) 757552284Sobrien goto cont; 757690075Sobrien#endif 757752284Sobrien 757850397Sobrien /* Emit debug info for the address of the current line. If this is 757950397Sobrien a new function, or the first line of a function, then we need 758050397Sobrien to handle it differently. */ 758150397Sobrien ASM_GENERATE_INTERNAL_LABEL (line_label, SEPARATE_LINE_CODE_LABEL, 758250397Sobrien lt_index); 758350397Sobrien if (function != line_info->function) 758450397Sobrien { 758550397Sobrien function = line_info->function; 758650397Sobrien 7587132718Skan /* Set the address register to the first line in the function. */ 758890075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_set_address"); 758990075Sobrien dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); 759090075Sobrien dw2_asm_output_data (1, DW_LNE_set_address, NULL); 759190075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL); 759250397Sobrien } 759350397Sobrien else 759450397Sobrien { 759550397Sobrien /* ??? See the DW_LNS_advance_pc comment above. */ 759650397Sobrien if (0) 759750397Sobrien { 759890075Sobrien dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, 759990075Sobrien "DW_LNS_fixed_advance_pc"); 760090075Sobrien dw2_asm_output_delta (2, line_label, prev_line_label, NULL); 760150397Sobrien } 760250397Sobrien else 760350397Sobrien { 760490075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_set_address"); 760590075Sobrien dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); 760690075Sobrien dw2_asm_output_data (1, DW_LNE_set_address, NULL); 760790075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL); 760850397Sobrien } 760950397Sobrien } 761090075Sobrien 761150397Sobrien strcpy (prev_line_label, line_label); 761250397Sobrien 761350397Sobrien /* Emit debug info for the source file of the current line, if 761450397Sobrien different from the previous line. */ 761550397Sobrien if (line_info->dw_file_num != current_file) 761650397Sobrien { 761750397Sobrien current_file = line_info->dw_file_num; 761890075Sobrien dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file"); 761990075Sobrien dw2_asm_output_data_uleb128 (current_file, "(\"%s\")", 7620132718Skan VARRAY_CHAR_PTR (file_table, 7621132718Skan current_file)); 762250397Sobrien } 762350397Sobrien 762450397Sobrien /* Emit debug info for the current line number, choosing the encoding 762550397Sobrien that uses the least amount of space. */ 762650397Sobrien if (line_info->dw_line_num != current_line) 762750397Sobrien { 762850397Sobrien line_offset = line_info->dw_line_num - current_line; 762950397Sobrien line_delta = line_offset - DWARF_LINE_BASE; 763050397Sobrien current_line = line_info->dw_line_num; 763150397Sobrien if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1)) 763290075Sobrien dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE + line_delta, 763390075Sobrien "line %lu", current_line); 763450397Sobrien else 763550397Sobrien { 763690075Sobrien dw2_asm_output_data (1, DW_LNS_advance_line, 763790075Sobrien "advance to line %lu", current_line); 763890075Sobrien dw2_asm_output_data_sleb128 (line_offset, NULL); 763990075Sobrien dw2_asm_output_data (1, DW_LNS_copy, "DW_LNS_copy"); 764050397Sobrien } 764150397Sobrien } 764252284Sobrien else 764390075Sobrien dw2_asm_output_data (1, DW_LNS_copy, "DW_LNS_copy"); 764450397Sobrien 764590075Sobrien#if 0 764652284Sobrien cont: 764790075Sobrien#endif 764850397Sobrien 764990075Sobrien lt_index++; 765090075Sobrien 765150397Sobrien /* If we're done with a function, end its sequence. */ 765250397Sobrien if (lt_index == separate_line_info_table_in_use 765350397Sobrien || separate_line_info_table[lt_index].function != function) 765450397Sobrien { 765550397Sobrien current_file = 1; 765650397Sobrien current_line = 1; 765750397Sobrien 765850397Sobrien /* Emit debug info for the address of the end of the function. */ 765950397Sobrien ASM_GENERATE_INTERNAL_LABEL (line_label, FUNC_END_LABEL, function); 766050397Sobrien if (0) 766150397Sobrien { 766290075Sobrien dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, 766390075Sobrien "DW_LNS_fixed_advance_pc"); 766490075Sobrien dw2_asm_output_delta (2, line_label, prev_line_label, NULL); 766550397Sobrien } 766650397Sobrien else 766750397Sobrien { 766890075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_set_address"); 766990075Sobrien dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); 767090075Sobrien dw2_asm_output_data (1, DW_LNE_set_address, NULL); 767190075Sobrien dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL); 767250397Sobrien } 767350397Sobrien 767450397Sobrien /* Output the marker for the end of this sequence. */ 767590075Sobrien dw2_asm_output_data (1, 0, "DW_LNE_end_sequence"); 767690075Sobrien dw2_asm_output_data_uleb128 (1, NULL); 767790075Sobrien dw2_asm_output_data (1, DW_LNE_end_sequence, NULL); 767850397Sobrien } 767950397Sobrien } 768090075Sobrien 768190075Sobrien /* Output the marker for the end of the line number info. */ 768290075Sobrien ASM_OUTPUT_LABEL (asm_out_file, l2); 768350397Sobrien} 768450397Sobrien 768550397Sobrien/* Given a pointer to a tree node for some base type, return a pointer to 768650397Sobrien a DIE that describes the given type. 768750397Sobrien 768850397Sobrien This routine must only be called for GCC type nodes that correspond to 768950397Sobrien Dwarf base (fundamental) types. */ 769050397Sobrien 769150397Sobrienstatic dw_die_ref 7692132718Skanbase_type_die (tree type) 769350397Sobrien{ 769490075Sobrien dw_die_ref base_type_result; 769590075Sobrien const char *type_name; 769690075Sobrien enum dwarf_type encoding; 769790075Sobrien tree name = TYPE_NAME (type); 769850397Sobrien 769990075Sobrien if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE) 770050397Sobrien return 0; 770150397Sobrien 770290075Sobrien if (name) 770390075Sobrien { 770490075Sobrien if (TREE_CODE (name) == TYPE_DECL) 770590075Sobrien name = DECL_NAME (name); 770650397Sobrien 770790075Sobrien type_name = IDENTIFIER_POINTER (name); 770890075Sobrien } 770990075Sobrien else 771090075Sobrien type_name = "__unknown__"; 771190075Sobrien 771250397Sobrien switch (TREE_CODE (type)) 771350397Sobrien { 771450397Sobrien case INTEGER_TYPE: 771550397Sobrien /* Carefully distinguish the C character types, without messing 7716132718Skan up if the language is not C. Note that we check only for the names 7717132718Skan that contain spaces; other names might occur by coincidence in other 7718132718Skan languages. */ 771950397Sobrien if (! (TYPE_PRECISION (type) == CHAR_TYPE_SIZE 772050397Sobrien && (type == char_type_node 772150397Sobrien || ! strcmp (type_name, "signed char") 772250397Sobrien || ! strcmp (type_name, "unsigned char")))) 772350397Sobrien { 772450397Sobrien if (TREE_UNSIGNED (type)) 772550397Sobrien encoding = DW_ATE_unsigned; 772650397Sobrien else 772750397Sobrien encoding = DW_ATE_signed; 772850397Sobrien break; 772950397Sobrien } 773090075Sobrien /* else fall through. */ 773150397Sobrien 773250397Sobrien case CHAR_TYPE: 773350397Sobrien /* GNU Pascal/Ada CHAR type. Not used in C. */ 773450397Sobrien if (TREE_UNSIGNED (type)) 773550397Sobrien encoding = DW_ATE_unsigned_char; 773650397Sobrien else 773750397Sobrien encoding = DW_ATE_signed_char; 773850397Sobrien break; 773950397Sobrien 774050397Sobrien case REAL_TYPE: 774150397Sobrien encoding = DW_ATE_float; 774250397Sobrien break; 774350397Sobrien 774490075Sobrien /* Dwarf2 doesn't know anything about complex ints, so use 774590075Sobrien a user defined type for it. */ 774650397Sobrien case COMPLEX_TYPE: 774790075Sobrien if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) 774890075Sobrien encoding = DW_ATE_complex_float; 774990075Sobrien else 775090075Sobrien encoding = DW_ATE_lo_user; 775150397Sobrien break; 775250397Sobrien 775350397Sobrien case BOOLEAN_TYPE: 775450397Sobrien /* GNU FORTRAN/Ada/C++ BOOLEAN type. */ 775550397Sobrien encoding = DW_ATE_boolean; 775650397Sobrien break; 775750397Sobrien 775850397Sobrien default: 775990075Sobrien /* No other TREE_CODEs are Dwarf fundamental types. */ 776090075Sobrien abort (); 776150397Sobrien } 776250397Sobrien 776390075Sobrien base_type_result = new_die (DW_TAG_base_type, comp_unit_die, type); 776490075Sobrien if (demangle_name_func) 776590075Sobrien type_name = (*demangle_name_func) (type_name); 776690075Sobrien 776750397Sobrien add_AT_string (base_type_result, DW_AT_name, type_name); 776850397Sobrien add_AT_unsigned (base_type_result, DW_AT_byte_size, 776950397Sobrien int_size_in_bytes (type)); 777050397Sobrien add_AT_unsigned (base_type_result, DW_AT_encoding, encoding); 777150397Sobrien 777250397Sobrien return base_type_result; 777350397Sobrien} 777450397Sobrien 777550397Sobrien/* Given a pointer to an arbitrary ..._TYPE tree node, return a pointer to 777650397Sobrien the Dwarf "root" type for the given input type. The Dwarf "root" type of 777750397Sobrien a given type is generally the same as the given type, except that if the 777850397Sobrien given type is a pointer or reference type, then the root type of the given 777950397Sobrien type is the root type of the "basis" type for the pointer or reference 778050397Sobrien type. (This definition of the "root" type is recursive.) Also, the root 778150397Sobrien type of a `const' qualified type or a `volatile' qualified type is the 778250397Sobrien root type of the given type without the qualifiers. */ 778350397Sobrien 778450397Sobrienstatic tree 7785132718Skanroot_type (tree type) 778650397Sobrien{ 778750397Sobrien if (TREE_CODE (type) == ERROR_MARK) 778850397Sobrien return error_mark_node; 778950397Sobrien 779050397Sobrien switch (TREE_CODE (type)) 779150397Sobrien { 779250397Sobrien case ERROR_MARK: 779350397Sobrien return error_mark_node; 779450397Sobrien 779550397Sobrien case POINTER_TYPE: 779650397Sobrien case REFERENCE_TYPE: 779750397Sobrien return type_main_variant (root_type (TREE_TYPE (type))); 779850397Sobrien 779950397Sobrien default: 780050397Sobrien return type_main_variant (type); 780150397Sobrien } 780250397Sobrien} 780350397Sobrien 7804117395Skan/* Given a pointer to an arbitrary ..._TYPE tree node, return nonzero if the 780550397Sobrien given input type is a Dwarf "fundamental" type. Otherwise return null. */ 780650397Sobrien 780750397Sobrienstatic inline int 7808132718Skanis_base_type (tree type) 780950397Sobrien{ 781050397Sobrien switch (TREE_CODE (type)) 781150397Sobrien { 781250397Sobrien case ERROR_MARK: 781350397Sobrien case VOID_TYPE: 781450397Sobrien case INTEGER_TYPE: 781550397Sobrien case REAL_TYPE: 781650397Sobrien case COMPLEX_TYPE: 781750397Sobrien case BOOLEAN_TYPE: 781850397Sobrien case CHAR_TYPE: 781950397Sobrien return 1; 782050397Sobrien 782150397Sobrien case SET_TYPE: 782250397Sobrien case ARRAY_TYPE: 782350397Sobrien case RECORD_TYPE: 782450397Sobrien case UNION_TYPE: 782550397Sobrien case QUAL_UNION_TYPE: 782650397Sobrien case ENUMERAL_TYPE: 782750397Sobrien case FUNCTION_TYPE: 782850397Sobrien case METHOD_TYPE: 782950397Sobrien case POINTER_TYPE: 783050397Sobrien case REFERENCE_TYPE: 783150397Sobrien case FILE_TYPE: 783250397Sobrien case OFFSET_TYPE: 783350397Sobrien case LANG_TYPE: 783490075Sobrien case VECTOR_TYPE: 783550397Sobrien return 0; 783650397Sobrien 783750397Sobrien default: 783850397Sobrien abort (); 783950397Sobrien } 784050397Sobrien 784150397Sobrien return 0; 784250397Sobrien} 784350397Sobrien 7844132718Skan/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE 7845132718Skan node, return the size in bits for the type if it is a constant, or else 7846132718Skan return the alignment for the type if the type's size is not constant, or 7847132718Skan else return BITS_PER_WORD if the type actually turns out to be an 7848132718Skan ERROR_MARK node. */ 7849132718Skan 7850132718Skanstatic inline unsigned HOST_WIDE_INT 7851132718Skansimple_type_size_in_bits (tree type) 7852132718Skan{ 7853132718Skan if (TREE_CODE (type) == ERROR_MARK) 7854132718Skan return BITS_PER_WORD; 7855132718Skan else if (TYPE_SIZE (type) == NULL_TREE) 7856132718Skan return 0; 7857132718Skan else if (host_integerp (TYPE_SIZE (type), 1)) 7858132718Skan return tree_low_cst (TYPE_SIZE (type), 1); 7859132718Skan else 7860132718Skan return TYPE_ALIGN (type); 7861132718Skan} 7862132718Skan 7863132718Skan/* Return true if the debug information for the given type should be 7864132718Skan emitted as a subrange type. */ 7865132718Skan 7866132718Skanstatic inline bool 7867132718Skanis_subrange_type (tree type) 7868132718Skan{ 7869132718Skan tree subtype = TREE_TYPE (type); 7870132718Skan 7871132718Skan if (TREE_CODE (type) == INTEGER_TYPE 7872132718Skan && subtype != NULL_TREE) 7873132718Skan { 7874132718Skan if (TREE_CODE (subtype) == INTEGER_TYPE) 7875132718Skan return true; 7876132718Skan if (TREE_CODE (subtype) == ENUMERAL_TYPE) 7877132718Skan return true; 7878132718Skan } 7879132718Skan return false; 7880132718Skan} 7881132718Skan 7882132718Skan/* Given a pointer to a tree node for a subrange type, return a pointer 7883132718Skan to a DIE that describes the given type. */ 7884132718Skan 7885132718Skanstatic dw_die_ref 7886132718Skansubrange_type_die (tree type, dw_die_ref context_die) 7887132718Skan{ 7888132718Skan dw_die_ref subtype_die; 7889132718Skan dw_die_ref subrange_die; 7890132718Skan tree name = TYPE_NAME (type); 7891132718Skan const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type); 7892132718Skan 7893132718Skan if (context_die == NULL) 7894132718Skan context_die = comp_unit_die; 7895132718Skan 7896132718Skan if (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE) 7897132718Skan subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die); 7898132718Skan else 7899132718Skan subtype_die = base_type_die (TREE_TYPE (type)); 7900132718Skan 7901132718Skan subrange_die = new_die (DW_TAG_subrange_type, context_die, type); 7902132718Skan 7903132718Skan if (name != NULL) 7904132718Skan { 7905132718Skan if (TREE_CODE (name) == TYPE_DECL) 7906132718Skan name = DECL_NAME (name); 7907132718Skan add_name_attribute (subrange_die, IDENTIFIER_POINTER (name)); 7908132718Skan } 7909132718Skan 7910132718Skan if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes) 7911132718Skan { 7912132718Skan /* The size of the subrange type and its base type do not match, 7913132718Skan so we need to generate a size attribute for the subrange type. */ 7914132718Skan add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes); 7915132718Skan } 7916132718Skan 7917132718Skan if (TYPE_MIN_VALUE (type) != NULL) 7918132718Skan add_bound_info (subrange_die, DW_AT_lower_bound, 7919132718Skan TYPE_MIN_VALUE (type)); 7920132718Skan if (TYPE_MAX_VALUE (type) != NULL) 7921132718Skan add_bound_info (subrange_die, DW_AT_upper_bound, 7922132718Skan TYPE_MAX_VALUE (type)); 7923132718Skan add_AT_die_ref (subrange_die, DW_AT_type, subtype_die); 7924132718Skan 7925132718Skan return subrange_die; 7926132718Skan} 7927132718Skan 792850397Sobrien/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging 792950397Sobrien entry that chains various modifiers in front of the given type. */ 793050397Sobrien 793150397Sobrienstatic dw_die_ref 7932132718Skanmodified_type_die (tree type, int is_const_type, int is_volatile_type, 7933132718Skan dw_die_ref context_die) 793450397Sobrien{ 793590075Sobrien enum tree_code code = TREE_CODE (type); 793690075Sobrien dw_die_ref mod_type_die = NULL; 793790075Sobrien dw_die_ref sub_die = NULL; 793890075Sobrien tree item_type = NULL; 793950397Sobrien 794050397Sobrien if (code != ERROR_MARK) 794150397Sobrien { 794290075Sobrien tree qualified_type; 794350397Sobrien 794490075Sobrien /* See if we already have the appropriately qualified variant of 794590075Sobrien this type. */ 7946117395Skan qualified_type 794790075Sobrien = get_qualified_type (type, 794890075Sobrien ((is_const_type ? TYPE_QUAL_CONST : 0) 7949117395Skan | (is_volatile_type 795090075Sobrien ? TYPE_QUAL_VOLATILE : 0))); 795150397Sobrien 795290075Sobrien /* If we do, then we can just use its DIE, if it exists. */ 795390075Sobrien if (qualified_type) 795450397Sobrien { 795590075Sobrien mod_type_die = lookup_type_die (qualified_type); 795690075Sobrien if (mod_type_die) 795790075Sobrien return mod_type_die; 795890075Sobrien } 795990075Sobrien 796090075Sobrien /* Handle C typedef types. */ 7961117395Skan if (qualified_type && TYPE_NAME (qualified_type) 796290075Sobrien && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL 796390075Sobrien && DECL_ORIGINAL_TYPE (TYPE_NAME (qualified_type))) 796490075Sobrien { 796590075Sobrien tree type_name = TYPE_NAME (qualified_type); 796690075Sobrien tree dtype = TREE_TYPE (type_name); 796790075Sobrien 796890075Sobrien if (qualified_type == dtype) 796950397Sobrien { 797050397Sobrien /* For a named type, use the typedef. */ 797190075Sobrien gen_type_die (qualified_type, context_die); 797290075Sobrien mod_type_die = lookup_type_die (qualified_type); 797350397Sobrien } 797450397Sobrien else if (is_const_type < TYPE_READONLY (dtype) 797550397Sobrien || is_volatile_type < TYPE_VOLATILE (dtype)) 797650397Sobrien /* cv-unqualified version of named type. Just use the unnamed 797750397Sobrien type to which it refers. */ 797850397Sobrien mod_type_die 797990075Sobrien = modified_type_die (DECL_ORIGINAL_TYPE (type_name), 798050397Sobrien is_const_type, is_volatile_type, 798150397Sobrien context_die); 798290075Sobrien 798350397Sobrien /* Else cv-qualified version of named type; fall through. */ 798450397Sobrien } 798550397Sobrien 798650397Sobrien if (mod_type_die) 798790075Sobrien /* OK. */ 798890075Sobrien ; 798950397Sobrien else if (is_const_type) 799050397Sobrien { 799190075Sobrien mod_type_die = new_die (DW_TAG_const_type, comp_unit_die, type); 799250397Sobrien sub_die = modified_type_die (type, 0, is_volatile_type, context_die); 799350397Sobrien } 799450397Sobrien else if (is_volatile_type) 799550397Sobrien { 799690075Sobrien mod_type_die = new_die (DW_TAG_volatile_type, comp_unit_die, type); 799750397Sobrien sub_die = modified_type_die (type, 0, 0, context_die); 799850397Sobrien } 799950397Sobrien else if (code == POINTER_TYPE) 800050397Sobrien { 800190075Sobrien mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die, type); 8002132718Skan add_AT_unsigned (mod_type_die, DW_AT_byte_size, 8003132718Skan simple_type_size_in_bits (type) / BITS_PER_UNIT); 800450397Sobrien#if 0 800550397Sobrien add_AT_unsigned (mod_type_die, DW_AT_address_class, 0); 800650397Sobrien#endif 800750397Sobrien item_type = TREE_TYPE (type); 800850397Sobrien } 800950397Sobrien else if (code == REFERENCE_TYPE) 801050397Sobrien { 801190075Sobrien mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); 8012132718Skan add_AT_unsigned (mod_type_die, DW_AT_byte_size, 8013132718Skan simple_type_size_in_bits (type) / BITS_PER_UNIT); 801450397Sobrien#if 0 801550397Sobrien add_AT_unsigned (mod_type_die, DW_AT_address_class, 0); 801690075Sobrien#endif 801750397Sobrien item_type = TREE_TYPE (type); 801850397Sobrien } 8019132718Skan else if (is_subrange_type (type)) 8020132718Skan mod_type_die = subrange_type_die (type, context_die); 802150397Sobrien else if (is_base_type (type)) 802250397Sobrien mod_type_die = base_type_die (type); 802350397Sobrien else 802450397Sobrien { 802550397Sobrien gen_type_die (type, context_die); 802650397Sobrien 802750397Sobrien /* We have to get the type_main_variant here (and pass that to the 802850397Sobrien `lookup_type_die' routine) because the ..._TYPE node we have 802950397Sobrien might simply be a *copy* of some original type node (where the 803050397Sobrien copy was created to help us keep track of typedef names) and 803150397Sobrien that copy might have a different TYPE_UID from the original 803250397Sobrien ..._TYPE node. */ 8033117395Skan if (TREE_CODE (type) != VECTOR_TYPE) 8034117395Skan mod_type_die = lookup_type_die (type_main_variant (type)); 8035117395Skan else 8036117395Skan /* Vectors have the debugging information in the type, 8037117395Skan not the main variant. */ 8038117395Skan mod_type_die = lookup_type_die (type); 803950397Sobrien if (mod_type_die == NULL) 804050397Sobrien abort (); 804150397Sobrien } 804290075Sobrien 804390075Sobrien /* We want to equate the qualified type to the die below. */ 8044102780Skan type = qualified_type; 804550397Sobrien } 804650397Sobrien 8047102780Skan if (type) 8048102780Skan equate_type_number_to_die (type, mod_type_die); 804950397Sobrien if (item_type) 805050397Sobrien /* We must do this after the equate_type_number_to_die call, in case 805150397Sobrien this is a recursive type. This ensures that the modified_type_die 805250397Sobrien recursion will terminate even if the type is recursive. Recursive 805350397Sobrien types are possible in Ada. */ 805450397Sobrien sub_die = modified_type_die (item_type, 805550397Sobrien TYPE_READONLY (item_type), 805650397Sobrien TYPE_VOLATILE (item_type), 805750397Sobrien context_die); 805850397Sobrien 805950397Sobrien if (sub_die != NULL) 806050397Sobrien add_AT_die_ref (mod_type_die, DW_AT_type, sub_die); 806150397Sobrien 806250397Sobrien return mod_type_die; 806350397Sobrien} 806450397Sobrien 806550397Sobrien/* Given a pointer to an arbitrary ..._TYPE tree node, return true if it is 806690075Sobrien an enumerated type. */ 806750397Sobrien 806850397Sobrienstatic inline int 8069132718Skantype_is_enum (tree type) 807050397Sobrien{ 807150397Sobrien return TREE_CODE (type) == ENUMERAL_TYPE; 807250397Sobrien} 807350397Sobrien 8074132718Skan/* Return the DBX register number described by a given RTL node. */ 807550397Sobrien 807690075Sobrienstatic unsigned int 8077132718Skandbx_reg_number (rtx rtl) 807890075Sobrien{ 807990075Sobrien unsigned regno = REGNO (rtl); 808090075Sobrien 808190075Sobrien if (regno >= FIRST_PSEUDO_REGISTER) 808290075Sobrien abort (); 808390075Sobrien 808490075Sobrien return DBX_REGISTER_NUMBER (regno); 808590075Sobrien} 808690075Sobrien 808790075Sobrien/* Return a location descriptor that designates a machine register or 8088132718Skan zero if there is none. */ 808990075Sobrien 809050397Sobrienstatic dw_loc_descr_ref 8091132718Skanreg_loc_descriptor (rtx rtl) 809250397Sobrien{ 809390075Sobrien unsigned reg; 8094132718Skan rtx regs; 809550397Sobrien 809690075Sobrien if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER) 809790075Sobrien return 0; 809890075Sobrien 8099132718Skan reg = dbx_reg_number (rtl); 8100132718Skan regs = (*targetm.dwarf_register_span) (rtl); 8101132718Skan 8102132718Skan if (HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl)) > 1 8103132718Skan || regs) 8104132718Skan return multiple_reg_loc_descriptor (rtl, regs); 810550397Sobrien else 8106132718Skan return one_reg_loc_descriptor (reg); 8107132718Skan} 810850397Sobrien 8109132718Skan/* Return a location descriptor that designates a machine register for 8110132718Skan a given hard register number. */ 8111132718Skan 8112132718Skanstatic dw_loc_descr_ref 8113132718Skanone_reg_loc_descriptor (unsigned int regno) 8114132718Skan{ 8115132718Skan if (regno <= 31) 8116132718Skan return new_loc_descr (DW_OP_reg0 + regno, 0, 0); 8117132718Skan else 8118132718Skan return new_loc_descr (DW_OP_regx, regno, 0); 8119132718Skan} 8120132718Skan 8121132718Skan/* Given an RTL of a register, return a location descriptor that 8122132718Skan designates a value that spans more than one register. */ 8123132718Skan 8124132718Skanstatic dw_loc_descr_ref 8125132718Skanmultiple_reg_loc_descriptor (rtx rtl, rtx regs) 8126132718Skan{ 8127132718Skan int nregs, size, i; 8128132718Skan unsigned reg; 8129132718Skan dw_loc_descr_ref loc_result = NULL; 8130132718Skan 8131132718Skan reg = dbx_reg_number (rtl); 8132132718Skan nregs = HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl)); 8133132718Skan 8134132718Skan /* Simple, contiguous registers. */ 8135132718Skan if (regs == NULL_RTX) 8136132718Skan { 8137132718Skan size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs; 8138132718Skan 8139132718Skan loc_result = NULL; 8140132718Skan while (nregs--) 8141132718Skan { 8142132718Skan dw_loc_descr_ref t; 8143132718Skan 8144132718Skan t = one_reg_loc_descriptor (reg); 8145132718Skan add_loc_descr (&loc_result, t); 8146132718Skan add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0)); 8147132718Skan ++reg; 8148132718Skan } 8149132718Skan return loc_result; 8150132718Skan } 8151132718Skan 8152132718Skan /* Now onto stupid register sets in non contiguous locations. */ 8153132718Skan 8154132718Skan if (GET_CODE (regs) != PARALLEL) 8155132718Skan abort (); 8156132718Skan 8157132718Skan size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0))); 8158132718Skan loc_result = NULL; 8159132718Skan 8160132718Skan for (i = 0; i < XVECLEN (regs, 0); ++i) 8161132718Skan { 8162132718Skan dw_loc_descr_ref t; 8163132718Skan 8164132718Skan t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i))); 8165132718Skan add_loc_descr (&loc_result, t); 8166132718Skan size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0))); 8167132718Skan add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0)); 8168132718Skan } 816950397Sobrien return loc_result; 817050397Sobrien} 817150397Sobrien 817290075Sobrien/* Return a location descriptor that designates a constant. */ 817390075Sobrien 817490075Sobrienstatic dw_loc_descr_ref 8175132718Skanint_loc_descriptor (HOST_WIDE_INT i) 817690075Sobrien{ 817790075Sobrien enum dwarf_location_atom op; 817890075Sobrien 817990075Sobrien /* Pick the smallest representation of a constant, rather than just 818090075Sobrien defaulting to the LEB encoding. */ 818190075Sobrien if (i >= 0) 818290075Sobrien { 818390075Sobrien if (i <= 31) 818490075Sobrien op = DW_OP_lit0 + i; 818590075Sobrien else if (i <= 0xff) 818690075Sobrien op = DW_OP_const1u; 818790075Sobrien else if (i <= 0xffff) 818890075Sobrien op = DW_OP_const2u; 818990075Sobrien else if (HOST_BITS_PER_WIDE_INT == 32 819090075Sobrien || i <= 0xffffffff) 819190075Sobrien op = DW_OP_const4u; 819290075Sobrien else 819390075Sobrien op = DW_OP_constu; 819490075Sobrien } 819590075Sobrien else 819690075Sobrien { 819790075Sobrien if (i >= -0x80) 819890075Sobrien op = DW_OP_const1s; 819990075Sobrien else if (i >= -0x8000) 820090075Sobrien op = DW_OP_const2s; 820190075Sobrien else if (HOST_BITS_PER_WIDE_INT == 32 820290075Sobrien || i >= -0x80000000) 820390075Sobrien op = DW_OP_const4s; 820490075Sobrien else 820590075Sobrien op = DW_OP_consts; 820690075Sobrien } 820790075Sobrien 820890075Sobrien return new_loc_descr (op, i, 0); 820990075Sobrien} 821090075Sobrien 821150397Sobrien/* Return a location descriptor that designates a base+offset location. */ 821250397Sobrien 821350397Sobrienstatic dw_loc_descr_ref 8214132718Skanbased_loc_descr (unsigned int reg, HOST_WIDE_INT offset) 821550397Sobrien{ 821690075Sobrien dw_loc_descr_ref loc_result; 821750397Sobrien /* For the "frame base", we use the frame pointer or stack pointer 821850397Sobrien registers, since the RTL for local variables is relative to one of 821950397Sobrien them. */ 822090075Sobrien unsigned fp_reg = DBX_REGISTER_NUMBER (frame_pointer_needed 822190075Sobrien ? HARD_FRAME_POINTER_REGNUM 822290075Sobrien : STACK_POINTER_REGNUM); 822350397Sobrien 822450397Sobrien if (reg == fp_reg) 822550397Sobrien loc_result = new_loc_descr (DW_OP_fbreg, offset, 0); 822650397Sobrien else if (reg <= 31) 822750397Sobrien loc_result = new_loc_descr (DW_OP_breg0 + reg, offset, 0); 822850397Sobrien else 822950397Sobrien loc_result = new_loc_descr (DW_OP_bregx, reg, offset); 823050397Sobrien 823150397Sobrien return loc_result; 823250397Sobrien} 823350397Sobrien 823450397Sobrien/* Return true if this RTL expression describes a base+offset calculation. */ 823550397Sobrien 823650397Sobrienstatic inline int 8237132718Skanis_based_loc (rtx rtl) 823850397Sobrien{ 823990075Sobrien return (GET_CODE (rtl) == PLUS 824090075Sobrien && ((GET_CODE (XEXP (rtl, 0)) == REG 824190075Sobrien && REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER 824290075Sobrien && GET_CODE (XEXP (rtl, 1)) == CONST_INT))); 824350397Sobrien} 824450397Sobrien 824550397Sobrien/* The following routine converts the RTL for a variable or parameter 824650397Sobrien (resident in memory) into an equivalent Dwarf representation of a 824750397Sobrien mechanism for getting the address of that same variable onto the top of a 824850397Sobrien hypothetical "address evaluation" stack. 824950397Sobrien 825050397Sobrien When creating memory location descriptors, we are effectively transforming 825150397Sobrien the RTL for a memory-resident object into its Dwarf postfix expression 825250397Sobrien equivalent. This routine recursively descends an RTL tree, turning 825390075Sobrien it into Dwarf postfix code as it goes. 825450397Sobrien 825590075Sobrien MODE is the mode of the memory reference, needed to handle some 825690075Sobrien autoincrement addressing modes. 825790075Sobrien 825890075Sobrien Return 0 if we can't represent the location. */ 825990075Sobrien 826050397Sobrienstatic dw_loc_descr_ref 8261132718Skanmem_loc_descriptor (rtx rtl, enum machine_mode mode) 826250397Sobrien{ 826350397Sobrien dw_loc_descr_ref mem_loc_result = NULL; 826490075Sobrien 826590075Sobrien /* Note that for a dynamically sized array, the location we will generate a 826650397Sobrien description of here will be the lowest numbered location which is 826750397Sobrien actually within the array. That's *not* necessarily the same as the 826850397Sobrien zeroth element of the array. */ 826950397Sobrien 8270132718Skan rtl = (*targetm.delegitimize_address) (rtl); 827190075Sobrien 827250397Sobrien switch (GET_CODE (rtl)) 827350397Sobrien { 827490075Sobrien case POST_INC: 827590075Sobrien case POST_DEC: 827690075Sobrien case POST_MODIFY: 827790075Sobrien /* POST_INC and POST_DEC can be handled just like a SUBREG. So we 827890075Sobrien just fall into the SUBREG code. */ 827990075Sobrien 828090075Sobrien /* ... fall through ... */ 828190075Sobrien 828250397Sobrien case SUBREG: 828350397Sobrien /* The case of a subreg may arise when we have a local (register) 8284132718Skan variable or a formal (register) parameter which doesn't quite fill 8285132718Skan up an entire register. For now, just assume that it is 8286132718Skan legitimate to make the Dwarf info refer to the whole register which 8287132718Skan contains the given subreg. */ 828890075Sobrien rtl = SUBREG_REG (rtl); 828950397Sobrien 829090075Sobrien /* ... fall through ... */ 829150397Sobrien 829250397Sobrien case REG: 829350397Sobrien /* Whenever a register number forms a part of the description of the 8294132718Skan method for calculating the (dynamic) address of a memory resident 8295132718Skan object, DWARF rules require the register number be referred to as 8296132718Skan a "base register". This distinction is not based in any way upon 8297132718Skan what category of register the hardware believes the given register 8298132718Skan belongs to. This is strictly DWARF terminology we're dealing with 8299132718Skan here. Note that in cases where the location of a memory-resident 8300132718Skan data object could be expressed as: OP_ADD (OP_BASEREG (basereg), 8301132718Skan OP_CONST (0)) the actual DWARF location descriptor that we generate 8302132718Skan may just be OP_BASEREG (basereg). This may look deceptively like 8303132718Skan the object in question was allocated to a register (rather than in 8304132718Skan memory) so DWARF consumers need to be aware of the subtle 8305132718Skan distinction between OP_REG and OP_BASEREG. */ 830690075Sobrien if (REGNO (rtl) < FIRST_PSEUDO_REGISTER) 8307132718Skan mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0); 830850397Sobrien break; 830950397Sobrien 831050397Sobrien case MEM: 831190075Sobrien mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl)); 831290075Sobrien if (mem_loc_result != 0) 831390075Sobrien add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0)); 831450397Sobrien break; 831550397Sobrien 8316117395Skan case LO_SUM: 8317117395Skan rtl = XEXP (rtl, 1); 8318117395Skan 8319117395Skan /* ... fall through ... */ 8320117395Skan 832190075Sobrien case LABEL_REF: 832290075Sobrien /* Some ports can transform a symbol ref into a label ref, because 8323132718Skan the symbol ref is too far away and has to be dumped into a constant 8324132718Skan pool. */ 832550397Sobrien case CONST: 832650397Sobrien case SYMBOL_REF: 832790075Sobrien /* Alternatively, the symbol in the constant pool might be referenced 832890075Sobrien by a different symbol. */ 832990075Sobrien if (GET_CODE (rtl) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (rtl)) 833090075Sobrien { 833196263Sobrien bool marked; 833296263Sobrien rtx tmp = get_pool_constant_mark (rtl, &marked); 833390075Sobrien 833490075Sobrien if (GET_CODE (tmp) == SYMBOL_REF) 833596263Sobrien { 833696263Sobrien rtl = tmp; 833796263Sobrien if (CONSTANT_POOL_ADDRESS_P (tmp)) 833896263Sobrien get_pool_constant_mark (tmp, &marked); 833996263Sobrien else 834096263Sobrien marked = true; 834196263Sobrien } 834296263Sobrien 834396263Sobrien /* If all references to this pool constant were optimized away, 834496263Sobrien it was not output and thus we can't represent it. 834596263Sobrien FIXME: might try to use DW_OP_const_value here, though 834696263Sobrien DW_OP_piece complicates it. */ 834796263Sobrien if (!marked) 834896263Sobrien return 0; 834990075Sobrien } 835090075Sobrien 835150397Sobrien mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0); 835250397Sobrien mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr; 835390075Sobrien mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl; 835490075Sobrien VARRAY_PUSH_RTX (used_rtx_varray, rtl); 835550397Sobrien break; 835650397Sobrien 835790075Sobrien case PRE_MODIFY: 835890075Sobrien /* Extract the PLUS expression nested inside and fall into 8359132718Skan PLUS code below. */ 836090075Sobrien rtl = XEXP (rtl, 1); 836190075Sobrien goto plus; 836290075Sobrien 836390075Sobrien case PRE_INC: 836490075Sobrien case PRE_DEC: 836590075Sobrien /* Turn these into a PLUS expression and fall into the PLUS code 836690075Sobrien below. */ 836790075Sobrien rtl = gen_rtx_PLUS (word_mode, XEXP (rtl, 0), 836890075Sobrien GEN_INT (GET_CODE (rtl) == PRE_INC 836990075Sobrien ? GET_MODE_UNIT_SIZE (mode) 837090075Sobrien : -GET_MODE_UNIT_SIZE (mode))); 837190075Sobrien 837290075Sobrien /* ... fall through ... */ 837390075Sobrien 837450397Sobrien case PLUS: 837590075Sobrien plus: 837650397Sobrien if (is_based_loc (rtl)) 8377132718Skan mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)), 837850397Sobrien INTVAL (XEXP (rtl, 1))); 837950397Sobrien else 838050397Sobrien { 838190075Sobrien mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode); 838290075Sobrien if (mem_loc_result == 0) 838390075Sobrien break; 838490075Sobrien 838590075Sobrien if (GET_CODE (XEXP (rtl, 1)) == CONST_INT 838690075Sobrien && INTVAL (XEXP (rtl, 1)) >= 0) 838790075Sobrien add_loc_descr (&mem_loc_result, 838890075Sobrien new_loc_descr (DW_OP_plus_uconst, 838990075Sobrien INTVAL (XEXP (rtl, 1)), 0)); 839090075Sobrien else 839190075Sobrien { 839290075Sobrien add_loc_descr (&mem_loc_result, 839390075Sobrien mem_loc_descriptor (XEXP (rtl, 1), mode)); 839490075Sobrien add_loc_descr (&mem_loc_result, 839590075Sobrien new_loc_descr (DW_OP_plus, 0, 0)); 839690075Sobrien } 839750397Sobrien } 839850397Sobrien break; 839950397Sobrien 840050397Sobrien case MULT: 840190075Sobrien { 840290075Sobrien /* If a pseudo-reg is optimized away, it is possible for it to 840390075Sobrien be replaced with a MEM containing a multiply. */ 840490075Sobrien dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode); 840590075Sobrien dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode); 840650397Sobrien 840790075Sobrien if (op0 == 0 || op1 == 0) 840890075Sobrien break; 840990075Sobrien 841090075Sobrien mem_loc_result = op0; 841190075Sobrien add_loc_descr (&mem_loc_result, op1); 841290075Sobrien add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0)); 841390075Sobrien break; 841490075Sobrien } 841590075Sobrien 841650397Sobrien case CONST_INT: 841790075Sobrien mem_loc_result = int_loc_descriptor (INTVAL (rtl)); 841850397Sobrien break; 841950397Sobrien 842090075Sobrien case ADDRESSOF: 842190075Sobrien /* If this is a MEM, return its address. Otherwise, we can't 842290075Sobrien represent this. */ 842390075Sobrien if (GET_CODE (XEXP (rtl, 0)) == MEM) 842490075Sobrien return mem_loc_descriptor (XEXP (XEXP (rtl, 0), 0), mode); 842590075Sobrien else 842690075Sobrien return 0; 842790075Sobrien 842850397Sobrien default: 842950397Sobrien abort (); 843050397Sobrien } 843150397Sobrien 843250397Sobrien return mem_loc_result; 843350397Sobrien} 843450397Sobrien 843550397Sobrien/* Return a descriptor that describes the concatenation of two locations. 843650397Sobrien This is typically a complex variable. */ 843750397Sobrien 843850397Sobrienstatic dw_loc_descr_ref 8439132718Skanconcat_loc_descriptor (rtx x0, rtx x1) 844050397Sobrien{ 844150397Sobrien dw_loc_descr_ref cc_loc_result = NULL; 844290075Sobrien dw_loc_descr_ref x0_ref = loc_descriptor (x0); 844390075Sobrien dw_loc_descr_ref x1_ref = loc_descriptor (x1); 844450397Sobrien 844590075Sobrien if (x0_ref == 0 || x1_ref == 0) 844690075Sobrien return 0; 844790075Sobrien 844890075Sobrien cc_loc_result = x0_ref; 844950397Sobrien add_loc_descr (&cc_loc_result, 845090075Sobrien new_loc_descr (DW_OP_piece, 845190075Sobrien GET_MODE_SIZE (GET_MODE (x0)), 0)); 845250397Sobrien 845390075Sobrien add_loc_descr (&cc_loc_result, x1_ref); 845450397Sobrien add_loc_descr (&cc_loc_result, 845590075Sobrien new_loc_descr (DW_OP_piece, 845690075Sobrien GET_MODE_SIZE (GET_MODE (x1)), 0)); 845750397Sobrien 845850397Sobrien return cc_loc_result; 845950397Sobrien} 846050397Sobrien 846150397Sobrien/* Output a proper Dwarf location descriptor for a variable or parameter 846250397Sobrien which is either allocated in a register or in a memory location. For a 846350397Sobrien register, we just generate an OP_REG and the register number. For a 846450397Sobrien memory location we provide a Dwarf postfix expression describing how to 846590075Sobrien generate the (dynamic) address of the object onto the address stack. 846650397Sobrien 846790075Sobrien If we don't know how to describe it, return 0. */ 846890075Sobrien 846950397Sobrienstatic dw_loc_descr_ref 8470132718Skanloc_descriptor (rtx rtl) 847150397Sobrien{ 847250397Sobrien dw_loc_descr_ref loc_result = NULL; 847390075Sobrien 847450397Sobrien switch (GET_CODE (rtl)) 847550397Sobrien { 847650397Sobrien case SUBREG: 847750397Sobrien /* The case of a subreg may arise when we have a local (register) 8478132718Skan variable or a formal (register) parameter which doesn't quite fill 8479132718Skan up an entire register. For now, just assume that it is 8480132718Skan legitimate to make the Dwarf info refer to the whole register which 8481132718Skan contains the given subreg. */ 848290075Sobrien rtl = SUBREG_REG (rtl); 848350397Sobrien 848490075Sobrien /* ... fall through ... */ 848550397Sobrien 848650397Sobrien case REG: 848750397Sobrien loc_result = reg_loc_descriptor (rtl); 848850397Sobrien break; 848950397Sobrien 849050397Sobrien case MEM: 849190075Sobrien loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl)); 849250397Sobrien break; 849350397Sobrien 849450397Sobrien case CONCAT: 849550397Sobrien loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1)); 849650397Sobrien break; 849750397Sobrien 849850397Sobrien default: 849950397Sobrien abort (); 850050397Sobrien } 850150397Sobrien 850250397Sobrien return loc_result; 850350397Sobrien} 850450397Sobrien 850590075Sobrien/* Similar, but generate the descriptor from trees instead of rtl. This comes 850690075Sobrien up particularly with variable length arrays. If ADDRESSP is nonzero, we are 850790075Sobrien looking for an address. Otherwise, we return a value. If we can't make a 850890075Sobrien descriptor, return 0. */ 850990075Sobrien 851090075Sobrienstatic dw_loc_descr_ref 8511132718Skanloc_descriptor_from_tree (tree loc, int addressp) 851290075Sobrien{ 851390075Sobrien dw_loc_descr_ref ret, ret1; 851490075Sobrien int indirect_p = 0; 851590075Sobrien int unsignedp = TREE_UNSIGNED (TREE_TYPE (loc)); 851690075Sobrien enum dwarf_location_atom op; 851790075Sobrien 851890075Sobrien /* ??? Most of the time we do not take proper care for sign/zero 851990075Sobrien extending the values properly. Hopefully this won't be a real 852090075Sobrien problem... */ 852190075Sobrien 852290075Sobrien switch (TREE_CODE (loc)) 852390075Sobrien { 852490075Sobrien case ERROR_MARK: 852590075Sobrien return 0; 852690075Sobrien 852790075Sobrien case WITH_RECORD_EXPR: 852890075Sobrien case PLACEHOLDER_EXPR: 852990075Sobrien /* This case involves extracting fields from an object to determine the 853090075Sobrien position of other fields. We don't try to encode this here. The 853190075Sobrien only user of this is Ada, which encodes the needed information using 853290075Sobrien the names of types. */ 853390075Sobrien return 0; 853490075Sobrien 853590075Sobrien case CALL_EXPR: 853690075Sobrien return 0; 853790075Sobrien 8538132718Skan case PREINCREMENT_EXPR: 8539132718Skan case PREDECREMENT_EXPR: 8540132718Skan case POSTINCREMENT_EXPR: 8541132718Skan case POSTDECREMENT_EXPR: 8542132718Skan /* There are no opcodes for these operations. */ 8543132718Skan return 0; 8544132718Skan 854590075Sobrien case ADDR_EXPR: 854690075Sobrien /* We can support this only if we can look through conversions and 854790075Sobrien find an INDIRECT_EXPR. */ 854890075Sobrien for (loc = TREE_OPERAND (loc, 0); 854990075Sobrien TREE_CODE (loc) == CONVERT_EXPR || TREE_CODE (loc) == NOP_EXPR 855090075Sobrien || TREE_CODE (loc) == NON_LVALUE_EXPR 855190075Sobrien || TREE_CODE (loc) == VIEW_CONVERT_EXPR 855290075Sobrien || TREE_CODE (loc) == SAVE_EXPR; 855390075Sobrien loc = TREE_OPERAND (loc, 0)) 855490075Sobrien ; 855590075Sobrien 855690075Sobrien return (TREE_CODE (loc) == INDIRECT_REF 855790075Sobrien ? loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp) 855890075Sobrien : 0); 855990075Sobrien 856090075Sobrien case VAR_DECL: 8561117395Skan if (DECL_THREAD_LOCAL (loc)) 8562117395Skan { 8563117395Skan rtx rtl; 8564117395Skan 8565117395Skan#ifndef ASM_OUTPUT_DWARF_DTPREL 8566117395Skan /* If this is not defined, we have no way to emit the data. */ 8567117395Skan return 0; 8568117395Skan#endif 8569117395Skan 8570117395Skan /* The way DW_OP_GNU_push_tls_address is specified, we can only 8571117395Skan look up addresses of objects in the current module. */ 8572117395Skan if (DECL_EXTERNAL (loc)) 8573117395Skan return 0; 8574117395Skan 8575117395Skan rtl = rtl_for_decl_location (loc); 8576117395Skan if (rtl == NULL_RTX) 8577117395Skan return 0; 8578117395Skan 8579117395Skan if (GET_CODE (rtl) != MEM) 8580117395Skan return 0; 8581117395Skan rtl = XEXP (rtl, 0); 8582117395Skan if (! CONSTANT_P (rtl)) 8583117395Skan return 0; 8584117395Skan 8585117395Skan ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0); 8586117395Skan ret->dw_loc_oprnd1.val_class = dw_val_class_addr; 8587117395Skan ret->dw_loc_oprnd1.v.val_addr = rtl; 8588117395Skan 8589117395Skan ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0); 8590117395Skan add_loc_descr (&ret, ret1); 8591117395Skan 8592117395Skan indirect_p = 1; 8593117395Skan break; 8594117395Skan } 8595132718Skan /* Fall through. */ 8596117395Skan 859790075Sobrien case PARM_DECL: 859890075Sobrien { 859990075Sobrien rtx rtl = rtl_for_decl_location (loc); 860090075Sobrien 860190075Sobrien if (rtl == NULL_RTX) 860290075Sobrien return 0; 860390075Sobrien else if (CONSTANT_P (rtl)) 860490075Sobrien { 860590075Sobrien ret = new_loc_descr (DW_OP_addr, 0, 0); 860690075Sobrien ret->dw_loc_oprnd1.val_class = dw_val_class_addr; 860790075Sobrien ret->dw_loc_oprnd1.v.val_addr = rtl; 860890075Sobrien indirect_p = 1; 860990075Sobrien } 861090075Sobrien else 861190075Sobrien { 861290075Sobrien enum machine_mode mode = GET_MODE (rtl); 861390075Sobrien 861490075Sobrien if (GET_CODE (rtl) == MEM) 861590075Sobrien { 861690075Sobrien indirect_p = 1; 861790075Sobrien rtl = XEXP (rtl, 0); 861890075Sobrien } 861990075Sobrien 862090075Sobrien ret = mem_loc_descriptor (rtl, mode); 862190075Sobrien } 862290075Sobrien } 862390075Sobrien break; 862490075Sobrien 862590075Sobrien case INDIRECT_REF: 862690075Sobrien ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); 862790075Sobrien indirect_p = 1; 862890075Sobrien break; 862990075Sobrien 863090075Sobrien case COMPOUND_EXPR: 863190075Sobrien return loc_descriptor_from_tree (TREE_OPERAND (loc, 1), addressp); 863290075Sobrien 863390075Sobrien case NOP_EXPR: 863490075Sobrien case CONVERT_EXPR: 863590075Sobrien case NON_LVALUE_EXPR: 863690075Sobrien case VIEW_CONVERT_EXPR: 863790075Sobrien case SAVE_EXPR: 8638132718Skan case MODIFY_EXPR: 863990075Sobrien return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp); 864090075Sobrien 864190075Sobrien case COMPONENT_REF: 864290075Sobrien case BIT_FIELD_REF: 864390075Sobrien case ARRAY_REF: 864490075Sobrien case ARRAY_RANGE_REF: 864590075Sobrien { 864690075Sobrien tree obj, offset; 864790075Sobrien HOST_WIDE_INT bitsize, bitpos, bytepos; 864890075Sobrien enum machine_mode mode; 864990075Sobrien int volatilep; 865090075Sobrien 865190075Sobrien obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode, 865290075Sobrien &unsignedp, &volatilep); 865390075Sobrien 865490075Sobrien if (obj == loc) 865590075Sobrien return 0; 865690075Sobrien 865790075Sobrien ret = loc_descriptor_from_tree (obj, 1); 865890075Sobrien if (ret == 0 865990075Sobrien || bitpos % BITS_PER_UNIT != 0 || bitsize % BITS_PER_UNIT != 0) 866090075Sobrien return 0; 866190075Sobrien 866290075Sobrien if (offset != NULL_TREE) 866390075Sobrien { 866490075Sobrien /* Variable offset. */ 866590075Sobrien add_loc_descr (&ret, loc_descriptor_from_tree (offset, 0)); 866690075Sobrien add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0)); 866790075Sobrien } 866890075Sobrien 866990075Sobrien if (!addressp) 867090075Sobrien indirect_p = 1; 867190075Sobrien 867290075Sobrien bytepos = bitpos / BITS_PER_UNIT; 867390075Sobrien if (bytepos > 0) 867490075Sobrien add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0)); 867590075Sobrien else if (bytepos < 0) 867690075Sobrien { 867790075Sobrien add_loc_descr (&ret, int_loc_descriptor (bytepos)); 867890075Sobrien add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0)); 867990075Sobrien } 868090075Sobrien break; 868190075Sobrien } 868290075Sobrien 868390075Sobrien case INTEGER_CST: 868490075Sobrien if (host_integerp (loc, 0)) 868590075Sobrien ret = int_loc_descriptor (tree_low_cst (loc, 0)); 868690075Sobrien else 868790075Sobrien return 0; 868890075Sobrien break; 868990075Sobrien 8690132718Skan case CONSTRUCTOR: 8691132718Skan { 8692132718Skan /* Get an RTL for this, if something has been emitted. */ 8693132718Skan rtx rtl = lookup_constant_def (loc); 8694132718Skan enum machine_mode mode; 8695132718Skan 8696132718Skan if (GET_CODE (rtl) != MEM) 8697132718Skan return 0; 8698132718Skan mode = GET_MODE (rtl); 8699132718Skan rtl = XEXP (rtl, 0); 8700132718Skan 8701132718Skan rtl = (*targetm.delegitimize_address) (rtl); 8702132718Skan 8703132718Skan indirect_p = 1; 8704132718Skan ret = mem_loc_descriptor (rtl, mode); 8705132718Skan break; 8706132718Skan } 8707132718Skan 8708117395Skan case TRUTH_AND_EXPR: 870990075Sobrien case TRUTH_ANDIF_EXPR: 871090075Sobrien case BIT_AND_EXPR: 871190075Sobrien op = DW_OP_and; 871290075Sobrien goto do_binop; 871390075Sobrien 871490075Sobrien case TRUTH_XOR_EXPR: 871590075Sobrien case BIT_XOR_EXPR: 871690075Sobrien op = DW_OP_xor; 871790075Sobrien goto do_binop; 871890075Sobrien 871990075Sobrien case TRUTH_OR_EXPR: 872090075Sobrien case TRUTH_ORIF_EXPR: 872190075Sobrien case BIT_IOR_EXPR: 872290075Sobrien op = DW_OP_or; 872390075Sobrien goto do_binop; 872490075Sobrien 8725132718Skan case FLOOR_DIV_EXPR: 8726132718Skan case CEIL_DIV_EXPR: 8727132718Skan case ROUND_DIV_EXPR: 872890075Sobrien case TRUNC_DIV_EXPR: 872990075Sobrien op = DW_OP_div; 873090075Sobrien goto do_binop; 873190075Sobrien 873290075Sobrien case MINUS_EXPR: 873390075Sobrien op = DW_OP_minus; 873490075Sobrien goto do_binop; 873590075Sobrien 8736132718Skan case FLOOR_MOD_EXPR: 8737132718Skan case CEIL_MOD_EXPR: 8738132718Skan case ROUND_MOD_EXPR: 873990075Sobrien case TRUNC_MOD_EXPR: 874090075Sobrien op = DW_OP_mod; 874190075Sobrien goto do_binop; 874290075Sobrien 874390075Sobrien case MULT_EXPR: 874490075Sobrien op = DW_OP_mul; 874590075Sobrien goto do_binop; 874690075Sobrien 874790075Sobrien case LSHIFT_EXPR: 874890075Sobrien op = DW_OP_shl; 874990075Sobrien goto do_binop; 875090075Sobrien 875190075Sobrien case RSHIFT_EXPR: 875290075Sobrien op = (unsignedp ? DW_OP_shr : DW_OP_shra); 875390075Sobrien goto do_binop; 875490075Sobrien 875590075Sobrien case PLUS_EXPR: 875690075Sobrien if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST 875790075Sobrien && host_integerp (TREE_OPERAND (loc, 1), 0)) 875890075Sobrien { 875990075Sobrien ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); 876090075Sobrien if (ret == 0) 876190075Sobrien return 0; 876290075Sobrien 876390075Sobrien add_loc_descr (&ret, 876490075Sobrien new_loc_descr (DW_OP_plus_uconst, 876590075Sobrien tree_low_cst (TREE_OPERAND (loc, 1), 876690075Sobrien 0), 876790075Sobrien 0)); 876890075Sobrien break; 876990075Sobrien } 877090075Sobrien 877190075Sobrien op = DW_OP_plus; 877290075Sobrien goto do_binop; 877390075Sobrien 877490075Sobrien case LE_EXPR: 877590075Sobrien if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) 877690075Sobrien return 0; 877790075Sobrien 877890075Sobrien op = DW_OP_le; 877990075Sobrien goto do_binop; 878090075Sobrien 878190075Sobrien case GE_EXPR: 878290075Sobrien if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) 878390075Sobrien return 0; 878490075Sobrien 878590075Sobrien op = DW_OP_ge; 878690075Sobrien goto do_binop; 878790075Sobrien 878890075Sobrien case LT_EXPR: 878990075Sobrien if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) 879090075Sobrien return 0; 879190075Sobrien 879290075Sobrien op = DW_OP_lt; 879390075Sobrien goto do_binop; 879490075Sobrien 879590075Sobrien case GT_EXPR: 879690075Sobrien if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) 879790075Sobrien return 0; 879890075Sobrien 879990075Sobrien op = DW_OP_gt; 880090075Sobrien goto do_binop; 880190075Sobrien 880290075Sobrien case EQ_EXPR: 880390075Sobrien op = DW_OP_eq; 880490075Sobrien goto do_binop; 880590075Sobrien 880690075Sobrien case NE_EXPR: 880790075Sobrien op = DW_OP_ne; 880890075Sobrien goto do_binop; 880990075Sobrien 881090075Sobrien do_binop: 881190075Sobrien ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); 881290075Sobrien ret1 = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0); 881390075Sobrien if (ret == 0 || ret1 == 0) 881490075Sobrien return 0; 881590075Sobrien 881690075Sobrien add_loc_descr (&ret, ret1); 881790075Sobrien add_loc_descr (&ret, new_loc_descr (op, 0, 0)); 881890075Sobrien break; 881990075Sobrien 882090075Sobrien case TRUTH_NOT_EXPR: 882190075Sobrien case BIT_NOT_EXPR: 882290075Sobrien op = DW_OP_not; 882390075Sobrien goto do_unop; 882490075Sobrien 882590075Sobrien case ABS_EXPR: 882690075Sobrien op = DW_OP_abs; 882790075Sobrien goto do_unop; 882890075Sobrien 882990075Sobrien case NEGATE_EXPR: 883090075Sobrien op = DW_OP_neg; 883190075Sobrien goto do_unop; 883290075Sobrien 883390075Sobrien do_unop: 883490075Sobrien ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); 883590075Sobrien if (ret == 0) 883690075Sobrien return 0; 883790075Sobrien 883890075Sobrien add_loc_descr (&ret, new_loc_descr (op, 0, 0)); 883990075Sobrien break; 884090075Sobrien 884190075Sobrien case MAX_EXPR: 884290075Sobrien loc = build (COND_EXPR, TREE_TYPE (loc), 884390075Sobrien build (LT_EXPR, integer_type_node, 884490075Sobrien TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)), 884590075Sobrien TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0)); 884690075Sobrien 884790075Sobrien /* ... fall through ... */ 884890075Sobrien 884990075Sobrien case COND_EXPR: 885090075Sobrien { 885190075Sobrien dw_loc_descr_ref lhs 885290075Sobrien = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0); 885390075Sobrien dw_loc_descr_ref rhs 885490075Sobrien = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0); 885590075Sobrien dw_loc_descr_ref bra_node, jump_node, tmp; 885690075Sobrien 885790075Sobrien ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); 885890075Sobrien if (ret == 0 || lhs == 0 || rhs == 0) 885990075Sobrien return 0; 886090075Sobrien 886190075Sobrien bra_node = new_loc_descr (DW_OP_bra, 0, 0); 886290075Sobrien add_loc_descr (&ret, bra_node); 886390075Sobrien 886490075Sobrien add_loc_descr (&ret, rhs); 886590075Sobrien jump_node = new_loc_descr (DW_OP_skip, 0, 0); 886690075Sobrien add_loc_descr (&ret, jump_node); 886790075Sobrien 886890075Sobrien add_loc_descr (&ret, lhs); 886990075Sobrien bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; 887090075Sobrien bra_node->dw_loc_oprnd1.v.val_loc = lhs; 887190075Sobrien 887290075Sobrien /* ??? Need a node to point the skip at. Use a nop. */ 887390075Sobrien tmp = new_loc_descr (DW_OP_nop, 0, 0); 887490075Sobrien add_loc_descr (&ret, tmp); 887590075Sobrien jump_node->dw_loc_oprnd1.val_class = dw_val_class_loc; 887690075Sobrien jump_node->dw_loc_oprnd1.v.val_loc = tmp; 887790075Sobrien } 887890075Sobrien break; 887990075Sobrien 8880132718Skan case EXPR_WITH_FILE_LOCATION: 8881132718Skan return loc_descriptor_from_tree (EXPR_WFL_NODE (loc), addressp); 8882132718Skan 8883146895Skan case FIX_TRUNC_EXPR: 8884146895Skan case FIX_CEIL_EXPR: 8885146895Skan case FIX_FLOOR_EXPR: 8886146895Skan case FIX_ROUND_EXPR: 8887146895Skan return 0; 8888146895Skan 888990075Sobrien default: 8890132718Skan /* Leave front-end specific codes as simply unknown. This comes 8891132718Skan up, for instance, with the C STMT_EXPR. */ 8892132718Skan if ((unsigned int) TREE_CODE (loc) 8893132718Skan >= (unsigned int) LAST_AND_UNUSED_TREE_CODE) 8894132718Skan return 0; 8895132718Skan 8896146895Skan#ifdef ENABLE_CHECKING 8897132718Skan /* Otherwise this is a generic code; we should just lists all of 8898132718Skan these explicitly. Aborting means we forgot one. */ 889990075Sobrien abort (); 8900146895Skan#else 8901146895Skan /* In a release build, we want to degrade gracefully: better to 8902146895Skan generate incomplete debugging information than to crash. */ 8903146895Skan return NULL; 8904146895Skan#endif 890590075Sobrien } 890690075Sobrien 890790075Sobrien /* Show if we can't fill the request for an address. */ 890890075Sobrien if (addressp && indirect_p == 0) 890990075Sobrien return 0; 891090075Sobrien 891190075Sobrien /* If we've got an address and don't want one, dereference. */ 891290075Sobrien if (!addressp && indirect_p > 0) 891390075Sobrien { 891490075Sobrien HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc)); 891590075Sobrien 891690075Sobrien if (size > DWARF2_ADDR_SIZE || size == -1) 891790075Sobrien return 0; 891890075Sobrien else if (size == DWARF2_ADDR_SIZE) 891990075Sobrien op = DW_OP_deref; 892090075Sobrien else 892190075Sobrien op = DW_OP_deref_size; 892290075Sobrien 892390075Sobrien add_loc_descr (&ret, new_loc_descr (op, size, 0)); 892490075Sobrien } 892590075Sobrien 892690075Sobrien return ret; 892790075Sobrien} 892890075Sobrien 892990075Sobrien/* Given a value, round it up to the lowest multiple of `boundary' 893050397Sobrien which is not less than the value itself. */ 893150397Sobrien 893290075Sobrienstatic inline HOST_WIDE_INT 8933132718Skanceiling (HOST_WIDE_INT value, unsigned int boundary) 893450397Sobrien{ 893550397Sobrien return (((value + boundary - 1) / boundary) * boundary); 893650397Sobrien} 893750397Sobrien 893850397Sobrien/* Given a pointer to what is assumed to be a FIELD_DECL node, return a 893950397Sobrien pointer to the declared type for the relevant field variable, or return 894050397Sobrien `integer_type_node' if the given node turns out to be an 894150397Sobrien ERROR_MARK node. */ 894250397Sobrien 894350397Sobrienstatic inline tree 8944132718Skanfield_type (tree decl) 894550397Sobrien{ 894690075Sobrien tree type; 894750397Sobrien 894850397Sobrien if (TREE_CODE (decl) == ERROR_MARK) 894950397Sobrien return integer_type_node; 895050397Sobrien 895150397Sobrien type = DECL_BIT_FIELD_TYPE (decl); 895250397Sobrien if (type == NULL_TREE) 895350397Sobrien type = TREE_TYPE (decl); 895450397Sobrien 895550397Sobrien return type; 895650397Sobrien} 895750397Sobrien 895890075Sobrien/* Given a pointer to a tree node, return the alignment in bits for 895990075Sobrien it, or else return BITS_PER_WORD if the node actually turns out to 896090075Sobrien be an ERROR_MARK node. */ 896150397Sobrien 896250397Sobrienstatic inline unsigned 8963132718Skansimple_type_align_in_bits (tree type) 896450397Sobrien{ 896550397Sobrien return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD; 896650397Sobrien} 896750397Sobrien 896890075Sobrienstatic inline unsigned 8969132718Skansimple_decl_align_in_bits (tree decl) 897090075Sobrien{ 8971117395Skan return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD; 897290075Sobrien} 897390075Sobrien 897490075Sobrien/* Given a pointer to a FIELD_DECL, compute and return the byte offset of the 897590075Sobrien lowest addressed byte of the "containing object" for the given FIELD_DECL, 897690075Sobrien or return 0 if we are unable to determine what that offset is, either 897790075Sobrien because the argument turns out to be a pointer to an ERROR_MARK node, or 897890075Sobrien because the offset is actually variable. (We can't handle the latter case 897990075Sobrien just yet). */ 898050397Sobrien 898190075Sobrienstatic HOST_WIDE_INT 8982132718Skanfield_byte_offset (tree decl) 898350397Sobrien{ 898490075Sobrien unsigned int type_align_in_bits; 898590075Sobrien unsigned int decl_align_in_bits; 898690075Sobrien unsigned HOST_WIDE_INT type_size_in_bits; 898790075Sobrien HOST_WIDE_INT object_offset_in_bits; 898890075Sobrien tree type; 898990075Sobrien tree field_size_tree; 899090075Sobrien HOST_WIDE_INT bitpos_int; 899190075Sobrien HOST_WIDE_INT deepest_bitpos; 899290075Sobrien unsigned HOST_WIDE_INT field_size_in_bits; 899350397Sobrien 899450397Sobrien if (TREE_CODE (decl) == ERROR_MARK) 899550397Sobrien return 0; 899690075Sobrien else if (TREE_CODE (decl) != FIELD_DECL) 899750397Sobrien abort (); 899850397Sobrien 899950397Sobrien type = field_type (decl); 900050397Sobrien field_size_tree = DECL_SIZE (decl); 900150397Sobrien 900290075Sobrien /* The size could be unspecified if there was an error, or for 900390075Sobrien a flexible array member. */ 900490075Sobrien if (! field_size_tree) 900590075Sobrien field_size_tree = bitsize_zero_node; 900690075Sobrien 900790075Sobrien /* We cannot yet cope with fields whose positions are variable, so 900850397Sobrien for now, when we see such things, we simply return 0. Someday, we may 900950397Sobrien be able to handle such cases, but it will be damn difficult. */ 901090075Sobrien if (! host_integerp (bit_position (decl), 0)) 901150397Sobrien return 0; 901250397Sobrien 901390075Sobrien bitpos_int = int_bit_position (decl); 901450397Sobrien 901590075Sobrien /* If we don't know the size of the field, pretend it's a full word. */ 901690075Sobrien if (host_integerp (field_size_tree, 1)) 901790075Sobrien field_size_in_bits = tree_low_cst (field_size_tree, 1); 901890075Sobrien else 901990075Sobrien field_size_in_bits = BITS_PER_WORD; 902090075Sobrien 902150397Sobrien type_size_in_bits = simple_type_size_in_bits (type); 902250397Sobrien type_align_in_bits = simple_type_align_in_bits (type); 9023117395Skan decl_align_in_bits = simple_decl_align_in_bits (decl); 902450397Sobrien 902590075Sobrien /* The GCC front-end doesn't make any attempt to keep track of the starting 902690075Sobrien bit offset (relative to the start of the containing structure type) of the 902790075Sobrien hypothetical "containing object" for a bit-field. Thus, when computing 902890075Sobrien the byte offset value for the start of the "containing object" of a 902990075Sobrien bit-field, we must deduce this information on our own. This can be rather 903090075Sobrien tricky to do in some cases. For example, handling the following structure 903190075Sobrien type definition when compiling for an i386/i486 target (which only aligns 903290075Sobrien long long's to 32-bit boundaries) can be very tricky: 903350397Sobrien 903450397Sobrien struct S { int field1; long long field2:31; }; 903550397Sobrien 903690075Sobrien Fortunately, there is a simple rule-of-thumb which can be used in such 903790075Sobrien cases. When compiling for an i386/i486, GCC will allocate 8 bytes for the 903890075Sobrien structure shown above. It decides to do this based upon one simple rule 903990075Sobrien for bit-field allocation. GCC allocates each "containing object" for each 904090075Sobrien bit-field at the first (i.e. lowest addressed) legitimate alignment 904190075Sobrien boundary (based upon the required minimum alignment for the declared type 904290075Sobrien of the field) which it can possibly use, subject to the condition that 904390075Sobrien there is still enough available space remaining in the containing object 904490075Sobrien (when allocated at the selected point) to fully accommodate all of the 904590075Sobrien bits of the bit-field itself. 904650397Sobrien 904790075Sobrien This simple rule makes it obvious why GCC allocates 8 bytes for each 904890075Sobrien object of the structure type shown above. When looking for a place to 904990075Sobrien allocate the "containing object" for `field2', the compiler simply tries 905090075Sobrien to allocate a 64-bit "containing object" at each successive 32-bit 905190075Sobrien boundary (starting at zero) until it finds a place to allocate that 64- 905290075Sobrien bit field such that at least 31 contiguous (and previously unallocated) 905390075Sobrien bits remain within that selected 64 bit field. (As it turns out, for the 905490075Sobrien example above, the compiler finds it is OK to allocate the "containing 905590075Sobrien object" 64-bit field at bit-offset zero within the structure type.) 905690075Sobrien 905790075Sobrien Here we attempt to work backwards from the limited set of facts we're 905890075Sobrien given, and we try to deduce from those facts, where GCC must have believed 905990075Sobrien that the containing object started (within the structure type). The value 906090075Sobrien we deduce is then used (by the callers of this routine) to generate 906190075Sobrien DW_AT_location and DW_AT_bit_offset attributes for fields (both bit-fields 906290075Sobrien and, in the case of DW_AT_location, regular fields as well). */ 906390075Sobrien 906450397Sobrien /* Figure out the bit-distance from the start of the structure to the 906550397Sobrien "deepest" bit of the bit-field. */ 906650397Sobrien deepest_bitpos = bitpos_int + field_size_in_bits; 906750397Sobrien 906850397Sobrien /* This is the tricky part. Use some fancy footwork to deduce where the 906950397Sobrien lowest addressed bit of the containing object must be. */ 907090075Sobrien object_offset_in_bits = deepest_bitpos - type_size_in_bits; 907150397Sobrien 907290075Sobrien /* Round up to type_align by default. This works best for bitfields. */ 907390075Sobrien object_offset_in_bits += type_align_in_bits - 1; 907490075Sobrien object_offset_in_bits /= type_align_in_bits; 907590075Sobrien object_offset_in_bits *= type_align_in_bits; 907650397Sobrien 907790075Sobrien if (object_offset_in_bits > bitpos_int) 907890075Sobrien { 907990075Sobrien /* Sigh, the decl must be packed. */ 908090075Sobrien object_offset_in_bits = deepest_bitpos - type_size_in_bits; 908150397Sobrien 908290075Sobrien /* Round up to decl_align instead. */ 908390075Sobrien object_offset_in_bits += decl_align_in_bits - 1; 908490075Sobrien object_offset_in_bits /= decl_align_in_bits; 908590075Sobrien object_offset_in_bits *= decl_align_in_bits; 908690075Sobrien } 908790075Sobrien 908890075Sobrien return object_offset_in_bits / BITS_PER_UNIT; 908950397Sobrien} 909050397Sobrien 909150397Sobrien/* The following routines define various Dwarf attributes and any data 909250397Sobrien associated with them. */ 909350397Sobrien 909450397Sobrien/* Add a location description attribute value to a DIE. 909550397Sobrien 909650397Sobrien This emits location attributes suitable for whole variables and 909750397Sobrien whole parameters. Note that the location attributes for struct fields are 909850397Sobrien generated by the routine `data_member_location_attribute' below. */ 909950397Sobrien 9100117395Skanstatic inline void 9101132718Skanadd_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind, 9102132718Skan dw_loc_descr_ref descr) 910350397Sobrien{ 910490075Sobrien if (descr != 0) 910590075Sobrien add_AT_loc (die, attr_kind, descr); 910650397Sobrien} 910750397Sobrien 910890075Sobrien/* Attach the specialized form of location attribute used for data members of 910990075Sobrien struct and union types. In the special case of a FIELD_DECL node which 911090075Sobrien represents a bit-field, the "offset" part of this special location 911190075Sobrien descriptor must indicate the distance in bytes from the lowest-addressed 911290075Sobrien byte of the containing struct or union type to the lowest-addressed byte of 911390075Sobrien the "containing object" for the bit-field. (See the `field_byte_offset' 911490075Sobrien function above). 911550397Sobrien 911690075Sobrien For any given bit-field, the "containing object" is a hypothetical object 911790075Sobrien (of some integral or enum type) within which the given bit-field lives. The 911890075Sobrien type of this hypothetical "containing object" is always the same as the 911990075Sobrien declared type of the individual bit-field itself (for GCC anyway... the 912090075Sobrien DWARF spec doesn't actually mandate this). Note that it is the size (in 912190075Sobrien bytes) of the hypothetical "containing object" which will be given in the 912290075Sobrien DW_AT_byte_size attribute for this bit-field. (See the 912390075Sobrien `byte_size_attribute' function below.) It is also used when calculating the 912490075Sobrien value of the DW_AT_bit_offset attribute. (See the `bit_offset_attribute' 912590075Sobrien function below.) */ 912690075Sobrien 912750397Sobrienstatic void 9128132718Skanadd_data_member_location_attribute (dw_die_ref die, tree decl) 912950397Sobrien{ 9130132718Skan HOST_WIDE_INT offset; 913190075Sobrien dw_loc_descr_ref loc_descr = 0; 913250397Sobrien 913350397Sobrien if (TREE_CODE (decl) == TREE_VEC) 913490075Sobrien { 913590075Sobrien /* We're working on the TAG_inheritance for a base class. */ 913690075Sobrien if (TREE_VIA_VIRTUAL (decl) && is_cxx ()) 913790075Sobrien { 913890075Sobrien /* For C++ virtual bases we can't just use BINFO_OFFSET, as they 913990075Sobrien aren't at a fixed offset from all (sub)objects of the same 914090075Sobrien type. We need to extract the appropriate offset from our 914190075Sobrien vtable. The following dwarf expression means 914290075Sobrien 914390075Sobrien BaseAddr = ObAddr + *((*ObAddr) - Offset) 914490075Sobrien 914590075Sobrien This is specific to the V3 ABI, of course. */ 914690075Sobrien 914790075Sobrien dw_loc_descr_ref tmp; 914890075Sobrien 914990075Sobrien /* Make a copy of the object address. */ 915090075Sobrien tmp = new_loc_descr (DW_OP_dup, 0, 0); 915190075Sobrien add_loc_descr (&loc_descr, tmp); 915290075Sobrien 915390075Sobrien /* Extract the vtable address. */ 915490075Sobrien tmp = new_loc_descr (DW_OP_deref, 0, 0); 915590075Sobrien add_loc_descr (&loc_descr, tmp); 915690075Sobrien 915790075Sobrien /* Calculate the address of the offset. */ 915890075Sobrien offset = tree_low_cst (BINFO_VPTR_FIELD (decl), 0); 915990075Sobrien if (offset >= 0) 916090075Sobrien abort (); 916190075Sobrien 916290075Sobrien tmp = int_loc_descriptor (-offset); 916390075Sobrien add_loc_descr (&loc_descr, tmp); 916490075Sobrien tmp = new_loc_descr (DW_OP_minus, 0, 0); 916590075Sobrien add_loc_descr (&loc_descr, tmp); 916690075Sobrien 916790075Sobrien /* Extract the offset. */ 916890075Sobrien tmp = new_loc_descr (DW_OP_deref, 0, 0); 916990075Sobrien add_loc_descr (&loc_descr, tmp); 917090075Sobrien 917190075Sobrien /* Add it to the object address. */ 917290075Sobrien tmp = new_loc_descr (DW_OP_plus, 0, 0); 917390075Sobrien add_loc_descr (&loc_descr, tmp); 917490075Sobrien } 917590075Sobrien else 917690075Sobrien offset = tree_low_cst (BINFO_OFFSET (decl), 0); 917790075Sobrien } 917850397Sobrien else 917950397Sobrien offset = field_byte_offset (decl); 918050397Sobrien 918190075Sobrien if (! loc_descr) 918290075Sobrien { 918390075Sobrien enum dwarf_location_atom op; 918450397Sobrien 918590075Sobrien /* The DWARF2 standard says that we should assume that the structure 918690075Sobrien address is already on the stack, so we can specify a structure field 918790075Sobrien address by using DW_OP_plus_uconst. */ 918890075Sobrien 918950397Sobrien#ifdef MIPS_DEBUGGING_INFO 919090075Sobrien /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst 919190075Sobrien operator correctly. It works only if we leave the offset on the 919290075Sobrien stack. */ 919390075Sobrien op = DW_OP_constu; 919450397Sobrien#else 919590075Sobrien op = DW_OP_plus_uconst; 919650397Sobrien#endif 919750397Sobrien 919890075Sobrien loc_descr = new_loc_descr (op, offset, 0); 919990075Sobrien } 920090075Sobrien 920150397Sobrien add_AT_loc (die, DW_AT_data_member_location, loc_descr); 920250397Sobrien} 920350397Sobrien 9204132718Skan/* Writes integer values to dw_vec_const array. */ 9205132718Skan 9206132718Skanstatic void 9207132718Skaninsert_int (HOST_WIDE_INT val, unsigned int size, unsigned char *dest) 9208132718Skan{ 9209132718Skan while (size != 0) 9210132718Skan { 9211132718Skan *dest++ = val & 0xff; 9212132718Skan val >>= 8; 9213132718Skan --size; 9214132718Skan } 9215132718Skan} 9216132718Skan 9217132718Skan/* Reads integers from dw_vec_const array. Inverse of insert_int. */ 9218132718Skan 9219132718Skanstatic HOST_WIDE_INT 9220132718Skanextract_int (const unsigned char *src, unsigned int size) 9221132718Skan{ 9222132718Skan HOST_WIDE_INT val = 0; 9223132718Skan 9224132718Skan src += size; 9225132718Skan while (size != 0) 9226132718Skan { 9227132718Skan val <<= 8; 9228132718Skan val |= *--src & 0xff; 9229132718Skan --size; 9230132718Skan } 9231132718Skan return val; 9232132718Skan} 9233132718Skan 9234132718Skan/* Writes floating point values to dw_vec_const array. */ 9235132718Skan 9236132718Skanstatic void 9237132718Skaninsert_float (rtx rtl, unsigned char *array) 9238132718Skan{ 9239132718Skan REAL_VALUE_TYPE rv; 9240132718Skan long val[4]; 9241132718Skan int i; 9242132718Skan 9243132718Skan REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl); 9244132718Skan real_to_target (val, &rv, GET_MODE (rtl)); 9245132718Skan 9246132718Skan /* real_to_target puts 32-bit pieces in each long. Pack them. */ 9247132718Skan for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++) 9248132718Skan { 9249132718Skan insert_int (val[i], 4, array); 9250132718Skan array += 4; 9251132718Skan } 9252132718Skan} 9253132718Skan 9254132718Skan/* Attach a DW_AT_const_value attribute for a variable or a parameter which 925550397Sobrien does not have a "location" either in memory or in a register. These 925650397Sobrien things can arise in GNU C when a constant is passed as an actual parameter 925750397Sobrien to an inlined function. They can also arise in C++ where declared 925850397Sobrien constants do not necessarily get memory "homes". */ 925950397Sobrien 926050397Sobrienstatic void 9261132718Skanadd_const_value_attribute (dw_die_ref die, rtx rtl) 926250397Sobrien{ 926350397Sobrien switch (GET_CODE (rtl)) 926450397Sobrien { 926550397Sobrien case CONST_INT: 926690075Sobrien { 926790075Sobrien HOST_WIDE_INT val = INTVAL (rtl); 9268117395Skan 9269132718Skan if (val < 0) 9270132718Skan add_AT_int (die, DW_AT_const_value, val); 9271132718Skan else 9272132718Skan add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val); 927390075Sobrien } 927450397Sobrien break; 927550397Sobrien 927650397Sobrien case CONST_DOUBLE: 927750397Sobrien /* Note that a CONST_DOUBLE rtx could represent either an integer or a 9278132718Skan floating-point constant. A CONST_DOUBLE is used whenever the 9279132718Skan constant requires more than one word in order to be adequately 9280132718Skan represented. We output CONST_DOUBLEs as blocks. */ 928150397Sobrien { 928290075Sobrien enum machine_mode mode = GET_MODE (rtl); 928350397Sobrien 928450397Sobrien if (GET_MODE_CLASS (mode) == MODE_FLOAT) 928550397Sobrien { 9286132718Skan unsigned int length = GET_MODE_SIZE (mode); 9287132718Skan unsigned char *array = ggc_alloc (length); 928850397Sobrien 9289132718Skan insert_float (rtl, array); 9290132718Skan add_AT_vec (die, DW_AT_const_value, length / 4, 4, array); 929150397Sobrien } 929250397Sobrien else 929390075Sobrien { 929490075Sobrien /* ??? We really should be using HOST_WIDE_INT throughout. */ 929590075Sobrien if (HOST_BITS_PER_LONG != HOST_BITS_PER_WIDE_INT) 929690075Sobrien abort (); 929790075Sobrien 929890075Sobrien add_AT_long_long (die, DW_AT_const_value, 929990075Sobrien CONST_DOUBLE_HIGH (rtl), CONST_DOUBLE_LOW (rtl)); 930090075Sobrien } 930150397Sobrien } 930250397Sobrien break; 930350397Sobrien 9304132718Skan case CONST_VECTOR: 9305132718Skan { 9306132718Skan enum machine_mode mode = GET_MODE (rtl); 9307132718Skan unsigned int elt_size = GET_MODE_UNIT_SIZE (mode); 9308132718Skan unsigned int length = CONST_VECTOR_NUNITS (rtl); 9309132718Skan unsigned char *array = ggc_alloc (length * elt_size); 9310132718Skan unsigned int i; 9311132718Skan unsigned char *p; 9312132718Skan 9313132718Skan if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) 9314132718Skan { 9315132718Skan for (i = 0, p = array; i < length; i++, p += elt_size) 9316132718Skan { 9317132718Skan rtx elt = CONST_VECTOR_ELT (rtl, i); 9318132718Skan HOST_WIDE_INT lo, hi; 9319132718Skan if (GET_CODE (elt) == CONST_INT) 9320132718Skan { 9321132718Skan lo = INTVAL (elt); 9322132718Skan hi = -(lo < 0); 9323132718Skan } 9324132718Skan else if (GET_CODE (elt) == CONST_DOUBLE) 9325132718Skan { 9326132718Skan lo = CONST_DOUBLE_LOW (elt); 9327132718Skan hi = CONST_DOUBLE_HIGH (elt); 9328132718Skan } 9329132718Skan else 9330132718Skan abort (); 9331132718Skan 9332132718Skan if (elt_size <= sizeof (HOST_WIDE_INT)) 9333132718Skan insert_int (lo, elt_size, p); 9334132718Skan else if (elt_size == 2 * sizeof (HOST_WIDE_INT)) 9335132718Skan { 9336132718Skan unsigned char *p0 = p; 9337132718Skan unsigned char *p1 = p + sizeof (HOST_WIDE_INT); 9338132718Skan 9339132718Skan if (WORDS_BIG_ENDIAN) 9340132718Skan { 9341132718Skan p0 = p1; 9342132718Skan p1 = p; 9343132718Skan } 9344132718Skan insert_int (lo, sizeof (HOST_WIDE_INT), p0); 9345132718Skan insert_int (hi, sizeof (HOST_WIDE_INT), p1); 9346132718Skan } 9347132718Skan else 9348132718Skan abort (); 9349132718Skan } 9350132718Skan } 9351132718Skan else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) 9352132718Skan { 9353132718Skan for (i = 0, p = array; i < length; i++, p += elt_size) 9354132718Skan { 9355132718Skan rtx elt = CONST_VECTOR_ELT (rtl, i); 9356132718Skan insert_float (elt, p); 9357132718Skan } 9358132718Skan } 9359132718Skan else 9360132718Skan abort (); 9361132718Skan 9362132718Skan add_AT_vec (die, DW_AT_const_value, length, elt_size, array); 9363132718Skan } 9364132718Skan break; 9365132718Skan 936650397Sobrien case CONST_STRING: 936750397Sobrien add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0)); 936850397Sobrien break; 936950397Sobrien 937050397Sobrien case SYMBOL_REF: 937150397Sobrien case LABEL_REF: 937250397Sobrien case CONST: 937390075Sobrien add_AT_addr (die, DW_AT_const_value, rtl); 937490075Sobrien VARRAY_PUSH_RTX (used_rtx_varray, rtl); 937550397Sobrien break; 937650397Sobrien 937750397Sobrien case PLUS: 937850397Sobrien /* In cases where an inlined instance of an inline function is passed 9379132718Skan the address of an `auto' variable (which is local to the caller) we 9380132718Skan can get a situation where the DECL_RTL of the artificial local 9381132718Skan variable (for the inlining) which acts as a stand-in for the 9382132718Skan corresponding formal parameter (of the inline function) will look 9383132718Skan like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). This is not 9384132718Skan exactly a compile-time constant expression, but it isn't the address 9385132718Skan of the (artificial) local variable either. Rather, it represents the 9386132718Skan *value* which the artificial local variable always has during its 9387132718Skan lifetime. We currently have no way to represent such quasi-constant 9388132718Skan values in Dwarf, so for now we just punt and generate nothing. */ 938950397Sobrien break; 939050397Sobrien 939150397Sobrien default: 939250397Sobrien /* No other kinds of rtx should be possible here. */ 939350397Sobrien abort (); 939450397Sobrien } 939550397Sobrien 939650397Sobrien} 939750397Sobrien 939890075Sobrienstatic rtx 9399132718Skanrtl_for_decl_location (tree decl) 940050397Sobrien{ 940190075Sobrien rtx rtl; 940250397Sobrien 940350397Sobrien /* Here we have to decide where we are going to say the parameter "lives" 940450397Sobrien (as far as the debugger is concerned). We only have a couple of 940550397Sobrien choices. GCC provides us with DECL_RTL and with DECL_INCOMING_RTL. 940650397Sobrien 940790075Sobrien DECL_RTL normally indicates where the parameter lives during most of the 940850397Sobrien activation of the function. If optimization is enabled however, this 940990075Sobrien could be either NULL or else a pseudo-reg. Both of those cases indicate 941050397Sobrien that the parameter doesn't really live anywhere (as far as the code 941150397Sobrien generation parts of GCC are concerned) during most of the function's 941250397Sobrien activation. That will happen (for example) if the parameter is never 941350397Sobrien referenced within the function. 941450397Sobrien 941550397Sobrien We could just generate a location descriptor here for all non-NULL 941650397Sobrien non-pseudo values of DECL_RTL and ignore all of the rest, but we can be 941750397Sobrien a little nicer than that if we also consider DECL_INCOMING_RTL in cases 941850397Sobrien where DECL_RTL is NULL or is a pseudo-reg. 941950397Sobrien 942050397Sobrien Note however that we can only get away with using DECL_INCOMING_RTL as 942150397Sobrien a backup substitute for DECL_RTL in certain limited cases. In cases 942250397Sobrien where DECL_ARG_TYPE (decl) indicates the same type as TREE_TYPE (decl), 942350397Sobrien we can be sure that the parameter was passed using the same type as it is 942450397Sobrien declared to have within the function, and that its DECL_INCOMING_RTL 942550397Sobrien points us to a place where a value of that type is passed. 942650397Sobrien 942750397Sobrien In cases where DECL_ARG_TYPE (decl) and TREE_TYPE (decl) are different, 942850397Sobrien we cannot (in general) use DECL_INCOMING_RTL as a substitute for DECL_RTL 942950397Sobrien because in these cases DECL_INCOMING_RTL points us to a value of some 943050397Sobrien type which is *different* from the type of the parameter itself. Thus, 943150397Sobrien if we tried to use DECL_INCOMING_RTL to generate a location attribute in 943250397Sobrien such cases, the debugger would end up (for example) trying to fetch a 943350397Sobrien `float' from a place which actually contains the first part of a 943450397Sobrien `double'. That would lead to really incorrect and confusing 943550397Sobrien output at debug-time. 943650397Sobrien 943750397Sobrien So, in general, we *do not* use DECL_INCOMING_RTL as a backup for DECL_RTL 943850397Sobrien in cases where DECL_ARG_TYPE (decl) != TREE_TYPE (decl). There 943950397Sobrien are a couple of exceptions however. On little-endian machines we can 944050397Sobrien get away with using DECL_INCOMING_RTL even when DECL_ARG_TYPE (decl) is 944150397Sobrien not the same as TREE_TYPE (decl), but only when DECL_ARG_TYPE (decl) is 944250397Sobrien an integral type that is smaller than TREE_TYPE (decl). These cases arise 944350397Sobrien when (on a little-endian machine) a non-prototyped function has a 944450397Sobrien parameter declared to be of type `short' or `char'. In such cases, 944550397Sobrien TREE_TYPE (decl) will be `short' or `char', DECL_ARG_TYPE (decl) will 944650397Sobrien be `int', and DECL_INCOMING_RTL will point to the lowest-order byte of the 944750397Sobrien passed `int' value. If the debugger then uses that address to fetch 944850397Sobrien a `short' or a `char' (on a little-endian machine) the result will be 944950397Sobrien the correct data, so we allow for such exceptional cases below. 945050397Sobrien 945150397Sobrien Note that our goal here is to describe the place where the given formal 945290075Sobrien parameter lives during most of the function's activation (i.e. between the 945390075Sobrien end of the prologue and the start of the epilogue). We'll do that as best 945490075Sobrien as we can. Note however that if the given formal parameter is modified 945590075Sobrien sometime during the execution of the function, then a stack backtrace (at 945690075Sobrien debug-time) will show the function as having been called with the *new* 945790075Sobrien value rather than the value which was originally passed in. This happens 945890075Sobrien rarely enough that it is not a major problem, but it *is* a problem, and 945990075Sobrien I'd like to fix it. 946050397Sobrien 946190075Sobrien A future version of dwarf2out.c may generate two additional attributes for 946290075Sobrien any given DW_TAG_formal_parameter DIE which will describe the "passed 946390075Sobrien type" and the "passed location" for the given formal parameter in addition 946490075Sobrien to the attributes we now generate to indicate the "declared type" and the 946590075Sobrien "active location" for each parameter. This additional set of attributes 946690075Sobrien could be used by debuggers for stack backtraces. Separately, note that 946790075Sobrien sometimes DECL_RTL can be NULL and DECL_INCOMING_RTL can be NULL also. 946890075Sobrien This happens (for example) for inlined-instances of inline function formal 946990075Sobrien parameters which are never referenced. This really shouldn't be 947090075Sobrien happening. All PARM_DECL nodes should get valid non-NULL 947190075Sobrien DECL_INCOMING_RTL values, but integrate.c doesn't currently generate these 947290075Sobrien values for inlined instances of inline function parameters, so when we see 947390075Sobrien such cases, we are just out-of-luck for the time being (until integrate.c 947450397Sobrien gets fixed). */ 947550397Sobrien 947650397Sobrien /* Use DECL_RTL as the "location" unless we find something better. */ 947790075Sobrien rtl = DECL_RTL_IF_SET (decl); 947850397Sobrien 947990075Sobrien /* When generating abstract instances, ignore everything except 9480117395Skan constants, symbols living in memory, and symbols living in 9481117395Skan fixed registers. */ 948290075Sobrien if (! reload_completed) 948350397Sobrien { 948490075Sobrien if (rtl 948590075Sobrien && (CONSTANT_P (rtl) 948690075Sobrien || (GET_CODE (rtl) == MEM 9487117395Skan && CONSTANT_P (XEXP (rtl, 0))) 9488117395Skan || (GET_CODE (rtl) == REG 9489117395Skan && TREE_CODE (decl) == VAR_DECL 9490117395Skan && TREE_STATIC (decl)))) 949196263Sobrien { 9492132718Skan rtl = (*targetm.delegitimize_address) (rtl); 949396263Sobrien return rtl; 949496263Sobrien } 949590075Sobrien rtl = NULL_RTX; 949690075Sobrien } 949790075Sobrien else if (TREE_CODE (decl) == PARM_DECL) 949890075Sobrien { 949950397Sobrien if (rtl == NULL_RTX || is_pseudo_reg (rtl)) 950050397Sobrien { 9501146895Skan tree declared_type = TREE_TYPE (decl); 9502146895Skan tree passed_type = DECL_ARG_TYPE (decl); 9503146895Skan enum machine_mode dmode = TYPE_MODE (declared_type); 9504146895Skan enum machine_mode pmode = TYPE_MODE (passed_type); 950550397Sobrien 950650397Sobrien /* This decl represents a formal parameter which was optimized out. 950750397Sobrien Note that DECL_INCOMING_RTL may be NULL in here, but we handle 950890075Sobrien all cases where (rtl == NULL_RTX) just below. */ 9509146895Skan if (dmode == pmode) 951050397Sobrien rtl = DECL_INCOMING_RTL (decl); 9511146895Skan else if (SCALAR_INT_MODE_P (dmode) 9512146895Skan && GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode) 9513146895Skan && DECL_INCOMING_RTL (decl)) 9514146895Skan { 9515146895Skan rtx inc = DECL_INCOMING_RTL (decl); 9516146895Skan if (REG_P (inc)) 9517146895Skan rtl = inc; 9518146895Skan else if (GET_CODE (inc) == MEM) 9519146895Skan { 9520146895Skan if (BYTES_BIG_ENDIAN) 9521146895Skan rtl = adjust_address_nv (inc, dmode, 9522146895Skan GET_MODE_SIZE (pmode) 9523146895Skan - GET_MODE_SIZE (dmode)); 9524146895Skan else 9525146895Skan rtl = inc; 9526146895Skan } 9527146895Skan } 952850397Sobrien } 952952284Sobrien 953052284Sobrien /* If the parm was passed in registers, but lives on the stack, then 953152284Sobrien make a big endian correction if the mode of the type of the 953252284Sobrien parameter is not the same as the mode of the rtl. */ 953352284Sobrien /* ??? This is the same series of checks that are made in dbxout.c before 953452284Sobrien we reach the big endian correction code there. It isn't clear if all 953552284Sobrien of these checks are necessary here, but keeping them all is the safe 953652284Sobrien thing to do. */ 953752284Sobrien else if (GET_CODE (rtl) == MEM 953852284Sobrien && XEXP (rtl, 0) != const0_rtx 953952284Sobrien && ! CONSTANT_P (XEXP (rtl, 0)) 954052284Sobrien /* Not passed in memory. */ 954152284Sobrien && GET_CODE (DECL_INCOMING_RTL (decl)) != MEM 954252284Sobrien /* Not passed by invisible reference. */ 954352284Sobrien && (GET_CODE (XEXP (rtl, 0)) != REG 954452284Sobrien || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM 954552284Sobrien || REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM 954652284Sobrien#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM 954752284Sobrien || REGNO (XEXP (rtl, 0)) == ARG_POINTER_REGNUM 954852284Sobrien#endif 954952284Sobrien ) 955052284Sobrien /* Big endian correction check. */ 955152284Sobrien && BYTES_BIG_ENDIAN 955252284Sobrien && TYPE_MODE (TREE_TYPE (decl)) != GET_MODE (rtl) 955352284Sobrien && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))) 955452284Sobrien < UNITS_PER_WORD)) 955552284Sobrien { 955652284Sobrien int offset = (UNITS_PER_WORD 955752284Sobrien - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl)))); 955890075Sobrien 955952284Sobrien rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)), 956052284Sobrien plus_constant (XEXP (rtl, 0), offset)); 956152284Sobrien } 956250397Sobrien } 956350397Sobrien 956490075Sobrien if (rtl != NULL_RTX) 956590075Sobrien { 956690075Sobrien rtl = eliminate_regs (rtl, 0, NULL_RTX); 956790075Sobrien#ifdef LEAF_REG_REMAP 956890075Sobrien if (current_function_uses_only_leaf_regs) 956990075Sobrien leaf_renumber_regs_insn (rtl); 957090075Sobrien#endif 957190075Sobrien } 957290075Sobrien 957390075Sobrien /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant, 957490075Sobrien and will have been substituted directly into all expressions that use it. 957590075Sobrien C does not have such a concept, but C++ and other languages do. */ 957690075Sobrien else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl)) 957796263Sobrien { 957896263Sobrien /* If a variable is initialized with a string constant without embedded 957996263Sobrien zeros, build CONST_STRING. */ 958096263Sobrien if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST 958196263Sobrien && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 958296263Sobrien { 958396263Sobrien tree arrtype = TREE_TYPE (decl); 958496263Sobrien tree enttype = TREE_TYPE (arrtype); 958596263Sobrien tree domain = TYPE_DOMAIN (arrtype); 958696263Sobrien tree init = DECL_INITIAL (decl); 958796263Sobrien enum machine_mode mode = TYPE_MODE (enttype); 958890075Sobrien 958996263Sobrien if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == 1 959096263Sobrien && domain 959196263Sobrien && integer_zerop (TYPE_MIN_VALUE (domain)) 959296263Sobrien && compare_tree_int (TYPE_MAX_VALUE (domain), 959396263Sobrien TREE_STRING_LENGTH (init) - 1) == 0 959496263Sobrien && ((size_t) TREE_STRING_LENGTH (init) 959596263Sobrien == strlen (TREE_STRING_POINTER (init)) + 1)) 959696263Sobrien rtl = gen_rtx_CONST_STRING (VOIDmode, TREE_STRING_POINTER (init)); 959796263Sobrien } 9598102780Skan /* If the initializer is something that we know will expand into an 9599102780Skan immediate RTL constant, expand it now. Expanding anything else 9600102780Skan tends to produce unresolved symbols; see debug/5770 and c++/6381. */ 9601102780Skan else if (TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST 9602102780Skan || TREE_CODE (DECL_INITIAL (decl)) == REAL_CST) 960396263Sobrien { 960496263Sobrien rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode, 960596263Sobrien EXPAND_INITIALIZER); 9606102780Skan /* If expand_expr returns a MEM, it wasn't immediate. */ 960796263Sobrien if (rtl && GET_CODE (rtl) == MEM) 9608102780Skan abort (); 960996263Sobrien } 961096263Sobrien } 961196263Sobrien 961296263Sobrien if (rtl) 9613132718Skan rtl = (*targetm.delegitimize_address) (rtl); 9614117395Skan 9615117395Skan /* If we don't look past the constant pool, we risk emitting a 9616117395Skan reference to a constant pool entry that isn't referenced from 9617117395Skan code, and thus is not emitted. */ 9618117395Skan if (rtl) 9619117395Skan rtl = avoid_constant_pool_reference (rtl); 9620117395Skan 962190075Sobrien return rtl; 962290075Sobrien} 962390075Sobrien 9624132718Skan/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value 962590075Sobrien data attribute for a variable or a parameter. We generate the 962690075Sobrien DW_AT_const_value attribute only in those cases where the given variable 962790075Sobrien or parameter does not have a true "location" either in memory or in a 962890075Sobrien register. This can happen (for example) when a constant is passed as an 962990075Sobrien actual argument in a call to an inline function. (It's possible that 963090075Sobrien these things can crop up in other ways also.) Note that one type of 963190075Sobrien constant value which can be passed into an inlined function is a constant 963290075Sobrien pointer. This can happen for example if an actual argument in an inlined 963390075Sobrien function call evaluates to a compile-time constant address. */ 963490075Sobrien 963590075Sobrienstatic void 9636132718Skanadd_location_or_const_value_attribute (dw_die_ref die, tree decl) 963790075Sobrien{ 963890075Sobrien rtx rtl; 9639117395Skan dw_loc_descr_ref descr; 964090075Sobrien 964190075Sobrien if (TREE_CODE (decl) == ERROR_MARK) 964290075Sobrien return; 964390075Sobrien else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL) 964490075Sobrien abort (); 964590075Sobrien 964690075Sobrien rtl = rtl_for_decl_location (decl); 964750397Sobrien if (rtl == NULL_RTX) 964850397Sobrien return; 964950397Sobrien 965050397Sobrien switch (GET_CODE (rtl)) 965150397Sobrien { 965250397Sobrien case ADDRESSOF: 9653117395Skan /* The address of a variable that was optimized away; 9654117395Skan don't emit anything. */ 965550397Sobrien break; 965650397Sobrien 965750397Sobrien case CONST_INT: 965850397Sobrien case CONST_DOUBLE: 9659132718Skan case CONST_VECTOR: 966050397Sobrien case CONST_STRING: 966150397Sobrien case SYMBOL_REF: 966250397Sobrien case LABEL_REF: 966350397Sobrien case CONST: 966450397Sobrien case PLUS: 966550397Sobrien /* DECL_RTL could be (plus (reg ...) (const_int ...)) */ 966650397Sobrien add_const_value_attribute (die, rtl); 966750397Sobrien break; 966850397Sobrien 966950397Sobrien case MEM: 9670117395Skan if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) 9671117395Skan { 9672117395Skan /* Need loc_descriptor_from_tree since that's where we know 9673117395Skan how to handle TLS variables. Want the object's address 9674117395Skan since the top-level DW_AT_location assumes such. See 9675117395Skan the confusion in loc_descriptor for reference. */ 9676117395Skan descr = loc_descriptor_from_tree (decl, 1); 9677117395Skan } 9678117395Skan else 9679117395Skan { 9680117395Skan case REG: 9681117395Skan case SUBREG: 9682117395Skan case CONCAT: 9683117395Skan descr = loc_descriptor (rtl); 9684117395Skan } 9685117395Skan add_AT_location_description (die, DW_AT_location, descr); 968650397Sobrien break; 9687132718Skan 9688132718Skan case PARALLEL: 9689132718Skan { 9690132718Skan rtvec par_elems = XVEC (rtl, 0); 9691132718Skan int num_elem = GET_NUM_ELEM (par_elems); 9692132718Skan enum machine_mode mode; 9693132718Skan int i; 9694132718Skan 9695132718Skan /* Create the first one, so we have something to add to. */ 9696132718Skan descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0)); 9697132718Skan mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0)); 9698132718Skan add_loc_descr (&descr, 9699132718Skan new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0)); 9700132718Skan for (i = 1; i < num_elem; i++) 9701132718Skan { 9702132718Skan dw_loc_descr_ref temp; 9703132718Skan 9704132718Skan temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0)); 9705132718Skan add_loc_descr (&descr, temp); 9706132718Skan mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0)); 9707132718Skan add_loc_descr (&descr, 9708132718Skan new_loc_descr (DW_OP_piece, 9709132718Skan GET_MODE_SIZE (mode), 0)); 9710132718Skan } 9711132718Skan } 9712132718Skan add_AT_location_description (die, DW_AT_location, descr); 9713132718Skan break; 9714132718Skan 971550397Sobrien default: 971650397Sobrien abort (); 971750397Sobrien } 971850397Sobrien} 971950397Sobrien 972090075Sobrien/* If we don't have a copy of this variable in memory for some reason (such 972190075Sobrien as a C++ member constant that doesn't have an out-of-line definition), 972290075Sobrien we should tell the debugger about the constant value. */ 972390075Sobrien 972490075Sobrienstatic void 9725132718Skantree_add_const_value_attribute (dw_die_ref var_die, tree decl) 972690075Sobrien{ 972790075Sobrien tree init = DECL_INITIAL (decl); 972890075Sobrien tree type = TREE_TYPE (decl); 972990075Sobrien 973090075Sobrien if (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl) && init 973190075Sobrien && initializer_constant_valid_p (init, type) == null_pointer_node) 973290075Sobrien /* OK */; 973390075Sobrien else 973490075Sobrien return; 973590075Sobrien 973690075Sobrien switch (TREE_CODE (type)) 973790075Sobrien { 973890075Sobrien case INTEGER_TYPE: 973990075Sobrien if (host_integerp (init, 0)) 974090075Sobrien add_AT_unsigned (var_die, DW_AT_const_value, 974190075Sobrien tree_low_cst (init, 0)); 974290075Sobrien else 974390075Sobrien add_AT_long_long (var_die, DW_AT_const_value, 974490075Sobrien TREE_INT_CST_HIGH (init), 974590075Sobrien TREE_INT_CST_LOW (init)); 974690075Sobrien break; 974790075Sobrien 974890075Sobrien default:; 974990075Sobrien } 975090075Sobrien} 975190075Sobrien 9752132718Skan/* Generate a DW_AT_name attribute given some string value to be included as 975350397Sobrien the value of the attribute. */ 975450397Sobrien 9755132718Skanstatic void 9756132718Skanadd_name_attribute (dw_die_ref die, const char *name_string) 975750397Sobrien{ 975850397Sobrien if (name_string != NULL && *name_string != 0) 975990075Sobrien { 976090075Sobrien if (demangle_name_func) 976190075Sobrien name_string = (*demangle_name_func) (name_string); 976290075Sobrien 976390075Sobrien add_AT_string (die, DW_AT_name, name_string); 976490075Sobrien } 976550397Sobrien} 976650397Sobrien 9767132718Skan/* Generate a DW_AT_comp_dir attribute for DIE. */ 9768132718Skan 9769132718Skanstatic void 9770132718Skanadd_comp_dir_attribute (dw_die_ref die) 9771132718Skan{ 9772132718Skan const char *wd = get_src_pwd (); 9773132718Skan if (wd != NULL) 9774132718Skan add_AT_string (die, DW_AT_comp_dir, wd); 9775132718Skan} 9776132718Skan 977750397Sobrien/* Given a tree node describing an array bound (either lower or upper) output 977850397Sobrien a representation for that bound. */ 977950397Sobrien 978050397Sobrienstatic void 9781132718Skanadd_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree bound) 978250397Sobrien{ 978350397Sobrien switch (TREE_CODE (bound)) 978450397Sobrien { 978550397Sobrien case ERROR_MARK: 978650397Sobrien return; 978750397Sobrien 978890075Sobrien /* All fixed-bounds are represented by INTEGER_CST nodes. */ 978950397Sobrien case INTEGER_CST: 979090075Sobrien if (! host_integerp (bound, 0) 979190075Sobrien || (bound_attr == DW_AT_lower_bound 979290075Sobrien && (((is_c_family () || is_java ()) && integer_zerop (bound)) 979390075Sobrien || (is_fortran () && integer_onep (bound))))) 979490075Sobrien /* use the default */ 979590075Sobrien ; 979650397Sobrien else 979790075Sobrien add_AT_unsigned (subrange_die, bound_attr, tree_low_cst (bound, 0)); 979850397Sobrien break; 979950397Sobrien 980050397Sobrien case CONVERT_EXPR: 980150397Sobrien case NOP_EXPR: 980250397Sobrien case NON_LVALUE_EXPR: 980390075Sobrien case VIEW_CONVERT_EXPR: 980450397Sobrien add_bound_info (subrange_die, bound_attr, TREE_OPERAND (bound, 0)); 980550397Sobrien break; 980690075Sobrien 980750397Sobrien case SAVE_EXPR: 980850397Sobrien /* If optimization is turned on, the SAVE_EXPRs that describe how to 9809132718Skan access the upper bound values may be bogus. If they refer to a 9810132718Skan register, they may only describe how to get at these values at the 9811132718Skan points in the generated code right after they have just been 9812132718Skan computed. Worse yet, in the typical case, the upper bound values 9813132718Skan will not even *be* computed in the optimized code (though the 9814132718Skan number of elements will), so these SAVE_EXPRs are entirely 9815132718Skan bogus. In order to compensate for this fact, we check here to see 9816132718Skan if optimization is enabled, and if so, we don't add an attribute 9817132718Skan for the (unknown and unknowable) upper bound. This should not 9818132718Skan cause too much trouble for existing (stupid?) debuggers because 9819132718Skan they have to deal with empty upper bounds location descriptions 9820132718Skan anyway in order to be able to deal with incomplete array types. 9821132718Skan Of course an intelligent debugger (GDB?) should be able to 9822132718Skan comprehend that a missing upper bound specification in an array 9823132718Skan type used for a storage class `auto' local array variable 9824132718Skan indicates that the upper bound is both unknown (at compile- time) 9825132718Skan and unknowable (at run-time) due to optimization. 982650397Sobrien 982750397Sobrien We assume that a MEM rtx is safe because gcc wouldn't put the 982850397Sobrien value there unless it was going to be used repeatedly in the 982950397Sobrien function, i.e. for cleanups. */ 983090075Sobrien if (SAVE_EXPR_RTL (bound) 983190075Sobrien && (! optimize || GET_CODE (SAVE_EXPR_RTL (bound)) == MEM)) 983250397Sobrien { 983390075Sobrien dw_die_ref ctx = lookup_decl_die (current_function_decl); 983490075Sobrien dw_die_ref decl_die = new_die (DW_TAG_variable, ctx, bound); 983590075Sobrien rtx loc = SAVE_EXPR_RTL (bound); 983650397Sobrien 983750397Sobrien /* If the RTL for the SAVE_EXPR is memory, handle the case where 983850397Sobrien it references an outer function's frame. */ 983950397Sobrien if (GET_CODE (loc) == MEM) 984050397Sobrien { 984150397Sobrien rtx new_addr = fix_lexical_addr (XEXP (loc, 0), bound); 984250397Sobrien 984350397Sobrien if (XEXP (loc, 0) != new_addr) 984490075Sobrien loc = gen_rtx_MEM (GET_MODE (loc), new_addr); 984550397Sobrien } 984650397Sobrien 984750397Sobrien add_AT_flag (decl_die, DW_AT_artificial, 1); 984850397Sobrien add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); 9849117395Skan add_AT_location_description (decl_die, DW_AT_location, 9850117395Skan loc_descriptor (loc)); 985150397Sobrien add_AT_die_ref (subrange_die, bound_attr, decl_die); 985250397Sobrien } 985350397Sobrien 985450397Sobrien /* Else leave out the attribute. */ 985550397Sobrien break; 985650397Sobrien 985750397Sobrien case VAR_DECL: 985890075Sobrien case PARM_DECL: 985990075Sobrien { 986090075Sobrien dw_die_ref decl_die = lookup_decl_die (bound); 986150397Sobrien 986290075Sobrien /* ??? Can this happen, or should the variable have been bound 986390075Sobrien first? Probably it can, since I imagine that we try to create 986490075Sobrien the types of parameters in the order in which they exist in 986590075Sobrien the list, and won't have created a forward reference to a 986690075Sobrien later parameter. */ 986790075Sobrien if (decl_die != NULL) 986890075Sobrien add_AT_die_ref (subrange_die, bound_attr, decl_die); 986990075Sobrien break; 987090075Sobrien } 987190075Sobrien 987250397Sobrien default: 987390075Sobrien { 987490075Sobrien /* Otherwise try to create a stack operation procedure to 987590075Sobrien evaluate the value of the array bound. */ 987690075Sobrien 987790075Sobrien dw_die_ref ctx, decl_die; 987890075Sobrien dw_loc_descr_ref loc; 987990075Sobrien 988090075Sobrien loc = loc_descriptor_from_tree (bound, 0); 988190075Sobrien if (loc == NULL) 988290075Sobrien break; 988390075Sobrien 988490075Sobrien if (current_function_decl == 0) 988590075Sobrien ctx = comp_unit_die; 988690075Sobrien else 988790075Sobrien ctx = lookup_decl_die (current_function_decl); 988890075Sobrien 988990075Sobrien /* If we weren't able to find a context, it's most likely the case 989090075Sobrien that we are processing the return type of the function. So 989190075Sobrien make a SAVE_EXPR to point to it and have the limbo DIE code 989290075Sobrien find the proper die. The save_expr function doesn't always 989390075Sobrien make a SAVE_EXPR, so do it ourselves. */ 989490075Sobrien if (ctx == 0) 989590075Sobrien bound = build (SAVE_EXPR, TREE_TYPE (bound), bound, 989690075Sobrien current_function_decl, NULL_TREE); 989790075Sobrien 989890075Sobrien decl_die = new_die (DW_TAG_variable, ctx, bound); 989990075Sobrien add_AT_flag (decl_die, DW_AT_artificial, 1); 990090075Sobrien add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); 990190075Sobrien add_AT_loc (decl_die, DW_AT_location, loc); 990290075Sobrien 990390075Sobrien add_AT_die_ref (subrange_die, bound_attr, decl_die); 990490075Sobrien break; 990590075Sobrien } 990650397Sobrien } 990750397Sobrien} 990850397Sobrien 990950397Sobrien/* Note that the block of subscript information for an array type also 991050397Sobrien includes information about the element type of type given array type. */ 991150397Sobrien 991250397Sobrienstatic void 9913132718Skanadd_subscript_info (dw_die_ref type_die, tree type) 991450397Sobrien{ 991550397Sobrien#ifndef MIPS_DEBUGGING_INFO 991690075Sobrien unsigned dimension_number; 991750397Sobrien#endif 991890075Sobrien tree lower, upper; 991990075Sobrien dw_die_ref subrange_die; 992050397Sobrien 992190075Sobrien /* The GNU compilers represent multidimensional array types as sequences of 992250397Sobrien one dimensional array types whose element types are themselves array 992350397Sobrien types. Here we squish that down, so that each multidimensional array 992490075Sobrien type gets only one array_type DIE in the Dwarf debugging info. The draft 992550397Sobrien Dwarf specification say that we are allowed to do this kind of 992650397Sobrien compression in C (because there is no difference between an array or 992790075Sobrien arrays and a multidimensional array in C) but for other source languages 992850397Sobrien (e.g. Ada) we probably shouldn't do this. */ 992950397Sobrien 993050397Sobrien /* ??? The SGI dwarf reader fails for multidimensional arrays with a 993150397Sobrien const enum type. E.g. const enum machine_mode insn_operand_mode[2][10]. 993250397Sobrien We work around this by disabling this feature. See also 993350397Sobrien gen_array_type_die. */ 993450397Sobrien#ifndef MIPS_DEBUGGING_INFO 993550397Sobrien for (dimension_number = 0; 993650397Sobrien TREE_CODE (type) == ARRAY_TYPE; 993750397Sobrien type = TREE_TYPE (type), dimension_number++) 993890075Sobrien#endif 993950397Sobrien { 994090075Sobrien tree domain = TYPE_DOMAIN (type); 994150397Sobrien 994250397Sobrien /* Arrays come in three flavors: Unspecified bounds, fixed bounds, 994390075Sobrien and (in GNU C only) variable bounds. Handle all three forms 9944132718Skan here. */ 994590075Sobrien subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL); 994650397Sobrien if (domain) 994750397Sobrien { 994850397Sobrien /* We have an array type with specified bounds. */ 994950397Sobrien lower = TYPE_MIN_VALUE (domain); 995050397Sobrien upper = TYPE_MAX_VALUE (domain); 995150397Sobrien 9952132718Skan /* Define the index type. */ 995350397Sobrien if (TREE_TYPE (domain)) 995450397Sobrien { 995550397Sobrien /* ??? This is probably an Ada unnamed subrange type. Ignore the 995650397Sobrien TREE_TYPE field. We can't emit debug info for this 995750397Sobrien because it is an unnamed integral type. */ 995850397Sobrien if (TREE_CODE (domain) == INTEGER_TYPE 995950397Sobrien && TYPE_NAME (domain) == NULL_TREE 996050397Sobrien && TREE_CODE (TREE_TYPE (domain)) == INTEGER_TYPE 996150397Sobrien && TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE) 996290075Sobrien ; 996350397Sobrien else 996450397Sobrien add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0, 996550397Sobrien type_die); 996650397Sobrien } 996750397Sobrien 996850397Sobrien /* ??? If upper is NULL, the array has unspecified length, 996950397Sobrien but it does have a lower bound. This happens with Fortran 997050397Sobrien dimension arr(N:*) 9971132718Skan Since the debugger is definitely going to need to know N 997250397Sobrien to produce useful results, go ahead and output the lower 997350397Sobrien bound solo, and hope the debugger can cope. */ 997450397Sobrien 997550397Sobrien add_bound_info (subrange_die, DW_AT_lower_bound, lower); 997650397Sobrien if (upper) 997750397Sobrien add_bound_info (subrange_die, DW_AT_upper_bound, upper); 997850397Sobrien } 997950397Sobrien 998090075Sobrien /* Otherwise we have an array type with an unspecified length. The 998190075Sobrien DWARF-2 spec does not say how to handle this; let's just leave out the 998290075Sobrien bounds. */ 998350397Sobrien } 998450397Sobrien} 998550397Sobrien 998650397Sobrienstatic void 9987132718Skanadd_byte_size_attribute (dw_die_ref die, tree tree_node) 998850397Sobrien{ 998990075Sobrien unsigned size; 999050397Sobrien 999150397Sobrien switch (TREE_CODE (tree_node)) 999250397Sobrien { 999350397Sobrien case ERROR_MARK: 999450397Sobrien size = 0; 999550397Sobrien break; 999650397Sobrien case ENUMERAL_TYPE: 999750397Sobrien case RECORD_TYPE: 999850397Sobrien case UNION_TYPE: 999950397Sobrien case QUAL_UNION_TYPE: 1000050397Sobrien size = int_size_in_bytes (tree_node); 1000150397Sobrien break; 1000250397Sobrien case FIELD_DECL: 1000350397Sobrien /* For a data member of a struct or union, the DW_AT_byte_size is 10004132718Skan generally given as the number of bytes normally allocated for an 10005132718Skan object of the *declared* type of the member itself. This is true 10006132718Skan even for bit-fields. */ 1000750397Sobrien size = simple_type_size_in_bits (field_type (tree_node)) / BITS_PER_UNIT; 1000850397Sobrien break; 1000950397Sobrien default: 1001050397Sobrien abort (); 1001150397Sobrien } 1001250397Sobrien 1001350397Sobrien /* Note that `size' might be -1 when we get to this point. If it is, that 1001450397Sobrien indicates that the byte size of the entity in question is variable. We 1001550397Sobrien have no good way of expressing this fact in Dwarf at the present time, 1001650397Sobrien so just let the -1 pass on through. */ 1001750397Sobrien add_AT_unsigned (die, DW_AT_byte_size, size); 1001850397Sobrien} 1001950397Sobrien 1002050397Sobrien/* For a FIELD_DECL node which represents a bit-field, output an attribute 1002150397Sobrien which specifies the distance in bits from the highest order bit of the 1002250397Sobrien "containing object" for the bit-field to the highest order bit of the 1002350397Sobrien bit-field itself. 1002450397Sobrien 1002590075Sobrien For any given bit-field, the "containing object" is a hypothetical object 1002690075Sobrien (of some integral or enum type) within which the given bit-field lives. The 1002790075Sobrien type of this hypothetical "containing object" is always the same as the 1002890075Sobrien declared type of the individual bit-field itself. The determination of the 1002990075Sobrien exact location of the "containing object" for a bit-field is rather 1003090075Sobrien complicated. It's handled by the `field_byte_offset' function (above). 1003150397Sobrien 1003250397Sobrien Note that it is the size (in bytes) of the hypothetical "containing object" 1003350397Sobrien which will be given in the DW_AT_byte_size attribute for this bit-field. 1003450397Sobrien (See `byte_size_attribute' above). */ 1003550397Sobrien 1003650397Sobrienstatic inline void 10037132718Skanadd_bit_offset_attribute (dw_die_ref die, tree decl) 1003850397Sobrien{ 1003990075Sobrien HOST_WIDE_INT object_offset_in_bytes = field_byte_offset (decl); 1004090075Sobrien tree type = DECL_BIT_FIELD_TYPE (decl); 1004190075Sobrien HOST_WIDE_INT bitpos_int; 1004290075Sobrien HOST_WIDE_INT highest_order_object_bit_offset; 1004390075Sobrien HOST_WIDE_INT highest_order_field_bit_offset; 1004490075Sobrien HOST_WIDE_INT unsigned bit_offset; 1004550397Sobrien 1004650397Sobrien /* Must be a field and a bit field. */ 1004750397Sobrien if (!type 1004850397Sobrien || TREE_CODE (decl) != FIELD_DECL) 1004950397Sobrien abort (); 1005050397Sobrien 1005150397Sobrien /* We can't yet handle bit-fields whose offsets are variable, so if we 1005250397Sobrien encounter such things, just return without generating any attribute 1005390075Sobrien whatsoever. Likewise for variable or too large size. */ 1005490075Sobrien if (! host_integerp (bit_position (decl), 0) 1005590075Sobrien || ! host_integerp (DECL_SIZE (decl), 1)) 1005650397Sobrien return; 1005750397Sobrien 1005890075Sobrien bitpos_int = int_bit_position (decl); 1005950397Sobrien 1006050397Sobrien /* Note that the bit offset is always the distance (in bits) from the 1006190075Sobrien highest-order bit of the "containing object" to the highest-order bit of 1006290075Sobrien the bit-field itself. Since the "high-order end" of any object or field 1006350397Sobrien is different on big-endian and little-endian machines, the computation 1006450397Sobrien below must take account of these differences. */ 1006550397Sobrien highest_order_object_bit_offset = object_offset_in_bytes * BITS_PER_UNIT; 1006650397Sobrien highest_order_field_bit_offset = bitpos_int; 1006750397Sobrien 1006850397Sobrien if (! BYTES_BIG_ENDIAN) 1006950397Sobrien { 1007090075Sobrien highest_order_field_bit_offset += tree_low_cst (DECL_SIZE (decl), 0); 1007150397Sobrien highest_order_object_bit_offset += simple_type_size_in_bits (type); 1007250397Sobrien } 1007350397Sobrien 1007450397Sobrien bit_offset 1007550397Sobrien = (! BYTES_BIG_ENDIAN 1007650397Sobrien ? highest_order_object_bit_offset - highest_order_field_bit_offset 1007750397Sobrien : highest_order_field_bit_offset - highest_order_object_bit_offset); 1007850397Sobrien 1007950397Sobrien add_AT_unsigned (die, DW_AT_bit_offset, bit_offset); 1008050397Sobrien} 1008150397Sobrien 1008250397Sobrien/* For a FIELD_DECL node which represents a bit field, output an attribute 1008350397Sobrien which specifies the length in bits of the given field. */ 1008450397Sobrien 1008550397Sobrienstatic inline void 10086132718Skanadd_bit_size_attribute (dw_die_ref die, tree decl) 1008750397Sobrien{ 1008850397Sobrien /* Must be a field and a bit field. */ 1008950397Sobrien if (TREE_CODE (decl) != FIELD_DECL 1009050397Sobrien || ! DECL_BIT_FIELD_TYPE (decl)) 1009150397Sobrien abort (); 1009290075Sobrien 1009390075Sobrien if (host_integerp (DECL_SIZE (decl), 1)) 1009490075Sobrien add_AT_unsigned (die, DW_AT_bit_size, tree_low_cst (DECL_SIZE (decl), 1)); 1009550397Sobrien} 1009650397Sobrien 1009750397Sobrien/* If the compiled language is ANSI C, then add a 'prototyped' 1009850397Sobrien attribute, if arg types are given for the parameters of a function. */ 1009950397Sobrien 1010050397Sobrienstatic inline void 10101132718Skanadd_prototyped_attribute (dw_die_ref die, tree func_type) 1010250397Sobrien{ 1010350397Sobrien if (get_AT_unsigned (comp_unit_die, DW_AT_language) == DW_LANG_C89 1010450397Sobrien && TYPE_ARG_TYPES (func_type) != NULL) 1010550397Sobrien add_AT_flag (die, DW_AT_prototyped, 1); 1010650397Sobrien} 1010750397Sobrien 1010850397Sobrien/* Add an 'abstract_origin' attribute below a given DIE. The DIE is found 1010950397Sobrien by looking in either the type declaration or object declaration 1011050397Sobrien equate table. */ 1011150397Sobrien 1011250397Sobrienstatic inline void 10113132718Skanadd_abstract_origin_attribute (dw_die_ref die, tree origin) 1011450397Sobrien{ 1011550397Sobrien dw_die_ref origin_die = NULL; 1011690075Sobrien 1011790075Sobrien if (TREE_CODE (origin) != FUNCTION_DECL) 1011890075Sobrien { 1011990075Sobrien /* We may have gotten separated from the block for the inlined 1012090075Sobrien function, if we're in an exception handler or some such; make 1012190075Sobrien sure that the abstract function has been written out. 1012290075Sobrien 10123132718Skan Doing this for nested functions is wrong, however; functions are 1012490075Sobrien distinct units, and our context might not even be inline. */ 1012590075Sobrien tree fn = origin; 1012690075Sobrien 1012790075Sobrien if (TYPE_P (fn)) 1012890075Sobrien fn = TYPE_STUB_DECL (fn); 1012990075Sobrien 1013090075Sobrien fn = decl_function_context (fn); 1013190075Sobrien if (fn) 1013290075Sobrien dwarf2out_abstract_function (fn); 1013390075Sobrien } 1013490075Sobrien 1013590075Sobrien if (DECL_P (origin)) 1013650397Sobrien origin_die = lookup_decl_die (origin); 1013790075Sobrien else if (TYPE_P (origin)) 1013850397Sobrien origin_die = lookup_type_die (origin); 1013950397Sobrien 1014090075Sobrien if (origin_die == NULL) 1014190075Sobrien abort (); 1014290075Sobrien 1014350397Sobrien add_AT_die_ref (die, DW_AT_abstract_origin, origin_die); 1014450397Sobrien} 1014550397Sobrien 1014650397Sobrien/* We do not currently support the pure_virtual attribute. */ 1014750397Sobrien 1014850397Sobrienstatic inline void 10149132718Skanadd_pure_or_virtual_attribute (dw_die_ref die, tree func_decl) 1015050397Sobrien{ 1015150397Sobrien if (DECL_VINDEX (func_decl)) 1015250397Sobrien { 1015350397Sobrien add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual); 1015450397Sobrien 1015590075Sobrien if (host_integerp (DECL_VINDEX (func_decl), 0)) 1015690075Sobrien add_AT_loc (die, DW_AT_vtable_elem_location, 1015790075Sobrien new_loc_descr (DW_OP_constu, 1015890075Sobrien tree_low_cst (DECL_VINDEX (func_decl), 0), 1015990075Sobrien 0)); 1016090075Sobrien 1016150397Sobrien /* GNU extension: Record what type this method came from originally. */ 1016250397Sobrien if (debug_info_level > DINFO_LEVEL_TERSE) 1016350397Sobrien add_AT_die_ref (die, DW_AT_containing_type, 1016450397Sobrien lookup_type_die (DECL_CONTEXT (func_decl))); 1016550397Sobrien } 1016650397Sobrien} 1016750397Sobrien 1016850397Sobrien/* Add source coordinate attributes for the given decl. */ 1016950397Sobrien 1017050397Sobrienstatic void 10171132718Skanadd_src_coords_attributes (dw_die_ref die, tree decl) 1017250397Sobrien{ 1017390075Sobrien unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl)); 1017450397Sobrien 1017550397Sobrien add_AT_unsigned (die, DW_AT_decl_file, file_index); 1017650397Sobrien add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl)); 1017750397Sobrien} 1017850397Sobrien 10179132718Skan/* Add a DW_AT_name attribute and source coordinate attribute for the 1018050397Sobrien given decl, but only if it actually has a name. */ 1018150397Sobrien 1018250397Sobrienstatic void 10183132718Skanadd_name_and_src_coords_attributes (dw_die_ref die, tree decl) 1018450397Sobrien{ 1018590075Sobrien tree decl_name; 1018650397Sobrien 1018790075Sobrien decl_name = DECL_NAME (decl); 1018850397Sobrien if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL) 1018950397Sobrien { 1019050397Sobrien add_name_attribute (die, dwarf2_name (decl, 0)); 1019190075Sobrien if (! DECL_ARTIFICIAL (decl)) 1019290075Sobrien add_src_coords_attributes (die, decl); 1019390075Sobrien 1019450397Sobrien if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) 1019590075Sobrien && TREE_PUBLIC (decl) 1019690075Sobrien && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) 1019790075Sobrien && !DECL_ABSTRACT (decl)) 1019850397Sobrien add_AT_string (die, DW_AT_MIPS_linkage_name, 1019950397Sobrien IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 1020050397Sobrien } 1020190075Sobrien 1020290075Sobrien#ifdef VMS_DEBUGGING_INFO 1020390075Sobrien /* Get the function's name, as described by its RTL. This may be different 1020490075Sobrien from the DECL_NAME name used in the source file. */ 1020590075Sobrien if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl)) 1020690075Sobrien { 1020790075Sobrien add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address, 1020890075Sobrien XEXP (DECL_RTL (decl), 0)); 1020990075Sobrien VARRAY_PUSH_RTX (used_rtx_varray, XEXP (DECL_RTL (decl), 0)); 1021090075Sobrien } 1021190075Sobrien#endif 1021250397Sobrien} 1021350397Sobrien 1021490075Sobrien/* Push a new declaration scope. */ 1021550397Sobrien 1021650397Sobrienstatic void 10217132718Skanpush_decl_scope (tree scope) 1021850397Sobrien{ 1021990075Sobrien VARRAY_PUSH_TREE (decl_scope_table, scope); 1022090075Sobrien} 1022150397Sobrien 1022290075Sobrien/* Pop a declaration scope. */ 1022350397Sobrien 1022490075Sobrienstatic inline void 10225132718Skanpop_decl_scope (void) 1022690075Sobrien{ 1022790075Sobrien if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0) 1022890075Sobrien abort (); 1022950397Sobrien 1023090075Sobrien VARRAY_POP (decl_scope_table); 1023150397Sobrien} 1023250397Sobrien 1023390075Sobrien/* Return the DIE for the scope that immediately contains this type. 1023490075Sobrien Non-named types get global scope. Named types nested in other 1023590075Sobrien types get their containing scope if it's open, or global scope 1023690075Sobrien otherwise. All other types (i.e. function-local named types) get 1023790075Sobrien the current active scope. */ 1023850397Sobrien 1023950397Sobrienstatic dw_die_ref 10240132718Skanscope_die_for (tree t, dw_die_ref context_die) 1024150397Sobrien{ 1024290075Sobrien dw_die_ref scope_die = NULL; 1024390075Sobrien tree containing_scope; 1024490075Sobrien int i; 1024550397Sobrien 1024690075Sobrien /* Non-types always go in the current scope. */ 1024790075Sobrien if (! TYPE_P (t)) 1024890075Sobrien abort (); 1024950397Sobrien 1025090075Sobrien containing_scope = TYPE_CONTEXT (t); 1025190075Sobrien 10252132718Skan /* Use the containing namespace if it was passed in (for a declaration). */ 1025350397Sobrien if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL) 10254132718Skan { 10255132718Skan if (context_die == lookup_decl_die (containing_scope)) 10256132718Skan /* OK */; 10257132718Skan else 10258132718Skan containing_scope = NULL_TREE; 10259132718Skan } 1026050397Sobrien 1026152284Sobrien /* Ignore function type "scopes" from the C frontend. They mean that 1026252284Sobrien a tagged type is local to a parmlist of a function declarator, but 1026352284Sobrien that isn't useful to DWARF. */ 1026452284Sobrien if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE) 1026552284Sobrien containing_scope = NULL_TREE; 1026652284Sobrien 10267146895Skan if (containing_scope == NULL_TREE 10268146895Skan || TREE_CODE (containing_scope) == TRANSLATION_UNIT_DECL) 1026950397Sobrien scope_die = comp_unit_die; 1027090075Sobrien else if (TYPE_P (containing_scope)) 1027150397Sobrien { 1027290075Sobrien /* For types, we can just look up the appropriate DIE. But 1027390075Sobrien first we check to see if we're in the middle of emitting it 1027490075Sobrien so we know where the new DIE should go. */ 1027590075Sobrien for (i = VARRAY_ACTIVE_SIZE (decl_scope_table) - 1; i >= 0; --i) 1027690075Sobrien if (VARRAY_TREE (decl_scope_table, i) == containing_scope) 1027790075Sobrien break; 1027850397Sobrien 1027950397Sobrien if (i < 0) 1028050397Sobrien { 1028150397Sobrien if (debug_info_level > DINFO_LEVEL_TERSE 1028250397Sobrien && !TREE_ASM_WRITTEN (containing_scope)) 1028350397Sobrien abort (); 1028452284Sobrien 1028552284Sobrien /* If none of the current dies are suitable, we get file scope. */ 1028652284Sobrien scope_die = comp_unit_die; 1028750397Sobrien } 1028890075Sobrien else 1028990075Sobrien scope_die = lookup_type_die (containing_scope); 1029050397Sobrien } 1029190075Sobrien else 1029290075Sobrien scope_die = context_die; 1029350397Sobrien 1029450397Sobrien return scope_die; 1029550397Sobrien} 1029650397Sobrien 1029790075Sobrien/* Returns nonzero if CONTEXT_DIE is internal to a function. */ 1029890075Sobrien 1029990075Sobrienstatic inline int 10300132718Skanlocal_scope_p (dw_die_ref context_die) 1030150397Sobrien{ 1030290075Sobrien for (; context_die; context_die = context_die->die_parent) 1030390075Sobrien if (context_die->die_tag == DW_TAG_inlined_subroutine 1030490075Sobrien || context_die->die_tag == DW_TAG_subprogram) 1030590075Sobrien return 1; 1030690075Sobrien 1030790075Sobrien return 0; 1030850397Sobrien} 1030950397Sobrien 10310132718Skan/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding 10311132718Skan whether or not to treat a DIE in this context as a declaration. */ 1031290075Sobrien 1031390075Sobrienstatic inline int 10314132718Skanclass_or_namespace_scope_p (dw_die_ref context_die) 1031590075Sobrien{ 1031690075Sobrien return (context_die 1031790075Sobrien && (context_die->die_tag == DW_TAG_structure_type 10318132718Skan || context_die->die_tag == DW_TAG_union_type 10319132718Skan || context_die->die_tag == DW_TAG_namespace)); 1032090075Sobrien} 1032190075Sobrien 1032250397Sobrien/* Many forms of DIEs require a "type description" attribute. This 1032350397Sobrien routine locates the proper "type descriptor" die for the type given 10324132718Skan by 'type', and adds a DW_AT_type attribute below the given die. */ 1032550397Sobrien 1032650397Sobrienstatic void 10327132718Skanadd_type_attribute (dw_die_ref object_die, tree type, int decl_const, 10328132718Skan int decl_volatile, dw_die_ref context_die) 1032950397Sobrien{ 1033090075Sobrien enum tree_code code = TREE_CODE (type); 1033190075Sobrien dw_die_ref type_die = NULL; 1033250397Sobrien 1033350397Sobrien /* ??? If this type is an unnamed subrange type of an integral or 1033450397Sobrien floating-point type, use the inner type. This is because we have no 1033550397Sobrien support for unnamed types in base_type_die. This can happen if this is 1033650397Sobrien an Ada subrange type. Correct solution is emit a subrange type die. */ 1033750397Sobrien if ((code == INTEGER_TYPE || code == REAL_TYPE) 1033850397Sobrien && TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0) 1033950397Sobrien type = TREE_TYPE (type), code = TREE_CODE (type); 1034050397Sobrien 1034190075Sobrien if (code == ERROR_MARK 1034290075Sobrien /* Handle a special case. For functions whose return type is void, we 1034390075Sobrien generate *no* type attribute. (Note that no object may have type 1034490075Sobrien `void', so this only applies to function return types). */ 1034590075Sobrien || code == VOID_TYPE) 1034650397Sobrien return; 1034750397Sobrien 1034850397Sobrien type_die = modified_type_die (type, 1034950397Sobrien decl_const || TYPE_READONLY (type), 1035050397Sobrien decl_volatile || TYPE_VOLATILE (type), 1035150397Sobrien context_die); 1035290075Sobrien 1035350397Sobrien if (type_die != NULL) 1035450397Sobrien add_AT_die_ref (object_die, DW_AT_type, type_die); 1035550397Sobrien} 1035650397Sobrien 1035750397Sobrien/* Given a tree pointer to a struct, class, union, or enum type node, return 1035850397Sobrien a pointer to the (string) tag name for the given type, or zero if the type 1035950397Sobrien was declared without a tag. */ 1036050397Sobrien 1036190075Sobrienstatic const char * 10362132718Skantype_tag (tree type) 1036350397Sobrien{ 1036490075Sobrien const char *name = 0; 1036550397Sobrien 1036650397Sobrien if (TYPE_NAME (type) != 0) 1036750397Sobrien { 1036890075Sobrien tree t = 0; 1036950397Sobrien 1037050397Sobrien /* Find the IDENTIFIER_NODE for the type name. */ 1037150397Sobrien if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 1037250397Sobrien t = TYPE_NAME (type); 1037350397Sobrien 1037490075Sobrien /* The g++ front end makes the TYPE_NAME of *each* tagged type point to 10375132718Skan a TYPE_DECL node, regardless of whether or not a `typedef' was 10376132718Skan involved. */ 1037750397Sobrien else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1037850397Sobrien && ! DECL_IGNORED_P (TYPE_NAME (type))) 1037950397Sobrien t = DECL_NAME (TYPE_NAME (type)); 1038050397Sobrien 1038150397Sobrien /* Now get the name as a string, or invent one. */ 1038250397Sobrien if (t != 0) 1038350397Sobrien name = IDENTIFIER_POINTER (t); 1038450397Sobrien } 1038550397Sobrien 1038650397Sobrien return (name == 0 || *name == '\0') ? 0 : name; 1038750397Sobrien} 1038850397Sobrien 1038950397Sobrien/* Return the type associated with a data member, make a special check 1039050397Sobrien for bit field types. */ 1039150397Sobrien 1039250397Sobrienstatic inline tree 10393132718Skanmember_declared_type (tree member) 1039450397Sobrien{ 1039550397Sobrien return (DECL_BIT_FIELD_TYPE (member) 1039690075Sobrien ? DECL_BIT_FIELD_TYPE (member) : TREE_TYPE (member)); 1039750397Sobrien} 1039850397Sobrien 1039950397Sobrien/* Get the decl's label, as described by its RTL. This may be different 1040050397Sobrien from the DECL_NAME name used in the source file. */ 1040150397Sobrien 1040250397Sobrien#if 0 1040390075Sobrienstatic const char * 10404132718Skandecl_start_label (tree decl) 1040550397Sobrien{ 1040650397Sobrien rtx x; 1040790075Sobrien const char *fnname; 1040890075Sobrien 1040950397Sobrien x = DECL_RTL (decl); 1041050397Sobrien if (GET_CODE (x) != MEM) 1041150397Sobrien abort (); 1041250397Sobrien 1041350397Sobrien x = XEXP (x, 0); 1041450397Sobrien if (GET_CODE (x) != SYMBOL_REF) 1041550397Sobrien abort (); 1041650397Sobrien 1041750397Sobrien fnname = XSTR (x, 0); 1041850397Sobrien return fnname; 1041950397Sobrien} 1042050397Sobrien#endif 1042150397Sobrien 1042250397Sobrien/* These routines generate the internal representation of the DIE's for 1042350397Sobrien the compilation unit. Debugging information is collected by walking 1042450397Sobrien the declaration trees passed in from dwarf2out_decl(). */ 1042550397Sobrien 1042650397Sobrienstatic void 10427132718Skangen_array_type_die (tree type, dw_die_ref context_die) 1042850397Sobrien{ 1042990075Sobrien dw_die_ref scope_die = scope_die_for (type, context_die); 1043090075Sobrien dw_die_ref array_die; 1043190075Sobrien tree element_type; 1043250397Sobrien 1043350397Sobrien /* ??? The SGI dwarf reader fails for array of array of enum types unless 1043450397Sobrien the inner array type comes before the outer array type. Thus we must 1043550397Sobrien call gen_type_die before we call new_die. See below also. */ 1043650397Sobrien#ifdef MIPS_DEBUGGING_INFO 1043750397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1043850397Sobrien#endif 1043950397Sobrien 1044090075Sobrien array_die = new_die (DW_TAG_array_type, scope_die, type); 1044196263Sobrien add_name_attribute (array_die, type_tag (type)); 1044296263Sobrien equate_type_number_to_die (type, array_die); 1044350397Sobrien 1044496263Sobrien if (TREE_CODE (type) == VECTOR_TYPE) 1044596263Sobrien { 1044696263Sobrien /* The frontend feeds us a representation for the vector as a struct 1044796263Sobrien containing an array. Pull out the array type. */ 1044896263Sobrien type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type))); 1044996263Sobrien add_AT_flag (array_die, DW_AT_GNU_vector, 1); 1045096263Sobrien } 1045196263Sobrien 1045250397Sobrien#if 0 1045350397Sobrien /* We default the array ordering. SDB will probably do 1045450397Sobrien the right things even if DW_AT_ordering is not present. It's not even 1045550397Sobrien an issue until we start to get into multidimensional arrays anyway. If 1045650397Sobrien SDB is ever caught doing the Wrong Thing for multi-dimensional arrays, 1045750397Sobrien then we'll have to put the DW_AT_ordering attribute back in. (But if 1045850397Sobrien and when we find out that we need to put these in, we will only do so 1045950397Sobrien for multidimensional arrays. */ 1046050397Sobrien add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_row_major); 1046150397Sobrien#endif 1046250397Sobrien 1046350397Sobrien#ifdef MIPS_DEBUGGING_INFO 1046450397Sobrien /* The SGI compilers handle arrays of unknown bound by setting 1046550397Sobrien AT_declaration and not emitting any subrange DIEs. */ 1046650397Sobrien if (! TYPE_DOMAIN (type)) 10467132718Skan add_AT_flag (array_die, DW_AT_declaration, 1); 1046850397Sobrien else 1046950397Sobrien#endif 1047050397Sobrien add_subscript_info (array_die, type); 1047150397Sobrien 1047250397Sobrien /* Add representation of the type of the elements of this array type. */ 1047350397Sobrien element_type = TREE_TYPE (type); 1047450397Sobrien 1047550397Sobrien /* ??? The SGI dwarf reader fails for multidimensional arrays with a 1047650397Sobrien const enum type. E.g. const enum machine_mode insn_operand_mode[2][10]. 1047750397Sobrien We work around this by disabling this feature. See also 1047850397Sobrien add_subscript_info. */ 1047950397Sobrien#ifndef MIPS_DEBUGGING_INFO 1048050397Sobrien while (TREE_CODE (element_type) == ARRAY_TYPE) 1048150397Sobrien element_type = TREE_TYPE (element_type); 1048250397Sobrien 1048350397Sobrien gen_type_die (element_type, context_die); 1048450397Sobrien#endif 1048550397Sobrien 1048650397Sobrien add_type_attribute (array_die, element_type, 0, 0, context_die); 1048750397Sobrien} 1048850397Sobrien 1048950397Sobrienstatic void 10490132718Skangen_set_type_die (tree type, dw_die_ref context_die) 1049150397Sobrien{ 1049290075Sobrien dw_die_ref type_die 1049390075Sobrien = new_die (DW_TAG_set_type, scope_die_for (type, context_die), type); 1049450397Sobrien 1049550397Sobrien equate_type_number_to_die (type, type_die); 1049650397Sobrien add_type_attribute (type_die, TREE_TYPE (type), 0, 0, context_die); 1049750397Sobrien} 1049850397Sobrien 1049950397Sobrien#if 0 1050050397Sobrienstatic void 10501132718Skangen_entry_point_die (tree decl, dw_die_ref context_die) 1050250397Sobrien{ 1050390075Sobrien tree origin = decl_ultimate_origin (decl); 1050490075Sobrien dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl); 1050590075Sobrien 1050650397Sobrien if (origin != NULL) 1050750397Sobrien add_abstract_origin_attribute (decl_die, origin); 1050850397Sobrien else 1050950397Sobrien { 1051050397Sobrien add_name_and_src_coords_attributes (decl_die, decl); 1051150397Sobrien add_type_attribute (decl_die, TREE_TYPE (TREE_TYPE (decl)), 1051250397Sobrien 0, 0, context_die); 1051350397Sobrien } 1051450397Sobrien 1051550397Sobrien if (DECL_ABSTRACT (decl)) 1051650397Sobrien equate_decl_number_to_die (decl, decl_die); 1051750397Sobrien else 1051850397Sobrien add_AT_lbl_id (decl_die, DW_AT_low_pc, decl_start_label (decl)); 1051950397Sobrien} 1052050397Sobrien#endif 1052150397Sobrien 1052252284Sobrien/* Walk through the list of incomplete types again, trying once more to 1052352284Sobrien emit full debugging info for them. */ 1052452284Sobrien 1052552284Sobrienstatic void 10526132718Skanretry_incomplete_types (void) 1052752284Sobrien{ 1052890075Sobrien int i; 1052952284Sobrien 1053090075Sobrien for (i = VARRAY_ACTIVE_SIZE (incomplete_types) - 1; i >= 0; i--) 1053190075Sobrien gen_type_die (VARRAY_TREE (incomplete_types, i), comp_unit_die); 1053252284Sobrien} 1053352284Sobrien 1053450397Sobrien/* Generate a DIE to represent an inlined instance of an enumeration type. */ 1053550397Sobrien 1053650397Sobrienstatic void 10537132718Skangen_inlined_enumeration_type_die (tree type, dw_die_ref context_die) 1053850397Sobrien{ 1053990075Sobrien dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die, type); 1054050397Sobrien 1054190075Sobrien /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may 1054290075Sobrien be incomplete and such types are not marked. */ 1054350397Sobrien add_abstract_origin_attribute (type_die, type); 1054450397Sobrien} 1054550397Sobrien 1054650397Sobrien/* Generate a DIE to represent an inlined instance of a structure type. */ 1054750397Sobrien 1054850397Sobrienstatic void 10549132718Skangen_inlined_structure_type_die (tree type, dw_die_ref context_die) 1055050397Sobrien{ 1055190075Sobrien dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die, type); 1055250397Sobrien 1055390075Sobrien /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may 1055490075Sobrien be incomplete and such types are not marked. */ 1055550397Sobrien add_abstract_origin_attribute (type_die, type); 1055650397Sobrien} 1055750397Sobrien 1055850397Sobrien/* Generate a DIE to represent an inlined instance of a union type. */ 1055950397Sobrien 1056050397Sobrienstatic void 10561132718Skangen_inlined_union_type_die (tree type, dw_die_ref context_die) 1056250397Sobrien{ 1056390075Sobrien dw_die_ref type_die = new_die (DW_TAG_union_type, context_die, type); 1056450397Sobrien 1056590075Sobrien /* We do not check for TREE_ASM_WRITTEN (type) being set, as the type may 1056690075Sobrien be incomplete and such types are not marked. */ 1056750397Sobrien add_abstract_origin_attribute (type_die, type); 1056850397Sobrien} 1056950397Sobrien 1057050397Sobrien/* Generate a DIE to represent an enumeration type. Note that these DIEs 1057150397Sobrien include all of the information about the enumeration values also. Each 1057250397Sobrien enumerated type name/value is listed as a child of the enumerated type 1057350397Sobrien DIE. */ 1057450397Sobrien 10575132718Skanstatic dw_die_ref 10576132718Skangen_enumeration_type_die (tree type, dw_die_ref context_die) 1057750397Sobrien{ 1057890075Sobrien dw_die_ref type_die = lookup_type_die (type); 1057950397Sobrien 1058050397Sobrien if (type_die == NULL) 1058150397Sobrien { 1058250397Sobrien type_die = new_die (DW_TAG_enumeration_type, 1058390075Sobrien scope_die_for (type, context_die), type); 1058450397Sobrien equate_type_number_to_die (type, type_die); 1058550397Sobrien add_name_attribute (type_die, type_tag (type)); 1058650397Sobrien } 1058750397Sobrien else if (! TYPE_SIZE (type)) 10588132718Skan return type_die; 1058950397Sobrien else 1059050397Sobrien remove_AT (type_die, DW_AT_declaration); 1059150397Sobrien 1059250397Sobrien /* Handle a GNU C/C++ extension, i.e. incomplete enum types. If the 1059350397Sobrien given enum type is incomplete, do not generate the DW_AT_byte_size 1059450397Sobrien attribute or the DW_AT_element_list attribute. */ 1059550397Sobrien if (TYPE_SIZE (type)) 1059650397Sobrien { 1059790075Sobrien tree link; 1059850397Sobrien 1059950397Sobrien TREE_ASM_WRITTEN (type) = 1; 1060050397Sobrien add_byte_size_attribute (type_die, type); 1060150397Sobrien if (TYPE_STUB_DECL (type) != NULL_TREE) 1060250397Sobrien add_src_coords_attributes (type_die, TYPE_STUB_DECL (type)); 1060350397Sobrien 1060450397Sobrien /* If the first reference to this type was as the return type of an 1060550397Sobrien inline function, then it may not have a parent. Fix this now. */ 1060650397Sobrien if (type_die->die_parent == NULL) 1060750397Sobrien add_child_die (scope_die_for (type, context_die), type_die); 1060850397Sobrien 1060950397Sobrien for (link = TYPE_FIELDS (type); 1061050397Sobrien link != NULL; link = TREE_CHAIN (link)) 1061150397Sobrien { 1061290075Sobrien dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link); 10613132718Skan tree value = TREE_VALUE (link); 1061450397Sobrien 1061550397Sobrien add_name_attribute (enum_die, 1061650397Sobrien IDENTIFIER_POINTER (TREE_PURPOSE (link))); 1061790075Sobrien 10618132718Skan if (host_integerp (value, TREE_UNSIGNED (TREE_TYPE (value)))) 10619132718Skan /* DWARF2 does not provide a way of indicating whether or 10620132718Skan not enumeration constants are signed or unsigned. GDB 10621132718Skan always assumes the values are signed, so we output all 10622132718Skan values as if they were signed. That means that 10623132718Skan enumeration constants with very large unsigned values 10624132718Skan will appear to have negative values in the debugger. */ 10625132718Skan add_AT_int (enum_die, DW_AT_const_value, 10626132718Skan tree_low_cst (value, tree_int_cst_sgn (value) > 0)); 1062750397Sobrien } 1062850397Sobrien } 1062950397Sobrien else 1063050397Sobrien add_AT_flag (type_die, DW_AT_declaration, 1); 10631132718Skan 10632132718Skan return type_die; 1063350397Sobrien} 1063450397Sobrien 1063550397Sobrien/* Generate a DIE to represent either a real live formal parameter decl or to 1063650397Sobrien represent just the type of some formal parameter position in some function 1063750397Sobrien type. 1063850397Sobrien 1063950397Sobrien Note that this routine is a bit unusual because its argument may be a 1064050397Sobrien ..._DECL node (i.e. either a PARM_DECL or perhaps a VAR_DECL which 1064150397Sobrien represents an inlining of some PARM_DECL) or else some sort of a ..._TYPE 1064250397Sobrien node. If it's the former then this function is being called to output a 1064350397Sobrien DIE to represent a formal parameter object (or some inlining thereof). If 1064450397Sobrien it's the latter, then this function is only being called to output a 1064550397Sobrien DW_TAG_formal_parameter DIE to stand as a placeholder for some formal 1064650397Sobrien argument type of some subprogram type. */ 1064750397Sobrien 1064850397Sobrienstatic dw_die_ref 10649132718Skangen_formal_parameter_die (tree node, dw_die_ref context_die) 1065050397Sobrien{ 1065190075Sobrien dw_die_ref parm_die 1065290075Sobrien = new_die (DW_TAG_formal_parameter, context_die, node); 1065390075Sobrien tree origin; 1065450397Sobrien 1065550397Sobrien switch (TREE_CODE_CLASS (TREE_CODE (node))) 1065650397Sobrien { 1065750397Sobrien case 'd': 1065850397Sobrien origin = decl_ultimate_origin (node); 1065950397Sobrien if (origin != NULL) 1066050397Sobrien add_abstract_origin_attribute (parm_die, origin); 1066150397Sobrien else 1066250397Sobrien { 1066350397Sobrien add_name_and_src_coords_attributes (parm_die, node); 1066450397Sobrien add_type_attribute (parm_die, TREE_TYPE (node), 1066550397Sobrien TREE_READONLY (node), 1066650397Sobrien TREE_THIS_VOLATILE (node), 1066750397Sobrien context_die); 1066850397Sobrien if (DECL_ARTIFICIAL (node)) 1066950397Sobrien add_AT_flag (parm_die, DW_AT_artificial, 1); 1067050397Sobrien } 1067150397Sobrien 1067250397Sobrien equate_decl_number_to_die (node, parm_die); 1067350397Sobrien if (! DECL_ABSTRACT (node)) 1067450397Sobrien add_location_or_const_value_attribute (parm_die, node); 1067550397Sobrien 1067650397Sobrien break; 1067750397Sobrien 1067850397Sobrien case 't': 1067950397Sobrien /* We were called with some kind of a ..._TYPE node. */ 1068050397Sobrien add_type_attribute (parm_die, node, 0, 0, context_die); 1068150397Sobrien break; 1068250397Sobrien 1068350397Sobrien default: 1068450397Sobrien abort (); 1068550397Sobrien } 1068650397Sobrien 1068750397Sobrien return parm_die; 1068850397Sobrien} 1068950397Sobrien 1069050397Sobrien/* Generate a special type of DIE used as a stand-in for a trailing ellipsis 1069150397Sobrien at the end of an (ANSI prototyped) formal parameters list. */ 1069250397Sobrien 1069350397Sobrienstatic void 10694132718Skangen_unspecified_parameters_die (tree decl_or_type, dw_die_ref context_die) 1069550397Sobrien{ 1069690075Sobrien new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type); 1069750397Sobrien} 1069850397Sobrien 1069950397Sobrien/* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a 1070050397Sobrien DW_TAG_unspecified_parameters DIE) to represent the types of the formal 1070150397Sobrien parameters as specified in some function type specification (except for 1070290075Sobrien those which appear as part of a function *definition*). */ 1070350397Sobrien 1070450397Sobrienstatic void 10705132718Skangen_formal_types_die (tree function_or_method_type, dw_die_ref context_die) 1070650397Sobrien{ 1070790075Sobrien tree link; 1070890075Sobrien tree formal_type = NULL; 1070990075Sobrien tree first_parm_type; 1071090075Sobrien tree arg; 1071150397Sobrien 1071290075Sobrien if (TREE_CODE (function_or_method_type) == FUNCTION_DECL) 1071390075Sobrien { 1071490075Sobrien arg = DECL_ARGUMENTS (function_or_method_type); 1071590075Sobrien function_or_method_type = TREE_TYPE (function_or_method_type); 1071690075Sobrien } 1071790075Sobrien else 1071890075Sobrien arg = NULL_TREE; 10719117395Skan 1072090075Sobrien first_parm_type = TYPE_ARG_TYPES (function_or_method_type); 1072150397Sobrien 1072290075Sobrien /* Make our first pass over the list of formal parameter types and output a 1072350397Sobrien DW_TAG_formal_parameter DIE for each one. */ 1072490075Sobrien for (link = first_parm_type; link; ) 1072550397Sobrien { 1072690075Sobrien dw_die_ref parm_die; 1072790075Sobrien 1072850397Sobrien formal_type = TREE_VALUE (link); 1072950397Sobrien if (formal_type == void_type_node) 1073050397Sobrien break; 1073150397Sobrien 1073250397Sobrien /* Output a (nameless) DIE to represent the formal parameter itself. */ 1073350397Sobrien parm_die = gen_formal_parameter_die (formal_type, context_die); 1073490075Sobrien if ((TREE_CODE (function_or_method_type) == METHOD_TYPE 1073590075Sobrien && link == first_parm_type) 1073690075Sobrien || (arg && DECL_ARTIFICIAL (arg))) 1073750397Sobrien add_AT_flag (parm_die, DW_AT_artificial, 1); 1073890075Sobrien 1073990075Sobrien link = TREE_CHAIN (link); 1074090075Sobrien if (arg) 1074190075Sobrien arg = TREE_CHAIN (arg); 1074250397Sobrien } 1074350397Sobrien 1074450397Sobrien /* If this function type has an ellipsis, add a 1074550397Sobrien DW_TAG_unspecified_parameters DIE to the end of the parameter list. */ 1074650397Sobrien if (formal_type != void_type_node) 1074750397Sobrien gen_unspecified_parameters_die (function_or_method_type, context_die); 1074850397Sobrien 1074990075Sobrien /* Make our second (and final) pass over the list of formal parameter types 1075050397Sobrien and output DIEs to represent those types (as necessary). */ 1075150397Sobrien for (link = TYPE_ARG_TYPES (function_or_method_type); 1075290075Sobrien link && TREE_VALUE (link); 1075350397Sobrien link = TREE_CHAIN (link)) 1075490075Sobrien gen_type_die (TREE_VALUE (link), context_die); 1075590075Sobrien} 1075690075Sobrien 1075790075Sobrien/* We want to generate the DIE for TYPE so that we can generate the 1075890075Sobrien die for MEMBER, which has been defined; we will need to refer back 1075990075Sobrien to the member declaration nested within TYPE. If we're trying to 1076090075Sobrien generate minimal debug info for TYPE, processing TYPE won't do the 1076190075Sobrien trick; we need to attach the member declaration by hand. */ 1076290075Sobrien 1076390075Sobrienstatic void 10764132718Skangen_type_die_for_member (tree type, tree member, dw_die_ref context_die) 1076590075Sobrien{ 1076690075Sobrien gen_type_die (type, context_die); 1076790075Sobrien 1076890075Sobrien /* If we're trying to avoid duplicate debug info, we may not have 1076990075Sobrien emitted the member decl for this function. Emit it now. */ 1077090075Sobrien if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) 1077190075Sobrien && ! lookup_decl_die (member)) 1077250397Sobrien { 1077390075Sobrien if (decl_ultimate_origin (member)) 1077490075Sobrien abort (); 1077550397Sobrien 1077690075Sobrien push_decl_scope (type); 1077790075Sobrien if (TREE_CODE (member) == FUNCTION_DECL) 1077890075Sobrien gen_subprogram_die (member, lookup_type_die (type)); 1077990075Sobrien else 1078090075Sobrien gen_variable_die (member, lookup_type_die (type)); 1078190075Sobrien 1078290075Sobrien pop_decl_scope (); 1078350397Sobrien } 1078450397Sobrien} 1078550397Sobrien 1078690075Sobrien/* Generate the DWARF2 info for the "abstract" instance of a function which we 1078790075Sobrien may later generate inlined and/or out-of-line instances of. */ 1078890075Sobrien 1078990075Sobrienstatic void 10790132718Skandwarf2out_abstract_function (tree decl) 1079190075Sobrien{ 1079290075Sobrien dw_die_ref old_die; 1079390075Sobrien tree save_fn; 1079490075Sobrien tree context; 1079590075Sobrien int was_abstract = DECL_ABSTRACT (decl); 1079690075Sobrien 1079790075Sobrien /* Make sure we have the actual abstract inline, not a clone. */ 1079890075Sobrien decl = DECL_ORIGIN (decl); 1079990075Sobrien 10800117395Skan old_die = lookup_decl_die (decl); 10801132718Skan if (old_die && get_AT (old_die, DW_AT_inline)) 1080290075Sobrien /* We've already generated the abstract instance. */ 1080390075Sobrien return; 1080490075Sobrien 1080590075Sobrien /* Be sure we've emitted the in-class declaration DIE (if any) first, so 1080690075Sobrien we don't get confused by DECL_ABSTRACT. */ 1080790075Sobrien if (debug_info_level > DINFO_LEVEL_TERSE) 1080890075Sobrien { 1080990075Sobrien context = decl_class_context (decl); 1081090075Sobrien if (context) 1081190075Sobrien gen_type_die_for_member 1081290075Sobrien (context, decl, decl_function_context (decl) ? NULL : comp_unit_die); 1081390075Sobrien } 10814117395Skan 1081590075Sobrien /* Pretend we've just finished compiling this function. */ 1081690075Sobrien save_fn = current_function_decl; 1081790075Sobrien current_function_decl = decl; 1081890075Sobrien 1081990075Sobrien set_decl_abstract_flags (decl, 1); 1082090075Sobrien dwarf2out_decl (decl); 1082190075Sobrien if (! was_abstract) 1082290075Sobrien set_decl_abstract_flags (decl, 0); 1082390075Sobrien 1082490075Sobrien current_function_decl = save_fn; 1082590075Sobrien} 1082690075Sobrien 1082750397Sobrien/* Generate a DIE to represent a declared function (either file-scope or 1082850397Sobrien block-local). */ 1082950397Sobrien 1083050397Sobrienstatic void 10831132718Skangen_subprogram_die (tree decl, dw_die_ref context_die) 1083250397Sobrien{ 1083350397Sobrien char label_id[MAX_ARTIFICIAL_LABEL_BYTES]; 1083490075Sobrien tree origin = decl_ultimate_origin (decl); 1083590075Sobrien dw_die_ref subr_die; 1083690075Sobrien rtx fp_reg; 1083790075Sobrien tree fn_arg_types; 1083890075Sobrien tree outer_scope; 1083990075Sobrien dw_die_ref old_die = lookup_decl_die (decl); 1084090075Sobrien int declaration = (current_function_decl != decl 10841132718Skan || class_or_namespace_scope_p (context_die)); 1084250397Sobrien 1084390075Sobrien /* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we 1084490075Sobrien started to generate the abstract instance of an inline, decided to output 1084590075Sobrien its containing class, and proceeded to emit the declaration of the inline 1084690075Sobrien from the member list for the class. If so, DECLARATION takes priority; 1084790075Sobrien we'll get back to the abstract instance when done with the class. */ 1084890075Sobrien 1084990075Sobrien /* The class-scope declaration DIE must be the primary DIE. */ 10850132718Skan if (origin && declaration && class_or_namespace_scope_p (context_die)) 1085150397Sobrien { 1085290075Sobrien origin = NULL; 1085390075Sobrien if (old_die) 1085490075Sobrien abort (); 1085550397Sobrien } 1085690075Sobrien 1085790075Sobrien if (origin != NULL) 1085850397Sobrien { 1085990075Sobrien if (declaration && ! local_scope_p (context_die)) 1086090075Sobrien abort (); 1086150397Sobrien 1086290075Sobrien /* Fixup die_parent for the abstract instance of a nested 1086390075Sobrien inline function. */ 1086490075Sobrien if (old_die && old_die->die_parent == NULL) 1086590075Sobrien add_child_die (context_die, old_die); 1086690075Sobrien 1086790075Sobrien subr_die = new_die (DW_TAG_subprogram, context_die, decl); 1086890075Sobrien add_abstract_origin_attribute (subr_die, origin); 1086950397Sobrien } 1087050397Sobrien else if (old_die) 1087150397Sobrien { 1087290075Sobrien unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl)); 1087350397Sobrien 1087490075Sobrien if (!get_AT_flag (old_die, DW_AT_declaration) 1087590075Sobrien /* We can have a normal definition following an inline one in the 1087690075Sobrien case of redefinition of GNU C extern inlines. 1087790075Sobrien It seems reasonable to use AT_specification in this case. */ 10878132718Skan && !get_AT (old_die, DW_AT_inline)) 1087952284Sobrien { 1088052284Sobrien /* ??? This can happen if there is a bug in the program, for 1088152284Sobrien instance, if it has duplicate function definitions. Ideally, 1088252284Sobrien we should detect this case and ignore it. For now, if we have 1088352284Sobrien already reported an error, any error at all, then assume that 1088490075Sobrien we got here because of an input error, not a dwarf2 bug. */ 1088552284Sobrien if (errorcount) 1088652284Sobrien return; 1088752284Sobrien abort (); 1088852284Sobrien } 1088950397Sobrien 1089050397Sobrien /* If the definition comes from the same place as the declaration, 1089150397Sobrien maybe use the old DIE. We always want the DIE for this function 1089250397Sobrien that has the *_pc attributes to be under comp_unit_die so the 1089390075Sobrien debugger can find it. We also need to do this for abstract 1089490075Sobrien instances of inlines, since the spec requires the out-of-line copy 1089590075Sobrien to have the same parent. For local class methods, this doesn't 1089690075Sobrien apply; we just use the old DIE. */ 1089790075Sobrien if ((old_die->die_parent == comp_unit_die || context_die == NULL) 1089890075Sobrien && (DECL_ARTIFICIAL (decl) 1089990075Sobrien || (get_AT_unsigned (old_die, DW_AT_decl_file) == file_index 1090090075Sobrien && (get_AT_unsigned (old_die, DW_AT_decl_line) 1090190075Sobrien == (unsigned) DECL_SOURCE_LINE (decl))))) 1090250397Sobrien { 1090350397Sobrien subr_die = old_die; 1090450397Sobrien 10905146895Skan /* Clear out the declaration attribute and the formal parameters. */ 1090650397Sobrien remove_AT (subr_die, DW_AT_declaration); 10907146895Skan remove_child_TAG (subr_die, DW_TAG_formal_parameter); 1090850397Sobrien } 1090950397Sobrien else 1091050397Sobrien { 1091190075Sobrien subr_die = new_die (DW_TAG_subprogram, context_die, decl); 10912132718Skan add_AT_specification (subr_die, old_die); 1091350397Sobrien if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index) 1091450397Sobrien add_AT_unsigned (subr_die, DW_AT_decl_file, file_index); 1091550397Sobrien if (get_AT_unsigned (old_die, DW_AT_decl_line) 1091690075Sobrien != (unsigned) DECL_SOURCE_LINE (decl)) 1091750397Sobrien add_AT_unsigned 1091850397Sobrien (subr_die, DW_AT_decl_line, DECL_SOURCE_LINE (decl)); 1091950397Sobrien } 1092050397Sobrien } 1092150397Sobrien else 1092250397Sobrien { 1092390075Sobrien subr_die = new_die (DW_TAG_subprogram, context_die, decl); 1092450397Sobrien 1092550397Sobrien if (TREE_PUBLIC (decl)) 1092650397Sobrien add_AT_flag (subr_die, DW_AT_external, 1); 1092750397Sobrien 1092850397Sobrien add_name_and_src_coords_attributes (subr_die, decl); 1092950397Sobrien if (debug_info_level > DINFO_LEVEL_TERSE) 1093050397Sobrien { 1093190075Sobrien add_prototyped_attribute (subr_die, TREE_TYPE (decl)); 1093290075Sobrien add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), 1093390075Sobrien 0, 0, context_die); 1093450397Sobrien } 1093550397Sobrien 1093650397Sobrien add_pure_or_virtual_attribute (subr_die, decl); 1093750397Sobrien if (DECL_ARTIFICIAL (decl)) 1093850397Sobrien add_AT_flag (subr_die, DW_AT_artificial, 1); 1093990075Sobrien 1094050397Sobrien if (TREE_PROTECTED (decl)) 1094150397Sobrien add_AT_unsigned (subr_die, DW_AT_accessibility, DW_ACCESS_protected); 1094250397Sobrien else if (TREE_PRIVATE (decl)) 1094350397Sobrien add_AT_unsigned (subr_die, DW_AT_accessibility, DW_ACCESS_private); 1094450397Sobrien } 1094550397Sobrien 1094650397Sobrien if (declaration) 1094750397Sobrien { 10948132718Skan if (!old_die || !get_AT (old_die, DW_AT_inline)) 1094990075Sobrien { 1095090075Sobrien add_AT_flag (subr_die, DW_AT_declaration, 1); 1095150397Sobrien 1095290075Sobrien /* The first time we see a member function, it is in the context of 1095390075Sobrien the class to which it belongs. We make sure of this by emitting 1095490075Sobrien the class first. The next time is the definition, which is 1095590075Sobrien handled above. The two may come from the same source text. */ 1095690075Sobrien if (DECL_CONTEXT (decl) || DECL_ABSTRACT (decl)) 1095790075Sobrien equate_decl_number_to_die (decl, subr_die); 1095890075Sobrien } 1095950397Sobrien } 1096050397Sobrien else if (DECL_ABSTRACT (decl)) 1096150397Sobrien { 10962132718Skan if (DECL_DECLARED_INLINE_P (decl)) 1096350397Sobrien { 10964132718Skan if (cgraph_function_possibly_inlined_p (decl)) 1096550397Sobrien add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined); 1096650397Sobrien else 10967132718Skan add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined); 1096850397Sobrien } 1096950397Sobrien else 10970132718Skan { 10971132718Skan if (cgraph_function_possibly_inlined_p (decl)) 10972132718Skan add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined); 10973132718Skan else 10974132718Skan add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined); 10975132718Skan } 1097650397Sobrien 1097750397Sobrien equate_decl_number_to_die (decl, subr_die); 1097850397Sobrien } 1097950397Sobrien else if (!DECL_EXTERNAL (decl)) 1098050397Sobrien { 10981132718Skan if (!old_die || !get_AT (old_die, DW_AT_inline)) 1098250397Sobrien equate_decl_number_to_die (decl, subr_die); 1098350397Sobrien 1098450397Sobrien ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL, 10985117395Skan current_function_funcdef_no); 1098650397Sobrien add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id); 1098750397Sobrien ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, 10988117395Skan current_function_funcdef_no); 1098950397Sobrien add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id); 1099050397Sobrien 1099150397Sobrien add_pubname (decl, subr_die); 1099250397Sobrien add_arange (decl, subr_die); 1099350397Sobrien 1099450397Sobrien#ifdef MIPS_DEBUGGING_INFO 1099550397Sobrien /* Add a reference to the FDE for this routine. */ 1099650397Sobrien add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, current_funcdef_fde); 1099750397Sobrien#endif 1099850397Sobrien 1099950397Sobrien /* Define the "frame base" location for this routine. We use the 11000132718Skan frame pointer or stack pointer registers, since the RTL for local 11001132718Skan variables is relative to one of them. */ 1100250397Sobrien fp_reg 1100350397Sobrien = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx; 1100450397Sobrien add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg)); 1100550397Sobrien 1100650397Sobrien#if 0 1100750397Sobrien /* ??? This fails for nested inline functions, because context_display 1100850397Sobrien is not part of the state saved/restored for inline functions. */ 1100950397Sobrien if (current_function_needs_context) 1101050397Sobrien add_AT_location_description (subr_die, DW_AT_static_link, 11011117395Skan loc_descriptor (lookup_static_chain (decl))); 1101250397Sobrien#endif 1101350397Sobrien } 1101450397Sobrien 1101550397Sobrien /* Now output descriptions of the arguments for this function. This gets 1101690075Sobrien (unnecessarily?) complex because of the fact that the DECL_ARGUMENT list 1101750397Sobrien for a FUNCTION_DECL doesn't indicate cases where there was a trailing 1101850397Sobrien `...' at the end of the formal parameter list. In order to find out if 1101950397Sobrien there was a trailing ellipsis or not, we must instead look at the type 1102050397Sobrien associated with the FUNCTION_DECL. This will be a node of type 1102150397Sobrien FUNCTION_TYPE. If the chain of type nodes hanging off of this 1102290075Sobrien FUNCTION_TYPE node ends with a void_type_node then there should *not* be 1102350397Sobrien an ellipsis at the end. */ 1102450397Sobrien 1102550397Sobrien /* In the case where we are describing a mere function declaration, all we 1102690075Sobrien need to do here (and all we *can* do here) is to describe the *types* of 1102750397Sobrien its formal parameters. */ 1102850397Sobrien if (debug_info_level <= DINFO_LEVEL_TERSE) 1102950397Sobrien ; 1103050397Sobrien else if (declaration) 1103190075Sobrien gen_formal_types_die (decl, subr_die); 1103250397Sobrien else 1103350397Sobrien { 11034132718Skan /* Generate DIEs to represent all known formal parameters. */ 1103590075Sobrien tree arg_decls = DECL_ARGUMENTS (decl); 1103690075Sobrien tree parm; 1103750397Sobrien 1103850397Sobrien /* When generating DIEs, generate the unspecified_parameters DIE 11039132718Skan instead if we come across the arg "__builtin_va_alist" */ 1104050397Sobrien for (parm = arg_decls; parm; parm = TREE_CHAIN (parm)) 1104150397Sobrien if (TREE_CODE (parm) == PARM_DECL) 1104250397Sobrien { 1104350397Sobrien if (DECL_NAME (parm) 1104450397Sobrien && !strcmp (IDENTIFIER_POINTER (DECL_NAME (parm)), 1104550397Sobrien "__builtin_va_alist")) 1104650397Sobrien gen_unspecified_parameters_die (parm, subr_die); 1104750397Sobrien else 1104850397Sobrien gen_decl_die (parm, subr_die); 1104950397Sobrien } 1105050397Sobrien 1105190075Sobrien /* Decide whether we need an unspecified_parameters DIE at the end. 11052132718Skan There are 2 more cases to do this for: 1) the ansi ... declaration - 11053132718Skan this is detectable when the end of the arg list is not a 11054132718Skan void_type_node 2) an unprototyped function declaration (not a 11055132718Skan definition). This just means that we have no info about the 11056132718Skan parameters at all. */ 1105750397Sobrien fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); 1105850397Sobrien if (fn_arg_types != NULL) 1105950397Sobrien { 11060132718Skan /* This is the prototyped case, check for.... */ 1106150397Sobrien if (TREE_VALUE (tree_last (fn_arg_types)) != void_type_node) 1106250397Sobrien gen_unspecified_parameters_die (decl, subr_die); 1106350397Sobrien } 1106450397Sobrien else if (DECL_INITIAL (decl) == NULL_TREE) 1106550397Sobrien gen_unspecified_parameters_die (decl, subr_die); 1106650397Sobrien } 1106750397Sobrien 1106850397Sobrien /* Output Dwarf info for all of the stuff within the body of the function 1106950397Sobrien (if it has one - it may be just a declaration). */ 1107050397Sobrien outer_scope = DECL_INITIAL (decl); 1107150397Sobrien 1107290075Sobrien /* OUTER_SCOPE is a pointer to the outermost BLOCK node created to represent 1107390075Sobrien a function. This BLOCK actually represents the outermost binding contour 1107490075Sobrien for the function, i.e. the contour in which the function's formal 1107590075Sobrien parameters and labels get declared. Curiously, it appears that the front 1107690075Sobrien end doesn't actually put the PARM_DECL nodes for the current function onto 1107790075Sobrien the BLOCK_VARS list for this outer scope, but are strung off of the 1107890075Sobrien DECL_ARGUMENTS list for the function instead. 1107990075Sobrien 1108090075Sobrien The BLOCK_VARS list for the `outer_scope' does provide us with a list of 1108190075Sobrien the LABEL_DECL nodes for the function however, and we output DWARF info 1108290075Sobrien for those in decls_for_scope. Just within the `outer_scope' there will be 1108390075Sobrien a BLOCK node representing the function's outermost pair of curly braces, 1108490075Sobrien and any blocks used for the base and member initializers of a C++ 1108550397Sobrien constructor function. */ 1108650397Sobrien if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK) 1108750397Sobrien { 1108850397Sobrien current_function_has_inlines = 0; 1108950397Sobrien decls_for_scope (outer_scope, subr_die, 0); 1109050397Sobrien 1109150397Sobrien#if 0 && defined (MIPS_DEBUGGING_INFO) 1109250397Sobrien if (current_function_has_inlines) 1109350397Sobrien { 1109450397Sobrien add_AT_flag (subr_die, DW_AT_MIPS_has_inlines, 1); 1109550397Sobrien if (! comp_unit_has_inlines) 1109650397Sobrien { 1109750397Sobrien add_AT_flag (comp_unit_die, DW_AT_MIPS_has_inlines, 1); 1109850397Sobrien comp_unit_has_inlines = 1; 1109950397Sobrien } 1110050397Sobrien } 1110150397Sobrien#endif 1110250397Sobrien } 1110350397Sobrien} 1110450397Sobrien 1110550397Sobrien/* Generate a DIE to represent a declared data object. */ 1110650397Sobrien 1110750397Sobrienstatic void 11108132718Skangen_variable_die (tree decl, dw_die_ref context_die) 1110950397Sobrien{ 1111090075Sobrien tree origin = decl_ultimate_origin (decl); 1111190075Sobrien dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl); 1111250397Sobrien 1111350397Sobrien dw_die_ref old_die = lookup_decl_die (decl); 1111490075Sobrien int declaration = (DECL_EXTERNAL (decl) 11115132718Skan || class_or_namespace_scope_p (context_die)); 1111650397Sobrien 1111750397Sobrien if (origin != NULL) 1111850397Sobrien add_abstract_origin_attribute (var_die, origin); 1111990075Sobrien 1112050397Sobrien /* Loop unrolling can create multiple blocks that refer to the same 1112190075Sobrien static variable, so we must test for the DW_AT_declaration flag. 1112290075Sobrien 1112390075Sobrien ??? Loop unrolling/reorder_blocks should perhaps be rewritten to 1112450397Sobrien copy decls and set the DECL_ABSTRACT flag on them instead of 1112590075Sobrien sharing them. 1112690075Sobrien 1112790075Sobrien ??? Duplicated blocks have been rewritten to use .debug_ranges. */ 1112850397Sobrien else if (old_die && TREE_STATIC (decl) 11129117395Skan && get_AT_flag (old_die, DW_AT_declaration) == 1) 1113050397Sobrien { 1113190075Sobrien /* This is a definition of a C++ class level static. */ 11132132718Skan add_AT_specification (var_die, old_die); 1113350397Sobrien if (DECL_NAME (decl)) 1113450397Sobrien { 1113590075Sobrien unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl)); 1113650397Sobrien 1113750397Sobrien if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index) 1113850397Sobrien add_AT_unsigned (var_die, DW_AT_decl_file, file_index); 1113950397Sobrien 1114050397Sobrien if (get_AT_unsigned (old_die, DW_AT_decl_line) 1114190075Sobrien != (unsigned) DECL_SOURCE_LINE (decl)) 1114250397Sobrien 1114350397Sobrien add_AT_unsigned (var_die, DW_AT_decl_line, 1114450397Sobrien DECL_SOURCE_LINE (decl)); 1114550397Sobrien } 1114650397Sobrien } 1114750397Sobrien else 1114850397Sobrien { 1114950397Sobrien add_name_and_src_coords_attributes (var_die, decl); 1115090075Sobrien add_type_attribute (var_die, TREE_TYPE (decl), TREE_READONLY (decl), 1115150397Sobrien TREE_THIS_VOLATILE (decl), context_die); 1115250397Sobrien 1115350397Sobrien if (TREE_PUBLIC (decl)) 1115450397Sobrien add_AT_flag (var_die, DW_AT_external, 1); 1115550397Sobrien 1115650397Sobrien if (DECL_ARTIFICIAL (decl)) 1115750397Sobrien add_AT_flag (var_die, DW_AT_artificial, 1); 1115850397Sobrien 1115950397Sobrien if (TREE_PROTECTED (decl)) 1116050397Sobrien add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected); 1116150397Sobrien else if (TREE_PRIVATE (decl)) 1116250397Sobrien add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private); 1116350397Sobrien } 1116450397Sobrien 1116550397Sobrien if (declaration) 1116650397Sobrien add_AT_flag (var_die, DW_AT_declaration, 1); 1116790075Sobrien 11168132718Skan if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl)) 1116950397Sobrien equate_decl_number_to_die (decl, var_die); 1117050397Sobrien 1117150397Sobrien if (! declaration && ! DECL_ABSTRACT (decl)) 1117250397Sobrien { 1117350397Sobrien add_location_or_const_value_attribute (var_die, decl); 1117450397Sobrien add_pubname (decl, var_die); 1117550397Sobrien } 1117690075Sobrien else 1117790075Sobrien tree_add_const_value_attribute (var_die, decl); 1117850397Sobrien} 1117950397Sobrien 1118050397Sobrien/* Generate a DIE to represent a label identifier. */ 1118150397Sobrien 1118250397Sobrienstatic void 11183132718Skangen_label_die (tree decl, dw_die_ref context_die) 1118450397Sobrien{ 1118590075Sobrien tree origin = decl_ultimate_origin (decl); 1118690075Sobrien dw_die_ref lbl_die = new_die (DW_TAG_label, context_die, decl); 1118790075Sobrien rtx insn; 1118850397Sobrien char label[MAX_ARTIFICIAL_LABEL_BYTES]; 1118950397Sobrien 1119050397Sobrien if (origin != NULL) 1119150397Sobrien add_abstract_origin_attribute (lbl_die, origin); 1119250397Sobrien else 1119350397Sobrien add_name_and_src_coords_attributes (lbl_die, decl); 1119450397Sobrien 1119550397Sobrien if (DECL_ABSTRACT (decl)) 1119650397Sobrien equate_decl_number_to_die (decl, lbl_die); 1119750397Sobrien else 1119850397Sobrien { 11199132718Skan insn = DECL_RTL_IF_SET (decl); 1120052284Sobrien 1120152284Sobrien /* Deleted labels are programmer specified labels which have been 11202132718Skan eliminated because of various optimizations. We still emit them 1120352284Sobrien here so that it is possible to put breakpoints on them. */ 11204132718Skan if (insn 11205132718Skan && (GET_CODE (insn) == CODE_LABEL 11206132718Skan || ((GET_CODE (insn) == NOTE 11207132718Skan && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))) 1120850397Sobrien { 1120990075Sobrien /* When optimization is enabled (via -O) some parts of the compiler 1121090075Sobrien (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which 1121150397Sobrien represent source-level labels which were explicitly declared by 1121250397Sobrien the user. This really shouldn't be happening though, so catch 1121350397Sobrien it if it ever does happen. */ 1121450397Sobrien if (INSN_DELETED_P (insn)) 1121550397Sobrien abort (); 1121650397Sobrien 1121790075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (insn)); 1121850397Sobrien add_AT_lbl_id (lbl_die, DW_AT_low_pc, label); 1121950397Sobrien } 1122050397Sobrien } 1122150397Sobrien} 1122250397Sobrien 1122350397Sobrien/* Generate a DIE for a lexical block. */ 1122450397Sobrien 1122550397Sobrienstatic void 11226132718Skangen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth) 1122750397Sobrien{ 1122890075Sobrien dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt); 1122950397Sobrien char label[MAX_ARTIFICIAL_LABEL_BYTES]; 1123050397Sobrien 1123150397Sobrien if (! BLOCK_ABSTRACT (stmt)) 1123250397Sobrien { 1123390075Sobrien if (BLOCK_FRAGMENT_CHAIN (stmt)) 1123490075Sobrien { 1123590075Sobrien tree chain; 1123690075Sobrien 1123790075Sobrien add_AT_range_list (stmt_die, DW_AT_ranges, add_ranges (stmt)); 1123890075Sobrien 1123990075Sobrien chain = BLOCK_FRAGMENT_CHAIN (stmt); 1124090075Sobrien do 1124190075Sobrien { 1124290075Sobrien add_ranges (chain); 1124390075Sobrien chain = BLOCK_FRAGMENT_CHAIN (chain); 1124490075Sobrien } 1124590075Sobrien while (chain); 1124690075Sobrien add_ranges (NULL); 1124790075Sobrien } 1124890075Sobrien else 1124990075Sobrien { 1125090075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, 1125190075Sobrien BLOCK_NUMBER (stmt)); 1125290075Sobrien add_AT_lbl_id (stmt_die, DW_AT_low_pc, label); 1125390075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, 1125490075Sobrien BLOCK_NUMBER (stmt)); 1125590075Sobrien add_AT_lbl_id (stmt_die, DW_AT_high_pc, label); 1125690075Sobrien } 1125750397Sobrien } 1125850397Sobrien 1125950397Sobrien decls_for_scope (stmt, stmt_die, depth); 1126050397Sobrien} 1126150397Sobrien 1126250397Sobrien/* Generate a DIE for an inlined subprogram. */ 1126350397Sobrien 1126450397Sobrienstatic void 11265132718Skangen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth) 1126650397Sobrien{ 11267122180Skan tree decl = block_ultimate_origin (stmt); 11268122180Skan 11269122180Skan /* Emit info for the abstract instance first, if we haven't yet. We 11270122180Skan must emit this even if the block is abstract, otherwise when we 11271122180Skan emit the block below (or elsewhere), we may end up trying to emit 11272122180Skan a die whose origin die hasn't been emitted, and crashing. */ 11273122180Skan dwarf2out_abstract_function (decl); 11274122180Skan 1127550397Sobrien if (! BLOCK_ABSTRACT (stmt)) 1127650397Sobrien { 1127790075Sobrien dw_die_ref subr_die 1127890075Sobrien = new_die (DW_TAG_inlined_subroutine, context_die, stmt); 1127950397Sobrien char label[MAX_ARTIFICIAL_LABEL_BYTES]; 1128050397Sobrien 1128150397Sobrien add_abstract_origin_attribute (subr_die, decl); 1128250397Sobrien ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, 1128390075Sobrien BLOCK_NUMBER (stmt)); 1128450397Sobrien add_AT_lbl_id (subr_die, DW_AT_low_pc, label); 1128590075Sobrien ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, 1128690075Sobrien BLOCK_NUMBER (stmt)); 1128750397Sobrien add_AT_lbl_id (subr_die, DW_AT_high_pc, label); 1128850397Sobrien decls_for_scope (stmt, subr_die, depth); 1128950397Sobrien current_function_has_inlines = 1; 1129050397Sobrien } 1129196263Sobrien else 1129296263Sobrien /* We may get here if we're the outer block of function A that was 1129396263Sobrien inlined into function B that was inlined into function C. When 1129496263Sobrien generating debugging info for C, dwarf2out_abstract_function(B) 1129596263Sobrien would mark all inlined blocks as abstract, including this one. 1129696263Sobrien So, we wouldn't (and shouldn't) expect labels to be generated 1129796263Sobrien for this one. Instead, just emit debugging info for 1129896263Sobrien declarations within the block. This is particularly important 1129996263Sobrien in the case of initializers of arguments passed from B to us: 1130096263Sobrien if they're statement expressions containing declarations, we 1130196263Sobrien wouldn't generate dies for their abstract variables, and then, 1130296263Sobrien when generating dies for the real variables, we'd die (pun 1130396263Sobrien intended :-) */ 1130496263Sobrien gen_lexical_block_die (stmt, context_die, depth); 1130550397Sobrien} 1130650397Sobrien 1130750397Sobrien/* Generate a DIE for a field in a record, or structure. */ 1130850397Sobrien 1130950397Sobrienstatic void 11310132718Skangen_field_die (tree decl, dw_die_ref context_die) 1131150397Sobrien{ 11312117395Skan dw_die_ref decl_die; 1131350397Sobrien 11314117395Skan if (TREE_TYPE (decl) == error_mark_node) 11315117395Skan return; 11316132718Skan 11317117395Skan decl_die = new_die (DW_TAG_member, context_die, decl); 1131850397Sobrien add_name_and_src_coords_attributes (decl_die, decl); 1131950397Sobrien add_type_attribute (decl_die, member_declared_type (decl), 1132050397Sobrien TREE_READONLY (decl), TREE_THIS_VOLATILE (decl), 1132150397Sobrien context_die); 1132250397Sobrien 1132350397Sobrien if (DECL_BIT_FIELD_TYPE (decl)) 1132450397Sobrien { 1132550397Sobrien add_byte_size_attribute (decl_die, decl); 1132650397Sobrien add_bit_size_attribute (decl_die, decl); 1132750397Sobrien add_bit_offset_attribute (decl_die, decl); 1132850397Sobrien } 1132950397Sobrien 1133050397Sobrien if (TREE_CODE (DECL_FIELD_CONTEXT (decl)) != UNION_TYPE) 1133150397Sobrien add_data_member_location_attribute (decl_die, decl); 1133250397Sobrien 1133350397Sobrien if (DECL_ARTIFICIAL (decl)) 1133450397Sobrien add_AT_flag (decl_die, DW_AT_artificial, 1); 1133550397Sobrien 1133650397Sobrien if (TREE_PROTECTED (decl)) 1133750397Sobrien add_AT_unsigned (decl_die, DW_AT_accessibility, DW_ACCESS_protected); 1133850397Sobrien else if (TREE_PRIVATE (decl)) 1133950397Sobrien add_AT_unsigned (decl_die, DW_AT_accessibility, DW_ACCESS_private); 1134050397Sobrien} 1134150397Sobrien 1134250397Sobrien#if 0 1134350397Sobrien/* Don't generate either pointer_type DIEs or reference_type DIEs here. 1134450397Sobrien Use modified_type_die instead. 1134550397Sobrien We keep this code here just in case these types of DIEs may be needed to 1134650397Sobrien represent certain things in other languages (e.g. Pascal) someday. */ 1134790075Sobrien 1134850397Sobrienstatic void 11349132718Skangen_pointer_type_die (tree type, dw_die_ref context_die) 1135050397Sobrien{ 1135190075Sobrien dw_die_ref ptr_die 1135290075Sobrien = new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type); 1135350397Sobrien 1135450397Sobrien equate_type_number_to_die (type, ptr_die); 1135550397Sobrien add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); 1135650397Sobrien add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); 1135750397Sobrien} 1135850397Sobrien 1135950397Sobrien/* Don't generate either pointer_type DIEs or reference_type DIEs here. 1136050397Sobrien Use modified_type_die instead. 1136150397Sobrien We keep this code here just in case these types of DIEs may be needed to 1136250397Sobrien represent certain things in other languages (e.g. Pascal) someday. */ 1136390075Sobrien 1136450397Sobrienstatic void 11365132718Skangen_reference_type_die (tree type, dw_die_ref context_die) 1136650397Sobrien{ 1136790075Sobrien dw_die_ref ref_die 1136890075Sobrien = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type); 1136950397Sobrien 1137050397Sobrien equate_type_number_to_die (type, ref_die); 1137150397Sobrien add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); 1137250397Sobrien add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE); 1137350397Sobrien} 1137450397Sobrien#endif 1137550397Sobrien 1137650397Sobrien/* Generate a DIE for a pointer to a member type. */ 1137790075Sobrien 1137850397Sobrienstatic void 11379132718Skangen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die) 1138050397Sobrien{ 1138190075Sobrien dw_die_ref ptr_die 1138290075Sobrien = new_die (DW_TAG_ptr_to_member_type, 1138390075Sobrien scope_die_for (type, context_die), type); 1138450397Sobrien 1138550397Sobrien equate_type_number_to_die (type, ptr_die); 1138650397Sobrien add_AT_die_ref (ptr_die, DW_AT_containing_type, 1138750397Sobrien lookup_type_die (TYPE_OFFSET_BASETYPE (type))); 1138850397Sobrien add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die); 1138950397Sobrien} 1139050397Sobrien 1139150397Sobrien/* Generate the DIE for the compilation unit. */ 1139250397Sobrien 1139390075Sobrienstatic dw_die_ref 11394132718Skangen_compile_unit_die (const char *filename) 1139550397Sobrien{ 1139690075Sobrien dw_die_ref die; 1139750397Sobrien char producer[250]; 1139890075Sobrien const char *language_string = lang_hooks.name; 1139990075Sobrien int language; 1140050397Sobrien 1140190075Sobrien die = new_die (DW_TAG_compile_unit, NULL, NULL); 1140250397Sobrien 11403132718Skan if (filename) 11404132718Skan { 11405132718Skan add_name_attribute (die, filename); 11406132718Skan /* Don't add cwd for <built-in>. */ 11407132718Skan if (filename[0] != DIR_SEPARATOR && filename[0] != '<') 11408132718Skan add_comp_dir_attribute (die); 11409132718Skan } 1141050397Sobrien 1141150397Sobrien sprintf (producer, "%s %s", language_string, version_string); 1141250397Sobrien 1141350397Sobrien#ifdef MIPS_DEBUGGING_INFO 1141450397Sobrien /* The MIPS/SGI compilers place the 'cc' command line options in the producer 1141550397Sobrien string. The SGI debugger looks for -g, -g1, -g2, or -g3; if they do 1141650397Sobrien not appear in the producer string, the debugger reaches the conclusion 1141750397Sobrien that the object file is stripped and has no debugging information. 1141850397Sobrien To get the MIPS/SGI debugger to believe that there is debugging 1141950397Sobrien information in the object file, we add a -g to the producer string. */ 1142050397Sobrien if (debug_info_level > DINFO_LEVEL_TERSE) 1142150397Sobrien strcat (producer, " -g"); 1142250397Sobrien#endif 1142350397Sobrien 1142490075Sobrien add_AT_string (die, DW_AT_producer, producer); 1142550397Sobrien 1142650397Sobrien if (strcmp (language_string, "GNU C++") == 0) 1142790075Sobrien language = DW_LANG_C_plus_plus; 1142850397Sobrien else if (strcmp (language_string, "GNU Ada") == 0) 11429132718Skan language = DW_LANG_Ada95; 1143050397Sobrien else if (strcmp (language_string, "GNU F77") == 0) 1143190075Sobrien language = DW_LANG_Fortran77; 1143250397Sobrien else if (strcmp (language_string, "GNU Pascal") == 0) 1143390075Sobrien language = DW_LANG_Pascal83; 1143490075Sobrien else if (strcmp (language_string, "GNU Java") == 0) 1143590075Sobrien language = DW_LANG_Java; 1143650397Sobrien else 1143790075Sobrien language = DW_LANG_C89; 1143850397Sobrien 1143990075Sobrien add_AT_unsigned (die, DW_AT_language, language); 1144090075Sobrien return die; 1144150397Sobrien} 1144250397Sobrien 1144350397Sobrien/* Generate a DIE for a string type. */ 1144450397Sobrien 1144550397Sobrienstatic void 11446132718Skangen_string_type_die (tree type, dw_die_ref context_die) 1144750397Sobrien{ 1144890075Sobrien dw_die_ref type_die 1144990075Sobrien = new_die (DW_TAG_string_type, scope_die_for (type, context_die), type); 1145050397Sobrien 1145150397Sobrien equate_type_number_to_die (type, type_die); 1145250397Sobrien 1145390075Sobrien /* ??? Fudge the string length attribute for now. 1145490075Sobrien TODO: add string length info. */ 1145590075Sobrien#if 0 1145690075Sobrien string_length_attribute (TYPE_MAX_VALUE (TYPE_DOMAIN (type))); 1145790075Sobrien bound_representation (upper_bound, 0, 'u'); 1145890075Sobrien#endif 1145950397Sobrien} 1146050397Sobrien 1146150397Sobrien/* Generate the DIE for a base class. */ 1146250397Sobrien 1146350397Sobrienstatic void 11464132718Skangen_inheritance_die (tree binfo, tree access, dw_die_ref context_die) 1146550397Sobrien{ 1146690075Sobrien dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo); 1146750397Sobrien 1146850397Sobrien add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die); 1146950397Sobrien add_data_member_location_attribute (die, binfo); 1147050397Sobrien 1147150397Sobrien if (TREE_VIA_VIRTUAL (binfo)) 1147250397Sobrien add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual); 1147390075Sobrien 11474132718Skan if (access == access_public_node) 1147550397Sobrien add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public); 11476132718Skan else if (access == access_protected_node) 1147750397Sobrien add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected); 1147850397Sobrien} 1147950397Sobrien 1148050397Sobrien/* Generate a DIE for a class member. */ 1148150397Sobrien 1148250397Sobrienstatic void 11483132718Skangen_member_die (tree type, dw_die_ref context_die) 1148450397Sobrien{ 1148590075Sobrien tree member; 11486132718Skan tree binfo = TYPE_BINFO (type); 1148790075Sobrien dw_die_ref child; 1148850397Sobrien 1148950397Sobrien /* If this is not an incomplete type, output descriptions of each of its 1149050397Sobrien members. Note that as we output the DIEs necessary to represent the 1149150397Sobrien members of this record or union type, we will also be trying to output 1149250397Sobrien DIEs to represent the *types* of those members. However the `type' 1149390075Sobrien function (above) will specifically avoid generating type DIEs for member 1149490075Sobrien types *within* the list of member DIEs for this (containing) type except 1149550397Sobrien for those types (of members) which are explicitly marked as also being 1149650397Sobrien members of this (containing) type themselves. The g++ front- end can 1149790075Sobrien force any given type to be treated as a member of some other (containing) 1149890075Sobrien type by setting the TYPE_CONTEXT of the given (member) type to point to 1149990075Sobrien the TREE node representing the appropriate (containing) type. */ 1150050397Sobrien 1150150397Sobrien /* First output info about the base classes. */ 11502132718Skan if (binfo && BINFO_BASETYPES (binfo)) 1150350397Sobrien { 11504132718Skan tree bases = BINFO_BASETYPES (binfo); 11505132718Skan tree accesses = BINFO_BASEACCESSES (binfo); 1150690075Sobrien int n_bases = TREE_VEC_LENGTH (bases); 1150790075Sobrien int i; 1150850397Sobrien 1150950397Sobrien for (i = 0; i < n_bases; i++) 11510132718Skan gen_inheritance_die (TREE_VEC_ELT (bases, i), 11511132718Skan (accesses ? TREE_VEC_ELT (accesses, i) 11512132718Skan : access_public_node), context_die); 1151350397Sobrien } 1151450397Sobrien 1151550397Sobrien /* Now output info about the data members and type members. */ 1151650397Sobrien for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member)) 1151790075Sobrien { 1151890075Sobrien /* If we thought we were generating minimal debug info for TYPE 1151990075Sobrien and then changed our minds, some of the member declarations 1152090075Sobrien may have already been defined. Don't define them again, but 1152190075Sobrien do put them in the right order. */ 1152250397Sobrien 1152390075Sobrien child = lookup_decl_die (member); 1152490075Sobrien if (child) 1152590075Sobrien splice_child_die (context_die, child); 1152690075Sobrien else 1152790075Sobrien gen_decl_die (member, context_die); 1152890075Sobrien } 1152990075Sobrien 1153050397Sobrien /* Now output info about the function members (if any). */ 1153150397Sobrien for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member)) 1153290075Sobrien { 1153390075Sobrien /* Don't include clones in the member list. */ 1153490075Sobrien if (DECL_ABSTRACT_ORIGIN (member)) 1153590075Sobrien continue; 1153690075Sobrien 1153790075Sobrien child = lookup_decl_die (member); 1153890075Sobrien if (child) 1153990075Sobrien splice_child_die (context_die, child); 1154090075Sobrien else 1154190075Sobrien gen_decl_die (member, context_die); 1154290075Sobrien } 1154350397Sobrien} 1154450397Sobrien 1154590075Sobrien/* Generate a DIE for a structure or union type. If TYPE_DECL_SUPPRESS_DEBUG 1154690075Sobrien is set, we pretend that the type was never defined, so we only get the 1154790075Sobrien member DIEs needed by later specification DIEs. */ 1154850397Sobrien 1154950397Sobrienstatic void 11550132718Skangen_struct_or_union_type_die (tree type, dw_die_ref context_die) 1155150397Sobrien{ 1155290075Sobrien dw_die_ref type_die = lookup_type_die (type); 1155390075Sobrien dw_die_ref scope_die = 0; 1155490075Sobrien int nested = 0; 1155590075Sobrien int complete = (TYPE_SIZE (type) 1155690075Sobrien && (! TYPE_STUB_DECL (type) 1155790075Sobrien || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)))); 11558132718Skan int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace); 1155950397Sobrien 1156090075Sobrien if (type_die && ! complete) 1156150397Sobrien return; 1156250397Sobrien 1156350397Sobrien if (TYPE_CONTEXT (type) != NULL_TREE 11564132718Skan && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type)) 11565132718Skan || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL)) 1156650397Sobrien nested = 1; 1156750397Sobrien 1156850397Sobrien scope_die = scope_die_for (type, context_die); 1156950397Sobrien 1157050397Sobrien if (! type_die || (nested && scope_die == comp_unit_die)) 1157150397Sobrien /* First occurrence of type or toplevel definition of nested class. */ 1157250397Sobrien { 1157390075Sobrien dw_die_ref old_die = type_die; 1157450397Sobrien 1157550397Sobrien type_die = new_die (TREE_CODE (type) == RECORD_TYPE 1157650397Sobrien ? DW_TAG_structure_type : DW_TAG_union_type, 1157790075Sobrien scope_die, type); 1157850397Sobrien equate_type_number_to_die (type, type_die); 1157950397Sobrien if (old_die) 11580132718Skan add_AT_specification (type_die, old_die); 1158190075Sobrien else 1158290075Sobrien add_name_attribute (type_die, type_tag (type)); 1158350397Sobrien } 1158450397Sobrien else 1158550397Sobrien remove_AT (type_die, DW_AT_declaration); 1158650397Sobrien 1158750397Sobrien /* If this type has been completed, then give it a byte_size attribute and 1158850397Sobrien then give a list of members. */ 11589132718Skan if (complete && !ns_decl) 1159050397Sobrien { 1159190075Sobrien /* Prevent infinite recursion in cases where the type of some member of 11592132718Skan this type is expressed in terms of this type itself. */ 1159350397Sobrien TREE_ASM_WRITTEN (type) = 1; 1159450397Sobrien add_byte_size_attribute (type_die, type); 1159550397Sobrien if (TYPE_STUB_DECL (type) != NULL_TREE) 1159650397Sobrien add_src_coords_attributes (type_die, TYPE_STUB_DECL (type)); 1159750397Sobrien 1159850397Sobrien /* If the first reference to this type was as the return type of an 1159950397Sobrien inline function, then it may not have a parent. Fix this now. */ 1160050397Sobrien if (type_die->die_parent == NULL) 1160150397Sobrien add_child_die (scope_die, type_die); 1160250397Sobrien 1160350397Sobrien push_decl_scope (type); 1160450397Sobrien gen_member_die (type, type_die); 1160550397Sobrien pop_decl_scope (); 1160650397Sobrien 1160750397Sobrien /* GNU extension: Record what type our vtable lives in. */ 1160850397Sobrien if (TYPE_VFIELD (type)) 1160950397Sobrien { 1161050397Sobrien tree vtype = DECL_FCONTEXT (TYPE_VFIELD (type)); 1161150397Sobrien 1161250397Sobrien gen_type_die (vtype, context_die); 1161350397Sobrien add_AT_die_ref (type_die, DW_AT_containing_type, 1161450397Sobrien lookup_type_die (vtype)); 1161550397Sobrien } 1161650397Sobrien } 1161750397Sobrien else 1161852284Sobrien { 1161952284Sobrien add_AT_flag (type_die, DW_AT_declaration, 1); 1162052284Sobrien 1162190075Sobrien /* We don't need to do this for function-local types. */ 1162290075Sobrien if (TYPE_STUB_DECL (type) 1162390075Sobrien && ! decl_function_context (TYPE_STUB_DECL (type))) 1162490075Sobrien VARRAY_PUSH_TREE (incomplete_types, type); 1162552284Sobrien } 1162650397Sobrien} 1162750397Sobrien 1162850397Sobrien/* Generate a DIE for a subroutine _type_. */ 1162950397Sobrien 1163050397Sobrienstatic void 11631132718Skangen_subroutine_type_die (tree type, dw_die_ref context_die) 1163250397Sobrien{ 1163390075Sobrien tree return_type = TREE_TYPE (type); 1163490075Sobrien dw_die_ref subr_die 1163590075Sobrien = new_die (DW_TAG_subroutine_type, 1163690075Sobrien scope_die_for (type, context_die), type); 1163750397Sobrien 1163850397Sobrien equate_type_number_to_die (type, subr_die); 1163950397Sobrien add_prototyped_attribute (subr_die, type); 1164050397Sobrien add_type_attribute (subr_die, return_type, 0, 0, context_die); 1164150397Sobrien gen_formal_types_die (type, subr_die); 1164250397Sobrien} 1164350397Sobrien 11644132718Skan/* Generate a DIE for a type definition. */ 1164550397Sobrien 1164650397Sobrienstatic void 11647132718Skangen_typedef_die (tree decl, dw_die_ref context_die) 1164850397Sobrien{ 1164990075Sobrien dw_die_ref type_die; 1165090075Sobrien tree origin; 1165150397Sobrien 1165250397Sobrien if (TREE_ASM_WRITTEN (decl)) 1165350397Sobrien return; 1165490075Sobrien 1165550397Sobrien TREE_ASM_WRITTEN (decl) = 1; 1165690075Sobrien type_die = new_die (DW_TAG_typedef, context_die, decl); 1165750397Sobrien origin = decl_ultimate_origin (decl); 1165850397Sobrien if (origin != NULL) 1165950397Sobrien add_abstract_origin_attribute (type_die, origin); 1166050397Sobrien else 1166150397Sobrien { 1166290075Sobrien tree type; 1166390075Sobrien 1166450397Sobrien add_name_and_src_coords_attributes (type_die, decl); 1166550397Sobrien if (DECL_ORIGINAL_TYPE (decl)) 1166650397Sobrien { 1166750397Sobrien type = DECL_ORIGINAL_TYPE (decl); 1166890075Sobrien 1166990075Sobrien if (type == TREE_TYPE (decl)) 1167090075Sobrien abort (); 1167190075Sobrien else 1167290075Sobrien equate_type_number_to_die (TREE_TYPE (decl), type_die); 1167350397Sobrien } 1167450397Sobrien else 1167550397Sobrien type = TREE_TYPE (decl); 1167690075Sobrien 1167750397Sobrien add_type_attribute (type_die, type, TREE_READONLY (decl), 1167850397Sobrien TREE_THIS_VOLATILE (decl), context_die); 1167950397Sobrien } 1168050397Sobrien 1168150397Sobrien if (DECL_ABSTRACT (decl)) 1168250397Sobrien equate_decl_number_to_die (decl, type_die); 1168350397Sobrien} 1168450397Sobrien 1168550397Sobrien/* Generate a type description DIE. */ 1168650397Sobrien 1168750397Sobrienstatic void 11688132718Skangen_type_die (tree type, dw_die_ref context_die) 1168950397Sobrien{ 1169090075Sobrien int need_pop; 1169190075Sobrien 1169250397Sobrien if (type == NULL_TREE || type == error_mark_node) 1169350397Sobrien return; 1169450397Sobrien 1169550397Sobrien if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1169650397Sobrien && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) 1169790075Sobrien { 11698117395Skan if (TREE_ASM_WRITTEN (type)) 11699117395Skan return; 11700117395Skan 11701117395Skan /* Prevent broken recursion; we can't hand off to the same type. */ 11702117395Skan if (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) == type) 11703117395Skan abort (); 11704117395Skan 1170550397Sobrien TREE_ASM_WRITTEN (type) = 1; 1170650397Sobrien gen_decl_die (TYPE_NAME (type), context_die); 1170750397Sobrien return; 1170850397Sobrien } 1170950397Sobrien 11710117395Skan /* We are going to output a DIE to represent the unqualified version 11711117395Skan of this type (i.e. without any const or volatile qualifiers) so 11712117395Skan get the main variant (i.e. the unqualified version) of this type 11713117395Skan now. (Vectors are special because the debugging info is in the 11714117395Skan cloned type itself). */ 11715117395Skan if (TREE_CODE (type) != VECTOR_TYPE) 11716117395Skan type = type_main_variant (type); 11717117395Skan 11718117395Skan if (TREE_ASM_WRITTEN (type)) 11719117395Skan return; 11720117395Skan 1172150397Sobrien switch (TREE_CODE (type)) 1172250397Sobrien { 1172350397Sobrien case ERROR_MARK: 1172450397Sobrien break; 1172550397Sobrien 1172650397Sobrien case POINTER_TYPE: 1172750397Sobrien case REFERENCE_TYPE: 1172850397Sobrien /* We must set TREE_ASM_WRITTEN in case this is a recursive type. This 1172950397Sobrien ensures that the gen_type_die recursion will terminate even if the 1173050397Sobrien type is recursive. Recursive types are possible in Ada. */ 1173150397Sobrien /* ??? We could perhaps do this for all types before the switch 1173250397Sobrien statement. */ 1173350397Sobrien TREE_ASM_WRITTEN (type) = 1; 1173450397Sobrien 1173550397Sobrien /* For these types, all that is required is that we output a DIE (or a 11736132718Skan set of DIEs) to represent the "basis" type. */ 1173750397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1173850397Sobrien break; 1173950397Sobrien 1174050397Sobrien case OFFSET_TYPE: 1174190075Sobrien /* This code is used for C++ pointer-to-data-member types. 1174250397Sobrien Output a description of the relevant class type. */ 1174350397Sobrien gen_type_die (TYPE_OFFSET_BASETYPE (type), context_die); 1174450397Sobrien 1174550397Sobrien /* Output a description of the type of the object pointed to. */ 1174650397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1174750397Sobrien 1174850397Sobrien /* Now output a DIE to represent this pointer-to-data-member type 11749132718Skan itself. */ 1175050397Sobrien gen_ptr_to_mbr_type_die (type, context_die); 1175150397Sobrien break; 1175250397Sobrien 1175350397Sobrien case SET_TYPE: 1175450397Sobrien gen_type_die (TYPE_DOMAIN (type), context_die); 1175550397Sobrien gen_set_type_die (type, context_die); 1175650397Sobrien break; 1175750397Sobrien 1175850397Sobrien case FILE_TYPE: 1175950397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1176050397Sobrien abort (); /* No way to represent these in Dwarf yet! */ 1176150397Sobrien break; 1176250397Sobrien 1176350397Sobrien case FUNCTION_TYPE: 1176450397Sobrien /* Force out return type (in case it wasn't forced out already). */ 1176550397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1176650397Sobrien gen_subroutine_type_die (type, context_die); 1176750397Sobrien break; 1176850397Sobrien 1176950397Sobrien case METHOD_TYPE: 1177050397Sobrien /* Force out return type (in case it wasn't forced out already). */ 1177150397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1177250397Sobrien gen_subroutine_type_die (type, context_die); 1177350397Sobrien break; 1177450397Sobrien 1177550397Sobrien case ARRAY_TYPE: 1177650397Sobrien if (TYPE_STRING_FLAG (type) && TREE_CODE (TREE_TYPE (type)) == CHAR_TYPE) 1177750397Sobrien { 1177850397Sobrien gen_type_die (TREE_TYPE (type), context_die); 1177950397Sobrien gen_string_type_die (type, context_die); 1178050397Sobrien } 1178150397Sobrien else 1178250397Sobrien gen_array_type_die (type, context_die); 1178350397Sobrien break; 1178450397Sobrien 1178590075Sobrien case VECTOR_TYPE: 1178696263Sobrien gen_array_type_die (type, context_die); 1178790075Sobrien break; 1178890075Sobrien 1178950397Sobrien case ENUMERAL_TYPE: 1179050397Sobrien case RECORD_TYPE: 1179150397Sobrien case UNION_TYPE: 1179250397Sobrien case QUAL_UNION_TYPE: 1179390075Sobrien /* If this is a nested type whose containing class hasn't been written 11794132718Skan out yet, writing it out will cover this one, too. This does not apply 11795132718Skan to instantiations of member class templates; they need to be added to 11796132718Skan the containing class as they are generated. FIXME: This hurts the 11797132718Skan idea of combining type decls from multiple TUs, since we can't predict 11798132718Skan what set of template instantiations we'll get. */ 1179950397Sobrien if (TYPE_CONTEXT (type) 1180052284Sobrien && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)) 1180150397Sobrien && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type))) 1180250397Sobrien { 1180350397Sobrien gen_type_die (TYPE_CONTEXT (type), context_die); 1180450397Sobrien 1180590075Sobrien if (TREE_ASM_WRITTEN (type)) 1180650397Sobrien return; 1180750397Sobrien 1180850397Sobrien /* If that failed, attach ourselves to the stub. */ 1180950397Sobrien push_decl_scope (TYPE_CONTEXT (type)); 1181050397Sobrien context_die = lookup_type_die (TYPE_CONTEXT (type)); 1181190075Sobrien need_pop = 1; 1181250397Sobrien } 1181390075Sobrien else 11814132718Skan { 11815132718Skan declare_in_namespace (type, context_die); 11816132718Skan need_pop = 0; 11817132718Skan } 1181850397Sobrien 1181950397Sobrien if (TREE_CODE (type) == ENUMERAL_TYPE) 1182050397Sobrien gen_enumeration_type_die (type, context_die); 1182150397Sobrien else 1182250397Sobrien gen_struct_or_union_type_die (type, context_die); 1182350397Sobrien 1182490075Sobrien if (need_pop) 1182550397Sobrien pop_decl_scope (); 1182650397Sobrien 1182750397Sobrien /* Don't set TREE_ASM_WRITTEN on an incomplete struct; we want to fix 1182850397Sobrien it up if it is ever completed. gen_*_type_die will set it for us 1182950397Sobrien when appropriate. */ 1183050397Sobrien return; 1183150397Sobrien 1183250397Sobrien case VOID_TYPE: 1183350397Sobrien case INTEGER_TYPE: 1183450397Sobrien case REAL_TYPE: 1183550397Sobrien case COMPLEX_TYPE: 1183650397Sobrien case BOOLEAN_TYPE: 1183750397Sobrien case CHAR_TYPE: 1183850397Sobrien /* No DIEs needed for fundamental types. */ 1183950397Sobrien break; 1184050397Sobrien 1184150397Sobrien case LANG_TYPE: 1184250397Sobrien /* No Dwarf representation currently defined. */ 1184350397Sobrien break; 1184450397Sobrien 1184550397Sobrien default: 1184650397Sobrien abort (); 1184750397Sobrien } 1184850397Sobrien 1184950397Sobrien TREE_ASM_WRITTEN (type) = 1; 1185050397Sobrien} 1185150397Sobrien 1185250397Sobrien/* Generate a DIE for a tagged type instantiation. */ 1185350397Sobrien 1185450397Sobrienstatic void 11855132718Skangen_tagged_type_instantiation_die (tree type, dw_die_ref context_die) 1185650397Sobrien{ 1185750397Sobrien if (type == NULL_TREE || type == error_mark_node) 1185850397Sobrien return; 1185950397Sobrien 1186050397Sobrien /* We are going to output a DIE to represent the unqualified version of 1186150397Sobrien this type (i.e. without any const or volatile qualifiers) so make sure 1186250397Sobrien that we have the main variant (i.e. the unqualified version) of this 1186350397Sobrien type now. */ 1186490075Sobrien if (type != type_main_variant (type)) 1186550397Sobrien abort (); 1186650397Sobrien 1186790075Sobrien /* Do not check TREE_ASM_WRITTEN (type) as it may not be set if this is 1186890075Sobrien an instance of an unresolved type. */ 1186990075Sobrien 1187050397Sobrien switch (TREE_CODE (type)) 1187150397Sobrien { 1187250397Sobrien case ERROR_MARK: 1187350397Sobrien break; 1187450397Sobrien 1187550397Sobrien case ENUMERAL_TYPE: 1187650397Sobrien gen_inlined_enumeration_type_die (type, context_die); 1187750397Sobrien break; 1187850397Sobrien 1187950397Sobrien case RECORD_TYPE: 1188050397Sobrien gen_inlined_structure_type_die (type, context_die); 1188150397Sobrien break; 1188250397Sobrien 1188350397Sobrien case UNION_TYPE: 1188450397Sobrien case QUAL_UNION_TYPE: 1188550397Sobrien gen_inlined_union_type_die (type, context_die); 1188650397Sobrien break; 1188750397Sobrien 1188850397Sobrien default: 1188950397Sobrien abort (); 1189050397Sobrien } 1189150397Sobrien} 1189250397Sobrien 1189350397Sobrien/* Generate a DW_TAG_lexical_block DIE followed by DIEs to represent all of the 1189450397Sobrien things which are local to the given block. */ 1189550397Sobrien 1189650397Sobrienstatic void 11897132718Skangen_block_die (tree stmt, dw_die_ref context_die, int depth) 1189850397Sobrien{ 1189990075Sobrien int must_output_die = 0; 1190090075Sobrien tree origin; 1190190075Sobrien tree decl; 1190290075Sobrien enum tree_code origin_code; 1190350397Sobrien 1190450397Sobrien /* Ignore blocks never really used to make RTL. */ 1190590075Sobrien if (stmt == NULL_TREE || !TREE_USED (stmt) 1190690075Sobrien || (!TREE_ASM_WRITTEN (stmt) && !BLOCK_ABSTRACT (stmt))) 1190750397Sobrien return; 1190850397Sobrien 1190990075Sobrien /* If the block is one fragment of a non-contiguous block, do not 1191090075Sobrien process the variables, since they will have been done by the 1191190075Sobrien origin block. Do process subblocks. */ 1191290075Sobrien if (BLOCK_FRAGMENT_ORIGIN (stmt)) 1191390075Sobrien { 1191490075Sobrien tree sub; 1191590075Sobrien 1191690075Sobrien for (sub = BLOCK_SUBBLOCKS (stmt); sub; sub = BLOCK_CHAIN (sub)) 1191790075Sobrien gen_block_die (sub, context_die, depth + 1); 1191890075Sobrien 1191990075Sobrien return; 1192090075Sobrien } 1192190075Sobrien 1192250397Sobrien /* Determine the "ultimate origin" of this block. This block may be an 1192350397Sobrien inlined instance of an inlined instance of inline function, so we have 1192450397Sobrien to trace all of the way back through the origin chain to find out what 1192550397Sobrien sort of node actually served as the original seed for the creation of 1192650397Sobrien the current block. */ 1192750397Sobrien origin = block_ultimate_origin (stmt); 1192850397Sobrien origin_code = (origin != NULL) ? TREE_CODE (origin) : ERROR_MARK; 1192950397Sobrien 1193050397Sobrien /* Determine if we need to output any Dwarf DIEs at all to represent this 1193150397Sobrien block. */ 1193250397Sobrien if (origin_code == FUNCTION_DECL) 1193350397Sobrien /* The outer scopes for inlinings *must* always be represented. We 1193450397Sobrien generate DW_TAG_inlined_subroutine DIEs for them. (See below.) */ 1193550397Sobrien must_output_die = 1; 1193650397Sobrien else 1193750397Sobrien { 1193850397Sobrien /* In the case where the current block represents an inlining of the 11939132718Skan "body block" of an inline function, we must *NOT* output any DIE for 11940132718Skan this block because we have already output a DIE to represent the whole 11941132718Skan inlined function scope and the "body block" of any function doesn't 11942132718Skan really represent a different scope according to ANSI C rules. So we 11943132718Skan check here to make sure that this block does not represent a "body 11944132718Skan block inlining" before trying to set the MUST_OUTPUT_DIE flag. */ 1194550397Sobrien if (! is_body_block (origin ? origin : stmt)) 1194650397Sobrien { 1194750397Sobrien /* Determine if this block directly contains any "significant" 1194850397Sobrien local declarations which we will need to output DIEs for. */ 1194950397Sobrien if (debug_info_level > DINFO_LEVEL_TERSE) 1195050397Sobrien /* We are not in terse mode so *any* local declaration counts 1195150397Sobrien as being a "significant" one. */ 1195250397Sobrien must_output_die = (BLOCK_VARS (stmt) != NULL); 1195350397Sobrien else 1195450397Sobrien /* We are in terse mode, so only local (nested) function 1195550397Sobrien definitions count as "significant" local declarations. */ 1195650397Sobrien for (decl = BLOCK_VARS (stmt); 1195750397Sobrien decl != NULL; decl = TREE_CHAIN (decl)) 1195850397Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 1195950397Sobrien && DECL_INITIAL (decl)) 1196050397Sobrien { 1196150397Sobrien must_output_die = 1; 1196250397Sobrien break; 1196350397Sobrien } 1196450397Sobrien } 1196550397Sobrien } 1196650397Sobrien 1196750397Sobrien /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block 1196850397Sobrien DIE for any block which contains no significant local declarations at 1196950397Sobrien all. Rather, in such cases we just call `decls_for_scope' so that any 1197050397Sobrien needed Dwarf info for any sub-blocks will get properly generated. Note 1197150397Sobrien that in terse mode, our definition of what constitutes a "significant" 1197250397Sobrien local declaration gets restricted to include only inlined function 1197350397Sobrien instances and local (nested) function definitions. */ 1197450397Sobrien if (must_output_die) 1197550397Sobrien { 1197650397Sobrien if (origin_code == FUNCTION_DECL) 1197750397Sobrien gen_inlined_subroutine_die (stmt, context_die, depth); 1197850397Sobrien else 1197950397Sobrien gen_lexical_block_die (stmt, context_die, depth); 1198050397Sobrien } 1198150397Sobrien else 1198250397Sobrien decls_for_scope (stmt, context_die, depth); 1198350397Sobrien} 1198450397Sobrien 1198550397Sobrien/* Generate all of the decls declared within a given scope and (recursively) 1198650397Sobrien all of its sub-blocks. */ 1198750397Sobrien 1198850397Sobrienstatic void 11989132718Skandecls_for_scope (tree stmt, dw_die_ref context_die, int depth) 1199050397Sobrien{ 1199190075Sobrien tree decl; 1199290075Sobrien tree subblocks; 1199350397Sobrien 1199450397Sobrien /* Ignore blocks never really used to make RTL. */ 1199550397Sobrien if (stmt == NULL_TREE || ! TREE_USED (stmt)) 1199650397Sobrien return; 1199750397Sobrien 1199850397Sobrien /* Output the DIEs to represent all of the data objects and typedefs 1199950397Sobrien declared directly within this block but not within any nested 1200050397Sobrien sub-blocks. Also, nested function and tag DIEs have been 1200150397Sobrien generated with a parent of NULL; fix that up now. */ 1200290075Sobrien for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl)) 1200350397Sobrien { 1200490075Sobrien dw_die_ref die; 1200550397Sobrien 1200650397Sobrien if (TREE_CODE (decl) == FUNCTION_DECL) 1200750397Sobrien die = lookup_decl_die (decl); 1200850397Sobrien else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)) 1200950397Sobrien die = lookup_type_die (TREE_TYPE (decl)); 1201050397Sobrien else 1201150397Sobrien die = NULL; 1201250397Sobrien 1201350397Sobrien if (die != NULL && die->die_parent == NULL) 1201450397Sobrien add_child_die (context_die, die); 1201550397Sobrien else 1201650397Sobrien gen_decl_die (decl, context_die); 1201750397Sobrien } 1201850397Sobrien 12019117395Skan /* If we're at -g1, we're not interested in subblocks. */ 12020117395Skan if (debug_info_level <= DINFO_LEVEL_TERSE) 12021117395Skan return; 12022117395Skan 1202350397Sobrien /* Output the DIEs to represent all sub-blocks (and the items declared 1202450397Sobrien therein) of this block. */ 1202550397Sobrien for (subblocks = BLOCK_SUBBLOCKS (stmt); 1202650397Sobrien subblocks != NULL; 1202750397Sobrien subblocks = BLOCK_CHAIN (subblocks)) 1202850397Sobrien gen_block_die (subblocks, context_die, depth + 1); 1202950397Sobrien} 1203050397Sobrien 1203150397Sobrien/* Is this a typedef we can avoid emitting? */ 1203250397Sobrien 1203350397Sobrienstatic inline int 12034132718Skanis_redundant_typedef (tree decl) 1203550397Sobrien{ 1203650397Sobrien if (TYPE_DECL_IS_STUB (decl)) 1203750397Sobrien return 1; 1203850397Sobrien 1203950397Sobrien if (DECL_ARTIFICIAL (decl) 1204050397Sobrien && DECL_CONTEXT (decl) 1204150397Sobrien && is_tagged_type (DECL_CONTEXT (decl)) 1204250397Sobrien && TREE_CODE (TYPE_NAME (DECL_CONTEXT (decl))) == TYPE_DECL 1204350397Sobrien && DECL_NAME (decl) == DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))) 1204450397Sobrien /* Also ignore the artificial member typedef for the class name. */ 1204550397Sobrien return 1; 1204650397Sobrien 1204750397Sobrien return 0; 1204850397Sobrien} 1204950397Sobrien 12050132718Skan/* Returns the DIE for namespace NS or aborts. 12051132718Skan 12052132718Skan Note that namespaces don't really have a lexical context, so there's no 12053132718Skan need to pass in a context_die. They always go inside their containing 12054132718Skan namespace, or comp_unit_die if none. */ 12055132718Skan 12056132718Skanstatic dw_die_ref 12057132718Skanforce_namespace_die (tree ns) 12058132718Skan{ 12059132718Skan dw_die_ref ns_die; 12060132718Skan 12061132718Skan dwarf2out_decl (ns); 12062132718Skan ns_die = lookup_decl_die (ns); 12063132718Skan if (!ns_die) 12064132718Skan abort(); 12065132718Skan 12066132718Skan return ns_die; 12067132718Skan} 12068132718Skan 12069132718Skan/* Force out any required namespaces to be able to output DECL, 12070132718Skan and return the new context_die for it, if it's changed. */ 12071132718Skan 12072132718Skanstatic dw_die_ref 12073132718Skansetup_namespace_context (tree thing, dw_die_ref context_die) 12074132718Skan{ 12075132718Skan tree context = DECL_P (thing) ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing); 12076132718Skan if (context && TREE_CODE (context) == NAMESPACE_DECL) 12077132718Skan /* Force out the namespace. */ 12078132718Skan context_die = force_namespace_die (context); 12079132718Skan 12080132718Skan return context_die; 12081132718Skan} 12082132718Skan 12083132718Skan/* Emit a declaration DIE for THING (which is either a DECL or a tagged 12084132718Skan type) within its namespace, if appropriate. 12085132718Skan 12086132718Skan For compatibility with older debuggers, namespace DIEs only contain 12087132718Skan declarations; all definitions are emitted at CU scope. */ 12088132718Skan 12089132718Skanstatic void 12090132718Skandeclare_in_namespace (tree thing, dw_die_ref context_die) 12091132718Skan{ 12092132718Skan dw_die_ref ns_context; 12093132718Skan 12094132718Skan if (debug_info_level <= DINFO_LEVEL_TERSE) 12095132718Skan return; 12096132718Skan 12097132718Skan ns_context = setup_namespace_context (thing, context_die); 12098132718Skan 12099132718Skan if (ns_context != context_die) 12100132718Skan { 12101132718Skan if (DECL_P (thing)) 12102132718Skan gen_decl_die (thing, ns_context); 12103132718Skan else 12104132718Skan gen_type_die (thing, ns_context); 12105132718Skan } 12106132718Skan} 12107132718Skan 12108132718Skan/* Generate a DIE for a namespace or namespace alias. */ 12109132718Skan 12110132718Skanstatic void 12111132718Skangen_namespace_die (tree decl) 12112132718Skan{ 12113132718Skan dw_die_ref context_die = setup_namespace_context (decl, comp_unit_die); 12114132718Skan 12115132718Skan /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace 12116132718Skan they are an alias of. */ 12117132718Skan if (DECL_ABSTRACT_ORIGIN (decl) == NULL) 12118132718Skan { 12119132718Skan /* Output a real namespace. */ 12120132718Skan dw_die_ref namespace_die 12121132718Skan = new_die (DW_TAG_namespace, context_die, decl); 12122132718Skan add_name_and_src_coords_attributes (namespace_die, decl); 12123132718Skan equate_decl_number_to_die (decl, namespace_die); 12124132718Skan } 12125132718Skan else 12126132718Skan { 12127132718Skan /* Output a namespace alias. */ 12128132718Skan 12129132718Skan /* Force out the namespace we are an alias of, if necessary. */ 12130132718Skan dw_die_ref origin_die 12131132718Skan = force_namespace_die (DECL_ABSTRACT_ORIGIN (decl)); 12132132718Skan 12133132718Skan /* Now create the namespace alias DIE. */ 12134132718Skan dw_die_ref namespace_die 12135132718Skan = new_die (DW_TAG_imported_declaration, context_die, decl); 12136132718Skan add_name_and_src_coords_attributes (namespace_die, decl); 12137132718Skan add_AT_die_ref (namespace_die, DW_AT_import, origin_die); 12138132718Skan equate_decl_number_to_die (decl, namespace_die); 12139132718Skan } 12140132718Skan} 12141132718Skan 1214250397Sobrien/* Generate Dwarf debug information for a decl described by DECL. */ 1214350397Sobrien 1214450397Sobrienstatic void 12145132718Skangen_decl_die (tree decl, dw_die_ref context_die) 1214650397Sobrien{ 1214790075Sobrien tree origin; 1214850397Sobrien 1214990075Sobrien if (DECL_P (decl) && DECL_IGNORED_P (decl)) 1215050397Sobrien return; 1215150397Sobrien 1215250397Sobrien switch (TREE_CODE (decl)) 1215350397Sobrien { 1215490075Sobrien case ERROR_MARK: 1215590075Sobrien break; 1215690075Sobrien 1215750397Sobrien case CONST_DECL: 1215890075Sobrien /* The individual enumerators of an enum type get output when we output 12159132718Skan the Dwarf representation of the relevant enum type itself. */ 1216050397Sobrien break; 1216150397Sobrien 1216250397Sobrien case FUNCTION_DECL: 1216350397Sobrien /* Don't output any DIEs to represent mere function declarations, 1216450397Sobrien unless they are class members or explicit block externs. */ 1216550397Sobrien if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE 1216690075Sobrien && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl))) 1216750397Sobrien break; 1216850397Sobrien 1216990075Sobrien /* If we're emitting a clone, emit info for the abstract instance. */ 1217090075Sobrien if (DECL_ORIGIN (decl) != decl) 1217190075Sobrien dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl)); 1217290075Sobrien 1217390075Sobrien /* If we're emitting an out-of-line copy of an inline function, 1217490075Sobrien emit info for the abstract instance and set up to refer to it. */ 12175132718Skan else if (cgraph_function_possibly_inlined_p (decl) 12176132718Skan && ! DECL_ABSTRACT (decl) 12177132718Skan && ! class_or_namespace_scope_p (context_die) 1217890075Sobrien /* dwarf2out_abstract_function won't emit a die if this is just 1217990075Sobrien a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in 1218090075Sobrien that case, because that works only if we have a die. */ 1218190075Sobrien && DECL_INITIAL (decl) != NULL_TREE) 1218250397Sobrien { 1218390075Sobrien dwarf2out_abstract_function (decl); 1218490075Sobrien set_decl_origin_self (decl); 1218590075Sobrien } 1218690075Sobrien 1218790075Sobrien /* Otherwise we're emitting the primary DIE for this decl. */ 1218890075Sobrien else if (debug_info_level > DINFO_LEVEL_TERSE) 1218990075Sobrien { 1219050397Sobrien /* Before we describe the FUNCTION_DECL itself, make sure that we 1219150397Sobrien have described its return type. */ 1219250397Sobrien gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die); 1219350397Sobrien 1219490075Sobrien /* And its virtual context. */ 1219590075Sobrien if (DECL_VINDEX (decl) != NULL_TREE) 1219690075Sobrien gen_type_die (DECL_CONTEXT (decl), context_die); 1219790075Sobrien 1219850397Sobrien /* And its containing type. */ 1219950397Sobrien origin = decl_class_context (decl); 1220050397Sobrien if (origin != NULL_TREE) 1220190075Sobrien gen_type_die_for_member (origin, decl, context_die); 12202132718Skan 12203132718Skan /* And its containing namespace. */ 12204132718Skan declare_in_namespace (decl, context_die); 1220550397Sobrien } 1220650397Sobrien 1220750397Sobrien /* Now output a DIE to represent the function itself. */ 1220850397Sobrien gen_subprogram_die (decl, context_die); 1220950397Sobrien break; 1221050397Sobrien 1221150397Sobrien case TYPE_DECL: 1221250397Sobrien /* If we are in terse mode, don't generate any DIEs to represent any 12213132718Skan actual typedefs. */ 1221450397Sobrien if (debug_info_level <= DINFO_LEVEL_TERSE) 1221550397Sobrien break; 1221650397Sobrien 1221790075Sobrien /* In the special case of a TYPE_DECL node representing the declaration 12218132718Skan of some type tag, if the given TYPE_DECL is marked as having been 12219132718Skan instantiated from some other (original) TYPE_DECL node (e.g. one which 12220132718Skan was generated within the original definition of an inline function) we 12221132718Skan have to generate a special (abbreviated) DW_TAG_structure_type, 12222132718Skan DW_TAG_union_type, or DW_TAG_enumeration_type DIE here. */ 1222390075Sobrien if (TYPE_DECL_IS_STUB (decl) && decl_ultimate_origin (decl) != NULL_TREE) 1222450397Sobrien { 1222550397Sobrien gen_tagged_type_instantiation_die (TREE_TYPE (decl), context_die); 1222650397Sobrien break; 1222750397Sobrien } 1222850397Sobrien 1222950397Sobrien if (is_redundant_typedef (decl)) 1223050397Sobrien gen_type_die (TREE_TYPE (decl), context_die); 1223150397Sobrien else 1223250397Sobrien /* Output a DIE to represent the typedef itself. */ 1223350397Sobrien gen_typedef_die (decl, context_die); 1223450397Sobrien break; 1223550397Sobrien 1223650397Sobrien case LABEL_DECL: 1223750397Sobrien if (debug_info_level >= DINFO_LEVEL_NORMAL) 1223850397Sobrien gen_label_die (decl, context_die); 1223950397Sobrien break; 1224050397Sobrien 1224150397Sobrien case VAR_DECL: 1224250397Sobrien /* If we are in terse mode, don't generate any DIEs to represent any 12243132718Skan variable declarations or definitions. */ 1224450397Sobrien if (debug_info_level <= DINFO_LEVEL_TERSE) 1224550397Sobrien break; 1224650397Sobrien 1224750397Sobrien /* Output any DIEs that are needed to specify the type of this data 12248132718Skan object. */ 1224950397Sobrien gen_type_die (TREE_TYPE (decl), context_die); 1225050397Sobrien 1225150397Sobrien /* And its containing type. */ 1225250397Sobrien origin = decl_class_context (decl); 1225350397Sobrien if (origin != NULL_TREE) 1225490075Sobrien gen_type_die_for_member (origin, decl, context_die); 1225550397Sobrien 12256132718Skan /* And its containing namespace. */ 12257132718Skan declare_in_namespace (decl, context_die); 12258132718Skan 1225950397Sobrien /* Now output the DIE to represent the data object itself. This gets 12260132718Skan complicated because of the possibility that the VAR_DECL really 12261132718Skan represents an inlined instance of a formal parameter for an inline 12262132718Skan function. */ 1226350397Sobrien origin = decl_ultimate_origin (decl); 1226450397Sobrien if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL) 1226550397Sobrien gen_formal_parameter_die (decl, context_die); 1226650397Sobrien else 1226750397Sobrien gen_variable_die (decl, context_die); 1226850397Sobrien break; 1226950397Sobrien 1227050397Sobrien case FIELD_DECL: 1227190075Sobrien /* Ignore the nameless fields that are used to skip bits but handle C++ 1227290075Sobrien anonymous unions. */ 1227350397Sobrien if (DECL_NAME (decl) != NULL_TREE 1227450397Sobrien || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE) 1227550397Sobrien { 1227650397Sobrien gen_type_die (member_declared_type (decl), context_die); 1227750397Sobrien gen_field_die (decl, context_die); 1227850397Sobrien } 1227950397Sobrien break; 1228050397Sobrien 1228150397Sobrien case PARM_DECL: 1228250397Sobrien gen_type_die (TREE_TYPE (decl), context_die); 1228350397Sobrien gen_formal_parameter_die (decl, context_die); 1228450397Sobrien break; 1228550397Sobrien 1228690075Sobrien case NAMESPACE_DECL: 12287132718Skan gen_namespace_die (decl); 1228890075Sobrien break; 1228990075Sobrien 1229050397Sobrien default: 12291132718Skan if ((int)TREE_CODE (decl) > NUM_TREE_CODES) 12292132718Skan /* Probably some frontend-internal decl. Assume we don't care. */ 12293132718Skan break; 1229450397Sobrien abort (); 1229550397Sobrien } 1229650397Sobrien} 1229750397Sobrien 1229890075Sobrien/* Add Ada "use" clause information for SGI Workshop debugger. */ 1229950397Sobrien 1230050397Sobrienvoid 12301132718Skandwarf2out_add_library_unit_info (const char *filename, const char *context_list) 1230250397Sobrien{ 1230390075Sobrien unsigned int file_index; 1230450397Sobrien 1230590075Sobrien if (filename != NULL) 1230650397Sobrien { 1230790075Sobrien dw_die_ref unit_die = new_die (DW_TAG_module, comp_unit_die, NULL); 1230890075Sobrien tree context_list_decl 1230990075Sobrien = build_decl (LABEL_DECL, get_identifier (context_list), 1231090075Sobrien void_type_node); 1231150397Sobrien 1231290075Sobrien TREE_PUBLIC (context_list_decl) = TRUE; 1231390075Sobrien add_name_attribute (unit_die, context_list); 1231490075Sobrien file_index = lookup_filename (filename); 1231590075Sobrien add_AT_unsigned (unit_die, DW_AT_decl_file, file_index); 1231690075Sobrien add_pubname (context_list_decl, unit_die); 1231750397Sobrien } 1231890075Sobrien} 1231950397Sobrien 1232090075Sobrien/* Output debug information for global decl DECL. Called from toplev.c after 1232190075Sobrien compilation proper has finished. */ 1232290075Sobrien 1232390075Sobrienstatic void 12324132718Skandwarf2out_global_decl (tree decl) 1232590075Sobrien{ 1232690075Sobrien /* Output DWARF2 information for file-scope tentative data object 1232790075Sobrien declarations, file-scope (extern) function declarations (which had no 1232890075Sobrien corresponding body) and file-scope tagged type declarations and 1232990075Sobrien definitions which have not yet been forced out. */ 1233090075Sobrien if (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)) 1233190075Sobrien dwarf2out_decl (decl); 1233290075Sobrien} 1233390075Sobrien 1233490075Sobrien/* Write the debugging output for DECL. */ 1233590075Sobrien 1233690075Sobrienvoid 12337132718Skandwarf2out_decl (tree decl) 1233890075Sobrien{ 1233990075Sobrien dw_die_ref context_die = comp_unit_die; 1234090075Sobrien 1234150397Sobrien switch (TREE_CODE (decl)) 1234250397Sobrien { 1234390075Sobrien case ERROR_MARK: 1234490075Sobrien return; 1234590075Sobrien 1234650397Sobrien case FUNCTION_DECL: 1234750397Sobrien /* What we would really like to do here is to filter out all mere 12348132718Skan file-scope declarations of file-scope functions which are never 12349132718Skan referenced later within this translation unit (and keep all of ones 12350132718Skan that *are* referenced later on) but we aren't clairvoyant, so we have 12351132718Skan no idea which functions will be referenced in the future (i.e. later 12352132718Skan on within the current translation unit). So here we just ignore all 12353132718Skan file-scope function declarations which are not also definitions. If 12354132718Skan and when the debugger needs to know something about these functions, 12355132718Skan it will have to hunt around and find the DWARF information associated 12356132718Skan with the definition of the function. 1235790075Sobrien 1235890075Sobrien We can't just check DECL_EXTERNAL to find out which FUNCTION_DECL 12359132718Skan nodes represent definitions and which ones represent mere 12360132718Skan declarations. We have to check DECL_INITIAL instead. That's because 12361132718Skan the C front-end supports some weird semantics for "extern inline" 12362132718Skan function definitions. These can get inlined within the current 12363132718Skan translation unit (an thus, we need to generate Dwarf info for their 12364132718Skan abstract instances so that the Dwarf info for the concrete inlined 12365132718Skan instances can have something to refer to) but the compiler never 12366132718Skan generates any out-of-lines instances of such things (despite the fact 12367132718Skan that they *are* definitions). 1236890075Sobrien 1236990075Sobrien The important point is that the C front-end marks these "extern 1237090075Sobrien inline" functions as DECL_EXTERNAL, but we need to generate DWARF for 1237190075Sobrien them anyway. Note that the C++ front-end also plays some similar games 1237290075Sobrien for inline function definitions appearing within include files which 1237390075Sobrien also contain `#pragma interface' pragmas. */ 1237450397Sobrien if (DECL_INITIAL (decl) == NULL_TREE) 1237550397Sobrien return; 1237650397Sobrien 1237750397Sobrien /* If we're a nested function, initially use a parent of NULL; if we're 1237850397Sobrien a plain function, this will be fixed up in decls_for_scope. If 1237950397Sobrien we're a method, it will be ignored, since we already have a DIE. */ 12380117395Skan if (decl_function_context (decl) 12381117395Skan /* But if we're in terse mode, we don't care about scope. */ 12382117395Skan && debug_info_level > DINFO_LEVEL_TERSE) 1238350397Sobrien context_die = NULL; 1238450397Sobrien break; 1238550397Sobrien 1238650397Sobrien case VAR_DECL: 1238790075Sobrien /* Ignore this VAR_DECL if it refers to a file-scope extern data object 12388132718Skan declaration and if the declaration was never even referenced from 12389132718Skan within this entire compilation unit. We suppress these DIEs in 12390132718Skan order to save space in the .debug section (by eliminating entries 12391132718Skan which are probably useless). Note that we must not suppress 12392132718Skan block-local extern declarations (whether used or not) because that 12393132718Skan would screw-up the debugger's name lookup mechanism and cause it to 12394132718Skan miss things which really ought to be in scope at a given point. */ 1239550397Sobrien if (DECL_EXTERNAL (decl) && !TREE_USED (decl)) 1239650397Sobrien return; 1239750397Sobrien 1239850397Sobrien /* If we are in terse mode, don't generate any DIEs to represent any 12399132718Skan variable declarations or definitions. */ 1240050397Sobrien if (debug_info_level <= DINFO_LEVEL_TERSE) 1240150397Sobrien return; 1240250397Sobrien break; 1240350397Sobrien 12404132718Skan case NAMESPACE_DECL: 12405132718Skan if (debug_info_level <= DINFO_LEVEL_TERSE) 12406132718Skan return; 12407132718Skan if (lookup_decl_die (decl) != NULL) 12408132718Skan return; 12409132718Skan break; 12410132718Skan 1241150397Sobrien case TYPE_DECL: 1241290075Sobrien /* Don't emit stubs for types unless they are needed by other DIEs. */ 1241390075Sobrien if (TYPE_DECL_SUPPRESS_DEBUG (decl)) 1241490075Sobrien return; 1241590075Sobrien 1241650397Sobrien /* Don't bother trying to generate any DIEs to represent any of the 12417132718Skan normal built-in types for the language we are compiling. */ 1241850397Sobrien if (DECL_SOURCE_LINE (decl) == 0) 1241950397Sobrien { 1242050397Sobrien /* OK, we need to generate one for `bool' so GDB knows what type 12421132718Skan comparisons have. */ 1242250397Sobrien if ((get_AT_unsigned (comp_unit_die, DW_AT_language) 1242350397Sobrien == DW_LANG_C_plus_plus) 1242490075Sobrien && TREE_CODE (TREE_TYPE (decl)) == BOOLEAN_TYPE 1242590075Sobrien && ! DECL_IGNORED_P (decl)) 1242650397Sobrien modified_type_die (TREE_TYPE (decl), 0, 0, NULL); 1242750397Sobrien 1242850397Sobrien return; 1242950397Sobrien } 1243050397Sobrien 1243150397Sobrien /* If we are in terse mode, don't generate any DIEs for types. */ 1243250397Sobrien if (debug_info_level <= DINFO_LEVEL_TERSE) 1243350397Sobrien return; 1243450397Sobrien 1243550397Sobrien /* If we're a function-scope tag, initially use a parent of NULL; 1243650397Sobrien this will be fixed up in decls_for_scope. */ 1243750397Sobrien if (decl_function_context (decl)) 1243850397Sobrien context_die = NULL; 1243950397Sobrien 1244050397Sobrien break; 1244150397Sobrien 1244250397Sobrien default: 1244350397Sobrien return; 1244450397Sobrien } 1244550397Sobrien 1244650397Sobrien gen_decl_die (decl, context_die); 1244750397Sobrien} 1244850397Sobrien 1244950397Sobrien/* Output a marker (i.e. a label) for the beginning of the generated code for 1245050397Sobrien a lexical block. */ 1245150397Sobrien 1245290075Sobrienstatic void 12453132718Skandwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED, 12454132718Skan unsigned int blocknum) 1245550397Sobrien{ 1245650397Sobrien function_section (current_function_decl); 1245790075Sobrien ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum); 1245850397Sobrien} 1245950397Sobrien 1246050397Sobrien/* Output a marker (i.e. a label) for the end of the generated code for a 1246150397Sobrien lexical block. */ 1246250397Sobrien 1246390075Sobrienstatic void 12464132718Skandwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum) 1246550397Sobrien{ 1246650397Sobrien function_section (current_function_decl); 1246790075Sobrien ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum); 1246850397Sobrien} 1246950397Sobrien 1247090075Sobrien/* Returns nonzero if it is appropriate not to emit any debugging 1247190075Sobrien information for BLOCK, because it doesn't contain any instructions. 1247250397Sobrien 1247390075Sobrien Don't allow this for blocks with nested functions or local classes 1247490075Sobrien as we would end up with orphans, and in the presence of scheduling 1247590075Sobrien we may end up calling them anyway. */ 1247690075Sobrien 1247790075Sobrienstatic bool 12478132718Skandwarf2out_ignore_block (tree block) 1247950397Sobrien{ 1248090075Sobrien tree decl; 1248150397Sobrien 1248290075Sobrien for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) 1248390075Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 1248490075Sobrien || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))) 1248590075Sobrien return 0; 1248690075Sobrien 1248790075Sobrien return 1; 1248850397Sobrien} 1248950397Sobrien 1249090075Sobrien/* Lookup FILE_NAME (in the list of filenames that we know about here in 1249150397Sobrien dwarf2out.c) and return its "index". The index of each (known) filename is 1249290075Sobrien just a unique number which is associated with only that one filename. We 1249390075Sobrien need such numbers for the sake of generating labels (in the .debug_sfnames 1249490075Sobrien section) and references to those files numbers (in the .debug_srcinfo 1249590075Sobrien and.debug_macinfo sections). If the filename given as an argument is not 1249690075Sobrien found in our current list, add it to the list and assign it the next 1249790075Sobrien available unique index number. In order to speed up searches, we remember 1249890075Sobrien the index of the filename was looked up last. This handles the majority of 1249990075Sobrien all searches. */ 1250050397Sobrien 1250150397Sobrienstatic unsigned 12502132718Skanlookup_filename (const char *file_name) 1250350397Sobrien{ 12504132718Skan size_t i, n; 12505132718Skan char *save_file_name; 1250650397Sobrien 1250790075Sobrien /* Check to see if the file name that was searched on the previous 1250890075Sobrien call matches this file name. If so, return the index. */ 12509132718Skan if (file_table_last_lookup_index != 0) 12510132718Skan { 12511132718Skan const char *last 12512132718Skan = VARRAY_CHAR_PTR (file_table, file_table_last_lookup_index); 12513132718Skan if (strcmp (file_name, last) == 0) 12514132718Skan return file_table_last_lookup_index; 12515132718Skan } 1251690075Sobrien 1251750397Sobrien /* Didn't match the previous lookup, search the table */ 12518132718Skan n = VARRAY_ACTIVE_SIZE (file_table); 12519132718Skan for (i = 1; i < n; i++) 12520132718Skan if (strcmp (file_name, VARRAY_CHAR_PTR (file_table, i)) == 0) 1252150397Sobrien { 12522132718Skan file_table_last_lookup_index = i; 1252350397Sobrien return i; 1252450397Sobrien } 1252550397Sobrien 1252650397Sobrien /* Add the new entry to the end of the filename table. */ 12527132718Skan file_table_last_lookup_index = n; 12528132718Skan save_file_name = (char *) ggc_strdup (file_name); 12529132718Skan VARRAY_PUSH_CHAR_PTR (file_table, save_file_name); 12530132718Skan VARRAY_PUSH_UINT (file_table_emitted, 0); 1253150397Sobrien 12532132718Skan return i; 12533132718Skan} 12534132718Skan 12535132718Skanstatic int 12536132718Skanmaybe_emit_file (int fileno) 12537132718Skan{ 12538132718Skan if (DWARF2_ASM_LINE_DEBUG_INFO && fileno > 0) 12539117395Skan { 12540132718Skan if (!VARRAY_UINT (file_table_emitted, fileno)) 12541132718Skan { 12542132718Skan VARRAY_UINT (file_table_emitted, fileno) = ++emitcount; 12543132718Skan fprintf (asm_out_file, "\t.file %u ", 12544132718Skan VARRAY_UINT (file_table_emitted, fileno)); 12545132718Skan output_quoted_string (asm_out_file, 12546132718Skan VARRAY_CHAR_PTR (file_table, fileno)); 12547132718Skan fputc ('\n', asm_out_file); 12548132718Skan } 12549132718Skan return VARRAY_UINT (file_table_emitted, fileno); 12550117395Skan } 12551132718Skan else 12552132718Skan return fileno; 1255350397Sobrien} 1255450397Sobrien 1255590075Sobrienstatic void 12556132718Skaninit_file_table (void) 1255790075Sobrien{ 1255890075Sobrien /* Allocate the initial hunk of the file_table. */ 12559132718Skan VARRAY_CHAR_PTR_INIT (file_table, 64, "file_table"); 12560132718Skan VARRAY_UINT_INIT (file_table_emitted, 64, "file_table_emitted"); 1256190075Sobrien 1256290075Sobrien /* Skip the first entry - file numbers begin at 1. */ 12563132718Skan VARRAY_PUSH_CHAR_PTR (file_table, NULL); 12564132718Skan VARRAY_PUSH_UINT (file_table_emitted, 0); 12565132718Skan file_table_last_lookup_index = 0; 1256690075Sobrien} 1256790075Sobrien 1256850397Sobrien/* Output a label to mark the beginning of a source code line entry 1256950397Sobrien and record information relating to this source line, in 1257050397Sobrien 'line_info_table' for later output of the .debug_line section. */ 1257150397Sobrien 1257290075Sobrienstatic void 12573132718Skandwarf2out_source_line (unsigned int line, const char *filename) 1257450397Sobrien{ 12575132718Skan if (debug_info_level >= DINFO_LEVEL_NORMAL 12576132718Skan && line != 0) 1257750397Sobrien { 1257850397Sobrien function_section (current_function_decl); 1257950397Sobrien 1258090075Sobrien /* If requested, emit something human-readable. */ 1258190075Sobrien if (flag_debug_asm) 1258290075Sobrien fprintf (asm_out_file, "\t%s %s:%d\n", ASM_COMMENT_START, 1258390075Sobrien filename, line); 1258490075Sobrien 1258590075Sobrien if (DWARF2_ASM_LINE_DEBUG_INFO) 1258650397Sobrien { 1258790075Sobrien unsigned file_num = lookup_filename (filename); 1258890075Sobrien 12589132718Skan file_num = maybe_emit_file (file_num); 12590132718Skan 1259190075Sobrien /* Emit the .loc directive understood by GNU as. */ 1259290075Sobrien fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line); 1259390075Sobrien 1259490075Sobrien /* Indicate that line number info exists. */ 1259590075Sobrien line_info_table_in_use++; 1259690075Sobrien 1259790075Sobrien /* Indicate that multiple line number tables exist. */ 1259890075Sobrien if (DECL_SECTION_NAME (current_function_decl)) 1259990075Sobrien separate_line_info_table_in_use++; 1260090075Sobrien } 1260190075Sobrien else if (DECL_SECTION_NAME (current_function_decl)) 1260290075Sobrien { 1260390075Sobrien dw_separate_line_info_ref line_info; 12604132718Skan (*targetm.asm_out.internal_label) (asm_out_file, SEPARATE_LINE_CODE_LABEL, 1260550397Sobrien separate_line_info_table_in_use); 1260650397Sobrien 1260750397Sobrien /* expand the line info table if necessary */ 1260850397Sobrien if (separate_line_info_table_in_use 1260950397Sobrien == separate_line_info_table_allocated) 1261050397Sobrien { 1261150397Sobrien separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT; 1261250397Sobrien separate_line_info_table 12613132718Skan = ggc_realloc (separate_line_info_table, 12614132718Skan separate_line_info_table_allocated 12615132718Skan * sizeof (dw_separate_line_info_entry)); 12616132718Skan memset (separate_line_info_table 12617132718Skan + separate_line_info_table_in_use, 12618132718Skan 0, 12619132718Skan (LINE_INFO_TABLE_INCREMENT 12620132718Skan * sizeof (dw_separate_line_info_entry))); 1262150397Sobrien } 1262250397Sobrien 1262350397Sobrien /* Add the new entry at the end of the line_info_table. */ 1262450397Sobrien line_info 1262550397Sobrien = &separate_line_info_table[separate_line_info_table_in_use++]; 1262650397Sobrien line_info->dw_file_num = lookup_filename (filename); 1262750397Sobrien line_info->dw_line_num = line; 12628117395Skan line_info->function = current_function_funcdef_no; 1262950397Sobrien } 1263050397Sobrien else 1263150397Sobrien { 1263290075Sobrien dw_line_info_ref line_info; 1263350397Sobrien 12634132718Skan (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL, 1263550397Sobrien line_info_table_in_use); 1263650397Sobrien 1263750397Sobrien /* Expand the line info table if necessary. */ 1263850397Sobrien if (line_info_table_in_use == line_info_table_allocated) 1263950397Sobrien { 1264050397Sobrien line_info_table_allocated += LINE_INFO_TABLE_INCREMENT; 1264150397Sobrien line_info_table 12642132718Skan = ggc_realloc (line_info_table, 12643132718Skan (line_info_table_allocated 12644132718Skan * sizeof (dw_line_info_entry))); 12645132718Skan memset (line_info_table + line_info_table_in_use, 0, 12646132718Skan LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry)); 1264750397Sobrien } 1264850397Sobrien 1264950397Sobrien /* Add the new entry at the end of the line_info_table. */ 1265050397Sobrien line_info = &line_info_table[line_info_table_in_use++]; 1265150397Sobrien line_info->dw_file_num = lookup_filename (filename); 1265250397Sobrien line_info->dw_line_num = line; 1265350397Sobrien } 1265450397Sobrien } 1265550397Sobrien} 1265650397Sobrien 1265790075Sobrien/* Record the beginning of a new source file. */ 1265850397Sobrien 1265990075Sobrienstatic void 12660132718Skandwarf2out_start_source_file (unsigned int lineno, const char *filename) 1266150397Sobrien{ 12662132718Skan if (flag_eliminate_dwarf2_dups) 1266390075Sobrien { 1266490075Sobrien /* Record the beginning of the file for break_out_includes. */ 12665117395Skan dw_die_ref bincl_die; 12666117395Skan 12667117395Skan bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL); 1266890075Sobrien add_AT_string (bincl_die, DW_AT_name, filename); 1266990075Sobrien } 1267090075Sobrien 1267190075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1267290075Sobrien { 1267390075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1267490075Sobrien dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file"); 1267590075Sobrien dw2_asm_output_data_uleb128 (lineno, "Included from line number %d", 1267690075Sobrien lineno); 12677132718Skan maybe_emit_file (lookup_filename (filename)); 1267890075Sobrien dw2_asm_output_data_uleb128 (lookup_filename (filename), 1267990075Sobrien "Filename we just started"); 1268090075Sobrien } 1268150397Sobrien} 1268250397Sobrien 1268390075Sobrien/* Record the end of a source file. */ 1268450397Sobrien 1268590075Sobrienstatic void 12686132718Skandwarf2out_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED) 1268750397Sobrien{ 1268890075Sobrien if (flag_eliminate_dwarf2_dups) 1268990075Sobrien /* Record the end of the file for break_out_includes. */ 1269090075Sobrien new_die (DW_TAG_GNU_EINCL, comp_unit_die, NULL); 1269190075Sobrien 1269290075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1269390075Sobrien { 1269490075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1269590075Sobrien dw2_asm_output_data (1, DW_MACINFO_end_file, "End file"); 1269690075Sobrien } 1269750397Sobrien} 1269850397Sobrien 1269990075Sobrien/* Called from debug_define in toplev.c. The `buffer' parameter contains 1270050397Sobrien the tail part of the directive line, i.e. the part which is past the 1270150397Sobrien initial whitespace, #, whitespace, directive-name, whitespace part. */ 1270250397Sobrien 1270390075Sobrienstatic void 12704132718Skandwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED, 12705132718Skan const char *buffer ATTRIBUTE_UNUSED) 1270650397Sobrien{ 1270790075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1270890075Sobrien { 1270990075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1271090075Sobrien dw2_asm_output_data (1, DW_MACINFO_define, "Define macro"); 1271190075Sobrien dw2_asm_output_data_uleb128 (lineno, "At line number %d", lineno); 1271290075Sobrien dw2_asm_output_nstring (buffer, -1, "The macro"); 1271390075Sobrien } 1271450397Sobrien} 1271550397Sobrien 1271690075Sobrien/* Called from debug_undef in toplev.c. The `buffer' parameter contains 1271750397Sobrien the tail part of the directive line, i.e. the part which is past the 1271850397Sobrien initial whitespace, #, whitespace, directive-name, whitespace part. */ 1271950397Sobrien 1272090075Sobrienstatic void 12721132718Skandwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED, 12722132718Skan const char *buffer ATTRIBUTE_UNUSED) 1272350397Sobrien{ 1272490075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1272590075Sobrien { 1272690075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1272790075Sobrien dw2_asm_output_data (1, DW_MACINFO_undef, "Undefine macro"); 1272890075Sobrien dw2_asm_output_data_uleb128 (lineno, "At line number %d", lineno); 1272990075Sobrien dw2_asm_output_nstring (buffer, -1, "The macro"); 1273090075Sobrien } 1273150397Sobrien} 1273250397Sobrien 1273350397Sobrien/* Set up for Dwarf output at the start of compilation. */ 1273450397Sobrien 1273590075Sobrienstatic void 12736132718Skandwarf2out_init (const char *filename ATTRIBUTE_UNUSED) 1273750397Sobrien{ 1273890075Sobrien init_file_table (); 1273990075Sobrien 1274050397Sobrien /* Allocate the initial hunk of the decl_die_table. */ 12741132718Skan decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT 12742132718Skan * sizeof (dw_die_ref)); 1274350397Sobrien decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT; 1274450397Sobrien decl_die_table_in_use = 0; 1274550397Sobrien 1274650397Sobrien /* Allocate the initial hunk of the decl_scope_table. */ 1274790075Sobrien VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table"); 1274850397Sobrien 1274950397Sobrien /* Allocate the initial hunk of the abbrev_die_table. */ 12750132718Skan abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT 12751132718Skan * sizeof (dw_die_ref)); 1275250397Sobrien abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT; 1275350397Sobrien /* Zero-th entry is allocated, but unused */ 1275450397Sobrien abbrev_die_table_in_use = 1; 1275550397Sobrien 1275650397Sobrien /* Allocate the initial hunk of the line_info_table. */ 12757132718Skan line_info_table = ggc_alloc_cleared (LINE_INFO_TABLE_INCREMENT 12758132718Skan * sizeof (dw_line_info_entry)); 1275950397Sobrien line_info_table_allocated = LINE_INFO_TABLE_INCREMENT; 1276090075Sobrien 1276150397Sobrien /* Zero-th entry is allocated, but unused */ 1276250397Sobrien line_info_table_in_use = 1; 1276350397Sobrien 1276490075Sobrien /* Generate the initial DIE for the .debug section. Note that the (string) 1276550397Sobrien value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE 1276690075Sobrien will (typically) be a relative pathname and that this pathname should be 1276750397Sobrien taken as being relative to the directory from which the compiler was 12768132718Skan invoked when the given (base) source file was compiled. We will fill 12769132718Skan in this value in dwarf2out_finish. */ 12770132718Skan comp_unit_die = gen_compile_unit_die (NULL); 1277150397Sobrien 1277290075Sobrien VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types"); 1277390075Sobrien 1277490075Sobrien VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray"); 1277590075Sobrien 1277650397Sobrien ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0); 1277790075Sobrien ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, 1277890075Sobrien DEBUG_ABBREV_SECTION_LABEL, 0); 1277990075Sobrien if (DWARF2_GENERATE_TEXT_SECTION_LABEL) 1278090075Sobrien ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0); 1278190075Sobrien else 1278290075Sobrien strcpy (text_section_label, stripattributes (TEXT_SECTION_NAME)); 1278390075Sobrien 1278490075Sobrien ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, 1278552284Sobrien DEBUG_INFO_SECTION_LABEL, 0); 1278690075Sobrien ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, 1278752284Sobrien DEBUG_LINE_SECTION_LABEL, 0); 1278890075Sobrien ASM_GENERATE_INTERNAL_LABEL (ranges_section_label, 1278990075Sobrien DEBUG_RANGES_SECTION_LABEL, 0); 1279090075Sobrien named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG); 1279152284Sobrien ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label); 1279290075Sobrien named_section_flags (DEBUG_INFO_SECTION, SECTION_DEBUG); 1279352284Sobrien ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label); 1279490075Sobrien named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG); 1279552284Sobrien ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label); 1279690075Sobrien 1279790075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1279890075Sobrien { 1279990075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1280090075Sobrien ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label, 1280190075Sobrien DEBUG_MACINFO_SECTION_LABEL, 0); 1280290075Sobrien ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label); 1280390075Sobrien } 1280490075Sobrien 1280590075Sobrien if (DWARF2_GENERATE_TEXT_SECTION_LABEL) 1280690075Sobrien { 1280790075Sobrien text_section (); 1280890075Sobrien ASM_OUTPUT_LABEL (asm_out_file, text_section_label); 1280990075Sobrien } 1281050397Sobrien} 1281150397Sobrien 1281290075Sobrien/* A helper function for dwarf2out_finish called through 1281390075Sobrien ht_forall. Emit one queued .debug_str string. */ 1281490075Sobrien 1281590075Sobrienstatic int 12816132718Skanoutput_indirect_string (void **h, void *v ATTRIBUTE_UNUSED) 1281790075Sobrien{ 12818132718Skan struct indirect_string_node *node = (struct indirect_string_node *) *h; 1281990075Sobrien 1282090075Sobrien if (node->form == DW_FORM_strp) 1282190075Sobrien { 1282290075Sobrien named_section_flags (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS); 1282390075Sobrien ASM_OUTPUT_LABEL (asm_out_file, node->label); 12824132718Skan assemble_string (node->str, strlen (node->str) + 1); 1282590075Sobrien } 1282690075Sobrien 1282790075Sobrien return 1; 1282890075Sobrien} 1282990075Sobrien 12830132718Skan 12831132718Skan 12832132718Skan/* Clear the marks for a die and its children. 12833132718Skan Be cool if the mark isn't set. */ 12834132718Skan 12835132718Skanstatic void 12836132718Skanprune_unmark_dies (dw_die_ref die) 12837132718Skan{ 12838132718Skan dw_die_ref c; 12839132718Skan die->die_mark = 0; 12840132718Skan for (c = die->die_child; c; c = c->die_sib) 12841132718Skan prune_unmark_dies (c); 12842132718Skan} 12843132718Skan 12844132718Skan 12845132718Skan/* Given DIE that we're marking as used, find any other dies 12846132718Skan it references as attributes and mark them as used. */ 12847132718Skan 12848132718Skanstatic void 12849132718Skanprune_unused_types_walk_attribs (dw_die_ref die) 12850132718Skan{ 12851132718Skan dw_attr_ref a; 12852132718Skan 12853132718Skan for (a = die->die_attr; a != NULL; a = a->dw_attr_next) 12854132718Skan { 12855132718Skan if (a->dw_attr_val.val_class == dw_val_class_die_ref) 12856132718Skan { 12857132718Skan /* A reference to another DIE. 12858132718Skan Make sure that it will get emitted. */ 12859132718Skan prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1); 12860132718Skan } 12861132718Skan else if (a->dw_attr == DW_AT_decl_file) 12862132718Skan { 12863132718Skan /* A reference to a file. Make sure the file name is emitted. */ 12864132718Skan a->dw_attr_val.v.val_unsigned = 12865132718Skan maybe_emit_file (a->dw_attr_val.v.val_unsigned); 12866132718Skan } 12867132718Skan } 12868132718Skan} 12869132718Skan 12870132718Skan 12871132718Skan/* Mark DIE as being used. If DOKIDS is true, then walk down 12872132718Skan to DIE's children. */ 12873132718Skan 12874132718Skanstatic void 12875132718Skanprune_unused_types_mark (dw_die_ref die, int dokids) 12876132718Skan{ 12877132718Skan dw_die_ref c; 12878132718Skan 12879132718Skan if (die->die_mark == 0) 12880132718Skan { 12881132718Skan /* We haven't done this node yet. Mark it as used. */ 12882132718Skan die->die_mark = 1; 12883132718Skan 12884132718Skan /* We also have to mark its parents as used. 12885132718Skan (But we don't want to mark our parents' kids due to this.) */ 12886132718Skan if (die->die_parent) 12887132718Skan prune_unused_types_mark (die->die_parent, 0); 12888132718Skan 12889132718Skan /* Mark any referenced nodes. */ 12890132718Skan prune_unused_types_walk_attribs (die); 12891132718Skan 12892132718Skan /* If this node is a specification, 12893132718Skan also mark the definition, if it exists. */ 12894132718Skan if (get_AT_flag (die, DW_AT_declaration) && die->die_definition) 12895132718Skan prune_unused_types_mark (die->die_definition, 1); 12896132718Skan } 12897132718Skan 12898132718Skan if (dokids && die->die_mark != 2) 12899132718Skan { 12900132718Skan /* We need to walk the children, but haven't done so yet. 12901132718Skan Remember that we've walked the kids. */ 12902132718Skan die->die_mark = 2; 12903132718Skan 12904132718Skan /* Walk them. */ 12905132718Skan for (c = die->die_child; c; c = c->die_sib) 12906132718Skan { 12907132718Skan /* If this is an array type, we need to make sure our 12908132718Skan kids get marked, even if they're types. */ 12909132718Skan if (die->die_tag == DW_TAG_array_type) 12910132718Skan prune_unused_types_mark (c, 1); 12911132718Skan else 12912132718Skan prune_unused_types_walk (c); 12913132718Skan } 12914132718Skan } 12915132718Skan} 12916132718Skan 12917132718Skan 12918132718Skan/* Walk the tree DIE and mark types that we actually use. */ 12919132718Skan 12920132718Skanstatic void 12921132718Skanprune_unused_types_walk (dw_die_ref die) 12922132718Skan{ 12923132718Skan dw_die_ref c; 12924132718Skan 12925132718Skan /* Don't do anything if this node is already marked. */ 12926132718Skan if (die->die_mark) 12927132718Skan return; 12928132718Skan 12929132718Skan switch (die->die_tag) { 12930132718Skan case DW_TAG_const_type: 12931132718Skan case DW_TAG_packed_type: 12932132718Skan case DW_TAG_pointer_type: 12933132718Skan case DW_TAG_reference_type: 12934132718Skan case DW_TAG_volatile_type: 12935132718Skan case DW_TAG_typedef: 12936132718Skan case DW_TAG_array_type: 12937132718Skan case DW_TAG_structure_type: 12938132718Skan case DW_TAG_union_type: 12939132718Skan case DW_TAG_class_type: 12940132718Skan case DW_TAG_friend: 12941132718Skan case DW_TAG_variant_part: 12942132718Skan case DW_TAG_enumeration_type: 12943132718Skan case DW_TAG_subroutine_type: 12944132718Skan case DW_TAG_string_type: 12945132718Skan case DW_TAG_set_type: 12946132718Skan case DW_TAG_subrange_type: 12947132718Skan case DW_TAG_ptr_to_member_type: 12948132718Skan case DW_TAG_file_type: 12949132718Skan /* It's a type node --- don't mark it. */ 12950132718Skan return; 12951132718Skan 12952132718Skan default: 12953132718Skan /* Mark everything else. */ 12954132718Skan break; 12955132718Skan } 12956132718Skan 12957132718Skan die->die_mark = 1; 12958132718Skan 12959132718Skan /* Now, mark any dies referenced from here. */ 12960132718Skan prune_unused_types_walk_attribs (die); 12961132718Skan 12962132718Skan /* Mark children. */ 12963132718Skan for (c = die->die_child; c; c = c->die_sib) 12964132718Skan prune_unused_types_walk (c); 12965132718Skan} 12966132718Skan 12967132718Skan 12968132718Skan/* Remove from the tree DIE any dies that aren't marked. */ 12969132718Skan 12970132718Skanstatic void 12971132718Skanprune_unused_types_prune (dw_die_ref die) 12972132718Skan{ 12973132718Skan dw_die_ref c, p, n; 12974132718Skan if (!die->die_mark) 12975132718Skan abort(); 12976132718Skan 12977132718Skan p = NULL; 12978132718Skan for (c = die->die_child; c; c = n) 12979132718Skan { 12980132718Skan n = c->die_sib; 12981132718Skan if (c->die_mark) 12982132718Skan { 12983132718Skan prune_unused_types_prune (c); 12984132718Skan p = c; 12985132718Skan } 12986132718Skan else 12987132718Skan { 12988132718Skan if (p) 12989132718Skan p->die_sib = n; 12990132718Skan else 12991132718Skan die->die_child = n; 12992132718Skan free_die (c); 12993132718Skan } 12994132718Skan } 12995132718Skan} 12996132718Skan 12997132718Skan 12998132718Skan/* Remove dies representing declarations that we never use. */ 12999132718Skan 13000132718Skanstatic void 13001132718Skanprune_unused_types (void) 13002132718Skan{ 13003132718Skan unsigned int i; 13004132718Skan limbo_die_node *node; 13005132718Skan 13006132718Skan /* Clear all the marks. */ 13007132718Skan prune_unmark_dies (comp_unit_die); 13008132718Skan for (node = limbo_die_list; node; node = node->next) 13009132718Skan prune_unmark_dies (node->die); 13010132718Skan 13011132718Skan /* Set the mark on nodes that are actually used. */ 13012132718Skan prune_unused_types_walk (comp_unit_die); 13013132718Skan for (node = limbo_die_list; node; node = node->next) 13014132718Skan prune_unused_types_walk (node->die); 13015132718Skan 13016132718Skan /* Also set the mark on nodes referenced from the 13017132718Skan pubname_table or arange_table. */ 13018132718Skan for (i = 0; i < pubname_table_in_use; i++) 13019132718Skan prune_unused_types_mark (pubname_table[i].die, 1); 13020132718Skan for (i = 0; i < arange_table_in_use; i++) 13021132718Skan prune_unused_types_mark (arange_table[i], 1); 13022132718Skan 13023132718Skan /* Get rid of nodes that aren't marked. */ 13024132718Skan prune_unused_types_prune (comp_unit_die); 13025132718Skan for (node = limbo_die_list; node; node = node->next) 13026132718Skan prune_unused_types_prune (node->die); 13027132718Skan 13028132718Skan /* Leave the marks clear. */ 13029132718Skan prune_unmark_dies (comp_unit_die); 13030132718Skan for (node = limbo_die_list; node; node = node->next) 13031132718Skan prune_unmark_dies (node->die); 13032132718Skan} 13033132718Skan 1303450397Sobrien/* Output stuff that dwarf requires at the end of every file, 1303550397Sobrien and generate the DWARF-2 debugging info. */ 1303650397Sobrien 1303790075Sobrienstatic void 13038132718Skandwarf2out_finish (const char *filename) 1303950397Sobrien{ 1304050397Sobrien limbo_die_node *node, *next_node; 1304190075Sobrien dw_die_ref die = 0; 1304250397Sobrien 13043132718Skan /* Add the name for the main input file now. We delayed this from 13044132718Skan dwarf2out_init to avoid complications with PCH. */ 13045132718Skan add_name_attribute (comp_unit_die, filename); 13046132718Skan if (filename[0] != DIR_SEPARATOR) 13047132718Skan add_comp_dir_attribute (comp_unit_die); 13048132718Skan else if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL) 13049132718Skan { 13050132718Skan size_t i; 13051132718Skan for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++) 13052132718Skan if (VARRAY_CHAR_PTR (file_table, i)[0] != DIR_SEPARATOR 13053132718Skan /* Don't add cwd for <built-in>. */ 13054132718Skan && VARRAY_CHAR_PTR (file_table, i)[0] != '<') 13055132718Skan { 13056132718Skan add_comp_dir_attribute (comp_unit_die); 13057132718Skan break; 13058132718Skan } 13059132718Skan } 13060132718Skan 1306150397Sobrien /* Traverse the limbo die list, and add parent/child links. The only 1306250397Sobrien dies without parents that should be here are concrete instances of 1306350397Sobrien inline functions, and the comp_unit_die. We can ignore the comp_unit_die. 1306450397Sobrien For concrete instances, we can get the parent die from the abstract 1306550397Sobrien instance. */ 1306650397Sobrien for (node = limbo_die_list; node; node = next_node) 1306750397Sobrien { 1306850397Sobrien next_node = node->next; 1306950397Sobrien die = node->die; 1307050397Sobrien 1307150397Sobrien if (die->die_parent == NULL) 1307250397Sobrien { 1307390075Sobrien dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); 1307490075Sobrien tree context; 1307590075Sobrien 1307690075Sobrien if (origin) 1307790075Sobrien add_child_die (origin->die_parent, die); 1307850397Sobrien else if (die == comp_unit_die) 1307990075Sobrien ; 1308090075Sobrien /* If this was an expression for a bound involved in a function 1308190075Sobrien return type, it may be a SAVE_EXPR for which we weren't able 1308290075Sobrien to find a DIE previously. So try now. */ 1308390075Sobrien else if (node->created_for 1308490075Sobrien && TREE_CODE (node->created_for) == SAVE_EXPR 1308590075Sobrien && 0 != (origin = (lookup_decl_die 1308690075Sobrien (SAVE_EXPR_CONTEXT 1308790075Sobrien (node->created_for))))) 1308890075Sobrien add_child_die (origin, die); 1308990075Sobrien else if (errorcount > 0 || sorrycount > 0) 1309090075Sobrien /* It's OK to be confused by errors in the input. */ 1309190075Sobrien add_child_die (comp_unit_die, die); 1309290075Sobrien else if (node->created_for 1309390075Sobrien && ((DECL_P (node->created_for) 13094117395Skan && (context = DECL_CONTEXT (node->created_for))) 1309590075Sobrien || (TYPE_P (node->created_for) 1309690075Sobrien && (context = TYPE_CONTEXT (node->created_for)))) 1309790075Sobrien && TREE_CODE (context) == FUNCTION_DECL) 1309890075Sobrien { 1309990075Sobrien /* In certain situations, the lexical block containing a 1310090075Sobrien nested function can be optimized away, which results 1310190075Sobrien in the nested function die being orphaned. Likewise 1310290075Sobrien with the return type of that nested function. Force 1310390075Sobrien this to be a child of the containing function. */ 1310490075Sobrien origin = lookup_decl_die (context); 1310590075Sobrien if (! origin) 1310690075Sobrien abort (); 1310790075Sobrien add_child_die (origin, die); 1310890075Sobrien } 1310950397Sobrien else 1311050397Sobrien abort (); 1311150397Sobrien } 1311250397Sobrien } 1311350397Sobrien 1311490075Sobrien limbo_die_list = NULL; 1311590075Sobrien 1311652284Sobrien /* Walk through the list of incomplete types again, trying once more to 1311752284Sobrien emit full debugging info for them. */ 1311852284Sobrien retry_incomplete_types (); 1311952284Sobrien 1312090075Sobrien /* We need to reverse all the dies before break_out_includes, or 1312190075Sobrien we'll see the end of an include file before the beginning. */ 1312290075Sobrien reverse_all_dies (comp_unit_die); 1312390075Sobrien 13124132718Skan if (flag_eliminate_unused_debug_types) 13125132718Skan prune_unused_types (); 13126132718Skan 1312790075Sobrien /* Generate separate CUs for each of the include files we've seen. 1312890075Sobrien They will go into limbo_die_list. */ 1312990075Sobrien if (flag_eliminate_dwarf2_dups) 1313090075Sobrien break_out_includes (comp_unit_die); 1313190075Sobrien 1313290075Sobrien /* Traverse the DIE's and add add sibling attributes to those DIE's 1313350397Sobrien that have children. */ 1313450397Sobrien add_sibling_attributes (comp_unit_die); 1313590075Sobrien for (node = limbo_die_list; node; node = node->next) 1313690075Sobrien add_sibling_attributes (node->die); 1313750397Sobrien 1313850397Sobrien /* Output a terminator label for the .text section. */ 1313990075Sobrien text_section (); 13140132718Skan (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0); 1314150397Sobrien 1314290075Sobrien /* Output the source line correspondence table. We must do this 1314390075Sobrien even if there is no line information. Otherwise, on an empty 1314490075Sobrien translation unit, we will generate a present, but empty, 1314590075Sobrien .debug_info section. IRIX 6.5 `nm' will then complain when 1314690075Sobrien examining the file. */ 1314790075Sobrien if (! DWARF2_ASM_LINE_DEBUG_INFO) 1314850397Sobrien { 1314990075Sobrien named_section_flags (DEBUG_LINE_SECTION, SECTION_DEBUG); 1315050397Sobrien output_line_info (); 1315190075Sobrien } 1315250397Sobrien 1315390075Sobrien /* Output location list section if necessary. */ 1315490075Sobrien if (have_location_lists) 1315590075Sobrien { 1315690075Sobrien /* Output the location lists info. */ 1315790075Sobrien named_section_flags (DEBUG_LOC_SECTION, SECTION_DEBUG); 1315890075Sobrien ASM_GENERATE_INTERNAL_LABEL (loc_section_label, 1315990075Sobrien DEBUG_LOC_SECTION_LABEL, 0); 1316090075Sobrien ASM_OUTPUT_LABEL (asm_out_file, loc_section_label); 1316190075Sobrien output_location_lists (die); 1316290075Sobrien have_location_lists = 0; 1316390075Sobrien } 1316450397Sobrien 1316590075Sobrien /* We can only use the low/high_pc attributes if all of the code was 1316690075Sobrien in .text. */ 1316790075Sobrien if (separate_line_info_table_in_use == 0) 1316890075Sobrien { 1316990075Sobrien add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, text_section_label); 1317090075Sobrien add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label); 1317150397Sobrien } 1317250397Sobrien 1317390075Sobrien /* If it wasn't, we need to give .debug_loc and .debug_ranges an appropriate 1317490075Sobrien "base address". Use zero so that these addresses become absolute. */ 1317590075Sobrien else if (have_location_lists || ranges_table_in_use) 1317690075Sobrien add_AT_addr (comp_unit_die, DW_AT_entry_pc, const0_rtx); 1317790075Sobrien 1317890075Sobrien if (debug_info_level >= DINFO_LEVEL_NORMAL) 1317990075Sobrien add_AT_lbl_offset (comp_unit_die, DW_AT_stmt_list, 1318090075Sobrien debug_line_section_label); 1318190075Sobrien 1318290075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 1318390075Sobrien add_AT_lbl_offset (comp_unit_die, DW_AT_macro_info, macinfo_section_label); 1318490075Sobrien 1318590075Sobrien /* Output all of the compilation units. We put the main one last so that 1318690075Sobrien the offsets are available to output_pubnames. */ 1318790075Sobrien for (node = limbo_die_list; node; node = node->next) 13188117395Skan output_comp_unit (node->die, 0); 1318990075Sobrien 13190117395Skan output_comp_unit (comp_unit_die, 0); 1319190075Sobrien 1319250397Sobrien /* Output the abbreviation table. */ 1319390075Sobrien named_section_flags (DEBUG_ABBREV_SECTION, SECTION_DEBUG); 1319450397Sobrien output_abbrev_section (); 1319550397Sobrien 1319690075Sobrien /* Output public names table if necessary. */ 1319750397Sobrien if (pubname_table_in_use) 1319850397Sobrien { 1319990075Sobrien named_section_flags (DEBUG_PUBNAMES_SECTION, SECTION_DEBUG); 1320050397Sobrien output_pubnames (); 1320150397Sobrien } 1320250397Sobrien 1320390075Sobrien /* Output the address range information. We only put functions in the arange 1320490075Sobrien table, so don't write it out if we don't have any. */ 1320550397Sobrien if (fde_table_in_use) 1320650397Sobrien { 1320790075Sobrien named_section_flags (DEBUG_ARANGES_SECTION, SECTION_DEBUG); 1320850397Sobrien output_aranges (); 1320950397Sobrien } 1321090075Sobrien 1321190075Sobrien /* Output ranges section if necessary. */ 1321290075Sobrien if (ranges_table_in_use) 1321390075Sobrien { 1321490075Sobrien named_section_flags (DEBUG_RANGES_SECTION, SECTION_DEBUG); 1321590075Sobrien ASM_OUTPUT_LABEL (asm_out_file, ranges_section_label); 1321690075Sobrien output_ranges (); 1321790075Sobrien } 1321890075Sobrien 1321990075Sobrien /* Have to end the primary source file. */ 1322090075Sobrien if (debug_info_level >= DINFO_LEVEL_VERBOSE) 13221117395Skan { 1322290075Sobrien named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG); 1322390075Sobrien dw2_asm_output_data (1, DW_MACINFO_end_file, "End file"); 13224117395Skan dw2_asm_output_data (1, 0, "End compilation unit"); 1322590075Sobrien } 1322690075Sobrien 1322790075Sobrien /* If we emitted any DW_FORM_strp form attribute, output the string 1322890075Sobrien table too. */ 1322990075Sobrien if (debug_str_hash) 13230132718Skan htab_traverse (debug_str_hash, output_indirect_string, NULL); 1323150397Sobrien} 13232117395Skan#else 13233117395Skan 13234117395Skan/* This should never be used, but its address is needed for comparisons. */ 13235117395Skanconst struct gcc_debug_hooks dwarf2_debug_hooks; 13236117395Skan 13237117395Skan#endif /* DWARF2_DEBUGGING_INFO */ 13238117395Skan 13239117395Skan#include "gt-dwarf2out.h" 13240