Exemple #1
0
jt_pqueue* jt_pqueue_new(void)
{
  jt_pqueue* pq = jt_new(jt_pqueue);
  pq->item = jt_newarray(jt_pqueueitem*, 4);
  pq->length = 0;
  pq->size = 4;
  
  return pq;
}
Exemple #2
0
jt_pqueueitem* jt_pqueue_newitem(uint5 priority)
{
  jt_pqueueitem* pqi = jt_new(jt_pqueueitem);
  
  pqi->priority = priority;
  pqi->data = 0;
  
  return pqi;
}
Exemple #3
0
/* add symbols in object file to local symbol map */
void readsymbols(section* symtab, section* strtab, jt_map** symbolmap)
{
  int i;
  Elf32_Sym* thissym;
  
  for (i=1; i<symtab->content->length/sizeof(Elf32_Sym); i++)
  {
    mapentry* mentry = jt_new(mapentry);

    thissym = buffer_IDX(symtab->content, Elf32_Sym, i);

    mentry->name = symbolname(thissym, strtab);
    mentry->binding = ELF32_ST_BIND(thissym->st_info);
    mentry->symtabentry = i;
    mentry->backpatches = 0;

#ifdef DEBUG
/*    fprintf(stderr, "Read symbol %s\n", mentry->name);*/
#endif
    jt_map_insert(symbolmap, mentry->name, mentry);
  }
}
Exemple #4
0
/*
 Must match write_elf in asm/elfutil.c
 */
