📄 dwarfread.c
字号:
SymReportError("no source file named \"", srcfile, "\"", NULL); return SYM_ERROR; } bestaddr = lookup_line(src,exec,line); sym->global = 0; sym->isym = src->dieref; sym->index = DWARF_INDEX; /* special tornado marker */ sym->exec = exec; sym->type[1] = tAddr; sym->type[2] = tNil; sym->nextt = 1; sym->value = bestaddr; return SYM_OK;}int Dwarf_SymLookup(char *execname, char *srcfile, char *symname, int flags, Symb *sym){ Dwarf_Error rc; struct dieinfo di; Dwarf_Die ddie; int err; Execfile *exec = NULL; Srcfile *src = NULL; Global *global = NULL; /* CPUWarning("Dwarf_SymLookup(%s,%s,%s,%x,%p)\n", execname, srcfile, symname, flags, sym); */ if (!exectab) exectab = AssocTabCreate(); if (AssocTabLookup(exectab, execname, (ATHeader**)&exec) != AT_OK) { SymReportError("no exec named \"", execname, "\"", NULL); return SYM_ERROR; } if( srcfile[0] ) { /* find matching source in exec->srcs, and then use src->globals */ if (AssocTabLookup(exec->srcs,srcfile,(ATHeader**)&src) != AT_OK ) { SymReportError("couldn't find src \"", srcfile, "\"", NULL); return SYM_ERROR; } AssocTabLookup(src->globals,symname,(ATHeader**)&global); } /* we count on global != NULL to indicate we already found it */ if( global == NULL ) { if (flags & SYM_TAGS) { if ( AssocTabLookup(exec->gStructs,symname,(ATHeader**)&global) != AT_OK ) { SymReportError("couldn't find symbol \"", symname, "\"", NULL); return SYM_ERROR; } } else { if ( AssocTabLookup(exec->globals,symname,(ATHeader**)&global) != AT_OK ) { SymReportError("couldn't find symbol \"", symname, "\"", NULL); return SYM_ERROR; } } } ASSERT(global!=NULL); /* fill in sym fields */ return FillInSym( sym, global->dieref, exec );}int Dwarf_SymFind(Symb *sym, char *name, int flags){ int st; int code; Dwarf_Off type; Dwarf_Die nextddie, ddie; struct dieinfo di; Execfile *exec; /*CPUWarning("Dwarf_SymFind(%p,%s,%x)\n", sym, name, flags);*/ exec = sym->exec; basicdieinfo (&di, NULL, sym->isym, exec); ddie = di.childdie; di.childdie = NULL; freedieinfo(&di,exec); code = SYM_ERROR; while (ddie) { basicdieinfo (&di, ddie, 0, exec); nextddie = di.sibdie; di.sibdie = NULL; /* ensure not freed */ if ( di.die_tag == DW_TAG_inheritance ) { /* we don't deal with all the visibility issues, but just * do a depth-first search through parent classes */ FillInSym(sym,GetTypeAbsOffset(di.ddie,exec),exec); if ( Dwarf_SymFind(sym, name, flags) == SYM_OK ) { code = SYM_OK; break; } } /* we effectively ignore blocks */ if ( (di.die_tag == DW_TAG_lexical_block) || ((flags & SYM_RECURSE) && (di.die_tag == DW_TAG_subprogram)) ) { FillInSym(sym,di.die_ref,exec); if ( Dwarf_SymFind(sym, name, flags) == SYM_OK ) { code = SYM_OK; break; } } if ( di.at_name && (strcmp(di.at_name,name) == 0) ) { FillInSym(sym,di.die_ref,exec); if ( (di.die_tag == DW_TAG_class_type) || (di.die_tag == DW_TAG_structure_type) || (di.die_tag == DW_TAG_enumeration_type) ) { if ( flags & SYM_TAGS ) { code = SYM_OK; break; } } else if ( !(flags & SYM_TAGS) ) { code = SYM_OK; break; } } freedieinfo(&di,exec); ddie = nextddie; } if( code != SYM_OK ) { SymReportError("couldn't find symbol \"", name, "\"", NULL); } return code;}int Dwarf_SymNext(Symb *sym){ SymReportError("Dwarf_Symnext not supported", NULL); return SYM_ERROR;}int Dwarf_SymIn(Symb *sym){ SymReportError("Dwarf_SymIn not supported", NULL); return SYM_ERROR;}int Dwarf_SymSubtype(Symb *sym, int flags){ int st; int code; Dwarf_Off type; struct dieinfo di; int i; /*CPUWarning("Dwarf_SymSubtype(%p,%x)\n", sym, flags);*/ if ( (sym->type[sym->nextt] == tPtr) || (sym->type[sym->nextt] == tAddr) || (sym->type[sym->nextt] == tArray)) { sym->nextt++; if( sym->type[sym->nextt] != tNil ) { return SYM_OK; } if( IS_CAST(sym) ) { /* this is a type cast and so our the dieref we have is for * the end type itself rather than some base object that his * this as it's type. */ type = sym->isym; } else { basicdieinfo (&di, NULL, sym->isym, sym->exec); type = GetTypeAbsOffset( di.ddie, sym->exec ); ASSERT(type != 0);#if 0 /* we assume if type is zero we have the type itself rather than * an object of the given type; so just use objects dieref */ if( type == 0 ) { type = sym->isym; } freedieinfo(&di,sym->exec);#endif } code = FillInSym (sym, type, sym->exec); ASSERT(code == SYM_OK); sym->nextt++; ASSERT(sym->type[sym->nextt] != tNil); return SYM_OK; } st = sym->type[sym->nextt]; ASSERT((st == tStruct) || (st == tUnion) || (st == tEnum) || (st == tTypedef)); /* sym->isym is the DIE_REF of either some object whose type * we are interested in, or of the actual type descriptor. */ if( IS_CAST(sym) ) { /* this is a type cast and so our the dieref we have is for * the end type itself rather than some base object that his * this as it's type. */ type = sym->isym; } else { basicdieinfo (&di, NULL, sym->isym, sym->exec); type = GetTypeAbsOffset( di.ddie, sym->exec ); ASSERT(type != 0); freedieinfo(&di,sym->exec); }#if 0 if( (st == tTypedef) && ( di.die_tag == DW_TAG_typedef )) { /* special case: for casts, the DIE_REF we have is for the last * type in the cast chain, not some object of the given type. * for typedefs, because they have types themselves, we can * fail to recognize this case, so we check whether the die * it represents is a typedef itself and use that as the type */ /* FIXME: if we have typedef of typedef we can get this case even * though it is not a cast case; we need a better check for this * case */ type = sym->isym; } else { type = GetTypeAbsOffset( di.ddie, sym->exec ); /* we assume if type is zero we have the type itself rather than * an object of the given type; so just use objects dieref */ if( type == 0 ) { type = sym->isym; } }#endif code = FillInSym (sym, type, sym->exec); ASSERT(code == SYM_OK); if (st == tStruct) { ASSERT(sym->type[sym->nextt] == tStructDef); } else if (st == tUnion) { ASSERT(sym->type[sym->nextt] == tUnionDef); } else if (st == tEnum) { ASSERT(sym->type[sym->nextt] == tEnumDef); } else if (st == tTypedef) { ASSERT(sym->type[sym->nextt] == tTypedefDef); sym->nextt++; if (flags & SYM_RESOLVE) { return SymSubtype(sym, flags); } } #if 1else { ASSERT(0); }#endif return SYM_OK;}int Dwarf_SymType(Symb *sym, int flags){ Dwarf_Off type; struct dieinfo di; Symb tmp; /*CPUWarning("Dwarf_Symtype(%p,%x)\n", sym, flags);*/ if ((sym->type[(sym)->nextt] != tTypedef) || !(flags & SYM_RESOLVE)) { return sym->type[(sym)->nextt]; } ASSERT(sym->type[(sym)->nextt] == tTypedef); tmp = *sym; if( Dwarf_SymSubtype(&tmp, 0) != SYM_OK ) { return SYM_ERROR; } return Dwarf_SymType(&tmp, flags);}Reg64 Dwarf_SymSize(Symb *sym){ /*CPUWarning("Dwarf_SymSize(%p)\n", sym);*/ /* FIXME: this should really just ask dwarf what the size of the * various objects are. */ switch (Dwarf_SymType(sym, SYM_RESOLVE)) { case tChar: case tUChar: return 1; case tShort: case tUShort: return 2; case tInt: case tUInt: return 4; case tLong: case tULong: case tPtr: return 8; case tFloat: return sizeof(float); case tDouble: return sizeof(double); case tLabel: return 4; case tProc: { Dwarf_Error rc; struct dieinfo di; Dwarf_Die ddie; int err; Dwarf_Addr atmp; DIE_REF dieref; dieref = sym->isym; err = dwarf_offdie(sym->exec->dwarf,dieref, &ddie, &rc); if( err == DW_DLV_ERROR ) { CPUWarning("dwarf_child failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } else if ( err != DW_DLV_OK ) { CPUWarning("Couldn't find symbol ref %d\n", dieref); ASSERT(0); } if( dwarf_highpc( ddie, &atmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_highpc failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } return atmp - sym->value; } /* FIXME: not sure about this; how exactly are array/addr types used */ case tAddr: return 8; case tArray: return 8; case tStruct: case tUnion: case tEnum: { Symb tmp = *sym; if (Dwarf_SymSubtype(&tmp, SYM_RESOLVE) != SYM_OK) { ASSERT(0); } return tmp.value; } case tStructDef: case tUnionDef: case tEnumDef: return sym->value; default: ASSERT(0); break; } /* never reached - for compiler */ ASSERT(0); return 0;}int Dwarf_SymTypeCast(char *execname, char *srcfile, int *types, char *name, Symb *sym){ Symb tmp; int *tp; /*CPUWarning("Dwarf_SymTypeCast(%s,%s,%p,%s,%p)\n", execname, srcfile, types, name, sym); */ sym->global = 1; sym->isym = -1; sym->filenum = -1; sym->name = NULL; sym->index = DWARF_INDEX; sym->exec = NULL; sym->nextt = 1; tp = types; while (*tp != tNil) { sym->type[sym->nextt++] = *tp; tp++; } ASSERT(sym->nextt<MAX_TYPES); sym->type[sym->nextt] = tNil; if (name[0]) { sym->nextt--; /* OK because we are going to reset it anyway */ if ((sym->type[sym->nextt] == tStruct) || (sym->type[sym->nextt] == tUnion) || (sym->type[sym->nextt] == tEnum)) { if (Dwarf_SymLookup(execname, srcfile, name, SYM_TAGS, &tmp) != SYM_OK) { SymReportError("couldn't find symbol \"", name, "\"", NULL); return SYM_ERROR; } } else if (sym->type[sym->nextt] == tTypedef) { if (Dwarf_SymLookup(execname, srcfile, name, 0, &tmp) != SYM_OK) { SymReportError("couldn't find symbol \"", name, "\"", NULL); return SYM_ERROR; } } else { ASSERT(0); } sym->exec = tmp.exec; sym->index = tmp.index; sym->isym = tmp.isym; } sym->nextt = 1; sym->value = 0; return SYM_OK;}int Dwarf_SymMakeAddr(Symb *sym){ /*CPUWarning("Dwarf_SymMakeAddr(%p)\n", sym);*/ ASSERT(sym->nextt > 0); sym->nextt--; sym->type[sym->nextt] = tAddr; return SYM_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -