dwarfdump.c (2936B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "elf.h" 5 #include "dwarf.h" 6 7 void printrules(Dwarf *d, ulong pc); 8 int exprfmt(Fmt*); 9 10 void 11 usage(void) 12 { 13 fprint(2, "usage: dwarfdump file\n"); 14 exits("usage"); 15 } 16 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; 26 27 ARGBEGIN{ 28 default: 29 usage(); 30 }ARGEND 31 32 if(argc != 1) 33 usage(); 34 35 fmtinstall('R', exprfmt); 36 fmtinstall('H', encodefmt); 37 38 if((elf = elfopen(argv[0])) == nil) 39 sysfatal("elfopen %s: %r", argv[0]); 40 if((d=dwarfopen(elf)) == nil) 41 sysfatal("dwarfopen: %r"); 42 43 if(dwarfenum(d, &s) < 0) 44 sysfatal("dwarfenumall: %r"); 45 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); 90 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 } 99 100 void 101 printrules(Dwarf *d, ulong pc) 102 { 103 int i; 104 DwarfExpr r[10]; 105 DwarfExpr cfa, ra; 106 107 if(dwarfunwind(d, pc, &cfa, &ra, r, nelem(r)) < 0) 108 print("\tcannot unwind from pc 0x%lux: %r\n", pc); 109 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"); 115 } 116 117 int 118 exprfmt(Fmt *fmt) 119 { 120 DwarfExpr *e; 121 122 if((e = va_arg(fmt->args, DwarfExpr*)) == nil) 123 return fmtstrcpy(fmt, "<nil>"); 124 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); 140 } 141 }