image* loadimage(FILE* f, int inlibrary)
{
  image* img = jt_new(image);
  uint5 total = 0;
  section* sections[SHN_COUNT];
  const uint5 numsections = sizeof(sections)/sizeof(section*);
  uint5 i;

  /* yucky innit. */
  sections[0]  = &img->null;
  sections[1]  = &img->shstrtab;
  sections[2]  = &img->text;
  sections[3]  = &img->data;
  sections[4]  = &img->rodata;
  sections[5]  = &img->bss;
  sections[6]  = &img->symtab;
  sections[7]  = &img->strtab;
  sections[8]  = &img->reltext;
  sections[9]  = &img->reldata;
  sections[10] = &img->relrodata;
  sections[11] = &img->relbss;

  img->symbolmap = 0;

  total += fread(&img->ehdr, sizeof(Elf32_Ehdr), 1, f) * sizeof(Elf32_Ehdr);
  
  if (img->ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
      img->ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
      img->ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
      img->ehdr.e_ident[EI_MAG3] != ELFMAG3)
  {
    fprintf(stderr, "Unrecognized file format\n");
    exit(1);
  }
  
  // read section headers
  for (i=0; i<numsections; i++)
  {
    total += fread(&sections[i]->header, sizeof(Elf32_Shdr), 1, f) *
               sizeof(Elf32_Shdr);
    fixshdr(&sections[i]->header);
  }
  
  // read section data
  for (i=0; i<numsections; i++)
  {
    total += loadsection(sections[i], f);
  }

#ifdef DEBUG  
  fprintf(stderr, "Read %d bytes total\n", total);
#endif
  
  /* fiddle symtab to make it host byte order */
  fixsymtab(img->symtab.content->buffer,
    img->symtab.content->length / sizeof(Elf32_Sym));
  
  img->used = IMAGE_UNUSED;
  img->library = inlibrary;
  
  return img;
}
Exemple #5
0
/* find global symbols defined in an object file, add to global symbol map.
   Overrides weak symbols with global symbols.
*/
void findglobals(image* in, jt_map** global)
{
  uint5 i;
  
  for (i=1; i<in->symtab.content->length/sizeof(Elf32_Sym); i++)
  {
    Elf32_Sym* sym = buffer_IDX(in->symtab.content, Elf32_Sym, i);
    char* name = symbolname(sym, &in->strtab);
    mapentry* oldmsym = jt_map_find(*global, name);
    uint5 newbinding = ELF32_ST_BIND(sym->st_info);
    
    if ((newbinding!=STB_GLOBAL && newbinding!=STB_WEAK) || 
        sym->st_shndx==SHN_UNDEF) continue;
    
    if (oldmsym)
    {
      if (!in->library)
      {
        /* We have a symbol with this name already */
        switch (oldmsym->binding)
        {
          case STB_GLOBAL:
          if (newbinding==STB_GLOBAL)
          {
            fprintf(stderr, "Multiply-defined global symbol %s\n", name);
            exit(1);
          }
          /* Else new symbol is weak, we can ignore it */
          break;

          case STB_WEAK:
          if (newbinding==STB_WEAK)
          {
            #ifdef DEBUG2
            fprintf(stderr, "Warning: multiply-defined weak symbol %s\n", name);
            #endif
          }
          else
          {
            /* Override old weak symbol */
            oldmsym->binding = STB_GLOBAL;
            oldmsym->symtabentry = i;
            oldmsym->in_image = in;
          }
          break;

          default:
          fprintf(stderr, "Non-global symbol in global symbol map? (%s)\n",
                  name);
          exit(1);
        }
      }
    }
    else
    {
      /* Generate a new global map entry */
      mapentry* msym = jt_new(mapentry);
      
      msym->name = name;
      msym->binding = newbinding;
      msym->symtabentry = i;
      msym->in_image = in;
      msym->index = -1u;
      msym->backpatches = 0;
      
      jt_map_insert(global, name, msym);
    }
  }
}
Exemple #6
0
void loadarchive(FILE* ar, program* prog, jt_clist* objects)
{
  char armagic[SARMAG];
  struct ar_hdr arheader;
  int entry = 0;
  int havesymtab = 0;
  
  fread(armagic, 1, SARMAG, ar);
  
  if (strncmp(armagic, ARMAG, SARMAG) != 0)
  {
    fprintf(stderr, "This does not look like an archive file\n");
    exit(1);
  }
  
  #ifdef DEBUG
  fprintf(stderr, "Got archive file!\n");
  #endif
  
  while (!feof(ar))
  {
    long posn = ftell(ar);
    int size;
    
    if ((posn & 1) == 1)
    {
      /* odd byte boundary, we must read another character, a newline */
      int c = fgetc(ar);
      if (c != '\n')
      {
        fprintf(stderr, "Was expecting newline padding for header\n");
        exit(1);
      }
    }
    
    /* first thing we try to read from the file this iteration: if it
     * fails, we've hit the end of the file (feof() didn't seem to work)
     */
    if (fread(&arheader, 1, sizeof(arheader), ar) != sizeof(arheader))
      break;

    if (strncmp(arheader.ar_fmag, ARFMAG, sizeof(ARFMAG)-1) != 0)
    {
      fprintf(stderr, "Bad archive header\n");
      exit(1);
    }
    
    sscanf(arheader.ar_size, "%d", &size);
    posn = ftell(ar);

    #ifdef DEBUG
    fprintf(stderr, "Good archive header, length=%d\n", size);
    #endif

    if (entry==0 && !havesymtab && arheader.ar_name[0] == '/' && 
        arheader.ar_name[1] == ' ')
    {
      archive_symtab* symtab = jt_new(archive_symtab);
      /* unnamed first entry is probably a symtab */
      if (readsymtab(ar, &arheader, symtab))
      {
        fprintf(stderr, "Error reading symbol table\n");
        exit(1);
      }
      havesymtab = 1;
      /* don't really want one of those, was just being polite */
      free(symtab->loc);
      free(symtab->name);
      free(symtab->nameidx);
      free(symtab);
    }
    else if (arheader.ar_name[0] == '/' && arheader.ar_name[1] == '/')
    {
      int posn = ftell(ar), size;
      #ifdef DEBUG
      fprintf(stderr, "Detected long filename section\n");
      #endif
      sscanf(arheader.ar_size, "%d", &size);
      fseek(ar, posn+size, SEEK_SET);
      #ifdef DEBUG
      fprintf(stderr, "Skipped %d bytes\n", size);
      #endif
    }
    else
    {
      jt_clist* newobj = jt_clist_append(objects);
      image* img;
      #ifdef DEBUG
      uint5 i;
      #endif
      /* read a file from the archive */
      
      #ifdef DEBUG
      fprintf(stderr, "Original filename: ");
      if (arheader.ar_name[0]=='/')
      {
        fprintf(stderr, "(long)\n");
      }
      else
      {
        for (i=0; i<16; i++)
        {
          if (arheader.ar_name[i]=='/') break;
          fputc(arheader.ar_name[i], stderr);
        }
        fputc('\n', stderr);
      }
      #endif
      
      newobj->data = img = loadimage(ar, 1);

      readsymbols(&img->symtab, &img->strtab, &img->symbolmap);
      
      findglobals(img, &prog->globalsymbolmap);
    }

    /* position over file */
    fseek(ar, posn+size, SEEK_SET);
    entry++;
  }
  
  #ifdef DEBUG
  fprintf(stderr, "Read library, returning...\n");
  #endif
}