DWARF: Handle expressions containing "-1" in dw2_asm_output_delta_uleb128.

Message ID 1527490246-27993-1-git-send-email-mark@klomp.org
State New
Headers show
Series
  • DWARF: Handle expressions containing "-1" in dw2_asm_output_delta_uleb128.
Related show

Commit Message

Mark Wielaard May 28, 2018, 6:50 a.m.
In dwarf2out.c dwarf2out_var_location () we create loclabels that might
contain -1 (for example ".LVL5-1"). Technically those are expressions,
not just plain labels. But they work fine everywhere we use them, except
when calculating an uleb128 delta between two labels.

For example we might create the following DWARF5 location list entry:

        .byte   0x3     # DW_LLE_startx_length (*.LLST0)
        .uleb128 0x6    # Location list range start index (*.LVL5-1)
        .uleb128 .LFE1-.LVL5-1        # Location list length (*.LLST0)
        .uleb128 0x1    # Location expression size
        .byte   0x54    # DW_OP_reg4
        .byte   0       # DW_LLE_end_of_list (*.LLST0)

Note the length is calculated using .uleb128 .LFE1-.LVL5-1. This is
wrong, since both .LVL5 and 1 are substracted from .LFE1, instead of
1 being subtracted from .LVL5 first, before substracting from .LFE1.

This happens because dw2_asm_output_delta_uleb128 expects two plain
labels and simply inserts a minus sign between them. To fix this we
simply look if the second label is actually an expression containing
a minus sign and then add brackets around it. That will emit the
correct .uleb128 expression:

        .uleb128 .LFE1-(.LVL5-1)        # Location list length (*.LLST0)

We cannot simply generate the loclabel containing brackets directly
because we do use them also in contexts that don't take a full
expression (for example we use them with .quad too).

gcc/

	* dwarf2asm.c (dw2_asm_output_delta_uleb128): Add brackets around
	lab2 if it is an expression containing a minus sign.

Comments

Jakub Jelinek May 28, 2018, 7:16 a.m. | #1
On Mon, May 28, 2018 at 08:50:46AM +0200, Mark Wielaard wrote:
> gcc/

> 

> 	* dwarf2asm.c (dw2_asm_output_delta_uleb128): Add brackets around

> 	lab2 if it is an expression containing a minus sign.


Ok, thanks.

> diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c

> index 93577d1..62a1da9 100644

> --- a/gcc/dwarf2asm.c

> +++ b/gcc/dwarf2asm.c

> @@ -811,7 +811,17 @@ dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,

>    fputs ("\t.uleb128 ", asm_out_file);

>    assemble_name (asm_out_file, lab1);

>    putc ('-', asm_out_file);

> -  assemble_name (asm_out_file, lab2);

> +  /* dwarf2out.c might give us an label expression (e.g. .LVL548-1)

> +     as second argument.  If so, make it a subexpression, to make

> +     sure the substraction is done in the right order.  */

> +  if (strchr (lab2, '-') != NULL)

> +    {

> +      putc ('(', asm_out_file);

> +      assemble_name (asm_out_file, lab2);

> +      putc (')', asm_out_file);

> +    }

> +  else

> +    assemble_name (asm_out_file, lab2);

>  

>    if (flag_debug_asm && comment)

>      {


	Jakub

Patch

diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 93577d1..62a1da9 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -811,7 +811,17 @@  dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
   fputs ("\t.uleb128 ", asm_out_file);
   assemble_name (asm_out_file, lab1);
   putc ('-', asm_out_file);
-  assemble_name (asm_out_file, lab2);
+  /* dwarf2out.c might give us an label expression (e.g. .LVL548-1)
+     as second argument.  If so, make it a subexpression, to make
+     sure the substraction is done in the right order.  */
+  if (strchr (lab2, '-') != NULL)
+    {
+      putc ('(', asm_out_file);
+      assemble_name (asm_out_file, lab2);
+      putc (')', asm_out_file);
+    }
+  else
+    assemble_name (asm_out_file, lab2);
 
   if (flag_debug_asm && comment)
     {