void main(int argc, char **argv) { int c; Pe *pe; Dwarf *d; DwarfSym s; char *cdir, *dir, *file; ulong line, mtime, length; if(argc != 2) usage(); #if 0 fmtinstall('R', exprfmt); fmtinstall('H', encodefmt); #endif if((pe = peopen(argv[1])) == nil) sysfatal("elfopen %s: %r", argv[1]); if((d=dwarfopen(pe)) == nil) sysfatal("dwarfopen: %r"); if(dwarfenum(d, &s) < 0) sysfatal("dwarfenumall: %r"); while(dwarfnextsym(d, &s) == 1){ switch(s.attrs.tag){ case TagCompileUnit: print("compileunit %s\n", s.attrs.name); break; case TagSubprogram: c = 't'; goto sym; case TagVariable: c = 'd'; goto sym; case TagConstant: c = 'c'; goto sym; case TagFormalParameter: if(!s.attrs.name) break; c = 'p'; sym: if(s.attrs.isexternal) c += 'A' - 'a'; print("%c %s", c, s.attrs.name); if(s.attrs.have.lowpc) print(" 0x%lux-0x%lux", s.attrs.lowpc, s.attrs.highpc); switch(s.attrs.have.location){ case TBlock: print(" @ %.*H", s.attrs.location.b.len, s.attrs.location.b.data); break; case TConstant: print(" @ 0x%lux", s.attrs.location.c); break; } if(s.attrs.have.ranges) print(" ranges@0x%lux", s.attrs.ranges); print("\n"); if(s.attrs.have.lowpc){ if(dwarfpctoline(d, s.attrs.lowpc, &cdir, &dir, &file, &line, &mtime, &length) < 0) print("\tcould not find source: %r\n"); else if(dir == nil) print("\t%s/%s:%lud mtime=%lud length=%lud\n", cdir, file, line, mtime, length); else print("\t%s/%s/%s:%lud mtime=%lud length=%lud\n", cdir, dir, file, line, mtime, length); if(0) printrules(d, s.attrs.lowpc); if(0) printrules(d, (s.attrs.lowpc+s.attrs.highpc)/2); } break; } } exits(0); }
BOOLEAN RosSymGetAddressInformation (PROSSYM_INFO RosSymInfo, ULONG_PTR RelativeAddress, PROSSYM_LINEINFO RosSymLineInfo) { ROSSYM_REGISTERS registers; DwarfParam params[sizeof(RosSymLineInfo->Parameters)/sizeof(RosSymLineInfo->Parameters[0])]; DwarfSym proc = { }; int i; int res = dwarfpctoline (RosSymInfo, &proc, RelativeAddress + RosSymInfo->pe->imagebase, &RosSymLineInfo->FileName, &RosSymLineInfo->FunctionName, &RosSymLineInfo->LineNumber); if (res == -1) { werrstr("Could not get basic function info"); return FALSE; } if (!(RosSymLineInfo->Flags & ROSSYM_LINEINFO_HAS_REGISTERS)) return TRUE; registers = RosSymLineInfo->Registers; DwarfExpr cfa = { }; ulong cfaLocation; if (dwarfregunwind (RosSymInfo, RelativeAddress + RosSymInfo->pe->imagebase, proc.attrs.framebase.c, &cfa, ®isters) == -1) { werrstr("Can't get cfa location for %s", RosSymLineInfo->FunctionName); return TRUE; } res = dwarfgetparams (RosSymInfo, &proc, RelativeAddress + RosSymInfo->pe->imagebase, sizeof(params)/sizeof(params[0]), params); if (res == -1) { werrstr("%s: could not get params at all", RosSymLineInfo->FunctionName); RosSymLineInfo->NumParams = 0; return TRUE; } werrstr("%s: res %d", RosSymLineInfo->FunctionName, res); RosSymLineInfo->NumParams = res; res = dwarfcomputecfa(RosSymInfo, &cfa, ®isters, &cfaLocation); if (res == -1) { werrstr("%s: could not get our own cfa", RosSymLineInfo->FunctionName); return TRUE; } for (i = 0; i < RosSymLineInfo->NumParams; i++) { werrstr("Getting arg %s, unit %x, type %x", params[i].name, params[i].unit, params[i].type); res = dwarfargvalue (RosSymInfo, &proc, RelativeAddress + RosSymInfo->pe->imagebase, cfaLocation, ®isters, ¶ms[i]); if (res == -1) { RosSymLineInfo->NumParams = i; return TRUE; } werrstr("%s: %x", params[i].name, params[i].value); RosSymLineInfo->Parameters[i].ValueName = malloc(strlen(params[i].name)+1); strcpy(RosSymLineInfo->Parameters[i].ValueName, params[i].name); free(params[i].name); RosSymLineInfo->Parameters[i].Value = params[i].value; } return TRUE; }