[llvm-dev] print signature of function from dwarf info in file?

Jonas Devlieghere via llvm-dev llvm-dev at lists.llvm.org
Fri Apr 6 09:34:47 PDT 2018


Hi Bill,

> On Apr 5, 2018, at 9:19 PM, Bill O'Hara via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Hi
> 
> I'm using llvm-5. Browsing the source of llvm-dwarfdump and trying it on some shared libraries, I see I can print the debug info (assuming it exists). For some function, I'm wondering if there's a short cut to prettyprinting the signature of a function in the library? I think, looking at the output, that enough information exists but it seems to involve looking at the subprogram and then chasing references to parameters elsewhere in the debug info and so on.

As far as I know we don’t currently have any code that does this. A while ago I added very rudimentary support for “pretty printing” types in libDebugInfo which might serve as a source of inspiration. 

http://reviews.llvm.org/rL315316

> Browsing the llvm headers, I see classes like DISubprogram which appear to represent a function. But no obvious way to get to a string for the function signature.

The DISubprogram is how we represent a function in the LLVM IR, which is used later in the compile process to generate the relevant DWARF entries. For your purpose, you should look in DebugInfo/DWARF. Most of the classes there correspond very closely to the concepts in the standard. 

> Can someone point me in the right direction?

In DWARF, a function will be represented as a DIE (Debug Info Entry) with a DW_TAG_subprogram tag. Thie DIE will have child DIE’s representing it’s arguments (DW_TAG_formal_parameter). I’d suggest using a small sample program and play around with it to get a better understanding how this information is stored in DWARF. 

For example:

$ cat foo.c
struct S {};

int foo(float f, struct S b) {
  return 10;
}

$ clang -c -g -O0 foo.c -o foo.o
$ llvm-dwarfdump -debug-info foo.o

0x0000002a:   DW_TAG_subprogram
                DW_AT_low_pc	(0x0000000000000000)
                DW_AT_high_pc	(0x0000000000000010)
                DW_AT_frame_base	(DW_OP_reg6 RBP)
                DW_AT_name	("foo")
                DW_AT_decl_file	("/private/tmp/foo.c")
                DW_AT_decl_line	(3)
                DW_AT_prototyped	(true)
                DW_AT_type	(0x00000060 "int")
                DW_AT_external	(true)

0x00000043:     DW_TAG_formal_parameter
                  DW_AT_location	(DW_OP_fbreg -12)
                  DW_AT_name	("f")
                  DW_AT_decl_file	("/private/tmp/foo.c")
                  DW_AT_decl_line	(3)
                  DW_AT_type	(0x00000067 "float")

0x00000051:     DW_TAG_formal_parameter
                  DW_AT_location	(DW_OP_fbreg -8)
                  DW_AT_name	("b")
                  DW_AT_decl_file	("/private/tmp/foo.c")
                  DW_AT_decl_line	(3)
                  DW_AT_type	(0x0000006e "S")

So with the type information mostly there, I’d iterate over the DIE’s until you come across a DW_TAG_subprogram and then use the type and name attributes to construct the function signatures.
 
> TIA!
> bill
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Cheers,
Jonas


More information about the llvm-dev mailing list