среда, 16 августа 2023 г.

gcc plugin to collect cross-references, part 5

Part 1, 2, 3 & 4

Lets check how RTL describes jump tables. I made simple test and output of gcc -fdump-final-insns looks like:

(jump_insn # 0 0 8 (parallel [
            (set (pc)
                (reg:DI 0 ax [93]))
            (use (label_ref #))
        ]) "swtest.c":14:3# {*tablejump_1}
     (nil)
 -> 8)
(barrier # 0 0)
(code_label # 0 0 8 (nil) [2 uses])
(jump_table_data # 0 0 (addr_vec:DI [
            (label_ref:DI #)
            (label_ref:DI #)
...
        ]))

As you can see jump_insn uses opcode tablejump_1 refering to label 8. Right after this label located RTL with code jump_table_data - perhaps this is bad idea to assume that it always will be true so it`s better to use function jump_table_for_label. Also for some unknown reason option -fdump-final-insns does not show content of jump tables. So at least lets try to find jump_table_datas from plugin

Surprisingly you cannot find then when iterating on instructions within each block (using FOR_ALL_BB_FN/FOR_BB_INSNS macros). I suspect this due to the fact that both label and jump_table belong to block with index 0. So I used another cycle: 
for ( insn = get_insns(); insn; insn = NEXT_INSN(insn) )
Then we can check if current RTL instruction is jump table with JUMP_TABLE_DATA_P. Jump tables have addr_vec in element with index 3 and each element is label_ref. Length of vector can be obtained from field num_elem. Pretty easy, so what we can do with this knowledge?
Well, we could at least put jump tables with their sizes into debug info

Lets check how this can be done
All debug info produced in gcc via structure gcc_debug_hooks and it even has field with neat name label. The problem that in dwarf2out.cc this field points to debug_nothing_rtx_code_label, which as you can guess really do nothing. Oops
 
Actually labels inserting in dwarf2 output somewhere inside function gen_label_die called from gen_decl_die. So we need to 
  1. find jump tables
  2. check that they are unnamed - respecting code_label does not have LABEL_DECL
  3. add LABEL_DECL with some name
  4. and put link to RTL with SET_DECL_RTL
And yes - we can now see our newly inserted labels in debug info. Without size for sure, bcs code in gen_label_die need to be patched to do this. Again
 
And finally run objdump -g to see
 <2><11a>: Abbrev Number: 14 (DW_TAG_label)
    <11b>   DW_AT_name        : (indirect string, offset: 0x5f): main_jt52
    <11f>   DW_AT_decl_file   : 1
    <120>   DW_AT_decl_line   : 4
    <121>   DW_AT_decl_column : 5
    <122>   DW_AT_byte_size   : 10
    <123>   DW_AT_low_pc      : 0x402050

Комментариев нет:

Отправить комментарий