Lets check if we can add our own attributes (if Google can afford it, then why is it forbidden to mere mortals?). For example I want to have in gcc and dwarf flag about functions/methods parameters direction - is some param IN or OUT. I chose the value of this dwarf attribure 0x28ff
It`s pretty obviously that we can add our own custom attribute in gcc - they even have example how to do this. But what about dwarf producer? Long story short - seems that you cannot do it from plugin. The only dwarf related pass for plugins is pass_dwarf2_frame. So we need to patch gcc. But before this we need to
build gcc from sources
At moment of writing latest stable version of gcc was 12.0 so run
git clone --branch releases/gcc-12 https://github.com/gcc-mirror/gcc.git
patch gcc
Lets see how gcc produces dwarf output. All symbol table formatters implement gcc_debug_hooks and currently gcc has 3 (btw there are patches for mingw to produce PDB, so in theory you could have vmlinux.pdb):
- dwarf2out.cc - this is our target
- godump.c
- vmsdbgout.c
bool add_param_direction(tree decl, dw_die_ref parm_die)
{
bool pa1 = lookup_attribute ("param_in", DECL_ATTRIBUTES (decl));
bool pa2 = lookup_attribute ("param_out", DECL_ATTRIBUTES (decl));
if ( !(pa1 ^ pa2) )
return false;
unsigned char pa_value = 0;
// seems that you can`t have flag with value 1 - see gcc_assert at line 9599
if ( pa1 )
pa_value = 2;
if ( pa2 )
pa_value = 3;
add_AT_flag(parm_die, (dwarf_attribute)0x28ff, pa_value);
return true;
}
tree handle_param_in_attribute (tree *node, tree name, tree ARG_UNUSED (args),
int ARG_UNUSED(flags), bool *no_add_attrs)
{
if ( !DECL_P (*node) )
{
warning (OPT_Wattributes, "%qE attribute can apply to params declarations only", name);
*no_add_attrs = true;
return NULL_TREE;
}
tree decl = *node;
if (TREE_CODE (decl) != PARM_DECL)
{
warning (OPT_Wattributes, "%qE attribute can apply to params only", name);
*no_add_attrs = true;
} else {
// check presense of param_out
if ( lookup_attribute ("param_out", DECL_ATTRIBUTES (decl)) )
{
warning (OPT_Wattributes, "%qE attribute useless when param_out was used", name);
*no_add_attrs = true;
DECL_ATTRIBUTES (decl) = remove_attribute("param_out", DECL_ATTRIBUTES (decl));
}
}
return NULL_TREE;
}
handle_param_in_attribute
checks that this attribute linked with function/method parameter. Then it checks that the same parameter don`t have attribute param_out - in this case it just removes both