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){
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 if(dir == nil)
85 print("\t%s/%s:%lud mtime=%lud length=%lud\n",
86 cdir, file, line, mtime, length);
87 else
88 print("\t%s/%s/%s:%lud mtime=%lud length=%lud\n",
89 cdir, dir, file, line, mtime, length);
91 if(0) printrules(d, s.attrs.lowpc);
92 if(0) printrules(d, (s.attrs.lowpc+s.attrs.highpc)/2);
93 }
94 break;
95 }
96 }
97 exits(0);
98 }
100 void
101 printrules(Dwarf *d, ulong pc)
103 int i;
104 DwarfExpr r[10];
105 DwarfExpr cfa, ra;
107 if(dwarfunwind(d, pc, &cfa, &ra, r, nelem(r)) < 0)
108 print("\tcannot unwind from pc 0x%lux: %r\n", pc);
110 print("\tpc=0x%lux cfa=%R ra=%R", pc, &cfa, &ra);
111 for(i=0; i<nelem(r); i++)
112 if(r[i].type != RuleSame)
113 print(" r%d=%R", i, &r[i]);
114 print("\n");
117 int
118 exprfmt(Fmt *fmt)
120 DwarfExpr *e;
122 if((e = va_arg(fmt->args, DwarfExpr*)) == nil)
123 return fmtstrcpy(fmt, "<nil>");
125 switch(e->type){
126 case RuleUndef:
127 return fmtstrcpy(fmt, "undef");
128 case RuleSame:
129 return fmtstrcpy(fmt, "same");
130 case RuleCfaOffset:
131 return fmtprint(fmt, "%ld(cfa)", e->offset);
132 case RuleRegister:
133 return fmtprint(fmt, "r%ld", e->reg);
134 case RuleRegOff:
135 return fmtprint(fmt, "%ld(r%ld)", e->offset, e->reg);
136 case RuleLocation:
137 return fmtprint(fmt, "l.%.*H", e->loc.len, e->loc.data);
138 default:
139 return fmtprint(fmt, "?%d", e->type);