dwarf2out.c: Add dw_loc_list_ref, a reference to a location list.
2001-05-18 Daniel Berlin <dan@cgsoftware.com> * dwarf2out.c: Add dw_loc_list_ref, a reference to a location list. Add have_location_lists, a variable to determine whether we need a .debug_loc section or not. (enum dw_val_class): Add dw_val_class_loc_list. (dw_val_struct): Add val_loc_list. (dw_loc_list_struct): New structure, represents location lists. (new_loc_list): New function, return a new location list, given the range and location expression. (add_loc_descr_to_loc_list): New function, add a location expression to a location list, given the expression and range. (output_loc_list): New function, output a location list. (gen_internal_sym): Modified to take symbol prefix, so we can reuse it for location list symbols. (add_AT_loc_list): New function, add a location list to a DIE at the named attribute. (AT_loc_list): New function, return the location list reference for a given attribute, if it's a location list. (print_die): Handle dw_val_class_loc_list. (size_of_die): Ditto. (value_format): Ditto. (output_die): Ditto. (output_location_lists): New function, output all of the location lists for a DIE and it's children. (dwarf2out_finish): Call output_location_lists if we have location lists. From-SVN: r42266
This commit is contained in:
parent
2b0cbc5d55
commit
63e4656873
@ -1,3 +1,33 @@
|
||||
2001-05-18 Daniel Berlin <dan@cgsoftware.com>
|
||||
|
||||
* dwarf2out.c: Add dw_loc_list_ref, a reference to a location
|
||||
list.
|
||||
Add have_location_lists, a variable to determine whether we need a
|
||||
.debug_loc section or not.
|
||||
(enum dw_val_class): Add dw_val_class_loc_list.
|
||||
(dw_val_struct): Add val_loc_list.
|
||||
(dw_loc_list_struct): New structure, represents location lists.
|
||||
(new_loc_list): New function, return a new location list, given
|
||||
the range and location expression.
|
||||
(add_loc_descr_to_loc_list): New function, add a location
|
||||
expression to a location list, given the expression and range.
|
||||
(output_loc_list): New function, output a location list.
|
||||
(gen_internal_sym): Modified to take symbol prefix, so we can
|
||||
reuse it for location list symbols.
|
||||
(add_AT_loc_list): New function, add a location list to a DIE at
|
||||
the named attribute.
|
||||
(AT_loc_list): New function, return the location list reference
|
||||
for a given attribute, if it's a location list.
|
||||
(print_die): Handle dw_val_class_loc_list.
|
||||
(size_of_die): Ditto.
|
||||
(value_format): Ditto.
|
||||
(output_die): Ditto.
|
||||
(output_location_lists): New function, output all of the location
|
||||
lists for a DIE and it's children.
|
||||
(dwarf2out_finish): Call output_location_lists if we have location
|
||||
lists.
|
||||
|
||||
|
||||
Fri May 18 15:39:16 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcse.c (try_replace_reg): First try global replace, later try to
|
||||
|
195
gcc/dwarf2out.c
195
gcc/dwarf2out.c
@ -2076,6 +2076,7 @@ dwarf2out_frame_finish ()
|
||||
typedef struct dw_val_struct *dw_val_ref;
|
||||
typedef struct die_struct *dw_die_ref;
|
||||
typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
|
||||
typedef struct dw_loc_list_struct *dw_loc_list_ref;
|
||||
|
||||
/* Each DIE may have a series of attribute/value pairs. Values
|
||||
can take on several forms. The forms that are used in this
|
||||
@ -2085,6 +2086,7 @@ typedef enum
|
||||
{
|
||||
dw_val_class_addr,
|
||||
dw_val_class_loc,
|
||||
dw_val_class_loc_list,
|
||||
dw_val_class_const,
|
||||
dw_val_class_unsigned_const,
|
||||
dw_val_class_long_long,
|
||||
@ -2126,6 +2128,7 @@ typedef struct dw_val_struct
|
||||
union
|
||||
{
|
||||
rtx val_addr;
|
||||
dw_loc_list_ref val_loc_list;
|
||||
dw_loc_descr_ref val_loc;
|
||||
long int val_int;
|
||||
long unsigned val_unsigned;
|
||||
@ -2157,6 +2160,19 @@ typedef struct dw_loc_descr_struct
|
||||
}
|
||||
dw_loc_descr_node;
|
||||
|
||||
/* Location lists are ranges + location descriptions for that range,
|
||||
so you can track variables that are in different places over
|
||||
their entire life. */
|
||||
typedef struct dw_loc_list_struct
|
||||
{
|
||||
dw_loc_list_ref dw_loc_next;
|
||||
const char *begin; /* Label for begin address of range */
|
||||
const char *end; /* Label for end address of range */
|
||||
char *ll_symbol; /* Label for beginning of location list. Only on head of list */
|
||||
const char *section; /* Section this loclist is relative to */
|
||||
dw_loc_descr_ref expr;
|
||||
} dw_loc_list_node;
|
||||
|
||||
static const char *dwarf_stack_op_name PARAMS ((unsigned));
|
||||
static dw_loc_descr_ref new_loc_descr PARAMS ((enum dwarf_location_atom,
|
||||
unsigned long,
|
||||
@ -2168,6 +2184,14 @@ static unsigned long size_of_locs PARAMS ((dw_loc_descr_ref));
|
||||
static void output_loc_operands PARAMS ((dw_loc_descr_ref));
|
||||
static void output_loc_sequence PARAMS ((dw_loc_descr_ref));
|
||||
|
||||
static dw_loc_list_ref new_loc_list PARAMS ((dw_loc_descr_ref,
|
||||
const char *, const char *,
|
||||
const char *, unsigned));
|
||||
static void add_loc_descr_to_loc_list PARAMS ((dw_loc_list_ref *,
|
||||
dw_loc_descr_ref,
|
||||
const char *, const char *, const char *));
|
||||
static void output_loc_list PARAMS ((dw_loc_list_ref));
|
||||
static char *gen_internal_sym PARAMS ((const char *));
|
||||
/* Convert a DWARF stack opcode into its string name. */
|
||||
|
||||
static const char *
|
||||
@ -2495,6 +2519,29 @@ new_loc_descr (op, oprnd1, oprnd2)
|
||||
return descr;
|
||||
}
|
||||
|
||||
/* Return a new location list, given the begin and end range, and the
|
||||
expression. gensym tells us whether to generate a new internal
|
||||
symbol for this location list node, which is done for the head of
|
||||
the list only. */
|
||||
static inline dw_loc_list_ref
|
||||
new_loc_list (expr, begin, end, section, gensym)
|
||||
register dw_loc_descr_ref expr;
|
||||
register const char *begin;
|
||||
register const char *end;
|
||||
register const char *section;
|
||||
register unsigned gensym;
|
||||
{
|
||||
register dw_loc_list_ref retlist
|
||||
= (dw_loc_list_ref) xcalloc (1, sizeof (dw_loc_list_node));
|
||||
retlist->begin = begin;
|
||||
retlist->end = end;
|
||||
retlist->expr = expr;
|
||||
retlist->section = section;
|
||||
if (gensym)
|
||||
retlist->ll_symbol = gen_internal_sym ("LLST");
|
||||
return retlist;
|
||||
}
|
||||
|
||||
/* Add a location description term to a location description expression. */
|
||||
|
||||
static inline void
|
||||
@ -2511,6 +2558,24 @@ add_loc_descr (list_head, descr)
|
||||
*d = descr;
|
||||
}
|
||||
|
||||
/* Add a location description expression to a location list */
|
||||
static inline void
|
||||
add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
|
||||
register dw_loc_list_ref *list_head;
|
||||
register dw_loc_descr_ref descr;
|
||||
register const char *begin;
|
||||
register const char *end;
|
||||
register const char *section;
|
||||
{
|
||||
register dw_loc_list_ref *d;
|
||||
|
||||
/* Find the end of the chain. */
|
||||
for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
|
||||
;
|
||||
/* Add a new location list node to the list */
|
||||
*d = new_loc_list (descr, begin, end, section, 0);
|
||||
}
|
||||
|
||||
/* Return the size of a location descriptor. */
|
||||
|
||||
static unsigned long
|
||||
@ -3249,6 +3314,9 @@ static unsigned arange_table_in_use;
|
||||
arange_table. */
|
||||
#define ARANGE_TABLE_INCREMENT 64
|
||||
|
||||
/* Whether we have location lists that need outputting */
|
||||
static unsigned have_location_lists;
|
||||
|
||||
/* A pointer to the base of a list of incomplete types which might be
|
||||
completed at some later time. */
|
||||
|
||||
@ -3319,6 +3387,9 @@ static void add_AT_fde_ref PARAMS ((dw_die_ref,
|
||||
static void add_AT_loc PARAMS ((dw_die_ref,
|
||||
enum dwarf_attribute,
|
||||
dw_loc_descr_ref));
|
||||
static void add_AT_loc_list PARAMS ((dw_die_ref,
|
||||
enum dwarf_attribute,
|
||||
dw_loc_list_ref));
|
||||
static void add_AT_addr PARAMS ((dw_die_ref,
|
||||
enum dwarf_attribute,
|
||||
rtx));
|
||||
@ -3366,11 +3437,11 @@ static void compute_section_prefix PARAMS ((dw_die_ref));
|
||||
static int is_type_die PARAMS ((dw_die_ref));
|
||||
static int is_comdat_die PARAMS ((dw_die_ref));
|
||||
static int is_symbol_die PARAMS ((dw_die_ref));
|
||||
static char *gen_internal_sym PARAMS ((void));
|
||||
static void assign_symbol_names PARAMS ((dw_die_ref));
|
||||
static void break_out_includes PARAMS ((dw_die_ref));
|
||||
static void add_sibling_attributes PARAMS ((dw_die_ref));
|
||||
static void build_abbrev_table PARAMS ((dw_die_ref));
|
||||
static void output_location_lists PARAMS ((dw_die_ref));
|
||||
static unsigned long size_of_string PARAMS ((const char *));
|
||||
static int constant_size PARAMS ((long unsigned));
|
||||
static unsigned long size_of_die PARAMS ((dw_die_ref));
|
||||
@ -3535,6 +3606,9 @@ static int file_info_cmp PARAMS ((const void *, const void *));
|
||||
#ifndef ABBREV_SECTION_LABEL
|
||||
#define ABBREV_SECTION_LABEL "Ldebug_abbrev"
|
||||
#endif
|
||||
#ifndef LOC_SECTION_LABEL
|
||||
#define LOC_SECTION_LABEL "Ldebug_loc"
|
||||
#endif
|
||||
|
||||
/* Definitions of defaults for formats and names of various special
|
||||
(artificial) labels which may be generated within this file (when the -g
|
||||
@ -3547,7 +3621,7 @@ 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];
|
||||
|
||||
static char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
|
||||
#ifndef TEXT_END_LABEL
|
||||
#define TEXT_END_LABEL "Letext"
|
||||
#endif
|
||||
@ -4381,6 +4455,34 @@ AT_loc (a)
|
||||
abort ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_AT_loc_list (die, attr_kind, loc_list)
|
||||
register dw_die_ref die;
|
||||
register enum dwarf_attribute attr_kind;
|
||||
register dw_loc_list_ref loc_list;
|
||||
{
|
||||
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_loc_list;
|
||||
attr->dw_attr_val.v.val_loc_list = loc_list;
|
||||
add_dwarf_attr (die, attr);
|
||||
have_location_lists = 1;
|
||||
}
|
||||
|
||||
static inline dw_loc_list_ref AT_loc_list PARAMS ((dw_attr_ref));
|
||||
|
||||
static inline dw_loc_list_ref
|
||||
AT_loc_list (a)
|
||||
register dw_attr_ref a;
|
||||
{
|
||||
if (a && AT_class (a) == dw_val_class_loc_list)
|
||||
return a->dw_attr_val.v.val_loc_list;
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Add an address constant attribute value to a DIE. */
|
||||
|
||||
static inline void
|
||||
@ -4858,6 +4960,9 @@ print_die (die, outfile)
|
||||
case dw_val_class_loc:
|
||||
fprintf (outfile, "location descriptor");
|
||||
break;
|
||||
case dw_val_class_loc_list:
|
||||
fprintf (outfile, "location list -> label:%s", AT_loc_list (a)->ll_symbol);
|
||||
break;
|
||||
case dw_val_class_const:
|
||||
fprintf (outfile, "%ld", AT_int (a));
|
||||
break;
|
||||
@ -5252,18 +5357,19 @@ is_symbol_die (c)
|
||||
{
|
||||
if (is_type_die (c))
|
||||
return 1;
|
||||
if (get_AT (c, DW_AT_declaration)
|
||||
if (get_AT (c, DW_AT_declaration)
|
||||
&& ! get_AT (c, DW_AT_specification))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
gen_internal_sym ()
|
||||
gen_internal_sym (prefix)
|
||||
const char *prefix;
|
||||
{
|
||||
char buf[256];
|
||||
static int label_num;
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LDIE", label_num++);
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
|
||||
return xstrdup (buf);
|
||||
}
|
||||
|
||||
@ -5285,7 +5391,7 @@ assign_symbol_names (die)
|
||||
die->die_symbol = xstrdup (p);
|
||||
}
|
||||
else
|
||||
die->die_symbol = gen_internal_sym ();
|
||||
die->die_symbol = gen_internal_sym ("LDIE");
|
||||
}
|
||||
|
||||
for (c = die->die_child; c != NULL; c = c->die_sib)
|
||||
@ -5370,6 +5476,24 @@ add_sibling_attributes (die)
|
||||
add_sibling_attributes (c);
|
||||
}
|
||||
|
||||
/* Output all location lists for the DIE and it's children */
|
||||
static void
|
||||
output_location_lists (die)
|
||||
register dw_die_ref die;
|
||||
{
|
||||
dw_die_ref c;
|
||||
dw_attr_ref d_attr;
|
||||
for (d_attr = die->die_attr; d_attr; d_attr = d_attr->dw_attr_next)
|
||||
{
|
||||
if (AT_class (d_attr) == dw_val_class_loc_list)
|
||||
{
|
||||
output_loc_list (AT_loc_list (d_attr));
|
||||
}
|
||||
}
|
||||
for (c = die->die_child; c != NULL; c = c->die_sib)
|
||||
output_location_lists (c);
|
||||
|
||||
}
|
||||
/* The format of each DIE (and its attribute value pairs)
|
||||
is encoded in an abbreviation table. This routine builds the
|
||||
abbreviation table and assigns a unique abbreviation id for
|
||||
@ -5508,6 +5632,9 @@ size_of_die (die)
|
||||
size += lsize;
|
||||
}
|
||||
break;
|
||||
case dw_val_class_loc_list:
|
||||
size += DWARF_OFFSET_SIZE;
|
||||
break;
|
||||
case dw_val_class_const:
|
||||
size += size_of_sleb128 (AT_int (a));
|
||||
break;
|
||||
@ -5643,6 +5770,8 @@ value_format (a)
|
||||
{
|
||||
case dw_val_class_addr:
|
||||
return DW_FORM_addr;
|
||||
case dw_val_class_loc_list:
|
||||
return DW_FORM_data4; /* FIXME: Could be DW_FORM_data8, with a > 32 bit size .debug_loc section */
|
||||
case dw_val_class_loc:
|
||||
switch (constant_size (size_of_locs (AT_loc (a))))
|
||||
{
|
||||
@ -5761,6 +5890,38 @@ output_die_symbol (die)
|
||||
ASM_OUTPUT_LABEL (asm_out_file, sym);
|
||||
}
|
||||
|
||||
/* Output the location list given to us */
|
||||
static void
|
||||
output_loc_list (list_head)
|
||||
register dw_loc_list_ref list_head;
|
||||
{
|
||||
register dw_loc_list_ref curr;
|
||||
ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol);
|
||||
if (strcmp (curr->section, ".text") == 0)
|
||||
{
|
||||
if (DWARF2_ADDR_SIZE == 4)
|
||||
dw2_asm_output_data (DWARF2_ADDR_SIZE, 0xffffffff, "Location list base address specifier fake entry");
|
||||
else if (DWARF2_ADDR_SIZE == 8)
|
||||
dw2_asm_output_data (DWARF2_ADDR_SIZE, 0xffffffffffffffffLL, "Location list base address specifier fake entry");
|
||||
else
|
||||
abort();
|
||||
dw2_asm_output_offset (DWARF2_ADDR_SIZE, curr->section, "Location list base address specifier base");
|
||||
}
|
||||
for (curr = list_head; curr != NULL; curr=curr->dw_loc_next)
|
||||
{
|
||||
int size;
|
||||
dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section, "Location list begin address (%s)", list_head->ll_symbol);
|
||||
dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section, "Location list end address (%s)", list_head->ll_symbol);
|
||||
size = size_of_locs (curr->expr);
|
||||
|
||||
/* Output the block length for this list of location operations. */
|
||||
dw2_asm_output_data (constant_size (size), size, "%s", "Location expression size");
|
||||
|
||||
output_loc_sequence (curr->expr);
|
||||
}
|
||||
dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Location list terminator begin (%s)", list_head->ll_symbol);
|
||||
dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Location list terminator end (%s)", list_head->ll_symbol);
|
||||
}
|
||||
/* Output the DIE and its attributes. Called recursively to generate
|
||||
the definitions of each child DIE. */
|
||||
|
||||
@ -5851,7 +6012,14 @@ output_die (die)
|
||||
case dw_val_class_flag:
|
||||
dw2_asm_output_data (1, AT_flag (a), "%s", name);
|
||||
break;
|
||||
|
||||
case dw_val_class_loc_list:
|
||||
{
|
||||
char *sym = AT_loc_list (a)->ll_symbol;
|
||||
if (sym == 0)
|
||||
abort();
|
||||
dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label, name);
|
||||
}
|
||||
break;
|
||||
case dw_val_class_die_ref:
|
||||
if (AT_ref_external (a))
|
||||
{
|
||||
@ -11173,7 +11341,9 @@ dwarf2out_init (asm_out_file, main_input_filename)
|
||||
DEBUG_INFO_SECTION_LABEL, 0);
|
||||
ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
|
||||
DEBUG_LINE_SECTION_LABEL, 0);
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (loc_section_label, LOC_SECTION_LABEL, 0);
|
||||
ASM_OUTPUT_SECTION (asm_out_file, LOC_SECTION);
|
||||
ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
|
||||
ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
|
||||
ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
|
||||
if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
|
||||
@ -11305,5 +11475,14 @@ dwarf2out_finish ()
|
||||
ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION);
|
||||
output_aranges ();
|
||||
}
|
||||
/* Output location list section if necessary */
|
||||
if (have_location_lists)
|
||||
{
|
||||
/* Output the location lists info. */
|
||||
ASM_OUTPUT_SECTION (asm_out_file, LOC_SECTION);
|
||||
output_location_lists (die);
|
||||
have_location_lists = 0;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* DWARF2_DEBUGGING_INFO */
|
||||
|
Loading…
Reference in New Issue
Block a user