KDAB / hotspot

The Linux perf GUI for performance analysis.
4.16k stars 257 forks source link

use proper dwarf parsing in disassembler #495

Open lievenhey opened 1 year ago

lievenhey commented 1 year ago

currently we are just parsing the output of objdump which in case of inlined functions is not useable. See #490

If I comple test.c

#include <stdio.h>

inline int square(int i) {
        return i * i;
}

int main() {
        for (int i = 0; i < 10000; i++) {
                int sum = 0;
                for (int j = 0; j < i; j++) {
                        sum += square(j);
                }
                printf("Sum: %d\n", sum);
        }
}

with -O3 -g I end up with the following in objdump:

0000000000001040 <main>:
main():
/tmp/test.c:7
    1040:       55                      push   %rbp
/tmp/test.c:13
    1041:       48 8d 2d bc 0f 00 00    lea    0xfbc(%rip),%rbp        # 2004 <_IO_stdin_used+0x4>
    ....
    square():
/tmp/test.c:4
    109b:       66 0f 6f d0             movdqa %xmm0,%xmm2
    109f:       66 0f f4 d0             pmuludq %xmm0,%xmm2
    10a3:       66 0f 73 d0 20          psrlq  $0x20,%xmm0
    10a8:       66 0f f4 c0             pmuludq %xmm0,%xmm0
    10ac:       66 0f 70 d2 08          pshufd $0x8,%xmm2,%xmm2
    10b1:       66 0f 70 c0 08          pshufd $0x8,%xmm0,%xmm0
    10b6:       66 0f 62 d0             punpckldq %xmm0,%xmm2
main():
/tmp/test.c:11 (discriminator 1)
    10ba:       66 0f fe ca             paddd  %xmm2,%xmm1
    ...

dwarfdump gives me:

0x000000f6: DW_TAG_inlined_subroutine
              DW_AT_abstract_origin     (0x00000166 "square")
              DW_AT_entry_pc    (0x000000000000109b)
              DW_AT_GNU_entry_view      (0x01)
              DW_AT_ranges      (0x0000006f
                 [0x000000000000109b, 0x00000000000010ba)
                 [0x00000000000010f0, 0x00000000000010f5))
              DW_AT_call_file   ("/tmp/test.c")
              DW_AT_call_line   (11)
              DW_AT_call_column (0x20)

0x00000166: DW_TAG_subprogram
              DW_AT_external    (true)
              DW_AT_name        ("square")
              DW_AT_decl_file   ("/tmp/test.c")
              DW_AT_decl_line   (3)
              DW_AT_decl_column (0x0c)
              DW_AT_prototyped  (true)
              DW_AT_type        (0x00000054 "int")
              DW_AT_inline      (DW_INL_declared_inlined)

so it may be worth investing some time into proper dwarf parsing.

GitMensch commented 1 year ago

Just to recheck: objdump is currently called twice per disassembly request - is that correct an if yes, would only one call be replaced by dwarfdump?

Would it be useful to link to libwarf (doesn't seem like this is currently done)?

[I see the error message that there's no support for --visualize-jumps twice]

XVilka commented 8 months ago

If you use Rizin library, you could get both disassembly (often capstone-based, depending on the architecture) and DWARF parsing. Along with other formats, like PDB, Mach-O support, and many other things.

GitMensch commented 8 months ago

Thank you for pointing that out (note: if HotSpot depends on that it may need to move from current GPL v2 or v3 to GPL v3 (or v3+) to use the LGPLv3 library - but I'm not sure).