diff options
Diffstat (limited to 'contrib/gcc/dwarf2out.c')
-rw-r--r-- | contrib/gcc/dwarf2out.c | 899 |
1 files changed, 575 insertions, 324 deletions
diff --git a/contrib/gcc/dwarf2out.c b/contrib/gcc/dwarf2out.c index b72d861..de3d26f 100644 --- a/contrib/gcc/dwarf2out.c +++ b/contrib/gcc/dwarf2out.c @@ -1,5 +1,5 @@ /* Output Dwarf2 format symbol table information from the GNU C compiler. - Copyright (C) 1992, 93, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93, 95-98, 1999 Free Software Foundation, Inc. Contributed by Gary Funck (gary@intrepid.com). Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com). Extensively modified by Jason Merrill (jason@cygnus.com). @@ -18,7 +18,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* The first part of this file deals with the DWARF 2 frame unwind information, which is also used by the GCC efficient exception handling @@ -71,10 +72,6 @@ dwarf2out_do_frame () #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) -#ifndef __GNUC__ -#define inline -#endif - /* How to start an assembler comment. */ #ifndef ASM_COMMENT_START #define ASM_COMMENT_START ";#" @@ -346,6 +343,16 @@ static void dwarf2out_stack_adjust PROTO((rtx)); } while (0) #endif +/* ??? This macro takes an RTX in dwarfout.c and a string in dwarf2out.c. + We resolve the conflict by creating a new macro ASM_OUTPUT_DWARF2_ADDR_CONST + for ports that want to support both DWARF1 and DWARF2. This needs a better + solution. See also the comments in sparc/sp64-elf.h. */ +#ifdef ASM_OUTPUT_DWARF2_ADDR_CONST +#undef ASM_OUTPUT_DWARF_ADDR_CONST +#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,ADDR) \ + ASM_OUTPUT_DWARF2_ADDR_CONST (FILE, ADDR) +#endif + #ifndef ASM_OUTPUT_DWARF_ADDR_CONST #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,ADDR) \ fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, (ADDR)) @@ -632,24 +639,28 @@ expand_builtin_dwarf_reg_size (reg_tree, target) } else { + /* Initialize last_end to be larger than any possible + DWARF_FRAME_REGNUM. */ + int last_end = 0x7fffffff; --n_ranges; t = build_int_2 (ranges[n_ranges].size, 0); - size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg); - for (; n_ranges--; ) + do { - if ((DWARF_FRAME_REGNUM (ranges[n_ranges].end) - - DWARF_FRAME_REGNUM (ranges[n_ranges].beg)) - != ranges[n_ranges].end - ranges[n_ranges].beg) + int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg); + int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end); + if (beg < 0) + continue; + if (end >= last_end) abort (); - if (DWARF_FRAME_REGNUM (ranges[n_ranges].beg) >= size) + last_end = end; + if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg) abort (); - size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg); t2 = fold (build (LE_EXPR, integer_type_node, reg_tree, - build_int_2 (DWARF_FRAME_REGNUM - (ranges[n_ranges].end), 0))); + build_int_2 (end, 0))); t = fold (build (COND_EXPR, integer_type_node, t2, build_int_2 (ranges[n_ranges].size, 0), t)); } + while (--n_ranges >= 0); } return expand_expr (t, target, Pmode, 0); } @@ -1026,7 +1037,7 @@ static void initial_return_save (rtl) register rtx rtl; { - unsigned reg = -1; + unsigned int reg = (unsigned int) -1; long offset = 0; switch (GET_CODE (rtl)) @@ -1175,6 +1186,230 @@ dwarf2out_stack_adjust (insn) dwarf2out_args_size (label, args_size); } +/* A temporary register used in adjusting SP or setting up the store_reg. */ +static unsigned cfa_temp_reg; + +/* A temporary value used in adjusting SP or setting up the store_reg. */ +static long cfa_temp_value; + +/* Record call frame debugging information for an expression, which either + sets SP or FP (adjusting how we calculate the frame address) or saves a + register to the stack. */ + +static void +dwarf2out_frame_debug_expr (expr, label) + rtx expr; + char *label; +{ + rtx src, dest; + long offset; + + /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of + the PARALLEL independantly. The first element is always processed if + it is a SET. This is for backward compatability. Other elements + are processed only if they are SETs and the RTX_FRAME_RELATED_P + flag is set in them. */ + + if (GET_CODE (expr) == PARALLEL) + { + int par_index; + int limit = XVECLEN (expr, 0); + + for (par_index = 0; par_index < limit; par_index++) + { + rtx x = XVECEXP (expr, 0, par_index); + + if (GET_CODE (x) == SET && + (RTX_FRAME_RELATED_P (x) || par_index == 0)) + dwarf2out_frame_debug_expr (x, label); + } + return; + } + + if (GET_CODE (expr) != SET) + abort (); + + src = SET_SRC (expr); + dest = SET_DEST (expr); + + switch (GET_CODE (dest)) + { + case REG: + /* Update the CFA rule wrt SP or FP. Make sure src is + relative to the current CFA register. */ + switch (GET_CODE (src)) + { + /* Setting FP from SP. */ + case REG: + if (cfa_reg != (unsigned) REGNO (src)) + abort (); + if (REGNO (dest) != STACK_POINTER_REGNUM + && !(frame_pointer_needed + && REGNO (dest) == HARD_FRAME_POINTER_REGNUM)) + abort (); + cfa_reg = REGNO (dest); + break; + + case PLUS: + case MINUS: + if (dest == stack_pointer_rtx) + { + /* Adjusting SP. */ + switch (GET_CODE (XEXP (src, 1))) + { + case CONST_INT: + offset = INTVAL (XEXP (src, 1)); + break; + case REG: + if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg) + abort (); + offset = cfa_temp_value; + break; + default: + abort (); + } + + if (XEXP (src, 0) == hard_frame_pointer_rtx) + { + /* Restoring SP from FP in the epilogue. */ + if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM) + abort (); + cfa_reg = STACK_POINTER_REGNUM; + } + else if (XEXP (src, 0) != stack_pointer_rtx) + abort (); + + if (GET_CODE (src) == PLUS) + offset = -offset; + if (cfa_reg == STACK_POINTER_REGNUM) + cfa_offset += offset; + if (cfa_store_reg == STACK_POINTER_REGNUM) + cfa_store_offset += offset; + } + else if (dest == hard_frame_pointer_rtx) + { + /* Either setting the FP from an offset of the SP, + or adjusting the FP */ + if (! frame_pointer_needed + || REGNO (dest) != HARD_FRAME_POINTER_REGNUM) + abort (); + + if (XEXP (src, 0) == stack_pointer_rtx + && GET_CODE (XEXP (src, 1)) == CONST_INT) + { + if (cfa_reg != STACK_POINTER_REGNUM) + abort (); + offset = INTVAL (XEXP (src, 1)); + if (GET_CODE (src) == PLUS) + offset = -offset; + cfa_offset += offset; + cfa_reg = HARD_FRAME_POINTER_REGNUM; + } + else if (XEXP (src, 0) == hard_frame_pointer_rtx + && GET_CODE (XEXP (src, 1)) == CONST_INT) + { + if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM) + abort (); + offset = INTVAL (XEXP (src, 1)); + if (GET_CODE (src) == PLUS) + offset = -offset; + cfa_offset += offset; + } + + else + abort(); + } + else + { + if (GET_CODE (src) != PLUS + || XEXP (src, 1) != stack_pointer_rtx) + abort (); + if (GET_CODE (XEXP (src, 0)) != REG + || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg) + abort (); + if (cfa_reg != STACK_POINTER_REGNUM) + abort (); + cfa_store_reg = REGNO (dest); + cfa_store_offset = cfa_offset - cfa_temp_value; + } + break; + + case CONST_INT: + cfa_temp_reg = REGNO (dest); + cfa_temp_value = INTVAL (src); + break; + + case IOR: + if (GET_CODE (XEXP (src, 0)) != REG + || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg + || (unsigned) REGNO (dest) != cfa_temp_reg + || GET_CODE (XEXP (src, 1)) != CONST_INT) + abort (); + cfa_temp_value |= INTVAL (XEXP (src, 1)); + break; + + default: + abort (); + } + dwarf2out_def_cfa (label, cfa_reg, cfa_offset); + break; + + case MEM: + /* Saving a register to the stack. Make sure dest is relative to the + CFA register. */ + if (GET_CODE (src) != REG) + abort (); + switch (GET_CODE (XEXP (dest, 0))) + { + /* With a push. */ + case PRE_INC: + case PRE_DEC: + offset = GET_MODE_SIZE (GET_MODE (dest)); + if (GET_CODE (XEXP (dest, 0)) == PRE_INC) + offset = -offset; + + if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM + || cfa_store_reg != STACK_POINTER_REGNUM) + abort (); + cfa_store_offset += offset; + if (cfa_reg == STACK_POINTER_REGNUM) + cfa_offset = cfa_store_offset; + + offset = -cfa_store_offset; + break; + + /* With an offset. */ + case PLUS: + case MINUS: + offset = INTVAL (XEXP (XEXP (dest, 0), 1)); + if (GET_CODE (XEXP (dest, 0)) == MINUS) + offset = -offset; + + if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) + abort (); + offset -= cfa_store_offset; + break; + + /* Without an offset. */ + case REG: + if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0))) + abort(); + offset = -cfa_store_offset; + break; + + default: + abort (); + } + dwarf2out_def_cfa (label, cfa_reg, cfa_offset); + dwarf2out_reg_save (label, REGNO (src), offset); + break; + + default: + abort (); + } +} + + /* Record call frame debugging information for INSN, which either sets SP or FP (adjusting how we calculate the frame address) or saves a register to the stack. If INSN is NULL_RTX, initialize our state. */ @@ -1184,12 +1419,7 @@ dwarf2out_frame_debug (insn) rtx insn; { char *label; - rtx src, dest; - long offset; - - /* A temporary register used in adjusting SP or setting up the store_reg. */ - static unsigned cfa_temp_reg; - static long cfa_temp_value; + rtx src; if (insn == NULL_RTX) { @@ -1213,185 +1443,13 @@ dwarf2out_frame_debug (insn) label = dwarf2out_cfi_label (); - insn = PATTERN (insn); - /* Assume that in a PARALLEL prologue insn, only the first elt is - significant. Currently this is true. */ - if (GET_CODE (insn) == PARALLEL) - insn = XVECEXP (insn, 0, 0); - if (GET_CODE (insn) != SET) - abort (); - - src = SET_SRC (insn); - dest = SET_DEST (insn); - - switch (GET_CODE (dest)) - { - case REG: - /* Update the CFA rule wrt SP or FP. Make sure src is - relative to the current CFA register. */ - switch (GET_CODE (src)) - { - /* Setting FP from SP. */ - case REG: - if (cfa_reg != REGNO (src)) - abort (); - if (REGNO (dest) != STACK_POINTER_REGNUM - && !(frame_pointer_needed - && REGNO (dest) == HARD_FRAME_POINTER_REGNUM)) - abort (); - cfa_reg = REGNO (dest); - break; + src = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); + if (src) + insn = XEXP (src, 0); + else + insn = PATTERN (insn); - case PLUS: - case MINUS: - if (dest == stack_pointer_rtx) - { - /* Adjusting SP. */ - switch (GET_CODE (XEXP (src, 1))) - { - case CONST_INT: - offset = INTVAL (XEXP (src, 1)); - break; - case REG: - if (REGNO (XEXP (src, 1)) != cfa_temp_reg) - abort (); - offset = cfa_temp_value; - break; - default: - abort (); - } - - if (XEXP (src, 0) == hard_frame_pointer_rtx) - { - /* Restoring SP from FP in the epilogue. */ - if (cfa_reg != HARD_FRAME_POINTER_REGNUM) - abort (); - cfa_reg = STACK_POINTER_REGNUM; - } - else if (XEXP (src, 0) != stack_pointer_rtx) - abort (); - - if (GET_CODE (src) == PLUS) - offset = -offset; - if (cfa_reg == STACK_POINTER_REGNUM) - cfa_offset += offset; - if (cfa_store_reg == STACK_POINTER_REGNUM) - cfa_store_offset += offset; - } - else if (dest == hard_frame_pointer_rtx) - { - /* Either setting the FP from an offset of the SP, - or adjusting the FP */ - if (! frame_pointer_needed - || REGNO (dest) != HARD_FRAME_POINTER_REGNUM) - abort (); - - if (XEXP (src, 0) == stack_pointer_rtx - && GET_CODE (XEXP (src, 1)) == CONST_INT) - { - if (cfa_reg != STACK_POINTER_REGNUM) - abort (); - offset = INTVAL (XEXP (src, 1)); - if (GET_CODE (src) == PLUS) - offset = -offset; - cfa_offset += offset; - cfa_reg = HARD_FRAME_POINTER_REGNUM; - } - else if (XEXP (src, 0) == hard_frame_pointer_rtx - && GET_CODE (XEXP (src, 1)) == CONST_INT) - { - if (cfa_reg != HARD_FRAME_POINTER_REGNUM) - abort (); - offset = INTVAL (XEXP (src, 1)); - if (GET_CODE (src) == PLUS) - offset = -offset; - cfa_offset += offset; - } - - else - abort(); - } - else - { - if (GET_CODE (src) != PLUS - || XEXP (src, 1) != stack_pointer_rtx) - abort (); - if (GET_CODE (XEXP (src, 0)) != REG - || REGNO (XEXP (src, 0)) != cfa_temp_reg) - abort (); - if (cfa_reg != STACK_POINTER_REGNUM) - abort (); - cfa_store_reg = REGNO (dest); - cfa_store_offset = cfa_offset - cfa_temp_value; - } - break; - - case CONST_INT: - cfa_temp_reg = REGNO (dest); - cfa_temp_value = INTVAL (src); - break; - - case IOR: - if (GET_CODE (XEXP (src, 0)) != REG - || REGNO (XEXP (src, 0)) != cfa_temp_reg - || REGNO (dest) != cfa_temp_reg - || GET_CODE (XEXP (src, 1)) != CONST_INT) - abort (); - cfa_temp_value |= INTVAL (XEXP (src, 1)); - break; - - default: - abort (); - } - dwarf2out_def_cfa (label, cfa_reg, cfa_offset); - break; - - case MEM: - /* Saving a register to the stack. Make sure dest is relative to the - CFA register. */ - if (GET_CODE (src) != REG) - abort (); - switch (GET_CODE (XEXP (dest, 0))) - { - /* With a push. */ - case PRE_INC: - case PRE_DEC: - offset = GET_MODE_SIZE (GET_MODE (dest)); - if (GET_CODE (XEXP (dest, 0)) == PRE_INC) - offset = -offset; - - if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM - || cfa_store_reg != STACK_POINTER_REGNUM) - abort (); - cfa_store_offset += offset; - if (cfa_reg == STACK_POINTER_REGNUM) - cfa_offset = cfa_store_offset; - - offset = -cfa_store_offset; - break; - - /* With an offset. */ - case PLUS: - case MINUS: - offset = INTVAL (XEXP (XEXP (dest, 0), 1)); - if (GET_CODE (src) == MINUS) - offset = -offset; - - if (cfa_store_reg != REGNO (XEXP (XEXP (dest, 0), 0))) - abort (); - offset -= cfa_store_offset; - break; - - default: - abort (); - } - dwarf2out_def_cfa (label, cfa_reg, cfa_offset); - dwarf2out_reg_save (label, REGNO (src), offset); - break; - - default: - abort (); - } + dwarf2out_frame_debug_expr (insn, label); } /* Return the size of an unsigned LEB128 quantity. */ @@ -1665,7 +1723,7 @@ output_call_frame_info (for_eh) #else tree label = get_file_function_name ('F'); - data_section (); + force_data_section (); ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); @@ -1803,8 +1861,16 @@ output_call_frame_info (for_eh) fputc ('\n', asm_out_file); ASM_OUTPUT_LABEL (asm_out_file, l1); + /* ??? This always emits a 4 byte offset when for_eh is true, but it + emits a target dependent sized offset when for_eh is not true. + This inconsistency may confuse gdb. The only case where we need a + non-4 byte offset is for the Irix6 N64 ABI, so we may lose SGI + compatibility if we emit a 4 byte offset. We need a 4 byte offset + though in order to be compatible with the dwarf_fde struct in frame.c. + If the for_eh case is changed, then the struct in frame.c has + to be adjusted appropriately. */ if (for_eh) - ASM_OUTPUT_DWARF_DELTA (asm_out_file, l1, "__FRAME_BEGIN__"); + ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, l1, "__FRAME_BEGIN__"); else ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (FRAME_SECTION)); if (flag_debug_asm) @@ -1982,7 +2048,7 @@ typedef enum dw_val_class_die_ref, dw_val_class_fde_ref, dw_val_class_lbl_id, - dw_val_class_section_offset, + dw_val_class_lbl_offset, dw_val_class_str } dw_val_class; @@ -2061,7 +2127,6 @@ typedef struct dw_val_struct unsigned val_fde_index; char *val_str; char *val_lbl_id; - char *val_section; unsigned char val_flag; } v; @@ -2361,6 +2426,22 @@ static unsigned pending_types; be enough for most typical programs. */ #define PENDING_TYPES_INCREMENT 64 +/* A pointer to the base of a list of incomplete types which might be + completed at some later time. */ + +static tree *incomplete_types_list; + +/* Number of elements currently allocated for the incomplete_types_list. */ +static unsigned incomplete_types_allocated; + +/* Number of elements of incomplete_types_list currently in use. */ +static unsigned incomplete_types; + +/* Size (in elements) of increments by which we may expand the incomplete + types list. Actually, a single hunk of space of this size should + be enough for most typical programs. */ +#define INCOMPLETE_TYPES_INCREMENT 64 + /* Record whether the function being analyzed contains inlined functions. */ static int current_function_has_inlines; #if 0 && defined (MIPS_DEBUGGING_INFO) @@ -2420,7 +2501,7 @@ static void add_AT_addr PROTO((dw_die_ref, enum dwarf_attribute, char *)); static void add_AT_lbl_id PROTO((dw_die_ref, enum dwarf_attribute, char *)); -static void add_AT_section_offset PROTO((dw_die_ref, +static void add_AT_lbl_offset PROTO((dw_die_ref, enum dwarf_attribute, char *)); static int is_extern_subr_die PROTO((dw_die_ref)); static dw_attr_ref get_AT PROTO((dw_die_ref, @@ -2593,6 +2674,22 @@ static unsigned lookup_filename PROTO((char *)); #define BSS_SECTION ".bss" #endif +/* Labels we insert at beginning sections we can reference instead of + the section names themselves. */ + +#ifndef TEXT_SECTION_LABEL +#define TEXT_SECTION_LABEL "Ltext" +#endif +#ifndef DEBUG_LINE_SECTION_LABEL +#define DEBUG_LINE_SECTION_LABEL "Ldebug_line" +#endif +#ifndef DEBUG_INFO_SECTION_LABEL +#define DEBUG_INFO_SECTION_LABEL "Ldebug_info" +#endif +#ifndef ABBREV_SECTION_LABEL +#define ABBREV_SECTION_LABEL "Ldebug_abbrev" +#endif + /* Definitions of defaults for formats and names of various special (artificial) labels which may be generated within this file (when the -g @@ -2601,6 +2698,10 @@ static unsigned lookup_filename PROTO((char *)); typically, overriding these defaults is unnecessary. */ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; #ifndef TEXT_END_LABEL #define TEXT_END_LABEL "Letext" @@ -2637,13 +2738,18 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; macro has the same effect as ASM_OUTPUT_LABELREF, but copies to a string rather than writing to a file. */ #ifndef ASM_NAME_TO_STRING -#define ASM_NAME_TO_STRING(STR, NAME) \ - do { \ - if ((NAME)[0] == '*') \ - dyn_string_append (STR, NAME + 1); \ - else \ - dyn_string_append (STR, NAME); \ - } \ +#define ASM_NAME_TO_STRING(STR, NAME) \ + do { \ + if ((NAME)[0] == '*') \ + dyn_string_append (STR, NAME + 1); \ + else \ + { \ + char *newstr; \ + STRIP_NAME_ENCODING (newstr, NAME); \ + dyn_string_append (STR, user_label_prefix); \ + dyn_string_append (STR, newstr); \ + } \ + } \ while (0) #endif @@ -3517,24 +3623,14 @@ static tree decl_ultimate_origin (decl) register tree decl; { - register tree immediate_origin = DECL_ABSTRACT_ORIGIN (decl); - - if (immediate_origin == NULL_TREE) - return NULL_TREE; - else - { - register tree ret_val; - register tree lookahead = immediate_origin; - - do - { - ret_val = lookahead; - lookahead = DECL_ABSTRACT_ORIGIN (ret_val); - } - while (lookahead != NULL && lookahead != ret_val); +#ifdef ENABLE_CHECKING + if (DECL_FROM_INLINE (DECL_ORIGIN (decl))) + /* Since the DECL_ABSTRACT_ORIGIN for a DECL is supposed to be the + most distant ancestor, this should never happen. */ + abort (); +#endif - return ret_val; - } + return DECL_ABSTRACT_ORIGIN (decl); } /* Determine the "ultimate origin" of a block. The block may be an inlined @@ -3807,17 +3903,17 @@ add_AT_lbl_id (die, attr_kind, lbl_id) /* Add a section offset attribute value to a DIE. */ static inline void -add_AT_section_offset (die, attr_kind, section) +add_AT_lbl_offset (die, attr_kind, label) register dw_die_ref die; register enum dwarf_attribute attr_kind; - register char *section; + register char *label; { register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node)); attr->dw_attr_next = NULL; attr->dw_attr = attr_kind; - attr->dw_attr_val.val_class = dw_val_class_section_offset; - attr->dw_attr_val.v.val_section = section; + attr->dw_attr_val.val_class = dw_val_class_lbl_offset; + attr->dw_attr_val.v.val_lbl_id = label; add_dwarf_attr (die, attr); } @@ -4280,11 +4376,9 @@ print_die (die, outfile) fprintf (outfile, "die -> <null>"); break; case dw_val_class_lbl_id: + case dw_val_class_lbl_offset: fprintf (outfile, "label: %s", a->dw_attr_val.v.val_lbl_id); break; - case dw_val_class_section_offset: - fprintf (outfile, "section: %s", a->dw_attr_val.v.val_section); - break; case dw_val_class_str: if (a->dw_attr_val.v.val_str != NULL) fprintf (outfile, "\"%s\"", a->dw_attr_val.v.val_str); @@ -4648,7 +4742,7 @@ size_of_die (die) case dw_val_class_lbl_id: size += PTR_SIZE; break; - case dw_val_class_section_offset: + case dw_val_class_lbl_offset: size += DWARF_OFFSET_SIZE; break; case dw_val_class_str: @@ -4750,14 +4844,15 @@ size_of_line_info () /* Prolog. */ size += size_of_line_prolog (); - /* Set address register instruction. */ - size += size_of_set_address; - current_file = 1; current_line = 1; for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) { - register dw_line_info_ref line_info; + register dw_line_info_ref line_info = &line_info_table[lt_index]; + + if (line_info->dw_line_num == current_line + && line_info->dw_file_num == current_file) + continue; /* Advance pc instruction. */ /* ??? See the DW_LNS_advance_pc comment in output_line_info. */ @@ -4766,7 +4861,6 @@ size_of_line_info () else size += size_of_set_address; - line_info = &line_info_table[lt_index]; if (line_info->dw_file_num != current_file) { /* Set file number instruction. */ @@ -4810,6 +4904,12 @@ size_of_line_info () { register dw_separate_line_info_ref line_info = &separate_line_info_table[lt_index]; + + if (line_info->dw_line_num == current_line + && line_info->dw_file_num == current_file + && line_info->function == function) + goto cont; + if (function != line_info->function) { function = line_info->function; @@ -4852,6 +4952,7 @@ size_of_line_info () } } + cont: ++lt_index; /* If we're done with a function, end its sequence. */ @@ -4961,7 +5062,7 @@ value_format (v) return DW_FORM_data; case dw_val_class_lbl_id: return DW_FORM_addr; - case dw_val_class_section_offset: + case dw_val_class_lbl_offset: return DW_FORM_data; case dw_val_class_str: return DW_FORM_string; @@ -5034,6 +5135,11 @@ output_abbrev_section () fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP); } + + /* We need to properly terminate the abbrev table for this + compilation unit, as per the standard, and not rely on + workarounds in e.g. gdb. */ + fprintf (asm_out_file, "\t%s\t0\n", ASM_BYTE_OP); } /* Output location description stack opcode's operands (if any). */ @@ -5183,7 +5289,6 @@ output_die (die) register unsigned long ref_offset; register unsigned long size; register dw_loc_descr_ref loc; - register int i; output_uleb128 (die->die_abbrev); if (flag_debug_asm) @@ -5286,24 +5391,27 @@ output_die (die) break; case dw_val_class_float: - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, - a->dw_attr_val.v.val_float.length * 4); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s %s", - ASM_COMMENT_START, dwarf_attr_name (a->dw_attr)); - - fputc ('\n', asm_out_file); - for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i) - { - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - a->dw_attr_val.v.val_float.array[i]); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s fp constant word %d", - ASM_COMMENT_START, i); + { + register unsigned int i; + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, + a->dw_attr_val.v.val_float.length * 4); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s %s", + ASM_COMMENT_START, dwarf_attr_name (a->dw_attr)); + + fputc ('\n', asm_out_file); + for (i = 0; i < a->dw_attr_val.v.val_float.length; ++i) + { + ASM_OUTPUT_DWARF_DATA4 (asm_out_file, + a->dw_attr_val.v.val_float.array[i]); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s fp constant word %u", + ASM_COMMENT_START, i); - fputc ('\n', asm_out_file); - } + fputc ('\n', asm_out_file); + } break; + } case dw_val_class_flag: ASM_OUTPUT_DWARF_DATA1 (asm_out_file, a->dw_attr_val.v.val_flag); @@ -5334,10 +5442,8 @@ output_die (die) ASM_OUTPUT_DWARF_ADDR (asm_out_file, a->dw_attr_val.v.val_lbl_id); break; - case dw_val_class_section_offset: - ASM_OUTPUT_DWARF_OFFSET (asm_out_file, - stripattributes - (a->dw_attr_val.v.val_section)); + case dw_val_class_lbl_offset: + ASM_OUTPUT_DWARF_OFFSET (asm_out_file, a->dw_attr_val.v.val_lbl_id); break; case dw_val_class_str: @@ -5346,7 +5452,7 @@ output_die (die) else ASM_OUTPUT_ASCII (asm_out_file, a->dw_attr_val.v.val_str, - strlen (a->dw_attr_val.v.val_str) + 1); + (int) strlen (a->dw_attr_val.v.val_str) + 1); break; default: @@ -5397,7 +5503,7 @@ output_compilation_unit_header () fprintf (asm_out_file, "\t%s DWARF version number", ASM_COMMENT_START); fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (ABBREV_SECTION)); + ASM_OUTPUT_DWARF_OFFSET (asm_out_file, abbrev_section_label); if (flag_debug_asm) fprintf (asm_out_file, "\t%s Offset Into Abbrev. Section", ASM_COMMENT_START); @@ -5470,7 +5576,7 @@ output_pubnames () fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START); fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION)); + ASM_OUTPUT_DWARF_OFFSET (asm_out_file, debug_info_section_label); if (flag_debug_asm) fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.", ASM_COMMENT_START); @@ -5498,7 +5604,8 @@ output_pubnames () } else { - ASM_OUTPUT_ASCII (asm_out_file, pub->name, strlen (pub->name) + 1); + ASM_OUTPUT_ASCII (asm_out_file, pub->name, + (int) strlen (pub->name) + 1); } fputc ('\n', asm_out_file); @@ -5550,7 +5657,7 @@ output_aranges () fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START); fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION)); + ASM_OUTPUT_DWARF_OFFSET (asm_out_file, debug_info_section_label); if (flag_debug_asm) fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.", ASM_COMMENT_START); @@ -5576,12 +5683,13 @@ output_aranges () ASM_COMMENT_START, 2 * PTR_SIZE); fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_SECTION); + ASM_OUTPUT_DWARF_ADDR (asm_out_file, text_section_label); if (flag_debug_asm) fprintf (asm_out_file, "\t%s Address", ASM_COMMENT_START); fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_ADDR_DELTA (asm_out_file, text_end_label, TEXT_SECTION); + ASM_OUTPUT_DWARF_ADDR_DELTA (asm_out_file, text_end_label, + text_section_label); if (flag_debug_asm) fprintf (asm_out_file, "%s Length", ASM_COMMENT_START); @@ -5734,7 +5842,7 @@ output_line_info () { ASM_OUTPUT_ASCII (asm_out_file, file_table[ft_index], - strlen (file_table[ft_index]) + 1); + (int) strlen (file_table[ft_index]) + 1); } fputc ('\n', asm_out_file); @@ -5756,27 +5864,25 @@ output_line_info () ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 0); fputc ('\n', asm_out_file); - /* Set the address register to the first location in the text section */ - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 0); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s DW_LNE_set_address", ASM_COMMENT_START); - - fputc ('\n', asm_out_file); - output_uleb128 (1 + PTR_SIZE); - fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address); - fputc ('\n', asm_out_file); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_SECTION); - fputc ('\n', asm_out_file); + /* We used to set the address register to the first location in the text + section here, but that didn't accomplish anything since we already + have a line note for the opening brace of the first function. */ /* Generate the line number to PC correspondence table, encoded as a series of state machine operations. */ current_file = 1; current_line = 1; - strcpy (prev_line_label, TEXT_SECTION); + strcpy (prev_line_label, text_section_label); for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) { - register dw_line_info_ref line_info; + register dw_line_info_ref line_info = &line_info_table[lt_index]; + + /* Don't emit anything for redundant notes. Just updating the + address doesn't accomplish anything, because we already assume + that anything after the last address is this line. */ + if (line_info->dw_line_num == current_line + && line_info->dw_file_num == current_file) + continue; /* Emit debug info for the address of the current line, choosing the encoding that uses the least amount of space. */ @@ -5820,7 +5926,6 @@ output_line_info () /* Emit debug info for the source file of the current line, if different from the previous line. */ - line_info = &line_info_table[lt_index]; if (line_info->dw_file_num != current_file) { current_file = line_info->dw_file_num; @@ -5838,35 +5943,48 @@ output_line_info () /* Emit debug info for the current line number, choosing the encoding that uses the least amount of space. */ - line_offset = line_info->dw_line_num - current_line; - line_delta = line_offset - DWARF_LINE_BASE; - current_line = line_info->dw_line_num; - if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1)) + if (line_info->dw_line_num != current_line) { - /* This can handle deltas from -10 to 234, using the current - definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE. This - takes 1 byte. */ - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, - DWARF_LINE_OPCODE_BASE + line_delta); - if (flag_debug_asm) - fprintf (asm_out_file, - "\t%s line %ld", ASM_COMMENT_START, current_line); + line_offset = line_info->dw_line_num - current_line; + line_delta = line_offset - DWARF_LINE_BASE; + current_line = line_info->dw_line_num; + if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1)) + { + /* This can handle deltas from -10 to 234, using the current + definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE. This + takes 1 byte. */ + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, + DWARF_LINE_OPCODE_BASE + line_delta); + if (flag_debug_asm) + fprintf (asm_out_file, + "\t%s line %ld", ASM_COMMENT_START, current_line); - fputc ('\n', asm_out_file); + fputc ('\n', asm_out_file); + } + else + { + /* This can handle any delta. This takes at least 4 bytes, + depending on the value being encoded. */ + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_advance_line); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s advance to line %ld", + ASM_COMMENT_START, current_line); + + fputc ('\n', asm_out_file); + output_sleb128 (line_offset); + fputc ('\n', asm_out_file); + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_copy); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s DW_LNS_copy", ASM_COMMENT_START); + fputc ('\n', asm_out_file); + } } else { - /* This can handle any delta. This takes at least 4 bytes, depending - on the value being encoded. */ - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_advance_line); - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s advance to line %ld", - ASM_COMMENT_START, current_line); - - fputc ('\n', asm_out_file); - output_sleb128 (line_offset); - fputc ('\n', asm_out_file); + /* We still need to start a new row, so output a copy insn. */ ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_copy); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s DW_LNS_copy", ASM_COMMENT_START); fputc ('\n', asm_out_file); } } @@ -5916,6 +6034,12 @@ output_line_info () register dw_separate_line_info_ref line_info = &separate_line_info_table[lt_index]; + /* Don't emit anything for redundant notes. */ + if (line_info->dw_line_num == current_line + && line_info->dw_file_num == current_file + && line_info->function == function) + goto cont; + /* Emit debug info for the address of the current line. If this is a new function, or the first line of a function, then we need to handle it differently. */ @@ -6016,10 +6140,21 @@ output_line_info () output_sleb128 (line_offset); fputc ('\n', asm_out_file); ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_copy); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s DW_LNS_copy", ASM_COMMENT_START); fputc ('\n', asm_out_file); } } + else + { + /* We still need to start a new row, so output a copy insn. */ + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_copy); + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s DW_LNS_copy", ASM_COMMENT_START); + fputc ('\n', asm_out_file); + } + cont: ++lt_index; /* If we're done with a function, end its sequence. */ @@ -7053,9 +7188,42 @@ add_location_or_const_value_attribute (die, decl) rtl = DECL_INCOMING_RTL (decl); else if (! BYTES_BIG_ENDIAN && TREE_CODE (declared_type) == INTEGER_TYPE - && TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type)) + && (GET_MODE_SIZE (TYPE_MODE (declared_type)) + <= GET_MODE_SIZE (TYPE_MODE (passed_type)))) rtl = DECL_INCOMING_RTL (decl); } + + /* If the parm was passed in registers, but lives on the stack, then + make a big endian correction if the mode of the type of the + parameter is not the same as the mode of the rtl. */ + /* ??? This is the same series of checks that are made in dbxout.c before + we reach the big endian correction code there. It isn't clear if all + of these checks are necessary here, but keeping them all is the safe + thing to do. */ + else if (GET_CODE (rtl) == MEM + && XEXP (rtl, 0) != const0_rtx + && ! CONSTANT_P (XEXP (rtl, 0)) + /* Not passed in memory. */ + && GET_CODE (DECL_INCOMING_RTL (decl)) != MEM + /* Not passed by invisible reference. */ + && (GET_CODE (XEXP (rtl, 0)) != REG + || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM + || REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM +#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM + || REGNO (XEXP (rtl, 0)) == ARG_POINTER_REGNUM +#endif + ) + /* Big endian correction check. */ + && BYTES_BIG_ENDIAN + && TYPE_MODE (TREE_TYPE (decl)) != GET_MODE (rtl) + && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))) + < UNITS_PER_WORD)) + { + int offset = (UNITS_PER_WORD + - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl)))); + rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)), + plus_constant (XEXP (rtl, 0), offset)); + } } if (rtl == NULL_RTX) @@ -7063,7 +7231,7 @@ add_location_or_const_value_attribute (die, decl) rtl = eliminate_regs (rtl, 0, NULL_RTX); #ifdef LEAF_REG_REMAP - if (leaf_function) + if (current_function_uses_only_leaf_regs) leaf_renumber_regs_insn (rtl); #endif @@ -7528,7 +7696,7 @@ push_decl_scope (scope) subtype. In such a case, we need to search the decl_scope_table to find the parent of this subtype. */ - if (TREE_CODE_CLASS (TREE_CODE (scope)) == 't') + if (AGGREGATE_TYPE_P (scope)) containing_scope = TYPE_CONTEXT (scope); else containing_scope = NULL_TREE; @@ -7580,6 +7748,12 @@ scope_die_for (t, context_die) if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL) containing_scope = NULL_TREE; + /* Ignore function type "scopes" from the C frontend. They mean that + a tagged type is local to a parmlist of a function declarator, but + that isn't useful to DWARF. */ + if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE) + containing_scope = NULL_TREE; + /* Function-local tags and functions get stuck in limbo until they are fixed up by decls_for_scope. */ if (context_die == NULL && containing_scope != NULL_TREE @@ -7616,12 +7790,14 @@ scope_die_for (t, context_die) if (i < 0) { - if (scope_die != comp_unit_die - || TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't') + if (TREE_CODE_CLASS (TREE_CODE (containing_scope)) != 't') abort (); if (debug_info_level > DINFO_LEVEL_TERSE && !TREE_ASM_WRITTEN (containing_scope)) abort (); + + /* If none of the current dies are suitable, we get file scope. */ + scope_die = comp_unit_die; } } @@ -7881,6 +8057,39 @@ output_pending_types_for_scope (context_die) } } +/* Remember a type in the incomplete_types_list. */ + +static void +add_incomplete_type (type) + tree type; +{ + if (incomplete_types == incomplete_types_allocated) + { + incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT; + incomplete_types_list + = (tree *) xrealloc (incomplete_types_list, + sizeof (tree) * incomplete_types_allocated); + } + + incomplete_types_list[incomplete_types++] = type; +} + +/* Walk through the list of incomplete types again, trying once more to + emit full debugging info for them. */ + +static void +retry_incomplete_types () +{ + register tree type; + + while (incomplete_types) + { + --incomplete_types; + type = incomplete_types_list[incomplete_types]; + gen_type_die (type, comp_unit_die); + } +} + /* Generate a DIE to represent an inlined instance of an enumeration type. */ static void @@ -8162,7 +8371,17 @@ gen_subprogram_die (decl, context_die) = lookup_filename (DECL_SOURCE_FILE (decl)); if (get_AT_flag (old_die, DW_AT_declaration) != 1) - abort (); + { + /* ??? This can happen if there is a bug in the program, for + instance, if it has duplicate function definitions. Ideally, + we should detect this case and ignore it. For now, if we have + already reported an error, any error at all, then assume that + we got here because of a input error, not a dwarf2 bug. */ + extern int errorcount; + if (errorcount) + return; + abort (); + } /* If the definition comes from the same place as the declaration, maybe use the old DIE. We always want the DIE for this function @@ -8490,7 +8709,13 @@ gen_label_die (decl, context_die) else { insn = DECL_RTL (decl); - if (GET_CODE (insn) == CODE_LABEL) + + /* Deleted labels are programmer specified labels which have been + eliminated because of various optimisations. We still emit them + here so that it is possible to put breakpoints on them. */ + if (GET_CODE (insn) == CODE_LABEL + || ((GET_CODE (insn) == NOTE + && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))) { /* When optimization is enabled (via -O) some parts of the compiler (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which @@ -8797,7 +9022,7 @@ gen_struct_or_union_type_die (type, context_die) return; if (TYPE_CONTEXT (type) != NULL_TREE - && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't') + && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))) nested = 1; scope_die = scope_die_for (type, context_die); @@ -8856,7 +9081,13 @@ gen_struct_or_union_type_die (type, context_die) } } else - add_AT_flag (type_die, DW_AT_declaration, 1); + { + add_AT_flag (type_die, DW_AT_declaration, 1); + + /* We can't do this for function-local types, and we don't need to. */ + if (TREE_PERMANENT (type)) + add_incomplete_type (type); + } } /* Generate a DIE for a subroutine _type_. */ @@ -9010,7 +9241,7 @@ gen_type_die (type, context_die) /* If this is a nested type whose containing class hasn't been written out yet, writing it out will cover this one, too. */ if (TYPE_CONTEXT (type) - && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't' + && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)) && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type))) { gen_type_die (TYPE_CONTEXT (type), context_die); @@ -9029,7 +9260,7 @@ gen_type_die (type, context_die) gen_struct_or_union_type_die (type, context_die); if (TYPE_CONTEXT (type) - && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't' + && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)) && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type))) pop_decl_scope (); @@ -9409,7 +9640,7 @@ dwarf2out_decl (decl) if (DECL_IGNORED_P (decl)) { if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_INITIAL (decl) != NULL) + && DECL_INITIAL (decl) != NULL) abort (); return; @@ -9775,6 +10006,21 @@ dwarf2out_init (asm_out_file, main_input_filename) gen_compile_unit_die (main_input_filename); ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, + DEBUG_INFO_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, + DEBUG_LINE_SECTION_LABEL, 0); + + ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION); + ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label); + ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION); + ASM_OUTPUT_LABEL (asm_out_file, text_section_label); + ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION); + ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label); + ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION); + ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label); } /* Output stuff that dwarf requires at the end of every file, @@ -9810,6 +10056,10 @@ dwarf2out_finish () free (node); } + /* Walk through the list of incomplete types again, trying once more to + emit full debugging info for them. */ + retry_incomplete_types (); + /* Traverse the DIE tree and add sibling attributes to those DIE's that have children. */ add_sibling_attributes (comp_unit_die); @@ -9842,11 +10092,12 @@ dwarf2out_finish () was in .text. */ if (separate_line_info_table_in_use == 0) { - add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, TEXT_SECTION); + add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, text_section_label); add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label); } - add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, DEBUG_LINE_SECTION); + add_AT_lbl_offset (comp_unit_die, DW_AT_stmt_list, + debug_line_section_label); } /* Output the abbreviation table. */ |