WadObjectFile * wad_arobject_load(const char *arpath, const char *robjname) { WadObjectFile *wo; WadFile *wf; int arlen; char *arptr; struct ar_hdr *ah; int offset; int msize; char *strtab = 0; int sobjname; char objname[MAX_PATH]; wad_strcpy(objname,robjname); wad_strcat(objname,"/"); sobjname = strlen(objname); wf = load_file(arpath); if (!wf) return 0; /* Doesn't exit */ arptr = (char *) wf->addr; arlen = wf->size; /* Now take a look at the archive */ if (strncmp(arptr,ARMAG,SARMAG) == 0) { /* printf("Got an archive\n"); */ } else { return 0; } /* Search the archive for the request member */ strtab = 0; offset = SARMAG; while (offset < arlen) { char mname[MAX_PATH]; ah = (struct ar_hdr *) (arptr + offset); if (strncmp(ah->ar_name,"// ", 3) == 0) { strtab = arptr + offset + sizeof(struct ar_hdr); } msize = atoi(ah->ar_size); offset += sizeof(struct ar_hdr); /* Try to figure out the filename */ if ((ah->ar_name[0] == '/') && (isdigit(ah->ar_name[1]))) { int soff; char *e; /* Must be in the string offset table */ soff = atoi(ah->ar_name+1); if (!strtab) { /* No offset table */ return 0; } e = strchr(strtab+soff,'\n'); if (e) { strncpy(mname, strtab+soff, (e - (strtab+soff))); mname[e-(strtab+soff)] = 0; } else { mname[0] = 0; } } else { /* Name must be in the name field */ strncpy(mname,ah->ar_name,16); mname[16] = 0; } /* Compare the names */ if (strncmp(mname,objname,sobjname) == 0) { /* Found the archive */ wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile)); wo->ptr = (void *) (arptr + offset); wo->len = msize; wo->path = 0; return wo; } offset += msize; } return 0; }
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; }
/* Try to make a formatted version of a local */ char *wad_format_var(WadLocal *l) { static char hexdigits[] = "0123456789abcdef"; static char buffer[1024]; double dval; float fval; buffer[0] = 0; switch(l->type) { case WAD_TYPE_INT32: wad_strcpy(buffer,wad_format_int(l->ptr,4,1)); break; case WAD_TYPE_UINT32: wad_strcpy(buffer,wad_format_int(l->ptr,4,0)); break; case WAD_TYPE_INT16: wad_strcpy(buffer,wad_format_int(l->ptr,2,1)); break; case WAD_TYPE_UINT16: wad_strcpy(buffer,wad_format_int(l->ptr,2,0)); break; case WAD_TYPE_INT8: wad_strcpy(buffer,wad_format_int(l->ptr,1,1)); break; case WAD_TYPE_UINT8: wad_strcpy(buffer,wad_format_int(l->ptr,1,0)); break; case WAD_TYPE_CHAR: buffer[0] = '\''; buffer[1] = *((char *) l->ptr); buffer[2] = '\''; buffer[3] = 0; break; case WAD_TYPE_FLOAT: wad_memcpy(&fval,l->ptr,sizeof(float)); sprintf(buffer,"%g",fval); break; case WAD_TYPE_DOUBLE: wad_memcpy(&dval,l->ptr,sizeof(double)); sprintf(buffer,"%g",dval); break; case WAD_TYPE_UNKNOWN: case WAD_TYPE_POINTER: default: /* Hmmm. Unknown data type. We'll just treat it as a word */ if (l->ptr) { int incr,i; int b; int leading = 1; char *c; char *ptr; #ifdef WAD_LITTLE_ENDIAN ptr = ((char *) l->ptr) + 3; incr = -1; #else ptr = (char *) l->ptr; incr =1 ; #endif wad_strcat(buffer,"0x"); c = buffer+2; for (i = 0; i < sizeof(void *); i++) { b = (int) *ptr; if (!leading || (b)) { if (!leading || (b & 0xf0)) *(c++) = hexdigits[(b & 0xf0) >> 4]; *(c++) = hexdigits[(b & 0xf)]; leading = 0; } ptr += incr; } if (leading) *(c++) = '0'; *c = 0; } }