Commit 63e46568 by Daniel Berlin Committed by Daniel Berlin

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
parent 2b0cbc5d
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> 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 * gcse.c (try_replace_reg): First try global replace, later try to
......
...@@ -2076,6 +2076,7 @@ dwarf2out_frame_finish () ...@@ -2076,6 +2076,7 @@ dwarf2out_frame_finish ()
typedef struct dw_val_struct *dw_val_ref; typedef struct dw_val_struct *dw_val_ref;
typedef struct die_struct *dw_die_ref; typedef struct die_struct *dw_die_ref;
typedef struct dw_loc_descr_struct *dw_loc_descr_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 /* Each DIE may have a series of attribute/value pairs. Values
can take on several forms. The forms that are used in this can take on several forms. The forms that are used in this
...@@ -2085,6 +2086,7 @@ typedef enum ...@@ -2085,6 +2086,7 @@ typedef enum
{ {
dw_val_class_addr, dw_val_class_addr,
dw_val_class_loc, dw_val_class_loc,
dw_val_class_loc_list,
dw_val_class_const, dw_val_class_const,
dw_val_class_unsigned_const, dw_val_class_unsigned_const,
dw_val_class_long_long, dw_val_class_long_long,
...@@ -2126,6 +2128,7 @@ typedef struct dw_val_struct ...@@ -2126,6 +2128,7 @@ typedef struct dw_val_struct
union union
{ {
rtx val_addr; rtx val_addr;
dw_loc_list_ref val_loc_list;
dw_loc_descr_ref val_loc; dw_loc_descr_ref val_loc;
long int val_int; long int val_int;
long unsigned val_unsigned; long unsigned val_unsigned;
...@@ -2157,6 +2160,19 @@ typedef struct dw_loc_descr_struct ...@@ -2157,6 +2160,19 @@ typedef struct dw_loc_descr_struct
} }
dw_loc_descr_node; 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 const char *dwarf_stack_op_name PARAMS ((unsigned));
static dw_loc_descr_ref new_loc_descr PARAMS ((enum dwarf_location_atom, static dw_loc_descr_ref new_loc_descr PARAMS ((enum dwarf_location_atom,
unsigned long, unsigned long,
...@@ -2168,6 +2184,14 @@ static unsigned long size_of_locs PARAMS ((dw_loc_descr_ref)); ...@@ -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_operands PARAMS ((dw_loc_descr_ref));
static void output_loc_sequence 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. */ /* Convert a DWARF stack opcode into its string name. */
static const char * static const char *
...@@ -2495,6 +2519,29 @@ new_loc_descr (op, oprnd1, oprnd2) ...@@ -2495,6 +2519,29 @@ new_loc_descr (op, oprnd1, oprnd2)
return descr; 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. */ /* Add a location description term to a location description expression. */
static inline void static inline void
...@@ -2511,6 +2558,24 @@ add_loc_descr (list_head, descr) ...@@ -2511,6 +2558,24 @@ add_loc_descr (list_head, descr)
*d = 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. */ /* Return the size of a location descriptor. */
static unsigned long static unsigned long
...@@ -3249,6 +3314,9 @@ static unsigned arange_table_in_use; ...@@ -3249,6 +3314,9 @@ static unsigned arange_table_in_use;
arange_table. */ arange_table. */
#define ARANGE_TABLE_INCREMENT 64 #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 /* A pointer to the base of a list of incomplete types which might be
completed at some later time. */ completed at some later time. */
...@@ -3319,6 +3387,9 @@ static void add_AT_fde_ref PARAMS ((dw_die_ref, ...@@ -3319,6 +3387,9 @@ static void add_AT_fde_ref PARAMS ((dw_die_ref,
static void add_AT_loc PARAMS ((dw_die_ref, static void add_AT_loc PARAMS ((dw_die_ref,
enum dwarf_attribute, enum dwarf_attribute,
dw_loc_descr_ref)); 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, static void add_AT_addr PARAMS ((dw_die_ref,
enum dwarf_attribute, enum dwarf_attribute,
rtx)); rtx));
...@@ -3366,11 +3437,11 @@ static void compute_section_prefix PARAMS ((dw_die_ref)); ...@@ -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_type_die PARAMS ((dw_die_ref));
static int is_comdat_die PARAMS ((dw_die_ref)); static int is_comdat_die PARAMS ((dw_die_ref));
static int is_symbol_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 assign_symbol_names PARAMS ((dw_die_ref));
static void break_out_includes PARAMS ((dw_die_ref)); static void break_out_includes PARAMS ((dw_die_ref));
static void add_sibling_attributes PARAMS ((dw_die_ref)); static void add_sibling_attributes PARAMS ((dw_die_ref));
static void build_abbrev_table 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 unsigned long size_of_string PARAMS ((const char *));
static int constant_size PARAMS ((long unsigned)); static int constant_size PARAMS ((long unsigned));
static unsigned long size_of_die PARAMS ((dw_die_ref)); static unsigned long size_of_die PARAMS ((dw_die_ref));
...@@ -3535,6 +3606,9 @@ static int file_info_cmp PARAMS ((const void *, const void *)); ...@@ -3535,6 +3606,9 @@ static int file_info_cmp PARAMS ((const void *, const void *));
#ifndef ABBREV_SECTION_LABEL #ifndef ABBREV_SECTION_LABEL
#define ABBREV_SECTION_LABEL "Ldebug_abbrev" #define ABBREV_SECTION_LABEL "Ldebug_abbrev"
#endif #endif
#ifndef LOC_SECTION_LABEL
#define LOC_SECTION_LABEL "Ldebug_loc"
#endif
/* Definitions of defaults for formats and names of various special /* Definitions of defaults for formats and names of various special
(artificial) labels which may be generated within this file (when the -g (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]; ...@@ -3547,7 +3621,7 @@ static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char abbrev_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_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_line_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 #ifndef TEXT_END_LABEL
#define TEXT_END_LABEL "Letext" #define TEXT_END_LABEL "Letext"
#endif #endif
...@@ -4381,6 +4455,34 @@ AT_loc (a) ...@@ -4381,6 +4455,34 @@ AT_loc (a)
abort (); 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. */ /* Add an address constant attribute value to a DIE. */
static inline void static inline void
...@@ -4858,6 +4960,9 @@ print_die (die, outfile) ...@@ -4858,6 +4960,9 @@ print_die (die, outfile)
case dw_val_class_loc: case dw_val_class_loc:
fprintf (outfile, "location descriptor"); fprintf (outfile, "location descriptor");
break; 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: case dw_val_class_const:
fprintf (outfile, "%ld", AT_int (a)); fprintf (outfile, "%ld", AT_int (a));
break; break;
...@@ -5259,11 +5364,12 @@ is_symbol_die (c) ...@@ -5259,11 +5364,12 @@ is_symbol_die (c)
} }
static char * static char *
gen_internal_sym () gen_internal_sym (prefix)
const char *prefix;
{ {
char buf[256]; char buf[256];
static int label_num; static int label_num;
ASM_GENERATE_INTERNAL_LABEL (buf, "LDIE", label_num++); ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
return xstrdup (buf); return xstrdup (buf);
} }
...@@ -5285,7 +5391,7 @@ assign_symbol_names (die) ...@@ -5285,7 +5391,7 @@ assign_symbol_names (die)
die->die_symbol = xstrdup (p); die->die_symbol = xstrdup (p);
} }
else 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) for (c = die->die_child; c != NULL; c = c->die_sib)
...@@ -5370,6 +5476,24 @@ add_sibling_attributes (die) ...@@ -5370,6 +5476,24 @@ add_sibling_attributes (die)
add_sibling_attributes (c); 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) /* The format of each DIE (and its attribute value pairs)
is encoded in an abbreviation table. This routine builds the is encoded in an abbreviation table. This routine builds the
abbreviation table and assigns a unique abbreviation id for abbreviation table and assigns a unique abbreviation id for
...@@ -5508,6 +5632,9 @@ size_of_die (die) ...@@ -5508,6 +5632,9 @@ size_of_die (die)
size += lsize; size += lsize;
} }
break; break;
case dw_val_class_loc_list:
size += DWARF_OFFSET_SIZE;
break;
case dw_val_class_const: case dw_val_class_const:
size += size_of_sleb128 (AT_int (a)); size += size_of_sleb128 (AT_int (a));
break; break;
...@@ -5643,6 +5770,8 @@ value_format (a) ...@@ -5643,6 +5770,8 @@ value_format (a)
{ {
case dw_val_class_addr: case dw_val_class_addr:
return DW_FORM_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: case dw_val_class_loc:
switch (constant_size (size_of_locs (AT_loc (a)))) switch (constant_size (size_of_locs (AT_loc (a))))
{ {
...@@ -5761,6 +5890,38 @@ output_die_symbol (die) ...@@ -5761,6 +5890,38 @@ output_die_symbol (die)
ASM_OUTPUT_LABEL (asm_out_file, sym); 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 /* Output the DIE and its attributes. Called recursively to generate
the definitions of each child DIE. */ the definitions of each child DIE. */
...@@ -5851,7 +6012,14 @@ output_die (die) ...@@ -5851,7 +6012,14 @@ output_die (die)
case dw_val_class_flag: case dw_val_class_flag:
dw2_asm_output_data (1, AT_flag (a), "%s", name); dw2_asm_output_data (1, AT_flag (a), "%s", name);
break; 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: case dw_val_class_die_ref:
if (AT_ref_external (a)) if (AT_ref_external (a))
{ {
...@@ -11173,7 +11341,9 @@ dwarf2out_init (asm_out_file, main_input_filename) ...@@ -11173,7 +11341,9 @@ dwarf2out_init (asm_out_file, main_input_filename)
DEBUG_INFO_SECTION_LABEL, 0); DEBUG_INFO_SECTION_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
DEBUG_LINE_SECTION_LABEL, 0); 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_SECTION (asm_out_file, ABBREV_SECTION);
ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label); ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
if (DWARF2_GENERATE_TEXT_SECTION_LABEL) if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
...@@ -11305,5 +11475,14 @@ dwarf2out_finish () ...@@ -11305,5 +11475,14 @@ dwarf2out_finish ()
ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION); ASM_OUTPUT_SECTION (asm_out_file, ARANGES_SECTION);
output_aranges (); 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 */ #endif /* DWARF2_DEBUGGING_INFO */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment