[RFC PATCH 1/2] [clang]: Add AuxAttr support

This patch adds EmitTypeAuxAttribute() function to CGDebugInfo, which
allows other parts of clang issue auxiliary information through an
enumeration type in Dwarf information. For example, by calling

  DI->EmitTypeAuxAttribute(type, "ID", 1234);

We can get following information in dwarf:

<1><3f>: Abbrev Number: 3 (DW_TAG_structure_type)
    <40> DW_AT_name : (indirect string, offset: 0xeb): my_str
    ...
<2><47>: Abbrev Number: 4 (DW_TAG_member)
    <48> DW_AT_name : (indirect string, offset: 0xe3): x
    <4c> DW_AT_type : <0x6d>
    ...
    ...
<2><5f>: Abbrev Number: 5 (DW_TAG_enumeration_type)
    <60> DW_AT_name : (indirect string, offset: 0x140): .llvm.aux.attr
    <64> DW_AT_byte_size : 0
<3><65>: Abbrev Number: 6 (DW_TAG_enumerator)
    <66> DW_AT_name : (indirect string, offset: 0x13c): .ID
    <6a> DW_AT_const_value : 1234

By DW_TAG_enumeration_type '.llvm.aux.attr', we can connect an
attribute named ".ID" to this structure type, whose value should be
1234.

Note that enumeration types and enumerators generated by
EmitTypeAuxAttribute() are all leaded with a '.', which would be never
issued by normal C programs.

Signed-off-by: Wang Nan <wangnan0@huawei.com>

This patch introduces a new builtin function __builtin_bpf_typeid()
for BPF.

The newly created builtin function issue a constant int64 according
to type feed to it (by utilizing vararg type, __builtin_bpf_typeid
accepts all types of variable), and connect the number with the
specific structure type in Dwarf info by utilizing
EmitTypeAuxAttribute(). The number is computed by simplly
count the number of types which feed to this builtin.

After this patch we have a reliable way to record data and its
type in BPF program. For example, in following program, we output
2 u64 values in different condition.

int func(void *ctx) {
   struct {
     u64 type;
     u64 cycles;
   } cycles_vals;

   struct {
     u64 type;
     u64 misses;
   } misses_vals;

   u32 key = bpf_get_smp_processor_id();

   if (key & 1) {
     cycles_vals.cycles = bpf_perf_event_read(&map_cycles, key);
     cycles_vals.type = __builtin_bpf_typeid(cycles_vals);
     bpf_output_trace_data(&cycles_vals, sizeof(cycles_vals));
   } else {
     misses_vals.misses = bpf_perf_event_read(&map_cache_misses, key);
     misses_vals.type = __builtin_bpf_typeid(misses_vals);
     bpf_output_trace_data(&misses_vals, sizeof(misses_vals));
   }
   return 0;
}

And we will get following Dwarf information:

<2><117>: Abbrev Number: 3 (DW_TAG_structure_type)
    <118> DW_AT_byte_size : 16
    ...
<3><11b>: Abbrev Number: 4 (DW_TAG_member)
    <11c> DW_AT_name : (indirect string, offset: 0x163): type
    ...
    <126> DW_AT_data_member_location: 0
<3><127>: Abbrev Number: 4 (DW_TAG_member)
    <128> DW_AT_name : (indirect string, offset: 0x168): cycles
    ...
    <132> DW_AT_data_member_location: 8
<3><133>: Abbrev Number: 15 (DW_TAG_enumeration_type)
    <134> DW_AT_name : (indirect string, offset: 0x173): .llvm.aux.attr
    <138> DW_AT_byte_size : 0
<4><139>: Abbrev Number: 16 (DW_TAG_enumerator)
    <13a> DW_AT_name : (indirect string, offset: 0x16f): .ID
    <13e> DW_AT_const_value : 1
<2><141>: Abbrev Number: 3 (DW_TAG_structure_type)
    <142> DW_AT_byte_size : 16
    ...
<3><145>: Abbrev Number: 4 (DW_TAG_member)
    <146> DW_AT_name : (indirect string, offset: 0x163): type
    ...
    <150> DW_AT_data_member_location: 0
<3><151>: Abbrev Number: 4 (DW_TAG_member)
    <152> DW_AT_name : (indirect string, offset: 0x182): misses
    ...
    <15c> DW_AT_data_member_location: 8
<3><15d>: Abbrev Number: 15 (DW_TAG_enumeration_type)
    <15e> DW_AT_name : (indirect string, offset: 0x173): .llvm.aux.attr
    <162> DW_AT_byte_size : 0
<4><163>: Abbrev Number: 16 (DW_TAG_enumerator)
    <164> DW_AT_name : (indirect string, offset: 0x16f): .ID
    <168> DW_AT_const_value : 2

Then we can connect type id and layout of structure together.

Signed-off-by: Wang Nan <wangnan0@huawei.com>

That's a rather unusual mechanism. Can you elaborate what the use-case for this would be and why this should be part of mainline clang?

-- adrian

Yikes. My mail client jumped a few years back and I accidentally replied to an old thread.

sorry for the noise!
-- adrian