dwarf_loader: Process DW_AT_count in DW_TAG_subrange_type

For array type, gcc and clang generates dwarf info with different tags.  For
example, with existing pahole,

  $ cat test.c
    int a[5][5];
  $ gcc -c -g test.c
  $ llvm-dwarfdump test.o
    ...
    0x0000001d:   DW_TAG_array_type
                  DW_AT_type    (0x0000003a "int")
                  DW_AT_sibling (0x00000033)

    0x00000026:     DW_TAG_subrange_type
                      DW_AT_type        (0x00000033 "long unsigned int")
                      DW_AT_upper_bound (0x04)

    0x0000002c:     DW_TAG_subrange_type
                      DW_AT_type        (0x00000033 "long unsigned int")
                      DW_AT_upper_bound (0x04)
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=3 index_type_id=3 nr_elems=25
    [2] INT long unsigned int size=8 bit_offset=0 nr_bits=64 encoding=(none)
    [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  $ clang -c -g test.c
  $ llvm-dwarfdump test.o
    ...
    0x00000033:   DW_TAG_array_type
                    DW_AT_type  (0x00000045 "int")

    0x00000038:     DW_TAG_subrange_type
                      DW_AT_type        (0x0000004c "__ARRAY_SIZE_TYPE__")
                      DW_AT_count       (0x05)

    0x0000003e:     DW_TAG_subrange_type
                      DW_AT_type        (0x0000004c "__ARRAY_SIZE_TYPE__")
                      DW_AT_count       (0x05)
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=0
    [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
    [3] INT __ARRAY_SIZE_TYPE__ size=8 bit_offset=0 nr_bits=64 encoding=(none)

Current pahole processed DW_AT_upper_bound under DW_TAG_subrange_type to
get array range, but it did not process DW_AT_count so during pahole
dwarf2btf conversion, the flattened array size is 0.

This patch fixed the issue by processing DW_AT_count properly.
With the change, for clang generated test.o, pahole btf conversion output is:
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=25
    [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
    [3] INT __ARRAY_SIZE_TYPE__ size=8 bit_offset=0 nr_bits=64 encoding=(none)

Committer testing:

Before:

  # pahole -C augmented_enter_connect_args augmented_syscalls.bpf.o
  struct augmented_enter_connect_args {
          struct syscall_enter_connect_args args;          /*     0    40 */
          char                       addr[0];              /*    40     0 */

          /* size: 56, cachelines: 1, members: 2 */
          /* padding: 16 */
          /* last cacheline: 56 bytes */
  };
  # file augmented_syscalls.bpf.o
  augmented_syscalls.bpf.o: ELF 64-bit LSB relocatable, *unknown arch 0xf7* version 1 (SYSV), with debug_info, not stripped
  #

After:

  # pahole -C augmented_enter_connect_args augmented_syscalls.bpf.o
  struct augmented_enter_connect_args {
	  struct syscall_enter_connect_args args;          /*     0    40 */
	  char                       addr[14];             /*    40    14 */

	  /* size: 56, cachelines: 1, members: 2 */
	  /* padding: 2 */
	  /* last cacheline: 56 bytes */
  };
  #

Signed-off-by: Yonghong Song <yhs@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Okash Khawaja <osk@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Yonghong Song 2018-08-23 14:04:13 -07:00 committed by Arnaldo Carvalho de Melo
parent 4a21c5c8db
commit eb6bd05766
1 changed files with 6 additions and 0 deletions

View File

@ -933,6 +933,12 @@ static uint64_t attr_upper_bound(Dwarf_Die *die)
if (dwarf_formudata(&attr, &num) == 0) {
return (uintmax_t)num + 1;
}
} else if (dwarf_attr(die, DW_AT_count, &attr) != NULL) {
Dwarf_Word num;
if (dwarf_formudata(&attr, &num) == 0) {
return (uintmax_t)num;
}
}
return 0;