Commit 2a3d56bf by Jakub Jelinek Committed by Jakub Jelinek

dwarf2out.h (enum dw_val_class): Add dw_val_class_loclistsptr.

	* dwarf2out.h (enum dw_val_class): Add dw_val_class_loclistsptr.
	* dwarf2out.c (struct dw_loc_list_struct): Change emitted field
	from bool to 1-bit uchar bitfield.  Add num_assigned and
	offset_emitted bitfields.
	(dw_val_equal_p): Compare v.val_lbl_id rather than v.val_unsigned
	for dw_val_class_lineptr and dw_val_class_macptr.  Handle
	dw_val_class_loclistsptr.
	(new_addr_loc_descr): Fix up formatting.
	(DEBUG_LOCLISTS_SECTION, DEBUG_DWO_LOCLISTS_SECTION): Define.
	(add_AT_low_high_pc): Fix up formatting.
	(add_AT_loclistsptr): New function.
	(AT_lbl): Allow dw_val_class_loclistsptr.
	(print_dw_val, attr_checksum, attr_checksum_ordered, same_dw_val_p):
	Handle dw_val_class_loclistsptr.
	(loc_list_idx): New variable.
	(output_loclists_offsets, assign_location_list_indexes): New
	functions.
	(size_of_die): For dw_val_class_loc_list -gsplit-dwarf -gdwarf-5
	add size_of_uleb128 of the index.  Drop never used
	dwarf_split_debug_info AT_index handling.  Handle
	dw_val_class_loclistsptr.
	(value_format): Return DW_FORM_loclistsx for dw_val_class_loc_list
	if -gsplit-dwarf -gdwarf-5.  Handle dw_val_class_loclistsptr.
	(output_loc_list): Handle DWARF 5 .debug_loclists* format.
	(output_loc_list_offset): Handle -gsplit-dwarf -gdwarf-5
	DW_FORM_loclistx indexes.
	(output_attr_index_or_value): Fix up formatting.  Don't handle
	dw_val_class_loc_list here.
	(output_die): Formatting fixes.  Handle dw_val_class_loclistsptr.
	For dw_val_class_loc_list call output_loc_list_offset rather than
	output_attr_index_or_value.
	(init_sections_and_labels): For -gdwarf-5 use .debug_loclists
	or .debug_loclists.dwo section name for debug_loc_section.
	(resolve_addr_in_expr): Formatting fix.
	(index_location_lists): Likewise.
	(dwarf2out_finish): If there are any location lists, for
	-gsplit-dwarf -gdwarf-5 add DW_AT_loclists_base attribute.  Call
	index_location_lists only if have_location_lists.  Call
	assign_location_list_indexes for -gsplit-dwarf -gdwarf-5.  Emit
	.debug_loclists{,.dwo} section header for -gdwarf-5, for -gdwarf-5
	-gsplit-dwarf also emit offset table.

