예제 #1
0
bool checkHeapSize(unsigned int base, unsigned int newaddr, unsigned int max) {
//msg("checkHeapSize: base: %x, newsize: %x, max: %x\n", base, newsize, max);
   if (newaddr > max) {
      return false;
   }
   segment_t *h = getseg(base);
   if (newaddr > h->endEA) {
      //need to grow our heap segment
      unsigned int newsize = ((newaddr - base) + 0xFFF) & ~0xFFF;
      set_segm_end(base, base + newsize, 0);
   }
   return true;
}
예제 #2
0
bool EmuHeap::checkHeapSize(unsigned int newsize) {
//msg("checkHeapSize: base: %x, newsize: %x, max: %x\n", base, newsize, max);
   if ((base + newsize) > max) {
      return false;
   }
   if (newsize > size) {
      //need to grow our heap segment
      segment_t *h = getseg(base);
      unsigned int newend = (newsize + 0xFFF) & ~0xFFF;  //round up to 4k boundary
      set_segm_end(base, base + newend, 0);
   }
   return true;
}
예제 #3
0
static void copy(ea_t &ea, ea_t &top)
{
  if ( sea == BADADDR )
  {
    if ( neflag & NEF_SEGS )
    {
      const char *sname = iscode ? "CODE" : "DATA";
      sel = setup_selector(0);
      add_segm(sel, ea, top, sname, sname);
    }
    sea = ea;
    eea = top;
  }
  else
  {
    if ( eea < top )
    {
      eea = top;
      set_segm_end(sea, eea, SEGMOD_KILL);
    }
  }
  mem2base(bytes, ea, top, -1);
}
예제 #4
0
//--------------------------------------------------------------------------
void idaapi load_file(linput_t *li, ushort neflag, const char * /*fileformatname*/)
{
  char line[BUFFSIZE], bigaddr = 0;
  ea_t addr, startEA = toEA(inf.baseaddr, 0), endEA = 0, seg_start = 0;
  char rstart = (inf.filetype == f_SREC) ? 'S' :
                                     ((inf.filetype == f_HEX) ? ':' : ';');
  register char *p;

  memset(&lc, 0, sizeof(local_data));
  inf.startIP = BADADDR;          // f_SREC without start record

  bool iscode = (neflag & NEF_CODE) != 0;
  int nb = iscode ? ph.cnbits : ph.dnbits;      // number of bits in a byte
  int bs = (nb + 7) / 8;                        // number of bytes
  sel_t sel = setup_selector(startEA >> 4);
  bool segment_created = false;

  bool cvt_to_bytes = false;
  if ( ph.id == PLFM_PIC )
  {
    // pic12xx and pic16xx use 12-bit and 14-bit words in program memory
    // pic18xx uses 16-bit opcodes but byte addressing
    if ( strncmp(inf.procName, "PIC18", 5) != 0 )
    {
      static const char form[] =
//      "PIC HEX file addressing mode\n"
//      "\n"
      "There are two flavors of HEX files for PIC: with word addressing\n"
      "and with byte addressing. It is not possible to recognize the\n"
      "flavor automatically. Please specify what addressing mode should\n"
      "be used to load the input file. If you don't know, try both and\n"
      "choose the one which produces the more meaningful result\n";
      int code = askbuttons_c("~B~yte addressing",
                              "~W~ord addressing",
                              "~C~ancel", 1, form);
      switch ( code )
      {
        case 1:
          break;
        case 0:
          cvt_to_bytes = true;
          break;
        default:
          loader_failure(NULL);
      }
    }
  }

  ea_t subs_addr = 0;
  for(lc.ln = 1; qlgets(p = line, BUFFSIZE, li); lc.ln++)
  {
    while ( *p == ' ' ) ++p;
    if ( *p == '\n' || *p == '\r' ) continue;
    if ( *p++ != rstart) errfmt( );

    int sz = 2;
    int mode = (inf.filetype == f_SREC) ? (uchar)*p++ : 0x100;
    lc.ptr = p;
    hexdata(0);
    if ( mode == 0x100 )
    {
      if ( !lc.len ) break;
      lc.len += 2;
      if ( inf.filetype == f_HEX )
        ++lc.len;
    }
    else
    {
      switch ( mode )
      {
        default:
            errfmt();

        case '0':
        case '5':
          continue;

        case '3':
        case '7':
          ++sz;
        case '2':
        case '8':
          ++sz;
        case '1':
        case '9':
          if ( mode > '3' ) mode = 0;
          --lc.len;
          break;
      }
    }
    addr = hexdata(sz) / bs;
    if ( !mode )
    {
      inf.startIP = addr;
      continue;
    }

    if ( inf.filetype == f_HEX )
    {
      int type = hexdata(1);      // record type
      switch ( type )
      {
        case 0xFF:                // mitsubishi hex format
        case 4:                   // Extended linear address record
          subs_addr = hexdata(2) << 16;
          break;
        case 2:                   // Extended segment address record
          subs_addr = hexdata(2) << 4;
          break;
      }
      if ( type != 0 )
      {
        if ( type == 1 )
          break;                  // end of file record
        continue;                 // not a data record
      }
    }
    addr += subs_addr / bs;
    if ( lc.len )
    {
      ea_t top = addr + lc.len / bs;
      p = line;
      while ( lc.len )
      {
        *p++ = (uchar)hexdata(1);
        if ( cvt_to_bytes ) // pic
          *p++ = '\0';
      }
      if ( top >= 0x10000l ) bigaddr = 1;
      addr += startEA;
      showAddr(addr);
      if ( (top += startEA) > endEA || !segment_created )
      {
        endEA = top;
        if ( neflag & NEF_SEGS )
        {
          if ( !segment_created )
          {
            if ( !add_segm(sel, addr, endEA, NULL, iscode ? CLASS_CODE : CLASS_DATA)) loader_failure(NULL );
            segment_created = true;
            seg_start = addr;
          }
          else
            set_segm_end(get_first_seg()->startEA, endEA, SEGMOD_KILL);
        }
      }
      if ( seg_start > addr )
      {
        set_segm_start(get_first_seg()->startEA, addr, SEGMOD_KILL);
        seg_start = addr;
      }
      mem2base(line, addr, top, -1);
    }
    {
      ushort chi;       // checksum
      ++lc.len;
      switch ( inf.filetype ) {
        case f_SREC:
          chi = (uchar)(~lc.sum);
          chi ^= (uchar)hexdata(1);
          break;
        case f_HEX:
          hexdata(1);
          chi = (uchar)lc.sum;
          break;
        default:  //MEX
          ++lc.len;
          chi = lc.sum;
          chi -= (ushort)hexdata(2);
          break;
      }
      if ( chi ) {
        static char first = 0;
        if ( !first ) {
          ++first;
          warning("Bad hex input file checksum, line %u. Ignore?", lc.ln);
        }
      }
    }
  }

  if ( (neflag & NEF_SEGS) != 0 )
  {
    if ( bigaddr )
    {
      set_segm_addressing(get_first_seg(), 1);
      if ( ph.id == PLFM_386 )
        inf.lflags |= LFLG_PC_FLAT;
    }
    set_default_dataseg(sel);
    inf.start_cs  = sel;
  }
  else
  {
    enable_flags(startEA, endEA, STT_CUR);
  }
  inf.af &= ~AF_FINAL;                    // behave as a binary file

  create_filename_cmt();
}