Exemple #1
0
//--------------------------------------------------------------------------
static ea_t get_segea(const GEOSappheader &ah, const ulong *segea, ushort s)
{
  if ( s >= ah.numseg )
  {
    ask_for_feedback("Bad segment number %d", s);
    return BADADDR;
  }
  return segea[s] == ulong(BADADDR) ? BADADDR : segea[s];
}
Exemple #2
0
//------------------------------------------------------------------------
inline bool pe64_to_pe(peheader_t &pe, const peheader64_t &pe64, bool silent)
{
    bool ok = true;
    switch ( pe64.magic )
    {
    default:
        if ( !silent )
        {
            ask_for_feedback("The input file has non-standard magic number (%x)",
                             pe64.magic);
        }
        ok = false;
    /* no break */
    case MAGIC_P32:
    case MAGIC_ROM:
        memcpy(&pe, &pe64, sizeof(pe));
        break;
    case MAGIC_P32_PLUS:
        memcpy(&pe, &pe64, offsetof(peheader_t, stackres));
        memcpy(&pe.loaderflags, &pe64.loaderflags,
               sizeof(pe) - qoffsetof(peheader_t, loaderflags));
        pe.stackres  = low(pe64.stackres);
        pe.stackcom  = low(pe64.stackcom);
        pe.heapres   = low(pe64.heapres);
        pe.heapcom   = low(pe64.heapcom);
        break;
    }
    // do various checks
    if ( !pe.is_efi()
            && (pe.objalign < pe.filealign
                || pe.filealign !=0 && (pe.filealign & (pe.filealign-1) ) != 0   // check for power of 2
                || pe.objalign  !=0 && (pe.objalign  & (pe.objalign -1) ) != 0) ) // check for power of 2
    {
        if ( !silent )
            pe_failure("Invalid file: bad alignment value specified (section alignment: %08X, file alignment: %08X)", pe.objalign, pe.filealign);
    }
    if ( pe.imagesize > 0x77000000 || pe.imagesize < pe.allhdrsize )
    {
        if ( !silent )
            pe_failure("Invalid file: bad ImageSize value %x", pe.imagesize);
    }
    if ( pe.nrvas && pe.nrvas < total_rvatab_count )
        memset(&pe.expdir+pe.nrvas, 0, total_rvatab_size-pe.nrvas*sizeof(petab_t));
    return ok;
}
Exemple #3
0
//-----------------------------------------------------------------------
static void read_fixup(linput_t *li)
{
  fixup fix;
  const int size = offsetof(fixup, fixups);
  lread(li, &fix, size);
  uint32 fptr = qltell(li);
  ea_t sea = getsea(fix.where_IN);
  if ( sea != BADADDR )
  {
    uchar *b = qnewarray(uchar, fix.length);
    if ( b == NULL ) nomem("read_fixup");
    lread(li, b, fix.length);

//    show_hex(b, fix.length, "\nFIXUP SEG %04X, %04X BYTES, KIND %02X\n",
//                  fix.where_IN,
//                  fix.length,
//                  b[0]);

    const uchar *ptr = b;
    const uchar *end = b + fix.length;
    while ( ptr < end )
    {
      fixup_data_t fd;
      uint32 where_offset = 0;
      uint32 what_offset = 0;
      ushort what_in = 9;
      bool selfrel = false;
      bool isfar = false;
      fd.type = FIXUP_OFF32;
      switch ( *ptr++ )
      {
        case 0x2C:      // GEN
          isfar = true;
          ask_for_feedback("Untested relocation type");
        case 0x24:      // GEN
          where_offset = readdw(ptr, false);
          what_offset = readdw(ptr, false);
          what_in = (ushort)readdw(ptr, false);
          break;
        case 0x2D:
          isfar = true;
        case 0x25:      // INTRA
          where_offset = readdw(ptr, false);
          what_offset = readdw(ptr, false);
          what_in = fix.where_IN;
          break;
        case 0x2A:      // CALL
          where_offset = readdw(ptr, false);
          what_offset = 0;
          what_in = (ushort)readdw(ptr, false);
          selfrel = true;
          break;
        case 0x2E:      // OFF32?
          isfar = true;
        case 0x26:
          where_offset = readdw(ptr, false);
          what_offset = 0;
          what_in = (ushort)readdw(ptr, false);
          break;
        default:
          ask_for_feedback("Unknown relocation type %02X", ptr[-1]);
          add_pgm_cmt("!!! Unknown relocation type %02X", ptr[-1]);
          break;
      }
      ea_t source = sea + where_offset;
      ea_t target = BADADDR;
      switch ( what_in >> 12 )
      {
        case 0x02:      // segments
          target = getsea(what_in);
          break;
        case 0x06:      // externs
          target = xea + 4 * ((what_in & 0xFFF) - 1);
          fd.type |= FIXUP_EXTDEF;
          break;
        default:
          ask_for_feedback("Unknown relocation target %04X", what_in);
          add_pgm_cmt("!!! Unknown relocation target %04X", what_in);
          break;
      }
      segment_t *ts = getseg(target);
      fd.sel = ts ? (ushort)ts->sel : 0;
      if ( (fd.type & FIXUP_EXTDEF) == 0 )
      {
        target += what_offset;
        what_offset = 0;
      }
      fd.off = target;
      fd.displacement = what_offset;
      target += what_offset;
      if ( selfrel )
      {
        fd.type |= FIXUP_SELFREL;
        target -= source + 4;
      }
      set_fixup(source, &fd);
      put_long(source, target);
      if ( isfar )
      {
        fd.type = FIXUP_SEG16;
        set_fixup(source+4, &fd);
        put_word(source+4, fd.sel);
      }
    }
    qfree(b);
  }