dwarfread.c
来自「一个用在mips体系结构中的操作系统」· C语言 代码 · 共 1,801 行 · 第 1/4 页
C
1,801 行
src->hipc = high_pc; src->dieref = di.die_ref; if (AssocTabEnter(exec->srcs, (ATHeader*)src) != AT_OK) { ASSERT(0); } /*CPUWarning("scanning '%s' for globals\n", src->head.label);*/ /* Now look for partial symbols */ scan_partial_symbols (di.childdie, exec, src); di.childdie = NULL; /* avoid freeing here */ } } freedieinfo(&di,exec); }}static voidbasicdieinfo ( struct dieinfo *dip, Dwarf_Die ddie, DIE_REF dieref, Execfile *exec ){ Dwarf_Error rc; Dwarf_Die tmpdie; Dwarf_Bool btmp; Dwarf_Attribute attr; int err; char *stmp; memset (dip, 0, sizeof (struct dieinfo)); /* if ddie not null, use it, otherwise we use dieref */ if( ddie == NULL ) { err = dwarf_offdie(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); } } dip->ddie = ddie; if( dwarf_tag( ddie, &dip->die_tag, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_tag failed: %s\n", dwarf_errmsg( rc ) ); ASSERT(0); } /* CPUWarning("tag: %x\n", dip->die_tag ); */ err = dwarf_siblingof( exec->dwarf, ddie, &tmpdie, &rc ); if( err == DW_DLV_ERROR ) { CPUWarning("dwarf_siblingof failed: %s\n", dwarf_errmsg( rc ) ); ASSERT(0); } else if( err == DW_DLV_OK ) { dip->sibdie = tmpdie; } err = dwarf_child( ddie, &tmpdie, &rc ); if( err == DW_DLV_ERROR ) { CPUWarning("dwarf_child failed: %s\n", dwarf_errmsg( rc ) ); ASSERT(0); } else if( err == DW_DLV_OK ) { dip->childdie = tmpdie; } dwarf_dieoffset( ddie, &dieref, &rc ); dip->die_ref = dieref; /* if there is a linkage name, we use that instead of the diename */ if( dwarf_attr(ddie,DW_AT_MIPS_linkage_name,&attr,&rc) == DW_DLV_OK ) { if( dwarf_formstring( attr, &stmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formstring failed: %s\n", dwarf_errmsg( rc ) ); ASSERT(0); } dip->at_name = stmp; dwarf_dealloc( exec->dwarf, attr, DW_DLA_ATTR); } else { err = dwarf_diename( ddie, &stmp, &rc ); if( err == DW_DLV_ERROR ) { CPUWarning("dwarf_diename failed: %s\n", dwarf_errmsg( rc ) ); ASSERT(0); } else if( err == DW_DLV_OK ) { dip->at_name = stmp; } }#if 0 if( dip->at_name && (strcmp(dip->at_name,"main") == 0) ) { CPUWarning("basicdieinfo, main: ref %lld\n", (Reg64)dip->die_ref); } if( dip->at_name /*&& (dip->die_tag == DW_TAG_subprogram)*/ ) { static int counter = 0; if( counter++ < 20 ) { CPUWarning("basicdieinfo, %s: ref %lld\n", dip->at_name, (Reg64)dip->die_ref); } }#endif}static voidPrintDieInfo( Dwarf_Die ddie, Execfile *exec ){ Dwarf_Unsigned tmp; Dwarf_Addr atmp; Dwarf_Bool btmp; Dwarf_Off otmp; Dwarf_Locdesc *ldtmp; Dwarf_Signed signedtmp; char *stmp; Dwarf_Signed atcnt; Dwarf_Attribute *atlist; Dwarf_Half attr; Dwarf_Error rc; Dwarf_Half from; Dwarf_Die tmpdie; int i; int err; if( (err = dwarf_attrlist( ddie, &atlist, &atcnt, &rc )) != DW_DLV_OK) { if( err != DW_DLV_NO_ENTRY ) { CPUWarning("dwarf_attrlist failed: %s\n", dwarf_errmsg(rc)); return; } } for( i = 0; i < atcnt; i++ ) { if( dwarf_whatattr( atlist[i], &attr, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_whatattr failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } /* CPUWarning(" attr: %x\n", attr ); */ switch (attr) { case DW_AT_type: if( dwarf_formref( atlist[i], &otmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formref failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("type %lld\n", (Reg64)otmp); break; case DW_AT_ordering: if( dwarf_arrayorder( ddie, &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_arrayorder failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("array order %lld\n", (Reg64)tmp); break; case DW_AT_bit_offset: if( dwarf_bitoffset( ddie, &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_bitoffset failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("bit off %lld\n", (Reg64)tmp); break; case DW_AT_sibling: /* we pick this up in the basicdieinfo routine */ break; case DW_AT_stmt_list: /* we get our info using special line info routines */ break; case DW_AT_low_pc: if( dwarf_lowpc( ddie, &atmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_lowpc failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("lowpc %llx\n", (Reg64)atmp); break; case DW_AT_high_pc: if( dwarf_highpc( ddie, &atmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_highpc failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("hipc %llx\n", (Reg64)atmp); break; case DW_AT_language: if( dwarf_srclang( ddie, &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_srclang failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("lang %lld\n", (Reg64)tmp); break; case DW_AT_byte_size: if( dwarf_bytesize( ddie, &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_bytesize failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("bytes %lld\n", (Reg64)tmp); break; case DW_AT_bit_size: if( dwarf_bitsize( ddie, &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_bitsize failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("bits %lld\n", (Reg64)tmp); break; case DW_AT_location: if( dwarf_loclist( atlist[i], &ldtmp, &signedtmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_loclist failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } if( signedtmp != 1 ) { CPUWarning("location list size %lld != 1\n", signedtmp ); ASSERT(0); } CPUWarning("location %p\n", ldtmp); break; case DW_AT_data_member_location: if( dwarf_loclist( atlist[i], &ldtmp, &signedtmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_loclist failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("dmloc %lld, %p\n", (Reg64)signedtmp, ldtmp); break; case DW_AT_name: if( dwarf_formstring( atlist[i], &stmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formstring failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("name %s\n", stmp); break; case DW_AT_comp_dir: if( dwarf_formstring( atlist[i], &stmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formstring failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } /* For now, ignore any "hostname:" portion, since gdb doesn't know how to deal with it. (FIXME). */ CPUWarning("compdir %s\n", stmp); break; case DW_AT_producer: if( dwarf_formstring( atlist[i], &stmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formstring failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("prod %s\n", stmp); break; case DW_AT_start_scope: if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("startscope %lld\n", (Reg64)tmp); break; case DW_AT_stride_size: CPUWarning("Dwarf stride size not handled yet\n"); ASSERT(0); if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("stride %lld\n", (Reg64)tmp); break; case DW_AT_prototyped: if( dwarf_formflag( atlist[i], &btmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formflag failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("proto %lld\n", (Reg64)btmp); break; case DW_AT_external: if( dwarf_formflag( atlist[i], &btmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formflag failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("external %lld\n", (Reg64)btmp); break; case DW_AT_encoding: if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("encode %lld\n", (Reg64)tmp); break; case DW_AT_upper_bound: if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("upperbound %lld\n", (Reg64)tmp); break; case DW_AT_lower_bound: if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("lowerbound %lld\n", (Reg64)tmp); break; case DW_AT_const_value: if( dwarf_formudata( atlist[i], &tmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formudata failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("const %lld\n", (Reg64)tmp); break; case DW_AT_declaration: if( dwarf_formflag( atlist[i], &btmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formflag failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("decl %lld\n", (Reg64)btmp); break; case DW_AT_specification: /* we may not need this... I'm not sure yet */ if( dwarf_formref( atlist[i], &otmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formref failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("specification %lld\n", (Reg64)otmp); break; case DW_AT_MIPS_linkage_name: /* It's not clear what name we should be using, but it seems gdb * is happier using the full name, even though it has all the * class context information if it wants it. */ if( dwarf_formstring( atlist[i], &stmp, &rc ) != DW_DLV_OK) { CPUWarning("dwarf_formstring failed: %s\n", dwarf_errmsg(rc) ); ASSERT(0); } CPUWarning("linkage %s\n", stmp); break; case DW_AT_frame_base: case DW_AT_MIPS_fde: case DW_AT_identifier_case: case DW_AT_decl_file: case DW_AT_decl_line: case DW_AT_address_class: case DW_AT_artificial: case DW_AT_abstract_origin: /* these are currently not handled/needed */ break; default: CPUWarning("Unhandled attribute: %x\n", attr); /* Found an attribute that we are unprepared to handle. However it is specifically one of the design goals of DWARF that consumers should ignore unknown attributes. As long as the form is one that we recognize (so we know how to skip it), we can just ignore the unknown attribute. */ break; } dwarf_dealloc( exec->dwarf, atlist[i], DW_DLA_ATTR); } dwarf_dealloc( exec->dwarf, atlist, DW_DLA_LIST); }/* * variables */static AssocTab *exectab = NULL;/* exported interface to simos */int Dwarf_SymLoad(char *pathname, char *execname){ int fd; char *filename; ATHeader *dummy; Execfile *exec; Dwarf_Error rc; if (!exectab) { exectab = AssocTabCreate(); } /* check if execname already used */ if (AssocTabLookup(exectab, execname, &dummy) == AT_OK) { SymReportError("execname already taken \"", execname, "\"", NULL); return SYM_ERROR; } if (!(filename = SearchForFile(pathname))) { SymReportError("no such file \"", pathname, "\"", NULL); return SYM_ERROR; } fd = open( filename, O_RDONLY ); if( fd < 0 ) { SymReportError("couldn't open \"", filename, "\"", NULL); return SYM_ERROR; } exec = (Execfile*)malloc(sizeof(Execfile)); if( dwarf_init(fd,DW_DLC_READ,NULL,NULL,&exec->dwarf,&rc) != DW_DLV_OK) { free(exec); close(fd); SymReportError("dwarf_init for \"", filename, "\" failed:", dwarf_errmsg(rc), NULL); return SYM_ERROR; } exec->head.label = SaveString(execname); exec->srcs = AssocTabCreate(); exec->globals = AssocTabCreate(); exec->gStructs = AssocTabCreate(); if (AssocTabEnter(exectab, (ATHeader*)exec) != AT_OK) { ASSERT(0); } scan_compilation_units (exec); return SYM_OK;}int Dwarf_SymAddr2Symbol(char *execname, int addr, Symb *sym){ SymReportError("Dwarf_SymAddr2Symbol not supported", NULL); return SYM_ERROR;}int Dwarf_SymLine2Addr(char *execname, char *srcfile, int line, Symb *sym){ Execfile *exec = NULL; Srcfile *src = NULL; VA bestaddr; CPUWarning("Dwarf_SymLine2Addr(%s,%s,%d,%p)\n", execname, srcfile, line, sym); if (!exectab) exectab = AssocTabCreate(); if (AssocTabLookup(exectab, execname, (ATHeader**)&exec) != AT_OK) { SymReportError("no exec named \"", execname, "\"", NULL); return SYM_ERROR; } if (AssocTabLookup(exec->srcs, StripPath(srcfile), (ATHeader**)&src) != AT_OK) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?