diff mbox

[v2,13/13] Add hook for modifying debug info for address spaces

Message ID 1445376433-14658-14-git-send-email-rth@redhat.com
State New
Headers show

Commit Message

Richard Henderson Oct. 20, 2015, 9:27 p.m. UTC
---
 gcc/config/i386/i386.c | 21 +++++++++++++++++++++
 gcc/doc/tm.texi        |  7 +++++++
 gcc/doc/tm.texi.in     |  2 ++
 gcc/dwarf2out.c        | 48 +++++++++++++++++++++++++++++-------------------
 gcc/target.def         | 10 ++++++++++
 gcc/targhooks.c        |  8 ++++++++
 gcc/targhooks.h        |  1 +
 7 files changed, 78 insertions(+), 19 deletions(-)

Comments

Jeff Law Oct. 21, 2015, 1:48 p.m. UTC | #1
On 10/20/2015 03:27 PM, Richard Henderson wrote:
> ---
>   gcc/config/i386/i386.c | 21 +++++++++++++++++++++
>   gcc/doc/tm.texi        |  7 +++++++
>   gcc/doc/tm.texi.in     |  2 ++
>   gcc/dwarf2out.c        | 48 +++++++++++++++++++++++++++++-------------------
>   gcc/target.def         | 10 ++++++++++
>   gcc/targhooks.c        |  8 ++++++++
>   gcc/targhooks.h        |  1 +
>   7 files changed, 78 insertions(+), 19 deletions(-)
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 8f833d1..9fb0fac 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -53707,6 +53707,27 @@ ix86_addr_space_convert (rtx op, tree from_type, tree to_type)
>   #undef TARGET_ADDR_SPACE_CONVERT
>   #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert
>
> +static int
> +ix86_addr_space_debug (addr_space_t as)
> +{
> +  /* Represent debugging for address spaces with DW_AT_segment,
> +     and the dwarf register for fsbase/gsbase.  */
> +  if (as == ADDR_SPACE_SEG_TLS)
> +    as = DEFAULT_TLS_SEG_REG;
> +
> +  /* ??? These register numbers are defined in the x86-64 abi,
> +     but there is no corresponding definition for the i386 abi.
> +     That said, {58,59} appear to be reserved, so perhaps best
> +     to use the same numbers in the 32-bit abi.  */
> +  if (as == ADDR_SPACE_SEG_FS)
> +    return ~58;  /* dwarf fsbase */
> +  else if (as == ADDR_SPACE_SEG_GS)
> +    return ~59;  /* dwarf gsbase */
> +  gcc_unreachable ();
> +}
So in the case where AS, as passed in is ADDR_SPACE_SEG_TLS, we then 
change it to DEFAULT_TLS_SEG_REG.

Yet I don't see DEFAULT_TLS_SEG_REG handled in the two cases below which 
would make one think we'd hit the gcc_unreachable ().  Of course 
DEFAULT_TLS_SEG_REG will be defined as ADDR_SPACE_SEG_FS or 
ADDR_SPACE_SEG_GS, so we can't actually hit the gcc_unreachable, but 
as-written that's non-obvious.

If you could clarify that with a comment I think this hunk is ready to go.
jeff
H.J. Lu Oct. 21, 2015, 2:53 p.m. UTC | #2
On Tue, Oct 20, 2015 at 2:27 PM, Richard Henderson <rth@redhat.com> wrote:
> ---
>  gcc/config/i386/i386.c | 21 +++++++++++++++++++++
>  gcc/doc/tm.texi        |  7 +++++++
>  gcc/doc/tm.texi.in     |  2 ++
>  gcc/dwarf2out.c        | 48 +++++++++++++++++++++++++++++-------------------
>  gcc/target.def         | 10 ++++++++++
>  gcc/targhooks.c        |  8 ++++++++
>  gcc/targhooks.h        |  1 +
>  7 files changed, 78 insertions(+), 19 deletions(-)
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 8f833d1..9fb0fac 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -53707,6 +53707,27 @@ ix86_addr_space_convert (rtx op, tree from_type, tree to_type)
>  #undef TARGET_ADDR_SPACE_CONVERT
>  #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert
>
> +static int
> +ix86_addr_space_debug (addr_space_t as)
> +{
> +  /* Represent debugging for address spaces with DW_AT_segment,
> +     and the dwarf register for fsbase/gsbase.  */
> +  if (as == ADDR_SPACE_SEG_TLS)
> +    as = DEFAULT_TLS_SEG_REG;
> +
> +  /* ??? These register numbers are defined in the x86-64 abi,
> +     but there is no corresponding definition for the i386 abi.
> +     That said, {58,59} appear to be reserved, so perhaps best
> +     to use the same numbers in the 32-bit abi.  */
> +  if (as == ADDR_SPACE_SEG_FS)
> +    return ~58;  /* dwarf fsbase */
> +  else if (as == ADDR_SPACE_SEG_GS)
> +    return ~59;  /* dwarf gsbase */
> +  gcc_unreachable ();
> +}

