int wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { Stab *s; int ns; int i; int found = 0; char *file, *lastfile = 0; char srcfile[MAX_PATH]; char objfile[MAX_PATH]; /* It appears to be necessary to clear the types table on each new stabs section */ init_hash(); if (!f->sym_name) return 0; s = (Stab *) sp; /* Stabs data */ ns = size/sizeof(Stab); /* number of stabs */ srcfile[0] = 0; objfile[0] = 0; for (i = 0; i < ns; i++, s++) { if (wad_debug_mode & DEBUG_STABS) { /* wad_printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, stabstr+s->n_strx); */ } if (s->n_type == N_LSYM) { stab_symbol(s,stabstr); continue; } if ((s->n_type == N_UNDF)) { /* && (s->n_desc >= 0)) { */ /* New stabs section. We need to be a little careful here. Do a recursive search of the subsection. */ if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, f)) { return 1; } /* On solaris, each stabs section seems to increment the stab string pointer. On Linux, the linker seems to do a certain amount of optimization that results in a single string table. */ #ifdef WAD_SOLARIS stabstr += s->n_value; /* Update the string table location*/ #endif i += s->n_desc; s += s->n_desc; objfile[0] = 0; srcfile[0] = 0; continue; } else if (s->n_type == N_SO) { /* Source file specification */ /* Look for directory */ file = stabstr+s->n_strx; if (strlen(file) && (file[strlen(file)-1] == '/')) { wad_strcpy(srcfile,file); } else { wad_strcat(srcfile,file); } objfile[0] = 0; /* If we have a file match, we might be looking for a local symbol. If so, we'll go ahead and set the srcfile field of the frame */ /* We're going to check for a file match. Maybe we're looking for a local symbol */ if (f->sym_file && strcmp(f->sym_file,file) == 0) { found = 1; } lastfile = file; } else if (s->n_type == N_OBJ) { /* Object file specifier */ if (objfile[0]) { wad_strcat(objfile,"/"); } wad_strcat(objfile,stabstr+s->n_strx); } else if (s->n_type == N_FUN) { if (match_stab_symbol(f->sym_name, stabstr+s->n_strx, f->sym_nlen)) { if (!f->sym_file || (strcmp(f->sym_file,lastfile) == 0)) { int n; /* Go find debugging information for the function */ n = scan_function(s+1, stabstr, ns -i - 1, f); f->loc_srcfile = wad_string_lookup(srcfile); f->loc_objfile = wad_string_lookup(objfile); return 1; } } } } /* If found, but no other debugging information was filled in, go ahead and copy the source and objfile information */ if ((found) && (!f->debug_check)) { f->loc_srcfile = wad_string_lookup(srcfile); f->loc_objfile = wad_string_lookup(objfile); } return found; }
int wad_elf_debug_info(WadFrame *f) { int nstab, nstabstr, nstabindex, nstabindexstr, nstabexcl, nstabexclstr; int ret; void *stab; char *stabstr; int stabsize; nstab = wad_elf_section_byname(f->object,".stab"); nstabstr = wad_elf_section_byname(f->object,".stabstr"); nstabindex = wad_elf_section_byname(f->object,".stab.index"); nstabindexstr = wad_elf_section_byname(f->object,".stab.indexstr"); nstabexcl = wad_elf_section_byname(f->object,".stab.excl"); nstabexclstr = wad_elf_section_byname(f->object,".stab.exclstr"); #ifdef DEBUG_DEBUG wad_printf("nstab = %d\n", nstab); wad_printf("nstabstr = %d\n", nstabstr); wad_printf("nstabindex = %d\n", nstabindex); wad_printf("nstabindexstr = %d\n", nstabindexstr); wad_printf("nstabexcl = %d\n", nstabexcl); wad_printf("nstabexclstr = %d\n", nstabexclstr); #endif /* Now start searching stabs */ /* Look in the .stab section */ if (nstab > 0) { stab = wad_elf_section_data(f->object,nstab); stabsize = wad_elf_section_size(f->object,nstab); stabstr = (char *) wad_elf_section_data(f->object,nstabstr); if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; } /* Look in the .stab.excl section. A solaris oddity? */ if (nstabexcl > 0) { stab = wad_elf_section_data(f->object,nstabexcl); stabsize = wad_elf_section_size(f->object, nstabexcl); stabstr = (char *) wad_elf_section_data(f->object, nstabexclstr); if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; } /* Look in the .stab.index section. A Solaris oddity? */ if (nstabindex > 0) { stab = wad_elf_section_data(f->object,nstabindex); stabsize = wad_elf_section_size(f->object, nstabindex); stabstr = (char *) wad_elf_section_data(f->object, nstabindexstr); if (wad_search_stab(stab,stabsize,stabstr, f)) { /* Hmmm. Might be in a different file */ WadObjectFile *wo1, *wold; char objfile[MAX_PATH]; /* printf("DEBUG %s\n", f->sym_name); */ wad_strcpy(objfile, f->loc_objfile); wo1 = wad_object_load(objfile); if (wo1) { wold = f->object; f->object = wo1; wad_find_debug(f); f->object = wold; return ret; } else { /* wad_printf("couldn't load %s\n", objfile); */ } /* if (!ret) return wad_search_stab(stab,stabsize,stabstr,f);*/ return ret; } } return 0; }