print signature of function from dwarf info in file?

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.

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.

Can someone point me in the right direction?

TIA!
bill

Hi Bill,

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@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Cheers,
Jonas