This is wrong for i386 psABI.  Please use the DWARF register
numbers listed in Table 2.14: DWARF Register Number Mapping
in Intel386 psABI:

https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI

Segment Register ES 40 %es
Segment Register CS 41 %cs
Segment Register SS 42 %ss
Segment Register DS 43 %ds
Segment Register FS 44 %fs
Segment Register GS 45 %gs
Richard Henderson Oct. 21, 2015, 5:17 p.m. UTC | #3
On 10/21/2015 04:53 AM, H.J. Lu wrote:
> On Tue, Oct 20, 2015 at 2:27 PM, Richard Henderson <rth@redhat.com> wrote:
>> ---
>>   gcc/config/i386/i386.c | 21 +++++++++++++++++++++
>>   gcc/doc/tm.texi        |  7 +++++++
>>   gcc/doc/tm.texi.in     |  2 ++
>>   gcc/dwarf2out.c        | 48 +++++++++++++++++++++++++++++-------------------
>>   gcc/target.def         | 10 ++++++++++
>>   gcc/targhooks.c        |  8 ++++++++
>>   gcc/targhooks.h        |  1 +
>>   7 files changed, 78 insertions(+), 19 deletions(-)
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 8f833d1..9fb0fac 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -53707,6 +53707,27 @@ ix86_addr_space_convert (rtx op, tree from_type, tree to_type)
>>   #undef TARGET_ADDR_SPACE_CONVERT
>>   #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert
>>
>> +static int
>> +ix86_addr_space_debug (addr_space_t as)
>> +{
>> +  /* Represent debugging for address spaces with DW_AT_segment,
>> +     and the dwarf register for fsbase/gsbase.  */
>> +  if (as == ADDR_SPACE_SEG_TLS)
>> +    as = DEFAULT_TLS_SEG_REG;
>> +
>> +  /* ??? These register numbers are defined in the x86-64 abi,
>> +     but there is no corresponding definition for the i386 abi.
>> +     That said, {58,59} appear to be reserved, so perhaps best
>> +     to use the same numbers in the 32-bit abi.  */
>> +  if (as == ADDR_SPACE_SEG_FS)
>> +    return ~58;  /* dwarf fsbase */
>> +  else if (as == ADDR_SPACE_SEG_GS)
>> +    return ~59;  /* dwarf gsbase */
>> +  gcc_unreachable ();
>> +}
>
> This is wrong for i386 psABI.  Please use the DWARF register
> numbers listed in Table 2.14: DWARF Register Number Mapping
> in Intel386 psABI:
>
> https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
>
> Segment Register ES 40 %es
> Segment Register CS 41 %cs
> Segment Register SS 42 %ss
> Segment Register DS 43 %ds
> Segment Register FS 44 %fs
> Segment Register GS 45 %gs

I'm not looking for the segment register (aka descriptor), I'm looking for the 
segment base.  Not the same thing.

As I note in the comment, there is no such definition in the i386 psabi, while 
there is in the x86-64 psabi.


