*** empty log message ***

From-SVN: r12911
This commit is contained in:
Jason Merrill 1996-10-07 22:02:43 +00:00
parent 85f8926ee5
commit e90b62db74
2 changed files with 277 additions and 40 deletions

View File

@ -193,6 +193,10 @@ enum dwarf_attribute
DW_AT_MIPS_loop_unroll_factor = 0x2005, DW_AT_MIPS_loop_unroll_factor = 0x2005,
DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_software_pipeline_depth = 0x2006,
DW_AT_MIPS_linkage_name = 0x2007, DW_AT_MIPS_linkage_name = 0x2007,
DW_AT_MIPS_stride = 0x2008,
DW_AT_MIPS_abstract_name = 0x2009,
DW_AT_MIPS_clone_origin = 0x200a,
DW_AT_MIPS_has_inlines = 0x200b,
/* GNU extensions. */ /* GNU extensions. */
DW_AT_sf_names = 0x2101, DW_AT_sf_names = 0x2101,
DW_AT_src_info = 0x2102, DW_AT_src_info = 0x2102,

View File

@ -105,6 +105,7 @@ typedef struct die_struct *dw_die_ref;
typedef struct dw_attr_struct *dw_attr_ref; typedef struct dw_attr_struct *dw_attr_ref;
typedef struct dw_val_struct *dw_val_ref; typedef struct dw_val_struct *dw_val_ref;
typedef struct dw_line_info_struct *dw_line_info_ref; typedef struct dw_line_info_struct *dw_line_info_ref;
typedef struct dw_separate_line_info_struct *dw_separate_line_info_ref;
typedef struct dw_loc_descr_struct *dw_loc_descr_ref; typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
typedef struct dw_cfi_struct *dw_cfi_ref; typedef struct dw_cfi_struct *dw_cfi_ref;
typedef struct dw_fde_struct *dw_fde_ref; typedef struct dw_fde_struct *dw_fde_ref;
@ -129,6 +130,16 @@ typedef struct dw_line_info_struct
} }
dw_line_info_entry; dw_line_info_entry;
/* Line information for functions in separate sections; each one gets its
own sequence. */
typedef struct dw_separate_line_info_struct
{
unsigned long dw_file_num;
unsigned long dw_line_num;
unsigned long function;
}
dw_separate_line_info_entry;
/* The dw_val_node describes an attibute's value, as it is /* The dw_val_node describes an attibute's value, as it is
represnted internally. */ represnted internally. */
typedef struct dw_val_struct typedef struct dw_val_struct
@ -448,12 +459,22 @@ static unsigned abbrev_die_table_in_use;
#define ABBREV_DIE_TABLE_INCREMENT 256 #define ABBREV_DIE_TABLE_INCREMENT 256
/* A pointer to the base of a table that contains line information /* A pointer to the base of a table that contains line information
for each source code line in the compilation unit. */ for each source code line in .text in the compilation unit. */
static dw_line_info_ref line_info_table; static dw_line_info_ref line_info_table;
/* Number of elements currently allocated for line_info_table. */ /* Number of elements currently allocated for line_info_table. */
static unsigned line_info_table_allocated; static unsigned line_info_table_allocated;
/* Number of elements in separate_line_info_table currently in use. */
static unsigned separate_line_info_table_in_use;
/* A pointer to the base of a table that contains line information
for each source code line outside of .text in the compilation unit. */
static dw_separate_line_info_ref separate_line_info_table;
/* Number of elements currently allocated for separate_line_info_table. */
static unsigned separate_line_info_table_allocated;
/* Number of elements in line_info_table currently in use. */ /* Number of elements in line_info_table currently in use. */
static unsigned line_info_table_in_use; static unsigned line_info_table_in_use;
@ -703,6 +724,9 @@ static unsigned lookup_filename ();
#ifndef LINE_CODE_LABEL_FMT #ifndef LINE_CODE_LABEL_FMT
#define LINE_CODE_LABEL_FMT ".L_LC%u" #define LINE_CODE_LABEL_FMT ".L_LC%u"
#endif #endif
#ifndef SEPARATE_LINE_CODE_LABEL_FMT
#define SEPARATE_LINE_CODE_LABEL_FMT ".L_SLC%u"
#endif
#ifndef SFNAMES_ENTRY_LABEL_FMT #ifndef SFNAMES_ENTRY_LABEL_FMT
#define SFNAMES_ENTRY_LABEL_FMT ".L_F%u" #define SFNAMES_ENTRY_LABEL_FMT ".L_F%u"
#endif #endif
@ -2212,7 +2236,7 @@ remove_AT (die, attr_kind)
if (die->die_attr_last == a->dw_attr_next) if (die->die_attr_last == a->dw_attr_next)
die->die_attr_last = a; die->die_attr_last = a;
a->dw_attr_next = a->dw_attr_next->dw_attr_next; a->dw_attr_next = a->dw_attr_next->dw_attr_next;
return; break;
} }
if (removed) if (removed)
free (removed); free (removed);
@ -2952,12 +2976,12 @@ static unsigned long
size_of_line_info () size_of_line_info ()
{ {
register unsigned long size; register unsigned long size;
register dw_line_info_ref line_info;
register unsigned long lt_index; register unsigned long lt_index;
register unsigned long current_line; register unsigned long current_line;
register long line_offset; register long line_offset;
register long line_delta; register long line_delta;
register unsigned long current_file; register unsigned long current_file;
register unsigned long function;
/* Version number. */ /* Version number. */
size = 2; size = 2;
/* Prolog length specifier. */ /* Prolog length specifier. */
@ -2971,6 +2995,7 @@ size_of_line_info ()
current_line = 1; current_line = 1;
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
{ {
register dw_line_info_ref line_info;
/* Advance pc instruction. */ /* Advance pc instruction. */
size += 1 + 2; size += 1 + 2;
line_info = &line_info_table[lt_index]; line_info = &line_info_table[lt_index];
@ -3005,6 +3030,65 @@ size_of_line_info ()
size += 1 + 2; size += 1 + 2;
/* End of line number info. marker. */ /* End of line number info. marker. */
size += 1 + size_of_uleb128 (1) + 1; size += 1 + size_of_uleb128 (1) + 1;
function = 0;
current_file = 1;
current_line = 1;
for (lt_index = 0; lt_index < separate_line_info_table_in_use; )
{
register dw_separate_line_info_ref line_info
= &separate_line_info_table[lt_index];
if (function != line_info->function)
{
function = line_info->function;
/* Set address register instruction. */
size += 1 + size_of_uleb128 (1 + PTR_SIZE)
+ 1 + PTR_SIZE;
}
else
{
/* Advance pc instruction. */
size += 1 + 2;
}
if (line_info->dw_file_num != current_file)
{
/* Set file number instruction. */
size += 1;
current_file = line_info->dw_file_num;
size += size_of_uleb128 (current_file);
}
if (line_info->dw_line_num != 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))
{
/* 1-byte special line number instruction. */
size += 1;
}
else
{
/* Advance line instruction. */
size += 1;
size += size_of_sleb128 (line_offset);
/* Generate line entry instruction. */
size += 1;
}
}
++lt_index;
/* If we're done with a function, end its sequence. */
if (lt_index == separate_line_info_table_in_use
|| separate_line_info_table[lt_index].function != function)
{
current_file = 1;
current_line = 1;
/* Advance pc instruction. */
size += 1 + 2;
/* End of line number info. marker. */
size += 1 + size_of_uleb128 (1) + 1;
}
}
return size; return size;
} }
@ -3999,21 +4083,18 @@ output_aranges ()
static void static void
output_line_info () output_line_info ()
{ {
register unsigned long line_info_len;
register unsigned long line_info_prolog_len;
char line_label[MAX_ARTIFICIAL_LABEL_BYTES]; char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
char prev_line_label[MAX_ARTIFICIAL_LABEL_BYTES]; char prev_line_label[MAX_ARTIFICIAL_LABEL_BYTES];
register unsigned opc; register unsigned opc;
register unsigned n_op_args; register unsigned n_op_args;
register dw_line_info_ref line_info;
register unsigned long ft_index; register unsigned long ft_index;
register unsigned long lt_index; register unsigned long lt_index;
register unsigned long current_line; register unsigned long current_line;
register long line_offset; register long line_offset;
register long line_delta; register long line_delta;
register unsigned long current_file; register unsigned long current_file;
line_info_len = size_of_line_info (); register unsigned long function;
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, line_info_len); ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size_of_line_info ());
if (flag_verbose_asm) if (flag_verbose_asm)
{ {
fprintf (asm_out_file, "\t%s Length of Source Line Info.", fprintf (asm_out_file, "\t%s Length of Source Line Info.",
@ -4027,8 +4108,7 @@ output_line_info ()
ASM_COMMENT_START); ASM_COMMENT_START);
} }
fputc ('\n', asm_out_file); fputc ('\n', asm_out_file);
line_info_prolog_len = size_of_line_prolog (); ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size_of_line_prolog ());
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, line_info_prolog_len);
if (flag_verbose_asm) if (flag_verbose_asm)
{ {
fprintf (asm_out_file, "\t%s Prolog Length", fprintf (asm_out_file, "\t%s Prolog Length",
@ -4149,6 +4229,7 @@ output_line_info ()
strcpy (prev_line_label, TEXT_SECTION); strcpy (prev_line_label, TEXT_SECTION);
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
{ {
register dw_line_info_ref line_info;
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_fixed_advance_pc); ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_fixed_advance_pc);
if (flag_verbose_asm) if (flag_verbose_asm)
{ {
@ -4234,6 +4315,121 @@ output_line_info ()
fputc ('\n', asm_out_file); fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_end_sequence); ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_end_sequence);
fputc ('\n', asm_out_file); fputc ('\n', asm_out_file);
function = 0;
current_file = 1;
current_line = 1;
for (lt_index = 0; lt_index < separate_line_info_table_in_use; )
{
register dw_separate_line_info_ref line_info
= &separate_line_info_table[lt_index];
sprintf (line_label, SEPARATE_LINE_CODE_LABEL_FMT, lt_index);
if (function != line_info->function)
{
function = line_info->function;
/* Set the address register to the first line in the function */
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 0);
if (flag_verbose_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, line_label);
fputc ('\n', asm_out_file);
}
else
{
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_fixed_advance_pc);
if (flag_verbose_asm)
fprintf (asm_out_file, "\t%s DW_LNS_fixed_advance_pc",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, line_label, prev_line_label);
fputc ('\n', asm_out_file);
}
if (line_info->dw_file_num != current_file)
{
current_file = line_info->dw_file_num;
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_set_file);
if (flag_verbose_asm)
{
fprintf (asm_out_file,
"\t%s DW_LNS_set_file", ASM_COMMENT_START);
}
fputc ('\n', asm_out_file);
output_uleb128 (current_file);
if (flag_verbose_asm)
{
fprintf (asm_out_file, "\t%s \"%s\"",
ASM_COMMENT_START, file_table[current_file]);
}
fputc ('\n', asm_out_file);
}
if (line_info->dw_line_num != 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))
{
ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
DWARF_LINE_OPCODE_BASE + line_delta);
if (flag_verbose_asm)
{
fprintf (asm_out_file,
"\t%s line %d", ASM_COMMENT_START, current_line);
}
fputc ('\n', asm_out_file);
}
else
{
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_advance_line);
if (flag_verbose_asm)
{
fprintf (asm_out_file,
"\t%s advance to line %d",
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);
fputc ('\n', asm_out_file);
}
}
++lt_index;
strcpy (prev_line_label, line_label);
/* If we're done with a function, end its sequence. */
if (lt_index == separate_line_info_table_in_use
|| separate_line_info_table[lt_index].function != function)
{
current_file = 1;
current_line = 1;
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNS_fixed_advance_pc);
if (flag_verbose_asm)
fprintf (asm_out_file, "\t%s DW_LNS_fixed_advance_pc",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
sprintf (line_label, FUNC_END_LABEL_FMT, function);
ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, line_label, prev_line_label);
fputc ('\n', asm_out_file);
/* Output the marker for the end of this sequence. */
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 0);
if (flag_verbose_asm)
fprintf (asm_out_file, "\t%s DW_LNE_end_sequence",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
output_uleb128 (1);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_end_sequence);
fputc ('\n', asm_out_file);
}
}
} }
/**************** attribute support utilities ********************************/ /**************** attribute support utilities ********************************/
@ -6562,15 +6758,9 @@ gen_compile_unit_die (main_input_filename)
{ {
add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C89); add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C89);
} }
add_AT_lbl_id (comp_unit_die, DW_AT_low_pc, TEXT_SECTION); if (debug_info_level >= DINFO_LEVEL_VERBOSE)
add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, TEXT_END_LABEL);
if (debug_info_level >= DINFO_LEVEL_NORMAL)
{ {
add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, LINE_SECTION); add_AT_unsigned (comp_unit_die, DW_AT_macro_info, 0);
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
add_AT_unsigned (comp_unit_die, DW_AT_macro_info, 0);
}
} }
} }
@ -6800,7 +6990,7 @@ gen_type_die (type, context_die)
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
case QUAL_UNION_TYPE: case QUAL_UNION_TYPE:
/* For a non-file-scope tagged type, we can always go ahead and output /* For a function-scope tagged type, we can always go ahead and output
a Dwarf description of this type right now, even if the type in a Dwarf description of this type right now, even if the type in
question is still incomplete, because if this local type *was* ever question is still incomplete, because if this local type *was* ever
completed anywhere within its scope, that complete definition would completed anywhere within its scope, that complete definition would
@ -6827,7 +7017,8 @@ gen_type_die (type, context_die)
ever going to know, so at that point in time, we can safely generate ever going to know, so at that point in time, we can safely generate
correct Dwarf descriptions for these file-scope tagged types. */ correct Dwarf descriptions for these file-scope tagged types. */
is_complete = TYPE_SIZE (type) != 0 is_complete = TYPE_SIZE (type) != 0
|| TYPE_CONTEXT (type) != NULL || (TYPE_CONTEXT (type) != NULL
&& TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) != 't')
|| finalizing; || finalizing;
if (TREE_CODE (type) == ENUMERAL_TYPE) if (TREE_CODE (type) == ENUMERAL_TYPE)
{ {
@ -7569,27 +7760,57 @@ dwarfout_line (filename, line)
{ {
char label[MAX_ARTIFICIAL_LABEL_BYTES]; char label[MAX_ARTIFICIAL_LABEL_BYTES];
register unsigned this_file_entry_num = lookup_filename (filename); register unsigned this_file_entry_num = lookup_filename (filename);
register dw_line_info_ref line_info;
if (debug_info_level >= DINFO_LEVEL_NORMAL) if (debug_info_level >= DINFO_LEVEL_NORMAL)
{ {
function_section (current_function_decl); function_section (current_function_decl);
sprintf (label, LINE_CODE_LABEL_FMT, line_info_table_in_use);
ASM_OUTPUT_LABEL (asm_out_file, label);
fputc ('\n', asm_out_file);
/* expand the line info table if necessary */ if (DECL_SECTION_NAME (current_function_decl))
if (line_info_table_in_use == line_info_table_allocated)
{ {
line_info_table_allocated += LINE_INFO_TABLE_INCREMENT; register dw_separate_line_info_ref line_info;
line_info_table sprintf (label, SEPARATE_LINE_CODE_LABEL_FMT,
= (dw_line_info_ref) separate_line_info_table_in_use);
xrealloc (line_info_table, ASM_OUTPUT_LABEL (asm_out_file, label);
line_info_table_allocated * sizeof (dw_line_info_entry)); fputc ('\n', asm_out_file);
/* expand the line info table if necessary */
if (separate_line_info_table_in_use
== separate_line_info_table_allocated)
{
separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
separate_line_info_table
= (dw_separate_line_info_ref) xrealloc
(separate_line_info_table,
separate_line_info_table_allocated
* sizeof (dw_separate_line_info_entry));
}
/* add the new entry at the end of the line_info_table. */
line_info
= &separate_line_info_table[separate_line_info_table_in_use++];
line_info->dw_file_num = lookup_filename (filename);
line_info->dw_line_num = line;
line_info->function = current_funcdef_number;
}
else
{
register dw_line_info_ref line_info;
sprintf (label, LINE_CODE_LABEL_FMT, line_info_table_in_use);
ASM_OUTPUT_LABEL (asm_out_file, label);
fputc ('\n', asm_out_file);
/* expand the line info table if necessary */
if (line_info_table_in_use == line_info_table_allocated)
{
line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
line_info_table
= (dw_line_info_ref) xrealloc
(line_info_table,
line_info_table_allocated * sizeof (dw_line_info_entry));
}
/* add the new entry at the end of the line_info_table. */
line_info = &line_info_table[line_info_table_in_use++];
line_info->dw_file_num = lookup_filename (filename);
line_info->dw_line_num = line;
} }
/* add the new entry at the end of the line_info_table. */
line_info = &line_info_table[line_info_table_in_use++];
line_info->dw_file_num = lookup_filename (filename);
line_info->dw_line_num = line;
} }
} }
@ -7762,17 +7983,29 @@ dwarfout_finish ()
ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL); ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL);
#endif #endif
/* Output the source line correspondence table. */
if (line_info_table_in_use > 1 || separate_line_info_table_in_use)
{
fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, LINE_SECTION);
output_line_info ();
/* We can only use the low/high_pc attributes if all of the code
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_high_pc, TEXT_END_LABEL);
}
add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, LINE_SECTION);
}
/* Output the abbreviation table. */ /* Output the abbreviation table. */
fputc ('\n', asm_out_file); fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION); ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
build_abbrev_table (comp_unit_die); build_abbrev_table (comp_unit_die);
output_abbrev_section (); output_abbrev_section ();
/* Output the source line correspondence table. */
fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, LINE_SECTION);
output_line_info ();
/* Initialize the beginning DIE offset - and calculate sizes/offsets. */ /* Initialize the beginning DIE offset - and calculate sizes/offsets. */
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE; next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
calc_die_sizes (comp_unit_die); calc_die_sizes (comp_unit_die);