*** 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_software_pipeline_depth = 0x2006,
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. */
DW_AT_sf_names = 0x2101,
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_val_struct *dw_val_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_cfi_struct *dw_cfi_ref;
typedef struct dw_fde_struct *dw_fde_ref;
@ -129,6 +130,16 @@ typedef struct dw_line_info_struct
}
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
represnted internally. */
typedef struct dw_val_struct
@ -448,12 +459,22 @@ static unsigned abbrev_die_table_in_use;
#define ABBREV_DIE_TABLE_INCREMENT 256
/* 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;
/* Number of elements currently allocated for line_info_table. */
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. */
static unsigned line_info_table_in_use;
@ -703,6 +724,9 @@ static unsigned lookup_filename ();
#ifndef LINE_CODE_LABEL_FMT
#define LINE_CODE_LABEL_FMT ".L_LC%u"
#endif
#ifndef SEPARATE_LINE_CODE_LABEL_FMT
#define SEPARATE_LINE_CODE_LABEL_FMT ".L_SLC%u"
#endif
#ifndef SFNAMES_ENTRY_LABEL_FMT
#define SFNAMES_ENTRY_LABEL_FMT ".L_F%u"
#endif
@ -2212,7 +2236,7 @@ remove_AT (die, attr_kind)
if (die->die_attr_last == a->dw_attr_next)
die->die_attr_last = a;
a->dw_attr_next = a->dw_attr_next->dw_attr_next;
return;
break;
}
if (removed)
free (removed);
@ -2952,12 +2976,12 @@ static unsigned long
size_of_line_info ()
{
register unsigned long size;
register dw_line_info_ref line_info;
register unsigned long lt_index;
register unsigned long current_line;
register long line_offset;
register long line_delta;
register unsigned long current_file;
register unsigned long function;
/* Version number. */
size = 2;
/* Prolog length specifier. */
@ -2971,6 +2995,7 @@ size_of_line_info ()
current_line = 1;
for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
{
register dw_line_info_ref line_info;
/* Advance pc instruction. */
size += 1 + 2;
line_info = &line_info_table[lt_index];
@ -3005,6 +3030,65 @@ size_of_line_info ()
size += 1 + 2;
/* End of line number info. marker. */
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;
}
@ -3999,21 +4083,18 @@ output_aranges ()
static void
output_line_info ()
{
register unsigned long line_info_len;
register unsigned long line_info_prolog_len;
char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
char prev_line_label[MAX_ARTIFICIAL_LABEL_BYTES];
register unsigned opc;
register unsigned n_op_args;
register dw_line_info_ref line_info;
register unsigned long ft_index;
register unsigned long lt_index;
register unsigned long current_line;
register long line_offset;
register long line_delta;
register unsigned long current_file;
line_info_len = size_of_line_info ();
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, line_info_len);
register unsigned long function;
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size_of_line_info ());
if (flag_verbose_asm)
{
fprintf (asm_out_file, "\t%s Length of Source Line Info.",
@ -4027,8 +4108,7 @@ output_line_info ()
ASM_COMMENT_START);
}
fputc ('\n', asm_out_file);
line_info_prolog_len = size_of_line_prolog ();
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, line_info_prolog_len);
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size_of_line_prolog ());
if (flag_verbose_asm)
{
fprintf (asm_out_file, "\t%s Prolog Length",
@ -4149,6 +4229,7 @@ output_line_info ()
strcpy (prev_line_label, TEXT_SECTION);
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);
if (flag_verbose_asm)
{
@ -4234,6 +4315,121 @@ output_line_info ()
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_end_sequence);
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 ********************************/
@ -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_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);
if (debug_info_level >= DINFO_LEVEL_NORMAL)
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, LINE_SECTION);
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
add_AT_unsigned (comp_unit_die, DW_AT_macro_info, 0);
}
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 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
question is still incomplete, because if this local type *was* ever
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
correct Dwarf descriptions for these file-scope tagged types. */
is_complete = TYPE_SIZE (type) != 0
|| TYPE_CONTEXT (type) != NULL
|| (TYPE_CONTEXT (type) != NULL
&& TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) != 't')
|| finalizing;
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
@ -7569,27 +7760,57 @@ dwarfout_line (filename, line)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
register unsigned this_file_entry_num = lookup_filename (filename);
register dw_line_info_ref line_info;
if (debug_info_level >= DINFO_LEVEL_NORMAL)
{
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 (line_info_table_in_use == line_info_table_allocated)
if (DECL_SECTION_NAME (current_function_decl))
{
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));
register dw_separate_line_info_ref line_info;
sprintf (label, SEPARATE_LINE_CODE_LABEL_FMT,
separate_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 (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);
#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. */
fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
build_abbrev_table (comp_unit_die);
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. */
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
calc_die_sizes (comp_unit_die);