r~
H.J. Lu Oct. 21, 2015, 5:23 p.m. UTC | #4
On Wed, Oct 21, 2015 at 10:17 AM, Richard Henderson <rth@redhat.com> wrote:
> On 10/21/2015 04:53 AM, H.J. Lu wrote:
>>
>> On Tue, Oct 20, 2015 at 2:27 PM, Richard Henderson <rth@redhat.com> wrote:
>>>
>>> ---
>>>   gcc/config/i386/i386.c | 21 +++++++++++++++++++++
>>>   gcc/doc/tm.texi        |  7 +++++++
>>>   gcc/doc/tm.texi.in     |  2 ++
>>>   gcc/dwarf2out.c        | 48
>>> +++++++++++++++++++++++++++++-------------------
>>>   gcc/target.def         | 10 ++++++++++
>>>   gcc/targhooks.c        |  8 ++++++++
>>>   gcc/targhooks.h        |  1 +
>>>   7 files changed, 78 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>>> index 8f833d1..9fb0fac 100644
>>> --- a/gcc/config/i386/i386.c
>>> +++ b/gcc/config/i386/i386.c
>>> @@ -53707,6 +53707,27 @@ ix86_addr_space_convert (rtx op, tree from_type,
>>> tree to_type)
>>>   #undef TARGET_ADDR_SPACE_CONVERT
>>>   #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert
>>>
>>> +static int
>>> +ix86_addr_space_debug (addr_space_t as)
>>> +{
>>> +  /* Represent debugging for address spaces with DW_AT_segment,
>>> +     and the dwarf register for fsbase/gsbase.  */
>>> +  if (as == ADDR_SPACE_SEG_TLS)
>>> +    as = DEFAULT_TLS_SEG_REG;
>>> +
>>> +  /* ??? These register numbers are defined in the x86-64 abi,
>>> +     but there is no corresponding definition for the i386 abi.
>>> +     That said, {58,59} appear to be reserved, so perhaps best
>>> +     to use the same numbers in the 32-bit abi.  */
>>> +  if (as == ADDR_SPACE_SEG_FS)
>>> +    return ~58;  /* dwarf fsbase */
>>> +  else if (as == ADDR_SPACE_SEG_GS)
>>> +    return ~59;  /* dwarf gsbase */
>>> +  gcc_unreachable ();
>>> +}
>>
>>
>> This is wrong for i386 psABI.  Please use the DWARF register
>> numbers listed in Table 2.14: DWARF Register Number Mapping
>> in Intel386 psABI:
>>
>> https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
>>
>> Segment Register ES 40 %es
>> Segment Register CS 41 %cs
>> Segment Register SS 42 %ss
>> Segment Register DS 43 %ds
>> Segment Register FS 44 %fs
>> Segment Register GS 45 %gs
>
>
> I'm not looking for the segment register (aka descriptor), I'm looking for
> the segment base.  Not the same thing.
>
> As I note in the comment, there is no such definition in the i386 psabi,
> while there is in the x86-64 psabi.

We can define them as 93 and 94.  50-92 were used for other registers
before and have been deprecated now.  But some old tools may
still use them.
Richard Henderson Oct. 21, 2015, 5:49 p.m. UTC | #5
On 10/21/2015 07:23 AM, H.J. Lu wrote:
> We can define them as 93 and 94.  50-92 were used for other registers
> before and have been deprecated now.  But some old tools may
> still use them.

Thanks.  I'll update the patch.


r~
H.J. Lu Oct. 21, 2015, 6:11 p.m. UTC | #6
On Wed, Oct 21, 2015 at 10:49 AM, Richard Henderson <rth@redhat.com> wrote:
> On 10/21/2015 07:23 AM, H.J. Lu wrote:
>>
>> We can define them as 93 and 94.  50-92 were used for other registers
>> before and have been deprecated now.  But some old tools may
>> still use them.
>
>

The i386 psABI draft is at

https://github.com/hjl-tools/x86-psABI/wiki/intel386-psABI-20151021.pdf
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8f833d1..9fb0fac 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -53707,6 +53707,27 @@  ix86_addr_space_convert (rtx op, tree from_type, tree to_type)
 #undef TARGET_ADDR_SPACE_CONVERT
 #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert
 
+static int
+ix86_addr_space_debug (addr_space_t as)
+{
+  /* Represent debugging for address spaces with DW_AT_segment,
+     and the dwarf register for fsbase/gsbase.  */
+  if (as == ADDR_SPACE_SEG_TLS)
+    as = DEFAULT_TLS_SEG_REG;
+
+  /* ??? These register numbers are defined in the x86-64 abi,
+     but there is no corresponding definition for the i386 abi.
+     That said, {58,59} appear to be reserved, so perhaps best
+     to use the same numbers in the 32-bit abi.  */
+  if (as == ADDR_SPACE_SEG_FS)
+    return ~58;  /* dwarf fsbase */
+  else if (as == ADDR_SPACE_SEG_GS)
+    return ~59;  /* dwarf gsbase */
+  gcc_unreachable ();
+}
+#undef TARGET_ADDR_SPACE_DEBUG
+#define TARGET_ADDR_SPACE_DEBUG ix86_addr_space_debug
+
 /* All use of segmentation is assumed to make address 0 valid.  */
 
 static bool
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d530a9c..79a0d01 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10330,6 +10330,13 @@  guaranteed that one of the two address spaces is a subset of the other,
 as determined by the @code{TARGET_ADDR_SPACE_SUBSET_P} target hook.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_ADDR_SPACE_DEBUG (addr_space_t @var{as})
