Ejemplo n.º 1
0
WadObjectFile *
wad_object_load(const char *path) {
    WadObjectFile *wo;
    WadFile *wf;
    WadObjectFile  *wad_arobject_load(const char *path, const char *name);

    if (wad_debug_mode & DEBUG_OBJECT) {
        wad_printf("wad: Loading object   '%s'", path);
    }
    for (wo = wad_objects; wo; wo=wo->next) {
        if (strcmp(wo->path,path) == 0) {
            if (wad_debug_mode & DEBUG_OBJECT) {
                wad_printf(" (cached)\n");
            }
            return wo;
        }
    }
    if (wad_debug_mode & DEBUG_OBJECT) {
        wad_printf("\n");
    }
    /* Didn't find it.  Now we need to go load some files */

    /* If this is an archive reference like /path/libfoo.a(blah.o), we need to
       split up the name a little bit */
    {
        char realfile[MAX_PATH];
        char *objfile;
        char *c;
        c = strchr(path,'(');
        if (c) {
            wad_strcpy(realfile,path);
            c = strchr(realfile,'(');
            *c = 0;
            objfile = c+1;
            c = strchr(objfile,')');
            *c = 0;

            /* Okay, I'm going to attempt to map this as a library file */
            wo = wad_arobject_load(realfile,objfile);
            if (wo) {
                /* Reset the path */
                wo->path = wad_strdup(path);
                wo->next = wad_objects;
                wad_objects = wo;
                return wo;
            }
        }
    }
    wf = load_file(path);
    if (!wf) return 0;

    wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile));
    wo->path = wad_strdup(path);
    wo->ptr = wf->addr;
    wo->len = wf->size;
    wo->next = wad_objects;
    wad_objects = wo;
    return wo;
}
Ejemplo n.º 2
0
static int 
segment_read(int fd, WadSegment *s)
{
  char pbuffer[1024];
  char *c;
  int  len;
  FILE *fs = (FILE *) fd;
  c = fgets(pbuffer,1024,fs);
  if (!c) return 0;

  pbuffer[strlen(pbuffer)-1] = 0;   /* Chop off endline */

  /* Break up the field into records */
  /*    0-8       : Starting address
	9-17      : Ending Address
	18        : r
	19        : w
	20        : x
	21        : p
	23-31     : Offset 
	49-       : Filename */

  len = strlen(pbuffer);
  pbuffer[8] = 0;
  pbuffer[17] = 0;
  pbuffer[31] = 0;
  if (len >= 49) {
    s->mapname = wad_strdup(pbuffer+49);
    s->mappath = s->mapname;
  }  else {
    s->mapname = "";
    s->mappath = s->mapname;
  }
  if (linux_first) {
    wad_strcpy(linux_firstsegment, s->mappath);
    linux_first = 0;
  }
  s->vaddr = (char *) strtoul(pbuffer,NULL,16);
  s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr);
  s->offset = strtoul(pbuffer+23,NULL,16);
  if (strcmp(linux_firstsegment, s->mappath) == 0) {
    s->base = 0;
  } else {
    s->base = s->vaddr;
  }
  s++;
  return 1;
}
Ejemplo n.º 3
0
static void
stab_symbol(Stab *s, char *stabstr) {
  char *str;
  char *pstr;
  char name[1024]; 
  char value[65536];

  str = stabstr+s->n_strx;
  pstr = stab_string_parm(str);
  if (!pstr) return;
  
  strncpy(name,str, pstr-str);
  name[(int)(pstr-str)] = 0;
  if ((pstr[1] == 't') || (pstr[1] == 'p') || (pstr[1] == 'r')) {
    /* A stabs type definition */
    /*    printf("stab lsym:  other=%d, desc=%d, value=%d, str='%s'\n", s->n_other,s->n_desc,s->n_value,
	  stabstr+s->n_strx); */
    /*    wad_printf("name = '%s', pstr='%s'\n", name, pstr+2); */
    wad_strcpy(value,pstr+2);
    type_add(name,value);
  }
}
Ejemplo n.º 4
0
static int
segment_read(int fs, WadSegment *s) {
  int     dz;
  int     n;
  prmap_t pmap;

  n = read(fs, &pmap, sizeof(prmap_t));
  if (n <= 0) return 0;
  s->mapname = wad_strdup(pmap.pr_mapname);
  s->mappath = (char *) wad_malloc(20+strlen(pmap.pr_mapname));
  wad_strcpy(s->mappath,"/proc/self/object/");
  strcat(s->mappath,pmap.pr_mapname);
  s->vaddr = (char *) pmap.pr_vaddr;

  /* This is a solaris oddity.  a.out section starts 1 page up, but
     symbols are relative to a base of 0 */

  if (strcmp(s->mapname,"a.out") == 0) s->base = 0;
  else s->base = s->vaddr;

  s->size  = pmap.pr_size;
  s->offset = pmap.pr_offset;
  return 1;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
/* 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;
    }
  }