Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "elf.h"
5 #include "dwarf.h"
7 void printrules(Dwarf *d, ulong pc);
8 int exprfmt(Fmt*);
10 void
11 usage(void)
12 {
13 fprint(2, "usage: dwarfdump file\n");
14 exits("usage");
15 }
17 void
18 main(int argc, char **argv)
19 {
20 int c;
21 Elf *elf;
22 Dwarf *d;
23 DwarfSym s;
24 char *cdir, *dir, *file;
25 ulong line, mtime, length;
27 ARGBEGIN{
28 default:
29 usage();
30 }ARGEND
32 if(argc != 1)
33 usage();
35 fmtinstall('R', exprfmt);
36 fmtinstall('H', encodefmt);
38 if((elf = elfopen(argv[0])) == nil)
39 sysfatal("elfopen %s: %r", argv[0]);
40 if((d=dwarfopen(elf)) == nil)
41 sysfatal("dwarfopen: %r");
43 if(dwarfenum(d, &s) < 0)
44 sysfatal("dwarfenumall: %r");
46 while(dwarfnextsym(d, &s, 1) == 1){
47 switch(s.attrs.tag){
48 case TagCompileUnit:
49 print("compileunit %s\n", s.attrs.name);
50 break;
51 case TagSubprogram:
52 c = 't';
53 goto sym;
54 case TagVariable:
55 c = 'd';
56 goto sym;
57 case TagConstant:
58 c = 'c';
59 goto sym;
60 case TagFormalParameter:
61 if(!s.attrs.name)
62 break;
63 c = 'p';
64 sym:
65 if(s.attrs.isexternal)
66 c += 'A' - 'a';
67 print("%c %s", c, s.attrs.name);
68 if(s.attrs.have.lowpc)
69 print(" 0x%lux-0x%lux", s.attrs.lowpc, s.attrs.highpc);
70 switch(s.attrs.have.location){
71 case TBlock:
72 print(" @ %.*H", s.attrs.location.b.len, s.attrs.location.b.data);
73 break;
74 case TConstant:
75 print(" @ 0x%lux", s.attrs.location.c);
76 break;
77 }
78 if(s.attrs.have.ranges)
79 print(" ranges@0x%lux", s.attrs.ranges);
80 print("\n");
81 if(s.attrs.have.lowpc){
82 if(dwarfpctoline(d, s.attrs.lowpc, &cdir, &dir, &file, &line, &mtime, &length) < 0)
83 print("\tcould not find source: %r\n");
84 else
85 print("\t%s/%s/%s:%lud mtime=%lud length=%lud\n",
86 cdir, dir, file, line, mtime, length);
88 if(0) printrules(d, s.attrs.lowpc);
89 if(0) printrules(d, (s.attrs.lowpc+s.attrs.highpc)/2);
90 }
91 break;
92 }
93 }
94 exits(0);
95 }
97 void
98 printrules(Dwarf *d, ulong pc)
99 {
100 int i;
101 DwarfExpr r[10];
102 DwarfExpr cfa, ra;
104 if(dwarfunwind(d, pc, &cfa, &ra, r, nelem(r)) < 0)
105 print("\tcannot unwind from pc 0x%lux: %r\n", pc);
107 print("\tpc=0x%lux cfa=%R ra=%R", pc, &cfa, &ra);
108 for(i=0; i<nelem(r); i++)
109 if(r[i].type != RuleSame)
110 print(" r%d=%R", i, &r[i]);
111 print("\n");
114 int
115 exprfmt(Fmt *fmt)
117 DwarfExpr *e;
119 if((e = va_arg(fmt->args, DwarfExpr*)) == nil)
120 return fmtstrcpy(fmt, "<nil>");
122 switch(e->type){
123 case RuleUndef:
124 return fmtstrcpy(fmt, "undef");
125 case RuleSame:
126 return fmtstrcpy(fmt, "same");
127 case RuleCfaOffset:
128 return fmtprint(fmt, "%ld(cfa)", e->offset);
129 case RuleRegister:
130 return fmtprint(fmt, "r%ld", e->reg);
131 case RuleRegOff:
132 return fmtprint(fmt, "%ld(r%ld)", e->offset, e->reg);
133 case RuleLocation:
134 return fmtprint(fmt, "l.%.*H", e->loc.len, e->loc.data);
135 default:
136 return fmtprint(fmt, "?%d", e->type);