+Define this to define how the address space is encoded in dwarf.
+The result, @var{r}, should be positive to indicate
+@code{DW_AT_address_class @var{r}} should be emitted; or negative
+to indicate @code{DW_AT_segment} with location in register @code{~@var{r}}.
+@end deftypefn
+
 @node Misc
 @section Miscellaneous Parameters
 @cindex parameters, miscellaneous
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index f8dad76..b57310c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7438,6 +7438,8 @@  c_register_addr_space ("__ea", ADDR_SPACE_EA);
 
 @hook TARGET_ADDR_SPACE_CONVERT
 
+@hook TARGET_ADDR_SPACE_DEBUG
+
 @node Misc
 @section Miscellaneous Parameters
 @cindex parameters, miscellaneous
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c1b7c7b..013e03f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10912,29 +10912,39 @@  modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
 	    mod_type_die = d;
 	  }
     }
-  else if (code == POINTER_TYPE)
+  else if (code == POINTER_TYPE || code == REFERENCE_TYPE)
     {
-      mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type);
-      add_AT_unsigned (mod_type_die, DW_AT_byte_size,
-		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
-      item_type = TREE_TYPE (type);
-      if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (item_type)))
-	add_AT_unsigned (mod_type_die, DW_AT_address_class,
-			 TYPE_ADDR_SPACE (item_type));
-    }
-  else if (code == REFERENCE_TYPE)
-    {
-      if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
-	mod_type_die = new_die (DW_TAG_rvalue_reference_type, mod_scope,
-				type);
-      else
-	mod_type_die = new_die (DW_TAG_reference_type, mod_scope, type);
+      dwarf_tag tag = DW_TAG_pointer_type;
+      if (code == REFERENCE_TYPE)
+	{
+	  if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
+	    tag = DW_TAG_rvalue_reference_type;
+	  else
+	    tag = DW_TAG_reference_type;
+	}
+      mod_type_die = new_die (tag, mod_scope, type);
+
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
 		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
-      if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (item_type)))
-	add_AT_unsigned (mod_type_die, DW_AT_address_class,
-			 TYPE_ADDR_SPACE (item_type));
+
+      addr_space_t as = TYPE_ADDR_SPACE (item_type);
+      if (!ADDR_SPACE_GENERIC_P (as))
+	{
+	  int action = targetm.addr_space.debug (as);
+	  if (action >= 0)
+	    {
+	      /* Positive values indicate an address_class.  */
+	      add_AT_unsigned (mod_type_die, DW_AT_address_class, action);
+	    }
+	  else
+	    {
+	      /* Negative values indicate an (inverted) segment base reg.  */
+	      dw_loc_descr_ref d
+		= one_reg_loc_descriptor (~action, VAR_INIT_STATUS_INITIALIZED);
+	      add_AT_loc (mod_type_die, DW_AT_segment, d);
+	    }
+	}
     }
   else if (code == INTEGER_TYPE
 	   && TREE_TYPE (type) != NULL_TREE
diff --git a/gcc/target.def b/gcc/target.def
index e33c87f..ed9f9c5 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3206,6 +3206,16 @@  as determined by the @code{TARGET_ADDR_SPACE_SUBSET_P} target hook.",
  rtx, (rtx op, tree from_type, tree to_type),
  default_addr_space_convert)
 
+/* Function to encode an address space into dwarf.  */
+DEFHOOK
+(debug,
+ "Define this to define how the address space is encoded in dwarf.\n\
+The result, @var{r}, should be positive to indicate\n\
+@code{DW_AT_address_class @var{r}} should be emitted; or negative\n\
+to indicate @code{DW_AT_segment} with location in register @code{~@var{r}}.",
+ int, (addr_space_t as),
+ default_addr_space_debug)
+
 HOOK_VECTOR_END (addr_space)
 
 #undef HOOK_PREFIX
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index d221d20..fd99460 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1265,6 +1265,14 @@  default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED)
   return false;
 }
 
+/* The default hook for debugging the address space is to return the
+   (positive) address space number to indicate DW_AT_address_class.  */
+int
+default_addr_space_debug (addr_space_t as)
+{
+  return as;
+}
+
 /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
    called for targets with only a generic address space.  */
 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ade3327..2bb2d1e 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -174,6 +174,7 @@  extern rtx default_addr_space_legitimize_address (rtx, rtx, machine_mode,
 						  addr_space_t);
 extern bool default_addr_space_subset_p (addr_space_t, addr_space_t);
 extern bool default_addr_space_zero_address_valid (addr_space_t);
+extern int default_addr_space_debug (addr_space_t);
 extern rtx default_addr_space_convert (rtx, tree, tree);
 extern unsigned int default_case_values_threshold (void);
 extern bool default_have_conditional_execution (void);