aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2014-07-01 21:35:41 +0000
committerCary Coutant <ccoutant@gcc.gnu.org>2014-07-01 14:35:41 -0700
commit25eff60debb13f86c0c11929544c43e476683057 (patch)
tree3da341b9b9019236c6bf551ddc093ff2e50a588d
parent454a17a31e4d68df961e769fc2b9233204bb3adc (diff)
downloadgcc-25eff60debb13f86c0c11929544c43e476683057.zip
gcc-25eff60debb13f86c0c11929544c43e476683057.tar.gz
gcc-25eff60debb13f86c0c11929544c43e476683057.tar.bz2
This patch fixes a couple of ICEs when using -gsplit-dwarf.
When compiling a small-enough compilation unit that has no address table entries, but complex enough that -freorder-blocks-and-partition produces location lists, dwarf2out_finish does not call index_location_lists, but optimize_location_lists will later assume that the addr_index_table has been indexed. Google ref: b/15417905 When resolve_addr_in_expr replaces a CONST_STRING rtx, it directly updates the pointer to the old expression with the new one. In the case of a DW_OP_GNU_addr_index or DW_OP_GNU_const_index, that pointer may be in an address table entry, which is keyed by the rtx. Instead of directly replacing the pointer, we need to remove the old address table entry (i.e., decrement its reference count), and add a new one. Google ref: b/15957101 gcc/ * dwarf2out.c (remove_addr_table_entry): Remove unnecessary hash table lookup. (resolve_addr_in_expr): When replacing the rtx in a location list entry, get a new address table entry. (dwarf2out_finish): Call index_location_lists even if there are no addr_index_table entries yet. From-SVN: r212211
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/dwarf2out.c35
2 files changed, 30 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ec1bb4a..d6f8553 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2014-07-01 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2out.c (remove_addr_table_entry): Remove unnecessary hash table
+ lookup.
+ (resolve_addr_in_expr): When replacing the rtx in a location list
+ entry, get a new address table entry.
+ (dwarf2out_finish): Call index_location_lists even if there are no
+ addr_index_table entries yet.
+
2014-07-01 Trevor Saunders <tsaunders@mozilla.com>
* config/i386/winnt.c (i386_pe_section_type_flags): Revert previous
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f692536..b65b37e 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4283,13 +4283,10 @@ add_addr_table_entry (void *addr, enum ate_kind kind)
static void
remove_addr_table_entry (addr_table_entry *entry)
{
- addr_table_entry *node;
-
gcc_assert (dwarf_split_debug_info && addr_index_table);
- node = (addr_table_entry *) htab_find (addr_index_table, entry);
/* After an index is assigned, the table is frozen. */
- gcc_assert (node->refcount > 0 && node->index == NO_INDEX_ASSIGNED);
- node->refcount--;
+ gcc_assert (entry->refcount > 0 && entry->index == NO_INDEX_ASSIGNED);
+ entry->refcount--;
}
/* Given a location list, remove all addresses it refers to from the
@@ -23288,11 +23285,16 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
break;
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
- if ((loc->dw_loc_opc == DW_OP_GNU_addr_index
- || (loc->dw_loc_opc == DW_OP_GNU_const_index && loc->dtprel))
- && resolve_one_addr (&loc->dw_loc_oprnd1.val_entry->addr.rtl,
- NULL))
- return false;
+ if (loc->dw_loc_opc == DW_OP_GNU_addr_index
+ || (loc->dw_loc_opc == DW_OP_GNU_const_index && loc->dtprel))
+ {
+ rtx rtl = loc->dw_loc_oprnd1.val_entry->addr.rtl;
+ if (resolve_one_addr (&rtl, NULL))
+ return false;
+ remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry);
+ loc->dw_loc_oprnd1.val_entry =
+ add_addr_table_entry (rtl, ate_kind_rtx);
+ }
break;
case DW_OP_const4u:
case DW_OP_const8u:
@@ -24391,18 +24393,23 @@ dwarf2out_finish (const char *filename)
dwarf_strict ? DW_AT_macro_info : DW_AT_GNU_macros,
macinfo_section_label);
- if (dwarf_split_debug_info && addr_index_table != NULL)
+ if (dwarf_split_debug_info)
{
/* optimize_location_lists calculates the size of the lists,
so index them first, and assign indices to the entries.
Although optimize_location_lists will remove entries from
the table, it only does so for duplicates, and therefore
only reduces ref_counts to 1. */
- unsigned int index = 0;
index_location_lists (comp_unit_die ());
- htab_traverse_noresize (addr_index_table,
- index_addr_table_entry, &index);
+
+ if (addr_index_table != NULL)
+ {
+ unsigned int index = 0;
+ htab_traverse_noresize (addr_index_table,
+ index_addr_table_entry, &index);
+ }
}
+
if (have_location_lists)
optimize_location_lists (comp_unit_die ());