先构造可执行文件
main.c
#include <stdio.h>
extern int add(int a, int b);
extern int sub(int a, int b);
int main()
{
int a = 10;
int b = 5;
int c = 0;
int d = 0;
c = add(a, b);
d = sub(a, b);
printf("a=%d,b=%d\n", a, b);
return 0;
}
add.c
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
sub.c
#include <stdio.h>
#include <string.h>
typedef struct Obj
{
int a;
int b;
int c;
} Obj_t;
Obj_t g_a;
Obj_t g_ar[12];
int sub(int a, int b)
{
memset(&g_a, 0, sizeof(g_a));
memset(&g_ar, 0, sizeof(g_ar));
return a - b + sizeof(g_a) + sizeof(g_ar);
}
golang代码解析
package main
import (
"debug/dwarf"
"debug/elf"
"encoding/binary"
"fmt"
"log"
)
func findSymbol(d *dwarf.Data, name string) error {
dr := d.Reader()
var lr *dwarf.LineReader = nil
var files []*dwarf.LineFile = nil
for {
e, err := dr.Next()
if e == nil || err != nil {
break
}
if e.Tag == dwarf.TagCompileUnit {
lr, err = d.LineReader(e)
if err != nil {
log.Println(err)
lr = nil
break
}
files = lr.Files()
for i := 0; i < len(files); i++ {
//log.Println(files[i].Name)
}
}
}
dr.Seek(0)
for {
e, err := dr.Next()
if e == nil || err != nil {
return err
}
aname, ok := e.Val(dwarf.AttrName).(string)
//log.Println(aname, e.Tag)
if !ok || aname != name {
continue
}
switch e.Tag {
case dwarf.TagVariable: // 变量
loc, ok := e.Val(dwarf.AttrLocation).([]uint8)
if !ok {
continue
}
if loc[0] != 3 {
return fmt.Errorf("can't determine variable addr")
}
lineNo, ok := e.Val(dwarf.AttrDeclLine).(int64)
if !ok {
lineNo = -1
}
fileNo, _ := e.Val(dwarf.AttrDeclFile).(int64)
addr := uint64(0)
switch len(loc) {
case 5:
addr = uint64(binary.LittleEndian.Uint32(loc[1:]))
case 9:
addr = uint64(binary.LittleEndian.Uint64(loc[1:]))
default:
return fmt.Errorf("unknown addr size")
}
off, ok := e.Val(dwarf.AttrType).(dwarf.Offset)
if !ok {
continue
}
typ, err := d.Type(off)
if err != nil {
return err
}
log.Printf("%s <%x> %s %s:%d\n", aname, addr, typ.String(), files[fileNo].Name, lineNo)
return nil
case dwarf.TagSubprogram:
pc, ok := e.Val(dwarf.AttrLowpc).(uint64)
if ok {
lineNo, ok := e.Val(dwarf.AttrDeclLine).(int64)
if !ok {
lineNo = -1
}
fileNo, _ := e.Val(dwarf.AttrDeclFile).(int64)
log.Printf("%s <%x> %s:%d\n", aname, pc, files[fileNo].Name, lineNo)
} else {
lineNo, ok := e.Val(dwarf.AttrDeclLine).(int64)
if !ok {
lineNo = -1
}
fileNo, _ := e.Val(dwarf.AttrDeclFile).(int64)
log.Printf("%s %s:%d\n", aname, files[fileNo].Name, lineNo)
}
}
}
}
func FindSymbol(elf_path string, vari string) {
log.SetFlags(log.LstdFlags | log.Lshortfile)
file, e1 := elf.Open(elf_path)
if e1 == nil {
defer file.Close()
dwlf, e2 := file.DWARF()
if e2 == nil {
findSymbol(dwlf, vari)
}
}
}
func main() {
FindSymbol("./c_out/a.out", "g_a")
FindSymbol("./c_out/a.out", "add")
FindSymbol("./c_out/a.out", "g_ar")
}
运行结果:
2023/10/27 16:59:27 main.go:77: g_a <4040> Obj_t /home/newstud/MyCode/temp/c_out/sub.c:10
2023/10/27 16:59:27 main.go:94: add /home/newstud/MyCode/temp/c_out/sub.c:3
2023/10/27 16:59:27 main.go:87: add <11d8> /home/newstud/MyCode/temp/c_out/sub.c:3
2023/10/27 16:59:27 main.go:77: g_ar <4060> [12]Obj_t /home/newstud/MyCode/temp/c_out/sub.c:11
通过readelf命令也可以查看:
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0x10a (32-bit)
Version: 5
Unit Type: DW_UT_compile (1)
Abbrev Offset: 0x0
Pointer Size: 8
<0><c>: Abbrev Number: 5 (DW_TAG_compile_unit)
<d> DW_AT_producer : (indirect string, offset: 0x13): GNU C17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
<11> DW_AT_language : 29 (C11)
<12> DW_AT_name : (indirect line string, offset: 0x20): main.c
<16> DW_AT_comp_dir : (indirect line string, offset: 0x0): /home/newstud/MyCode/temp/c_out
<1a> DW_AT_low_pc : 0x1169
<22> DW_AT_high_pc : 0x6f
<2a> DW_AT_stmt_list : 0x0
<1><2e>: Abbrev Number: 1 (DW_TAG_base_type)
<2f> DW_AT_byte_size : 8
<30> DW_AT_encoding : 7 (unsigned)
<31> DW_AT_name : (indirect string, offset: 0xa1): long unsigned int
<1><35>: Abbrev Number: 1 (DW_TAG_base_type)
<36> DW_AT_byte_size : 4
<37> DW_AT_encoding : 7 (unsigned)
<38> DW_AT_name : (indirect string, offset: 0xa6): unsigned int
<1><3c>: Abbrev Number: 1 (DW_TAG_base_type)
<3d> DW_AT_byte_size : 1
<3e> DW_AT_encoding : 8 (unsigned char)
<3f> DW_AT_name : (indirect string, offset: 0xb3): unsigned char
<1><43>: Abbrev Number: 1 (DW_TAG_base_type)
<44> DW_AT_byte_size : 2
<45> DW_AT_encoding : 7 (unsigned)
<46> DW_AT_name : (indirect string, offset: 0x0): short unsigned int
<1><4a>: Abbrev Number: 1 (DW_TAG_base_type)
<4b> DW_AT_byte_size : 1
<4c> DW_AT_encoding : 6 (signed char)
<4d> DW_AT_name : (indirect string, offset: 0xb5): signed char
<1><51>: Abbrev Number: 1 (DW_TAG_base_type)
<52> DW_AT_byte_size : 2
<53> DW_AT_encoding : 5 (signed)
<54> DW_AT_name : (indirect string, offset: 0xd6): short int
<1><58>: Abbrev Number: 6 (DW_TAG_base_type)
<59> DW_AT_byte_size : 4
<5a> DW_AT_encoding : 5 (signed)
<5b> DW_AT_name : int
<1><5f>: Abbrev Number: 1 (DW_TAG_base_type)
<60> DW_AT_byte_size : 8
<61> DW_AT_encoding : 5 (signed)
<62> DW_AT_name : (indirect string, offset: 0xc6): long int
<1><66>: Abbrev Number: 1 (DW_TAG_base_type)
<67> DW_AT_byte_size : 1
<68> DW_AT_encoding : 6 (signed char)
<69> DW_AT_name : (indirect string, offset: 0xbc): char
<1><6d>: Abbrev Number: 7 (DW_TAG_const_type)
<6e> DW_AT_type : <0x66>
<1><72>: Abbrev Number: 8 (DW_TAG_subprogram)
<73> DW_AT_external : 1
<73> DW_AT_name : (indirect string, offset: 0xcf): printf
<77> DW_AT_decl_file : 2
<78> DW_AT_decl_line : 356
<7a> DW_AT_decl_column : 12
<7b> DW_AT_prototyped : 1
<7b> DW_AT_type : <0x58>
<7f> DW_AT_declaration : 1
<7f> DW_AT_sibling : <0x8a>
<2><83>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<84> DW_AT_type : <0x8a>
<2><88>: Abbrev Number: 9 (DW_TAG_unspecified_parameters)
<2><89>: Abbrev Number: 0
<1><8a>: Abbrev Number: 10 (DW_TAG_pointer_type)
<8b> DW_AT_byte_size : 8
<8c> DW_AT_type : <0x6d>
<1><90>: Abbrev Number: 4 (DW_TAG_subprogram)
<91> DW_AT_external : 1
<91> DW_AT_name : sub
<95> DW_AT_decl_file : 1
<95> DW_AT_decl_line : 4
<96> DW_AT_decl_column : 12
<96> DW_AT_prototyped : 1
<96> DW_AT_type : <0x58>
<9a> DW_AT_declaration : 1
<9a> DW_AT_sibling : <0xa9>
<2><9e>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<9f> DW_AT_type : <0x58>
<2><a3>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<a4> DW_AT_type : <0x58>
<2><a8>: Abbrev Number: 0
<1><a9>: Abbrev Number: 4 (DW_TAG_subprogram)
<aa> DW_AT_external : 1
<aa> DW_AT_name : add
<ae> DW_AT_decl_file : 1
<ae> DW_AT_decl_line : 3
<af> DW_AT_decl_column : 12
<af> DW_AT_prototyped : 1
<af> DW_AT_type : <0x58>
<b3> DW_AT_declaration : 1
<b3> DW_AT_sibling : <0xc2>
<2><b7>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<b8> DW_AT_type : <0x58>
<2><bc>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<bd> DW_AT_type : <0x58>
<2><c1>: Abbrev Number: 0
<1><c2>: Abbrev Number: 11 (DW_TAG_subprogram)
<c3> DW_AT_external : 1
<c3> DW_AT_name : (indirect string, offset: 0xc1): main
<c7> DW_AT_decl_file : 1
<c8> DW_AT_decl_line : 6
<c9> DW_AT_decl_column : 5
<ca> DW_AT_type : <0x58>
<ce> DW_AT_low_pc : 0x1169
<d6> DW_AT_high_pc : 0x6f
<de> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<e0> DW_AT_call_all_tail_calls: 1
<2><e0>: Abbrev Number: 3 (DW_TAG_variable)
<e1> DW_AT_name : a
<e3> DW_AT_decl_file : 1
<e3> DW_AT_decl_line : 8
<e4> DW_AT_decl_column : 9
<e4> DW_AT_type : <0x58>
<e8> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<2><eb>: Abbrev Number: 3 (DW_TAG_variable)
<ec> DW_AT_name : b
<ee> DW_AT_decl_file : 1
<ee> DW_AT_decl_line : 9
<ef> DW_AT_decl_column : 9
<ef> DW_AT_type : <0x58>
<f3> DW_AT_location : 2 byte block: 91 64 (DW_OP_fbreg: -28)
<2><f6>: Abbrev Number: 3 (DW_TAG_variable)
<f7> DW_AT_name : c
<f9> DW_AT_decl_file : 1
<f9> DW_AT_decl_line : 10
<fa> DW_AT_decl_column : 9
<fa> DW_AT_type : <0x58>
<fe> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)
<2><101>: Abbrev Number: 3 (DW_TAG_variable)
<102> DW_AT_name : d
<104> DW_AT_decl_file : 1
<104> DW_AT_decl_line : 11
<105> DW_AT_decl_column : 9
<105> DW_AT_type : <0x58>
<109> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
<2><10c>: Abbrev Number: 0
<1><10d>: Abbrev Number: 0
Compilation Unit @ offset 0x10e:
Length: 0x9f (32-bit)
Version: 5
Unit Type: DW_UT_compile (1)
Abbrev Offset: 0xa2
Pointer Size: 8
<0><11a>: Abbrev Number: 3 (DW_TAG_compile_unit)
<11b> DW_AT_producer : (indirect string, offset: 0x13): GNU C17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
<11f> DW_AT_language : 29 (C11)
<120> DW_AT_name : (indirect line string, offset: 0x3c): add.c
<124> DW_AT_comp_dir : (indirect line string, offset: 0x0): /home/newstud/MyCode/temp/c_out
<128> DW_AT_low_pc : 0x11d8
<130> DW_AT_high_pc : 0x18
<138> DW_AT_stmt_list : 0x66
<1><13c>: Abbrev Number: 1 (DW_TAG_base_type)
<13d> DW_AT_byte_size : 8
<13e> DW_AT_encoding : 7 (unsigned)
<13f> DW_AT_name : (indirect string, offset: 0xa1): long unsigned int
<1><143>: Abbrev Number: 1 (DW_TAG_base_type)
<144> DW_AT_byte_size : 4
<145> DW_AT_encoding : 7 (unsigned)
<146> DW_AT_name : (indirect string, offset: 0xa6): unsigned int
<1><14a>: Abbrev Number: 1 (DW_TAG_base_type)
<14b> DW_AT_byte_size : 1
<14c> DW_AT_encoding : 8 (unsigned char)
<14d> DW_AT_name : (indirect string, offset: 0xb3): unsigned char
<1><151>: Abbrev Number: 1 (DW_TAG_base_type)
<152> DW_AT_byte_size : 2
<153> DW_AT_encoding : 7 (unsigned)
<154> DW_AT_name : (indirect string, offset: 0x0): short unsigned int
<1><158>: Abbrev Number: 1 (DW_TAG_base_type)
<159> DW_AT_byte_size : 1
<15a> DW_AT_encoding : 6 (signed char)
<15b> DW_AT_name : (indirect string, offset: 0xb5): signed char
<1><15f>: Abbrev Number: 1 (DW_TAG_base_type)
<160> DW_AT_byte_size : 2
<161> DW_AT_encoding : 5 (signed)
<162> DW_AT_name : (indirect string, offset: 0xd6): short int
<1><166>: Abbrev Number: 4 (DW_TAG_base_type)
<167> DW_AT_byte_size : 4
<168> DW_AT_encoding : 5 (signed)
<169> DW_AT_name : int
<1><16d>: Abbrev Number: 1 (DW_TAG_base_type)
<16e> DW_AT_byte_size : 8
<16f> DW_AT_encoding : 5 (signed)
<170> DW_AT_name : (indirect string, offset: 0xc6): long int
<1><174>: Abbrev Number: 1 (DW_TAG_base_type)
<175> DW_AT_byte_size : 1
<176> DW_AT_encoding : 6 (signed char)
<177> DW_AT_name : (indirect string, offset: 0xbc): char
<1><17b>: Abbrev Number: 5 (DW_TAG_subprogram)
<17c> DW_AT_external : 1
<17c> DW_AT_name : add
<180> DW_AT_decl_file : 1
<181> DW_AT_decl_line : 3
<182> DW_AT_decl_column : 5
<183> DW_AT_prototyped : 1
<183> DW_AT_type : <0x166>
<187> DW_AT_low_pc : 0x11d8
<18f> DW_AT_high_pc : 0x18
<197> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<199> DW_AT_call_all_calls: 1
<2><199>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<19a> DW_AT_name : a
<19c> DW_AT_decl_file : 1
<19c> DW_AT_decl_line : 3
<19c> DW_AT_decl_column : 13
<19d> DW_AT_type : <0x166>
<1a1> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
<2><1a4>: Abbrev Number: 2 (DW_TAG_formal_parameter)
<1a5> DW_AT_name : b
<1a7> DW_AT_decl_file : 1
<1a7> DW_AT_decl_line : 3
<1a7> DW_AT_decl_column : 20
<1a8> DW_AT_type : <0x166>
<1ac> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)
<2><1af>: Abbrev Number: 0
<1><1b0>: Abbrev Number: 0
Compilation Unit @ offset 0x1b1:
Length: 0x13e (32-bit)
Version: 5
Unit Type: DW_UT_compile (1)
Abbrev Offset: 0xfa
Pointer Size: 8
<0><1bd>: Abbrev Number: 6 (DW_TAG_compile_unit)
<1be> DW_AT_producer : (indirect string, offset: 0x13): GNU C17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
<1c2> DW_AT_language : 29 (C11)
<1c3> DW_AT_name : (indirect line string, offset: 0x42): sub.c
<1c7> DW_AT_comp_dir : (indirect line string, offset: 0x0): /home/newstud/MyCode/temp/c_out
<1cb> DW_AT_low_pc : 0x11f0
<1d3> DW_AT_high_pc : 0x51
<1db> DW_AT_stmt_list : 0xb5
<1><1df>: Abbrev Number: 4 (DW_TAG_typedef)
<1e0> DW_AT_name : (indirect string, offset: 0xe0): size_t
<1e4> DW_AT_decl_file : 2
<1e5> DW_AT_decl_line : 209
<1e6> DW_AT_decl_column : 23
<1e7> DW_AT_type : <0x1eb>
<1><1eb>: Abbrev Number: 1 (DW_TAG_base_type)
<1ec> DW_AT_byte_size : 8
<1ed> DW_AT_encoding : 7 (unsigned)
<1ee> DW_AT_name : (indirect string, offset: 0xa1): long unsigned int
<1><1f2>: Abbrev Number: 1 (DW_TAG_base_type)
<1f3> DW_AT_byte_size : 4
<1f4> DW_AT_encoding : 7 (unsigned)
<1f5> DW_AT_name : (indirect string, offset: 0xa6): unsigned int
<1><1f9>: Abbrev Number: 7 (DW_TAG_pointer_type)
<1fa> DW_AT_byte_size : 8
<1><1fb>: Abbrev Number: 1 (DW_TAG_base_type)
<1fc> DW_AT_byte_size : 1
<1fd> DW_AT_encoding : 8 (unsigned char)
<1fe> DW_AT_name : (indirect string, offset: 0xb3): unsigned char
<1><202>: Abbrev Number: 1 (DW_TAG_base_type)
<203> DW_AT_byte_size : 2
<204> DW_AT_encoding : 7 (unsigned)
<205> DW_AT_name : (indirect string, offset: 0x0): short unsigned int
<1><209>: Abbrev Number: 1 (DW_TAG_base_type)
<20a> DW_AT_byte_size : 1
<20b> DW_AT_encoding : 6 (signed char)
<20c> DW_AT_name : (indirect string, offset: 0xb5): signed char
<1><210>: Abbrev Number: 1 (DW_TAG_base_type)
<211> DW_AT_byte_size : 2
<212> DW_AT_encoding : 5 (signed)
<213> DW_AT_name : (indirect string, offset: 0xd6): short int
<1><217>: Abbrev Number: 8 (DW_TAG_base_type)
<218> DW_AT_byte_size : 4
<219> DW_AT_encoding : 5 (signed)
<21a> DW_AT_name : int
<1><21e>: Abbrev Number: 1 (DW_TAG_base_type)
<21f> DW_AT_byte_size : 8
<220> DW_AT_encoding : 5 (signed)
<221> DW_AT_name : (indirect string, offset: 0xc6): long int
<1><225>: Abbrev Number: 1 (DW_TAG_base_type)
<226> DW_AT_byte_size : 1
<227> DW_AT_encoding : 6 (signed char)
<228> DW_AT_name : (indirect string, offset: 0xbc): char
<1><22c>: Abbrev Number: 9 (DW_TAG_structure_type)
<22d> DW_AT_name : Obj
<231> DW_AT_byte_size : 12
<232> DW_AT_decl_file : 1
<233> DW_AT_decl_line : 3
<234> DW_AT_decl_column : 16
<235> DW_AT_sibling : <0x255>
<2><239>: Abbrev Number: 2 (DW_TAG_member)
<23a> DW_AT_name : a
<23c> DW_AT_decl_file : 1
<23c> DW_AT_decl_line : 5
<23d> DW_AT_decl_column : 9
<23d> DW_AT_type : <0x217>
<241> DW_AT_data_member_location: 0
<2><242>: Abbrev Number: 2 (DW_TAG_member)
<243> DW_AT_name : b
<245> DW_AT_decl_file : 1
<245> DW_AT_decl_line : 6
<246> DW_AT_decl_column : 9
<246> DW_AT_type : <0x217>
<24a> DW_AT_data_member_location: 4
<2><24b>: Abbrev Number: 2 (DW_TAG_member)
<24c> DW_AT_name : c
<24e> DW_AT_decl_file : 1
<24e> DW_AT_decl_line : 7
<24f> DW_AT_decl_column : 9
<24f> DW_AT_type : <0x217>
<253> DW_AT_data_member_location: 8
<2><254>: Abbrev Number: 0
<1><255>: Abbrev Number: 4 (DW_TAG_typedef)
<256> DW_AT_name : (indirect string, offset: 0xec): Obj_t
<25a> DW_AT_decl_file : 1
<25b> DW_AT_decl_line : 8
<25c> DW_AT_decl_column : 3
<25d> DW_AT_type : <0x22c>
<1><261>: Abbrev Number: 10 (DW_TAG_variable)
<262> DW_AT_name : g_a
<266> DW_AT_decl_file : 1
<267> DW_AT_decl_line : 10
<268> DW_AT_decl_column : 7
<269> DW_AT_type : <0x255>
<26d> DW_AT_external : 1
<26d> DW_AT_location : 9 byte block: 3 40 40 0 0 0 0 0 0 (DW_OP_addr: 4040)
<1><277>: Abbrev Number: 11 (DW_TAG_array_type)
<278> DW_AT_type : <0x255>
<27c> DW_AT_sibling : <0x287>
<2><280>: Abbrev Number: 12 (DW_TAG_subrange_type)
<281> DW_AT_type : <0x1eb>
<285> DW_AT_upper_bound : 11
<2><286>: Abbrev Number: 0
<1><287>: Abbrev Number: 13 (DW_TAG_variable)
<288> DW_AT_name : (indirect string, offset: 0xe7): g_ar
<28c> DW_AT_decl_file : 1
<28d> DW_AT_decl_line : 11
<28e> DW_AT_decl_column : 7
<28f> DW_AT_type : <0x277>
<293> DW_AT_external : 1
<293> DW_AT_location : 9 byte block: 3 60 40 0 0 0 0 0 0 (DW_OP_addr: 4060)
<1><29d>: Abbrev Number: 14 (DW_TAG_subprogram)
<29e> DW_AT_external : 1
<29e> DW_AT_name : (indirect string, offset: 0xf2): memset
<2a2> DW_AT_decl_file : 3
<2a3> DW_AT_decl_line : 61
<2a4> DW_AT_decl_column : 14
<2a5> DW_AT_prototyped : 1
<2a5> DW_AT_type : <0x1f9>
<2a9> DW_AT_declaration : 1
<2a9> DW_AT_sibling : <0x2bd>
<2><2ad>: Abbrev Number: 3 (DW_TAG_formal_parameter)
<2ae> DW_AT_type : <0x1f9>
<2><2b2>: Abbrev Number: 3 (DW_TAG_formal_parameter)
<2b3> DW_AT_type : <0x217>
<2><2b7>: Abbrev Number: 3 (DW_TAG_formal_parameter)
<2b8> DW_AT_type : <0x1df>
<2><2bc>: Abbrev Number: 0
<1><2bd>: Abbrev Number: 15 (DW_TAG_subprogram)
<2be> DW_AT_external : 1
<2be> DW_AT_name : sub
<2c2> DW_AT_decl_file : 1
<2c3> DW_AT_decl_line : 13
<2c4> DW_AT_decl_column : 5
<2c5> DW_AT_prototyped : 1
<2c5> DW_AT_type : <0x217>
<2c9> DW_AT_low_pc : 0x11f0
<2d1> DW_AT_high_pc : 0x51
<2d9> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<2db> DW_AT_call_all_tail_calls: 1
<2><2db>: Abbrev Number: 5 (DW_TAG_formal_parameter)
<2dc> DW_AT_name : a
<2de> DW_AT_decl_file : 1
<2de> DW_AT_decl_line : 13
<2de> DW_AT_decl_column : 13
<2df> DW_AT_type : <0x217>
<2e3> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
<2><2e6>: Abbrev Number: 5 (DW_TAG_formal_parameter)
<2e7> DW_AT_name : b
<2e9> DW_AT_decl_file : 1
<2e9> DW_AT_decl_line : 13
<2e9> DW_AT_decl_column : 20
<2ea> DW_AT_type : <0x217>
<2ee> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)
<2><2f1>: Abbrev Number: 0
<1><2f2>: Abbrev Number: 0