aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-07-08 16:50:16 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-07-08 16:50:16 +0200
commitb298f92498764494e449b572ef7e638b3166759c (patch)
tree14466025a3d452eb729d9ef4821d853bf0a5d6da /gcc
parent5dde3b0174313d39691008d01204b59223a54496 (diff)
downloadgcc-b298f92498764494e449b572ef7e638b3166759c.zip
gcc-b298f92498764494e449b572ef7e638b3166759c.tar.gz
gcc-b298f92498764494e449b572ef7e638b3166759c.tar.bz2
dwarf2out.c (mem_loc_descriptor): Use DW_OP_const[48]u instead of DW_OP_addr for DW_OP_GNU_push_tls_address operand.
* dwarf2out.c (mem_loc_descriptor): Use DW_OP_const[48]u instead of DW_OP_addr for DW_OP_GNU_push_tls_address operand. (loc_list_from_tree): Likewise. (output_loc_operands): Handle outputting DW_OP_const[48]u with loc->dtprel set. (resolve_addr_in_expr): Handle loc->dtprel like DW_OP_addr. From-SVN: r161958
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/dwarf2out.c33
2 files changed, 38 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8d5761f..e2339f6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2010-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (mem_loc_descriptor): Use DW_OP_const[48]u
+ instead of DW_OP_addr for DW_OP_GNU_push_tls_address operand.
+ (loc_list_from_tree): Likewise.
+ (output_loc_operands): Handle outputting DW_OP_const[48]u
+ with loc->dtprel set.
+ (resolve_addr_in_expr): Handle loc->dtprel like DW_OP_addr.
+
2010-07-08 Jan Hubicka <jh@suse.cz>
* ipa.c: Include pointer-set.h
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 5340ffc..d177871 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4928,10 +4928,28 @@ output_loc_operands (dw_loc_descr_ref loc)
dw2_asm_output_data (2, val1->v.val_int, NULL);
break;
case DW_OP_const4u:
+ if (loc->dtprel)
+ {
+ gcc_assert (targetm.asm_out.output_dwarf_dtprel);
+ targetm.asm_out.output_dwarf_dtprel (asm_out_file, 4,
+ val1->v.val_addr);
+ fputc ('\n', asm_out_file);
+ break;
+ }
+ /* FALLTHRU */
case DW_OP_const4s:
dw2_asm_output_data (4, val1->v.val_int, NULL);
break;
case DW_OP_const8u:
+ if (loc->dtprel)
+ {
+ gcc_assert (targetm.asm_out.output_dwarf_dtprel);
+ targetm.asm_out.output_dwarf_dtprel (asm_out_file, 8,
+ val1->v.val_addr);
+ fputc ('\n', asm_out_file);
+ break;
+ }
+ /* FALLTHRU */
case DW_OP_const8s:
gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
dw2_asm_output_data (8, val1->v.val_int, NULL);
@@ -13586,7 +13604,11 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel)
break;
- temp = new_loc_descr (DW_OP_addr, 0, 0);
+ /* We used to emit DW_OP_addr here, but that's wrong, since
+ DW_OP_addr should be relocated by the debug info consumer,
+ while DW_OP_GNU_push_tls_address operand should not. */
+ temp = new_loc_descr (DWARF2_ADDR_SIZE == 4
+ ? DW_OP_const4u : DW_OP_const8u, 0, 0);
temp->dw_loc_oprnd1.val_class = dw_val_class_addr;
temp->dw_loc_oprnd1.v.val_addr = rtl;
temp->dtprel = true;
@@ -15071,10 +15093,13 @@ loc_list_from_tree (tree loc, int want_address)
/* The way DW_OP_GNU_push_tls_address is specified, we
can only look up addresses of objects in the current
- module. */
+ module. We used DW_OP_addr as first op, but that's
+ wrong, because DW_OP_addr is relocated by the debug
+ info consumer, while DW_OP_GNU_push_tls_address
+ operand shouldn't be. */
if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc))
return 0;
- first_op = DW_OP_addr;
+ first_op = DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u;
dtprel = true;
second_op = DW_OP_GNU_push_tls_address;
}
@@ -22093,7 +22118,7 @@ static bool
resolve_addr_in_expr (dw_loc_descr_ref loc)
{
for (; loc; loc = loc->dw_loc_next)
- if ((loc->dw_loc_opc == DW_OP_addr
+ if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel)
&& resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL))
|| (loc->dw_loc_opc == DW_OP_implicit_value
&& loc->dw_loc_oprnd2.val_class == dw_val_class_addr