I continuing to improve my gcc plugin for collecting cross-references: 1, 2, 3, 4, 5, 6& 7. On this week I decided to see if I can extract source of complex types like records and most prominent kind of them is arguments of function - they are easy to identify in asm (but not so easy to bind them in gcc RTL expressions)
Having function declaration fdecl we can extract arguments with something like:
for (tree arg = DECL_ARGUMENTS (fdecl); arg; arg = DECL_CHAIN (arg))
{
auto a = DECL_RTL_IF_SET (arg);
if ( a && REG_EXPR(a) ) { // do something with argument in REG_EXPR(a)
I need only arguments that are a pointer or reference to record/union so I filtered them in method check_arg
Those was easiest part, and now try to find how arguments can be tracked in RTL.
We can see using of arguments in expression like
insn 7 6 8 2 (set (reg/f:DI 0 ax [orig:82 _1 ] [82])
(mem/f:DI (plus:DI (reg/f:DI 0 ax [85])
(const_int 88 [0x58])) [170 this_3(D)->m_outfp+0 S8 A64])) "my_plugin.h":53:14 80 {*movdi_internal}
They come from RTX with type MEM and tree code COMPONENT_REF where left part in TREE_OPERAND (expr, 0) is SSA_NAME (and right part in TREE_OPERAND (expr, 1) in this case is FIELD_DECL)
You can check if SSA has name with SSA_NAME_IDENTIFIER and extract name of SSA with IDENTIFIER_POINTER. But linking just by name is bad idea - you could legally have local variable with the same name as argument, so it's better to extract type with SSA_NAME_VAR
Unfortunately this nice and simple method does not work for cases described in my previous post- we have type info scattered in several RTX:
- SET REG RMEM without COMPONENT_REF - instead we have nameless SSA_NAME pointing to type of referred field, so we cannot extract type of class and field name
- EXPR_LIST (seems that it always has index 6) with note (notes can be extracted with GET_MODE) REG_EQUAL containing expression like PLUS MEM CONST_INT where MEM is PARM_DECL but offset is just constant integer
So I couldn't come up with a more elegant solution than:
- identify that currently processed RTX has noteREG_EQUAL
- while processing MEM expression within REG_EQUAL store reference to argument and it's type
- and finally while processing CONST_INT check that it has both base type and expression PLUS above in stack and then manually find field at that offset in base type (see method add_fref_from_equal). Value of offset can be extracted with XWINT. Open question is what to do if base type is union - it this case we can have several fields on the same offset