From-SVN: r241718
parent 25f40934
2016-10-31 Jakub Jelinek <jakub@redhat.com> 2016-10-31 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.h (enum dw_val_class): Add dw_val_class_loclistsptr.
* dwarf2out.c (struct dw_loc_list_struct): Change emitted field
from bool to 1-bit uchar bitfield. Add num_assigned and
offset_emitted bitfields.
(dw_val_equal_p): Compare v.val_lbl_id rather than v.val_unsigned
for dw_val_class_lineptr and dw_val_class_macptr. Handle
dw_val_class_loclistsptr.
(new_addr_loc_descr): Fix up formatting.
(DEBUG_LOCLISTS_SECTION, DEBUG_DWO_LOCLISTS_SECTION): Define.
(add_AT_low_high_pc): Fix up formatting.
(add_AT_loclistsptr): New function.
(AT_lbl): Allow dw_val_class_loclistsptr.
(print_dw_val, attr_checksum, attr_checksum_ordered, same_dw_val_p):
Handle dw_val_class_loclistsptr.
(loc_list_idx): New variable.
(output_loclists_offsets, assign_location_list_indexes): New
functions.
(size_of_die): For dw_val_class_loc_list -gsplit-dwarf -gdwarf-5
add size_of_uleb128 of the index. Drop never used
dwarf_split_debug_info AT_index handling. Handle
dw_val_class_loclistsptr.
(value_format): Return DW_FORM_loclistsx for dw_val_class_loc_list
if -gsplit-dwarf -gdwarf-5. Handle dw_val_class_loclistsptr.
(output_loc_list): Handle DWARF 5 .debug_loclists* format.
(output_loc_list_offset): Handle -gsplit-dwarf -gdwarf-5
DW_FORM_loclistx indexes.
(output_attr_index_or_value): Fix up formatting. Don't handle
dw_val_class_loc_list here.
(output_die): Formatting fixes. Handle dw_val_class_loclistsptr.
For dw_val_class_loc_list call output_loc_list_offset rather than
output_attr_index_or_value.
(init_sections_and_labels): For -gdwarf-5 use .debug_loclists
or .debug_loclists.dwo section name for debug_loc_section.
(resolve_addr_in_expr): Formatting fix.
(index_location_lists): Likewise.
(dwarf2out_finish): If there are any location lists, for
-gsplit-dwarf -gdwarf-5 add DW_AT_loclists_base attribute. Call
index_location_lists only if have_location_lists. Call
assign_location_list_indexes for -gsplit-dwarf -gdwarf-5. Emit
.debug_loclists{,.dwo} section header for -gdwarf-5, for -gdwarf-5
-gsplit-dwarf also emit offset table.
* dwarf2out.c (DWARF_LARGEST_DATA_FORM_BITS): Define. * dwarf2out.c (DWARF_LARGEST_DATA_FORM_BITS): Define.
(size_of_die, value_format, output_die): Use (size_of_die, value_format, output_die): Use
DW_FORM_data16 for 128-bit dw_val_class_const_double or DW_FORM_data16 for 128-bit dw_val_class_const_double or
...@@ -1276,7 +1276,13 @@ typedef struct GTY(()) dw_loc_list_struct { ...@@ -1276,7 +1276,13 @@ typedef struct GTY(()) dw_loc_list_struct {
bool resolved_addr; bool resolved_addr;
/* True if this list has been replaced by dw_loc_next. */ /* True if this list has been replaced by dw_loc_next. */
bool replaced; bool replaced;
bool emitted; /* True if it has been emitted into .debug_loc* / .debug_loclists*
section. */
unsigned char emitted : 1;
/* True if hash field is index rather than hash value. */
unsigned char num_assigned : 1;
/* True if .debug_loclists.dwo offset has been emitted for it already. */
unsigned char offset_emitted : 1;
/* True if the range should be emitted even if begin and end /* True if the range should be emitted even if begin and end
are the same. */ are the same. */
bool force; bool force;
...@@ -1366,8 +1372,6 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b) ...@@ -1366,8 +1372,6 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b)
case dw_val_class_unsigned_const_implicit: case dw_val_class_unsigned_const_implicit:
case dw_val_class_const_implicit: case dw_val_class_const_implicit:
case dw_val_class_range_list: case dw_val_class_range_list:
case dw_val_class_lineptr:
case dw_val_class_macptr:
/* These are all HOST_WIDE_INT, signed or unsigned. */ /* These are all HOST_WIDE_INT, signed or unsigned. */
return a->v.val_unsigned == b->v.val_unsigned; return a->v.val_unsigned == b->v.val_unsigned;
...@@ -1380,6 +1384,9 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b) ...@@ -1380,6 +1384,9 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b)
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
return a->v.val_fde_index == b->v.val_fde_index; return a->v.val_fde_index == b->v.val_fde_index;
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr:
case dw_val_class_macptr:
case dw_val_class_loclistsptr:
case dw_val_class_high_pc: case dw_val_class_high_pc:
return strcmp (a->v.val_lbl_id, b->v.val_lbl_id) == 0; return strcmp (a->v.val_lbl_id, b->v.val_lbl_id) == 0;
case dw_val_class_str: case dw_val_class_str:
...@@ -3310,6 +3317,8 @@ static inline rtx AT_addr (dw_attr_node *); ...@@ -3310,6 +3317,8 @@ static inline rtx AT_addr (dw_attr_node *);
static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_loclistsptr (dw_die_ref, enum dwarf_attribute,
const char *);
static void add_AT_offset (dw_die_ref, enum dwarf_attribute, static void add_AT_offset (dw_die_ref, enum dwarf_attribute,
unsigned HOST_WIDE_INT); unsigned HOST_WIDE_INT);
static void add_AT_range_list (dw_die_ref, enum dwarf_attribute, static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
...@@ -3662,6 +3671,12 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel) ...@@ -3662,6 +3671,12 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel)
#ifndef DEBUG_DWO_LOC_SECTION #ifndef DEBUG_DWO_LOC_SECTION
#define DEBUG_DWO_LOC_SECTION ".debug_loc.dwo" #define DEBUG_DWO_LOC_SECTION ".debug_loc.dwo"
#endif #endif
#ifndef DEBUG_LOCLISTS_SECTION
#define DEBUG_LOCLISTS_SECTION ".debug_loclists"
#endif
#ifndef DEBUG_DWO_LOCLISTS_SECTION
#define DEBUG_DWO_LOCLISTS_SECTION ".debug_loclists.dwo"
#endif
#ifndef DEBUG_PUBNAMES_SECTION #ifndef DEBUG_PUBNAMES_SECTION
#define DEBUG_PUBNAMES_SECTION \ #define DEBUG_PUBNAMES_SECTION \
((debug_generate_pub_sections == 2) \ ((debug_generate_pub_sections == 2) \
...@@ -4715,6 +4730,22 @@ add_AT_lineptr (dw_die_ref die, enum dwarf_attribute attr_kind, ...@@ -4715,6 +4730,22 @@ add_AT_lineptr (dw_die_ref die, enum dwarf_attribute attr_kind,
} }
/* Add a section offset attribute value to a DIE, an offset into the /* Add a section offset attribute value to a DIE, an offset into the
debug_loclists section. */
static inline void
add_AT_loclistsptr (dw_die_ref die, enum dwarf_attribute attr_kind,
const char *label)
{
dw_attr_node attr;
attr.dw_attr = attr_kind;
attr.dw_attr_val.val_class = dw_val_class_loclistsptr;
attr.dw_attr_val.val_entry = NULL;
attr.dw_attr_val.v.val_lbl_id = xstrdup (label);
add_dwarf_attr (die, &attr);
}
/* Add a section offset attribute value to a DIE, an offset into the
debug_macinfo section. */ debug_macinfo section. */
static inline void static inline void
...@@ -4796,6 +4827,7 @@ AT_lbl (dw_attr_node *a) ...@@ -4796,6 +4827,7 @@ AT_lbl (dw_attr_node *a)
gcc_assert (a && (AT_class (a) == dw_val_class_lbl_id gcc_assert (a && (AT_class (a) == dw_val_class_lbl_id
|| AT_class (a) == dw_val_class_lineptr || AT_class (a) == dw_val_class_lineptr
|| AT_class (a) == dw_val_class_macptr || AT_class (a) == dw_val_class_macptr
|| AT_class (a) == dw_val_class_loclistsptr
|| AT_class (a) == dw_val_class_high_pc)); || AT_class (a) == dw_val_class_high_pc));
return a->dw_attr_val.v.val_lbl_id; return a->dw_attr_val.v.val_lbl_id;
} }
...@@ -5795,6 +5827,7 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile) ...@@ -5795,6 +5827,7 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
case dw_val_class_high_pc: case dw_val_class_high_pc:
fprintf (outfile, "label: %s", val->v.val_lbl_id); fprintf (outfile, "label: %s", val->v.val_lbl_id);
break; break;
...@@ -6187,6 +6220,7 @@ attr_checksum (dw_attr_node *at, struct md5_ctx *ctx, int *mark) ...@@ -6187,6 +6220,7 @@ attr_checksum (dw_attr_node *at, struct md5_ctx *ctx, int *mark)
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
case dw_val_class_high_pc: case dw_val_class_high_pc:
break; break;
...@@ -6482,6 +6516,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_node *at, ...@@ -6482,6 +6516,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_node *at,
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
case dw_val_class_high_pc: case dw_val_class_high_pc:
break; break;
...@@ -6978,6 +7013,7 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) ...@@ -6978,6 +7013,7 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark)
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
case dw_val_class_high_pc: case dw_val_class_high_pc:
return 1; return 1;
...@@ -8259,6 +8295,59 @@ output_location_lists (dw_die_ref die) ...@@ -8259,6 +8295,59 @@ output_location_lists (dw_die_ref die)
FOR_EACH_CHILD (die, c, output_location_lists (c)); FOR_EACH_CHILD (die, c, output_location_lists (c));
} }
/* During assign_location_list_indexes and output_loclists_offset the
current index, after it the number of assigned indexes (i.e. how
large the .debug_loclists* offset table should be). */
static unsigned int loc_list_idx;
/* Output all location list offsets for the DIE and its children. */
static void
output_loclists_offsets (dw_die_ref die)
{
dw_die_ref c;
dw_attr_node *a;
unsigned ix;
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
if (AT_class (a) == dw_val_class_loc_list)
{
dw_loc_list_ref l = AT_loc_list (a);
if (l->offset_emitted)
continue;
dw2_asm_output_delta (DWARF_OFFSET_SIZE, l->ll_symbol,
loc_section_label, NULL);
gcc_assert (l->hash == loc_list_idx);
loc_list_idx++;
l->offset_emitted = true;
}
FOR_EACH_CHILD (die, c, output_loclists_offsets (c));
}
/* Recursively set indexes of location lists. */
static void
assign_location_list_indexes (dw_die_ref die)
{
dw_die_ref c;
dw_attr_node *a;
unsigned ix;
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
if (AT_class (a) == dw_val_class_loc_list)
{
dw_loc_list_ref list = AT_loc_list (a);
if (!list->num_assigned)
{
list->num_assigned = true;
list->hash = loc_list_idx++;
}
}
FOR_EACH_CHILD (die, c, assign_location_list_indexes (c));
}
/* We want to limit the number of external references, because they are /* We want to limit the number of external references, because they are
larger than local references: a relocation takes multiple words, and larger than local references: a relocation takes multiple words, and
even a sig8 reference is always eight bytes, whereas a local reference even a sig8 reference is always eight bytes, whereas a local reference
...@@ -8728,10 +8817,10 @@ size_of_die (dw_die_ref die) ...@@ -8728,10 +8817,10 @@ size_of_die (dw_die_ref die)
} }
break; break;
case dw_val_class_loc_list: case dw_val_class_loc_list:
if (dwarf_split_debug_info && AT_index (a) != NOT_INDEXED) if (dwarf_split_debug_info && dwarf_version >= 5)
{ {
gcc_assert (AT_index (a) != NO_INDEX_ASSIGNED); gcc_assert (AT_loc_list (a)->num_assigned);
size += size_of_uleb128 (AT_index (a)); size += size_of_uleb128 (AT_loc_list (a)->hash);
} }
else else
size += DWARF_OFFSET_SIZE; size += DWARF_OFFSET_SIZE;
...@@ -8820,6 +8909,7 @@ size_of_die (dw_die_ref die) ...@@ -8820,6 +8909,7 @@ size_of_die (dw_die_ref die)
break; break;
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
size += DWARF_OFFSET_SIZE; size += DWARF_OFFSET_SIZE;
break; break;
case dw_val_class_str: case dw_val_class_str:
...@@ -9085,8 +9175,13 @@ value_format (dw_attr_node *a) ...@@ -9085,8 +9175,13 @@ value_format (dw_attr_node *a)
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
case dw_val_class_range_list:
case dw_val_class_loc_list: case dw_val_class_loc_list:
if (dwarf_split_debug_info
&& dwarf_version >= 5
&& AT_loc_list (a)->num_assigned)
return DW_FORM_loclistx;
/* FALLTHRU */
case dw_val_class_range_list:
if (dwarf_version >= 4) if (dwarf_version >= 4)
return DW_FORM_sec_offset; return DW_FORM_sec_offset;
/* FALLTHRU */ /* FALLTHRU */
...@@ -9215,6 +9310,7 @@ value_format (dw_attr_node *a) ...@@ -9215,6 +9310,7 @@ value_format (dw_attr_node *a)
? DW_FORM_addr : DW_FORM_GNU_addr_index); ? DW_FORM_addr : DW_FORM_GNU_addr_index);
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
case dw_val_class_loclistsptr:
return dwarf_version >= 4 ? DW_FORM_sec_offset : DW_FORM_data; return dwarf_version >= 4 ? DW_FORM_sec_offset : DW_FORM_data;
case dw_val_class_str: case dw_val_class_str:
return AT_string_form (a); return AT_string_form (a);
...@@ -9392,14 +9488,18 @@ gen_llsym (dw_loc_list_ref list) ...@@ -9392,14 +9488,18 @@ gen_llsym (dw_loc_list_ref list)
static void static void
output_loc_list (dw_loc_list_ref list_head) output_loc_list (dw_loc_list_ref list_head)
{ {
dw_loc_list_ref curr = list_head;
if (list_head->emitted) if (list_head->emitted)
return; return;
list_head->emitted = true; list_head->emitted = true;
ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol); ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol);
dw_loc_list_ref curr = list_head;
#ifdef HAVE_AS_LEB128
const char *last_section = NULL;
const char *base_label = NULL;
#endif
/* Walk the location list, and output each range + expression. */ /* Walk the location list, and output each range + expression. */
for (curr = list_head; curr != NULL; curr = curr->dw_loc_next) for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
{ {
...@@ -9414,8 +9514,126 @@ output_loc_list (dw_loc_list_ref list_head) ...@@ -9414,8 +9514,126 @@ output_loc_list (dw_loc_list_ref list_head)
in a single range are unlikely very useful. */ in a single range are unlikely very useful. */
if (size > 0xffff) if (size > 0xffff)
continue; continue;
if (dwarf_version >= 5)
{
if (dwarf_split_debug_info) if (dwarf_split_debug_info)
{ {
/* For -gsplit-dwarf, emit DW_LLE_starx_length, which has
uleb128 index into .debug_addr and uleb128 length. */
dw2_asm_output_data (1, DW_LLE_startx_length,
"DW_LLE_startx_length (%s)",
list_head->ll_symbol);
dw2_asm_output_data_uleb128 (curr->begin_entry->index,
"Location list range start index "
"(%s)", curr->begin);
/* FIXME: This will ICE ifndef HAVE_AS_LEB128.
For that case we probably need to emit DW_LLE_startx_endx,
but we'd need 2 .debug_addr entries rather than just one. */
dw2_asm_output_delta_uleb128 (curr->end, curr->begin,
"Location list length (%s)",
list_head->ll_symbol);
}
#ifdef HAVE_AS_LEB128
else if (!have_multiple_function_sections)
{
/* If all code is in .text section, the base address is
already provided by the CU attributes. Use
DW_LLE_offset_pair where both addresses are uleb128 encoded
offsets against that base. */
dw2_asm_output_data (1, DW_LLE_offset_pair,
"DW_LLE_offset_pair (%s)",
list_head->ll_symbol);
dw2_asm_output_delta_uleb128 (curr->begin, curr->section,
"Location list begin address (%s)",
list_head->ll_symbol);
dw2_asm_output_delta_uleb128 (curr->end, curr->section,
"Location list end address (%s)",
list_head->ll_symbol);
}
else
{
/* Otherwise, find out how many consecutive entries could share
the same base entry. If just one, emit DW_LLE_start_length,
otherwise emit DW_LLE_base_address for the base address
followed by a series of DW_LLE_offset_pair. */
if (last_section == NULL || curr->section != last_section)
{
dw_loc_list_ref curr2;
for (curr2 = curr->dw_loc_next; curr2 != NULL;
curr2 = curr2->dw_loc_next)
{
if (strcmp (curr2->begin, curr2->end) == 0
&& !curr2->force)
continue;
if ((unsigned long) size_of_locs (curr2->expr) > 0xffff)
continue;
break;
}
if (curr2 == NULL || curr->section != curr2->section)
last_section = NULL;
else
{
last_section = curr->section;
base_label = curr->begin;
dw2_asm_output_data (1, DW_LLE_base_address,
"DW_LLE_base_address (%s)",
list_head->ll_symbol);
dw2_asm_output_addr (DWARF2_ADDR_SIZE, base_label,
"Base address (%s)",
list_head->ll_symbol);
}
}
/* Only one entry with the same base address. Use
DW_LLE_start_length with absolute address and uleb128
length. */
if (last_section == NULL)
{
dw2_asm_output_data (1, DW_LLE_start_length,
"DW_LLE_start_length (%s)",
list_head->ll_symbol);
dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
"Location list begin address (%s)",
list_head->ll_symbol);
dw2_asm_output_delta_uleb128 (curr->end, curr->begin,
"Location list length "
"(%s)", list_head->ll_symbol);
}
/* Otherwise emit DW_LLE_offset_pair, relative to above emitted
DW_LLE_base_address. */
else
{
dw2_asm_output_data (1, DW_LLE_offset_pair,
"DW_LLE_offset_pair (%s)",
list_head->ll_symbol);
dw2_asm_output_delta_uleb128 (curr->begin, base_label,
"Location list begin address "
"(%s)", list_head->ll_symbol);
dw2_asm_output_delta_uleb128 (curr->end, base_label,
"Location list end address "
"(%s)", list_head->ll_symbol);
}
}
#else
/* The assembler does not support .uleb128 directive. Emit
DW_LLE_start_end with a pair of absolute addresses. */
else
{
dw2_asm_output_data (1, DW_LLE_start_end,
"DW_LLE_start_end (%s)",
list_head->ll_symbol);
dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
"Location list begin address (%s)",
list_head->ll_symbol);
dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->end,
"Location list end address (%s)",
list_head->ll_symbol);
}
#endif
}
else if (dwarf_split_debug_info)
{
/* For -gsplit-dwarf -gdwarf-{2,3,4} emit index into .debug_addr
and 4 byte length. */
dw2_asm_output_data (1, DW_LLE_GNU_start_length_entry, dw2_asm_output_data (1, DW_LLE_GNU_start_length_entry,
"Location list start/length entry (%s)", "Location list start/length entry (%s)",
list_head->ll_symbol); list_head->ll_symbol);
...@@ -9431,6 +9649,7 @@ output_loc_list (dw_loc_list_ref list_head) ...@@ -9431,6 +9649,7 @@ output_loc_list (dw_loc_list_ref list_head)
} }
else if (!have_multiple_function_sections) else if (!have_multiple_function_sections)
{ {
/* Pair of relative addresses against start of text section. */
dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section, dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
"Location list begin address (%s)", "Location list begin address (%s)",
list_head->ll_symbol); list_head->ll_symbol);
...@@ -9440,6 +9659,7 @@ output_loc_list (dw_loc_list_ref list_head) ...@@ -9440,6 +9659,7 @@ output_loc_list (dw_loc_list_ref list_head)
} }
else else
{ {
/* Pair of absolute addresses. */
dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin, dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
"Location list begin address (%s)", "Location list begin address (%s)",
list_head->ll_symbol); list_head->ll_symbol);
...@@ -9455,7 +9675,11 @@ output_loc_list (dw_loc_list_ref list_head) ...@@ -9455,7 +9675,11 @@ output_loc_list (dw_loc_list_ref list_head)
output_loc_sequence (curr->expr, -1); output_loc_sequence (curr->expr, -1);
} }
if (dwarf_split_debug_info) /* And finally list termination. */
if (dwarf_version >= 5)
dw2_asm_output_data (1, DW_LLE_end_of_list,
"DW_LLE_end_of_list (%s)", list_head->ll_symbol);
else if (dwarf_split_debug_info)
dw2_asm_output_data (1, DW_LLE_GNU_end_of_list_entry, dw2_asm_output_data (1, DW_LLE_GNU_end_of_list_entry,
"Location list terminator (%s)", "Location list terminator (%s)",
list_head->ll_symbol); list_head->ll_symbol);
...@@ -9500,11 +9724,18 @@ output_loc_list_offset (dw_attr_node *a) ...@@ -9500,11 +9724,18 @@ output_loc_list_offset (dw_attr_node *a)
char *sym = AT_loc_list (a)->ll_symbol; char *sym = AT_loc_list (a)->ll_symbol;
gcc_assert (sym); gcc_assert (sym);
if (dwarf_split_debug_info) if (!dwarf_split_debug_info)
dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label, dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
"%s", dwarf_attr_name (a->dw_attr)); "%s", dwarf_attr_name (a->dw_attr));
else if (dwarf_version >= 5)
{
gcc_assert (AT_loc_list (a)->num_assigned);
dw2_asm_output_data_uleb128 (AT_loc_list (a)->hash, "%s (%s)",
dwarf_attr_name (a->dw_attr),
sym);
}
else else
dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section, dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label,
"%s", dwarf_attr_name (a->dw_attr)); "%s", dwarf_attr_name (a->dw_attr));
} }
...@@ -9529,9 +9760,6 @@ output_attr_index_or_value (dw_attr_node *a) ...@@ -9529,9 +9760,6 @@ output_attr_index_or_value (dw_attr_node *a)
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name); dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name);
break; break;
case dw_val_class_loc_list:
output_loc_list_offset (a);
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
...@@ -9738,7 +9966,7 @@ output_die (dw_die_ref die) ...@@ -9738,7 +9966,7 @@ output_die (dw_die_ref die)
break; break;
case dw_val_class_loc_list: case dw_val_class_loc_list:
output_attr_index_or_value (a); output_loc_list_offset (a);
break; break;
case dw_val_class_die_ref: case dw_val_class_die_ref:
...@@ -9746,8 +9974,8 @@ output_die (dw_die_ref die) ...@@ -9746,8 +9974,8 @@ output_die (dw_die_ref die)
{ {
if (AT_ref (a)->comdat_type_p) if (AT_ref (a)->comdat_type_p)
{ {
comdat_type_node *type_node = comdat_type_node *type_node
AT_ref (a)->die_id.die_type_node; = AT_ref (a)->die_id.die_type_node;
gcc_assert (type_node); gcc_assert (type_node);
output_signature (type_node->signature, name); output_signature (type_node->signature, name);
...@@ -9814,6 +10042,11 @@ output_die (dw_die_ref die) ...@@ -9814,6 +10042,11 @@ output_die (dw_die_ref die)
debug_macinfo_section, "%s", name); debug_macinfo_section, "%s", name);
break; break;
case dw_val_class_loclistsptr:
dw2_asm_output_offset (DWARF_OFFSET_SIZE, AT_lbl (a),
debug_loc_section, "%s", name);
break;
case dw_val_class_str: case dw_val_class_str:
if (a->dw_attr_val.v.val_str->form == DW_FORM_strp) if (a->dw_attr_val.v.val_str->form == DW_FORM_strp)
dw2_asm_output_offset (DWARF_OFFSET_SIZE, dw2_asm_output_offset (DWARF_OFFSET_SIZE,
...@@ -26023,7 +26256,9 @@ init_sections_and_labels (void) ...@@ -26023,7 +26256,9 @@ init_sections_and_labels (void)
SECTION_DEBUG, NULL); SECTION_DEBUG, NULL);
debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION, debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
SECTION_DEBUG, NULL); SECTION_DEBUG, NULL);
debug_loc_section = get_section (DEBUG_LOC_SECTION, debug_loc_section = get_section (dwarf_version >= 5
? DEBUG_LOCLISTS_SECTION
: DEBUG_LOC_SECTION,
SECTION_DEBUG, NULL); SECTION_DEBUG, NULL);
debug_macinfo_section_name debug_macinfo_section_name
= (dwarf_strict && dwarf_version < 5) = (dwarf_strict && dwarf_version < 5)
...@@ -26059,7 +26294,9 @@ init_sections_and_labels (void) ...@@ -26059,7 +26294,9 @@ init_sections_and_labels (void)
NULL); NULL);
ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label, ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
DEBUG_SKELETON_INFO_SECTION_LABEL, 0); DEBUG_SKELETON_INFO_SECTION_LABEL, 0);
debug_loc_section = get_section (DEBUG_DWO_LOC_SECTION, debug_loc_section = get_section (dwarf_version >= 5
? DEBUG_DWO_LOCLISTS_SECTION
: DEBUG_DWO_LOC_SECTION,
SECTION_DEBUG | SECTION_EXCLUDE, NULL); SECTION_DEBUG | SECTION_EXCLUDE, NULL);
debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION, debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION,
DEBUG_STR_DWO_SECTION_FLAGS, NULL); DEBUG_STR_DWO_SECTION_FLAGS, NULL);
...@@ -27160,8 +27397,8 @@ resolve_addr_in_expr (dw_loc_descr_ref loc) ...@@ -27160,8 +27397,8 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
if (!resolve_one_addr (&rtl)) if (!resolve_one_addr (&rtl))
return false; return false;
remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry); remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry);
loc->dw_loc_oprnd1.val_entry = loc->dw_loc_oprnd1.val_entry
add_addr_table_entry (rtl, ate_kind_rtx); = add_addr_table_entry (rtl, ate_kind_rtx);
} }
break; break;
case DW_OP_const4u: case DW_OP_const4u:
...@@ -28248,8 +28485,7 @@ index_location_lists (dw_die_ref die) ...@@ -28248,8 +28485,7 @@ index_location_lists (dw_die_ref die)
continue; continue;
curr->begin_entry curr->begin_entry
= add_addr_table_entry (xstrdup (curr->begin), = add_addr_table_entry (xstrdup (curr->begin), ate_kind_label);
ate_kind_label);
} }
} }
...@@ -28458,12 +28694,18 @@ dwarf2out_finish (const char *) ...@@ -28458,12 +28694,18 @@ dwarf2out_finish (const char *)
if (dwarf_split_debug_info) if (dwarf_split_debug_info)
{ {
if (have_location_lists)
{
if (dwarf_version >= 5)
add_AT_loclistsptr (comp_unit_die (), DW_AT_loclists_base,
loc_section_label);
/* optimize_location_lists calculates the size of the lists, /* optimize_location_lists calculates the size of the lists,
so index them first, and assign indices to the entries. so index them first, and assign indices to the entries.
Although optimize_location_lists will remove entries from Although optimize_location_lists will remove entries from
the table, it only does so for duplicates, and therefore the table, it only does so for duplicates, and therefore
only reduces ref_counts to 1. */ only reduces ref_counts to 1. */
index_location_lists (comp_unit_die ()); index_location_lists (comp_unit_die ());
}
if (addr_index_table != NULL) if (addr_index_table != NULL)
{ {
...@@ -28474,8 +28716,14 @@ dwarf2out_finish (const char *) ...@@ -28474,8 +28716,14 @@ dwarf2out_finish (const char *)
} }
} }
loc_list_idx = 0;
if (have_location_lists) if (have_location_lists)
{
optimize_location_lists (comp_unit_die ()); optimize_location_lists (comp_unit_die ());
/* And finally assign indexes to the entries for -gsplit-dwarf. */
if (dwarf_version >= 5 && dwarf_split_debug_info)
assign_location_list_indexes (comp_unit_die ());
}
save_macinfo_strings (); save_macinfo_strings ();
...@@ -28573,10 +28821,38 @@ dwarf2out_finish (const char *) ...@@ -28573,10 +28821,38 @@ dwarf2out_finish (const char *)
/* Output location list section if necessary. */ /* Output location list section if necessary. */
if (have_location_lists) if (have_location_lists)
{ {
char l1[MAX_ARTIFICIAL_LABEL_BYTES];
char l2[MAX_ARTIFICIAL_LABEL_BYTES];
/* Output the location lists info. */ /* Output the location lists info. */
switch_to_section (debug_loc_section); switch_to_section (debug_loc_section);
if (dwarf_version >= 5)
{
ASM_GENERATE_INTERNAL_LABEL (l1, DEBUG_LOC_SECTION_LABEL, 1);
ASM_GENERATE_INTERNAL_LABEL (l2, DEBUG_LOC_SECTION_LABEL, 2);
if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
dw2_asm_output_data (4, 0xffffffff,
"Initial length escape value indicating "
"64-bit DWARF extension");
dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1,
"Length of Location Lists");
ASM_OUTPUT_LABEL (asm_out_file, l1);
dw2_asm_output_data (2, dwarf_version, "DWARF Version");
dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
dw2_asm_output_data (1, 0, "Segment Size");
dw2_asm_output_data (4, dwarf_split_debug_info ? loc_list_idx : 0,
"Offset Entry Count");
}
ASM_OUTPUT_LABEL (asm_out_file, loc_section_label); ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
if (dwarf_version >= 5 && dwarf_split_debug_info)
{
unsigned int save_loc_list_idx = loc_list_idx;
loc_list_idx = 0;
output_loclists_offsets (comp_unit_die ());
gcc_assert (save_loc_list_idx == loc_list_idx);
}
output_location_lists (comp_unit_die ()); output_location_lists (comp_unit_die ());
if (dwarf_version >= 5)
ASM_OUTPUT_LABEL (asm_out_file, l2);
} }
output_pubtables (); output_pubtables ();
......
...@@ -147,6 +147,7 @@ enum dw_val_class ...@@ -147,6 +147,7 @@ enum dw_val_class
dw_val_class_lineptr, dw_val_class_lineptr,
dw_val_class_str, dw_val_class_str,
dw_val_class_macptr, dw_val_class_macptr,
dw_val_class_loclistsptr,
dw_val_class_file, dw_val_class_file,
dw_val_class_data8, dw_val_class_data8,
dw_val_class_decl_ref, dw_val_class_decl_ref,
......
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