llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.76k stars 11.89k forks source link

llvm-dwarfdump does not handle DW_OP_implicit_pointer #53824

Open wcohen opened 2 years ago

wcohen commented 2 years ago

When using llvm-dwarfdump on some gcc generated code I found that it did not decode location information for items using DW_OP_implicit_pointer. I was able to reproduce the problems from a small example from https://patchwork.ozlabs.org/project/gcc/patch/20100812080522.GL702@tyan-ft48-01.lab.bos.redhat.com/#153158 , dw_op_implicit_pointer.c:

struct S
{
  int *x, y;
};

int u[6];

static inline void
add (struct S *a, struct S *b, int c)
{
  *a->x += *b->x;
  a->y += b->y;
  u[c + 0]++;
  a = (struct S *) 0;
  u[c + 1]++;
  a = b;
  u[c + 2]++;
}

int
foo (int i)
{
  int j = i;
  struct S p[2] = { {&i, i * 2}, {&j, j * 2} };
  add (&p[0], &p[1], 0);
  p[0].x = &j;
  p[1].x = &i;
  add (&p[0], &p[1], 3);
  return i + j;
}

int
bar (int i)
{
  int *j = &i;
  int **k = &j;
  int ***l = &k;
  i++;
  return i;
}

compiled with the following on Fedora 35 with gcc-11.2.1-7.fc35.x86_64:

gcc -g -O2 -c dw_op_implicit_pointer.c

Look through the resulting dw_op_implicit_pointer.o with llvm-13.0.0-4.fc35.x86_64

llvm-dwarfdump dw_op_implicit_pointer.o

See entries like the following where the DW_OP_implicit_pointer (a0) is not decoded:

0x00000153:       DW_TAG_formal_parameter
                    DW_AT_abstract_origin   (0x000001dd "b")
                    DW_AT_location  (0x00000081: 
                       [0x0000000000000000, 0x0000000000000018): <decoding error> a0 00 00 00 00 10)
                    DW_AT_GNU_entry_view    (0x0000007f)
wcohen commented 2 years ago

Looking at Table 7.9: DWARF operation encodings in DWARF.pdf it is likely that llvm-dwarfdump is not decoding any of the DWOP* that are listed as "New in DWARF Version 5" in the table.

llvmbot commented 2 years ago

@llvm/issue-subscribers-debuginfo

pogo59 commented 2 years ago

Looking at Table 7.9: DWARF operation encodings in DWARF.pdf it is likely that llvm-dwarfdump is not decoding any of the DWOP* that are listed as "New in DWARF Version 5" in the table.

Not completely true; I do see code to handle DW_OP_entry_value. It's more likely that llvm-dwarfdump has not been enhanced to decode any operators that LLVM itself does not emit.

Thanks for the report!

wcohen commented 2 years ago

I took a look at the llvm-dwarfdump output to see if there were any other <decoding errors> in the output. Found there were a number like the following:

0x000c5030:     DW_TAG_formal_parameter
                  DW_AT_abstract_origin (0x0005ddcd "__str")
                  DW_AT_location    (0x0003834e: 
                     [0x000000000045d8c0, 0x000000000045d90e): <decoding error> fa cd dd 05 00 9f)
                  DW_AT_GNU_entry_view  (0x0003834c)

fa is GNU one of the GNU extensions listed in /usr/include/dwarf.h:

    /* GNU extensions.  */
    DW_OP_GNU_push_tls_address = 0xe0,
    DW_OP_GNU_uninit = 0xf0,
    DW_OP_GNU_encoded_addr = 0xf1,
    DW_OP_GNU_implicit_pointer = 0xf2,
    DW_OP_GNU_entry_value = 0xf3,
    DW_OP_GNU_const_type = 0xf4,
    DW_OP_GNU_regval_type = 0xf5,
    DW_OP_GNU_deref_type = 0xf6,
    DW_OP_GNU_convert = 0xf7,
    DW_OP_GNU_reinterpret = 0xf9,
    DW_OP_GNU_parameter_ref = 0xfa,

    /* GNU Debug Fission extensions.  */
    DW_OP_GNU_addr_index = 0xfb,
    DW_OP_GNU_const_index = 0xfc,

    DW_OP_GNU_variable_value = 0xfd,

Also saw some errors decoding the location lists like the following which looks like it had problems a4 (DW_OP_const_type):

0x0030af67:                   DW_TAG_variable
                                DW_AT_abstract_origin   (0x0028c54a "__num")
                                DW_AT_location  (0x000f63a7: 
                                   [0x0000000000485f6b, 0x0000000000485f7a): DW_OP_reg0 RAX
                                   [0x0000000000485f7a, 0x0000000000485f90): DW_OP_breg1 RDX+0, DW_OP_breg1 RDX+0, DW_OP_lit2, DW_OP_shr, DW_OP_convert (0x00201c5d) "long unsigned int", DW_OP_convert (0x00201c56) "__int128 unsigned", DW_OP_constu 0x28f5c28f5c28f5c3, DW_OP_convert (0x00201c56) "__int128 unsigned", DW_OP_mul, DW_OP_const1u 0x40, DW_OP_convert (0x00201c56) "__int128 unsigned", DW_OP_shr, <decoding error> a4 2b 10 fc ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 1a a8 32 a8 00 73 00 22 35 1e 32 24 1c 31 24 9f)
                                DW_AT_GNU_entry_view    (0x000f63a3)