Skip to content

DWARF representation of vector extension types #8

@hainest

Description

@hainest

test.c

#include <immintrin.h>

void foo(__m256 a, float b[8]){}

void bar() {
  __m256 a;
  float b[8];
}

Compiled with gcc-11 -std=c11 -mavx -O3 -g -gdwarf-5 -fPIC -shared -o libtest.so test.c. Dumping with readelf gives1

// float
<1><66>: Abbrev Number: 1 (DW_TAG_base_type)
   <67>   DW_AT_byte_size   : 4
   <68>   DW_AT_encoding    : 4  (float)
   <69>   DW_AT_name        : (indirect string, offset: 0x125): float

// __m256 -> typedef float __m256 __attribute__ ((__vector_size__ (32), __may_alias__));
<1><90>: Abbrev Number: 6 (DW_TAG_typedef)
   <91>   DW_AT_name        : (indirect string, offset: 0xea): __m256
   <98>   DW_AT_type        : <0x9c>
<1><9c>: Abbrev Number: 7 (DW_TAG_array_type)
   <9d>   DW_AT_GNU_vector  : 1
   <9d>   DW_AT_type        : <0x66>

// float[8]
<1><d9>: Abbrev Number: 10 (DW_TAG_array_type)
   <da>   DW_AT_type        : <0x66>
   <de>   DW_AT_sibling     : <0xe9>
<2><e2>: Abbrev Number: 11 (DW_TAG_subrange_type)
   <e3>   DW_AT_type        : <0x35>
   <e7>   DW_AT_upper_bound : 7

// void foo(__m256 a, float b[8]){}
<1><e9>: Abbrev Number: 12 (DW_TAG_subprogram)
   <ea>   DW_AT_name        : foo
<2><107>: Abbrev Number: 3 (DW_TAG_formal_parameter)
   <108>   DW_AT_name        : a
   <10b>   DW_AT_type        : <0x90>
   <10f>   DW_AT_location    : 1 byte block: 61  (DW_OP_reg17 (xmm0))
<2><111>: Abbrev Number: 3 (DW_TAG_formal_parameter)
   <112>   DW_AT_name        : b
   <115>   DW_AT_type        : <0x11c>
   <119>   DW_AT_location    : 1 byte block: 55  (DW_OP_reg5 (rdi))
<1><11c>: Abbrev Number: 13 (DW_TAG_pointer_type)
   <11d>   DW_AT_byte_size   : 8
   <11e>   DW_AT_type        : <0x66>

// void bar() {
//   __m256 a;
//   float b[8];
// }
<1><a8>: Abbrev Number: 9 (DW_TAG_subprogram)
   <a9>   DW_AT_name        : bar
<2><c6>: Abbrev Number: 2 (DW_TAG_variable)
   <c7>   DW_AT_name        : a
   <cb>   DW_AT_type        : <0x90>
<2><cf>: Abbrev Number: 2 (DW_TAG_variable)
   <d0>   DW_AT_name        : b
   <d4>   DW_AT_type        : <0xd9>

The key problem is that DWARF treats vector types as arrays. The only indication you get that you are dealing with a vector type is 1) the name string is __m256 and 2) the non-standard DW_AT_GNU_vector. This is problematic for high-level parsers like Dyninst where that information isn't available until after the determination of array-ness has been made. Also, vectors aren't logically arrays, either; the AMD64 ABI treats them differently (not sure about the others). From a language perspective, they aren't the same because vectors don't possess the awful array-to-pointer decay. You can index them when using gcc, but I'm not sure if that's portable.

I see no reason why we can't just have a DW_TAG_vector_type that has a DW_AT_name, DW_AT_type, and a DW_AT_byte_size.


[1] readelf.log

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions