plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }