//--------------------------------------------------------------------------
static void declare_class(ea_t ea, const char *entryname)
{
  static const char class_name[] = "ClassStruct";
  struc_t *sptr = get_struc(get_struc_id(class_name));
  if ( sptr == NULL )
  {
    sptr = get_struc(add_struc(BADADDR, class_name));
    if ( sptr == NULL )
      return;
    opinfo_t mt;
    mt.ri.flags = REF_OFF32;
    mt.ri.target = BADADDR;
    mt.ri.base = 0;
    mt.ri.tdelta = 0;
    add_struc_member(sptr, "superClass",   BADADDR, offflag()|dwrdflag(), &mt,  4);
    add_struc_member(sptr, "masterOffset", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "methodCount",  BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "instanceSize", BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "vdRelocTable", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "relocTable",   BADADDR, wordflag(), NULL, 2);
    mt.ec.tid = get_class_struct_flags_enum();
    mt.ec.serial = 0;
    add_struc_member(sptr, "flags",        BADADDR, enumflag()|byteflag(), &mt, 1);
    add_struc_member(sptr, "masterMethods",BADADDR, byteflag(), NULL, 1);
  }
  asize_t size = get_struc_size(sptr);
  doStruct(ea, size, sptr->id);
  int count = get_word(ea+6);
//  bool c_handlers = get_byte(ea+14) & (1<<6);
  ea += size;
  ea_t messages = ea;
  doWord(ea, count*2);
  op_dec(ea, 0);
  ea += 2*count;
  doDwrd(ea, count*4);
  set_offset(ea, 0, 0);
  for ( int i=0; i < count; i++ )
  {
    ea_t idx = ea + 4*i;
    ea_t pea = toEA(get_word(idx+2), get_word(idx));
    auto_make_proc(pea);
    char name[MAXSTR];
    qsnprintf(name, sizeof(name), "%s_%u", entryname, get_word(messages+2*i));
    add_entry(pea, pea, name, true);
  }
// commented out because it doesn't work properly
// see geoplan.geo, entry number 1 for example
//  if ( c_handlers )
//    declare_parameter_types(ea+count*4, count);
}
Beispiel #2
0
static int notify(processor_t::idp_notify msgid, ...)   // Various messages
{
  va_list va;
  va_start(va, msgid);

// A well behaving processor module should call invoke_callbacks()
// in his notify() function. If this function returns 0, then
// the processor module should process the notification itself
// Otherwise the code should be returned to the caller:

  int code = invoke_callbacks(HT_IDP, msgid, va);
  if ( code ) return code;

  switch ( msgid )
  {
    case processor_t::newfile:
      {
// ig: вообще у меня теперь такая точка зрения:
//     не надо в коде задавать вид имен.
//     при желании это можно сделать в ida.cfg:
//      #ifdef __80196__
//        DUMMY_NAMES_TYPE = NM_SHORT
//      #endif

        segment_t *sptr = get_first_seg();
        if( sptr != NULL )    set_segm_class( sptr, "CODE" );

        ea_t ea, ea1;

        for( int i = 0; i < qnumber(entries); i++ )
        {
          ea = toEA( inf.baseaddr, entries[i].off );

          if( isEnabled(ea) )
          {
            switch( entries[i].type )
            {
              case I196F_BTS:
                doByte( ea, entries[i+1].off-entries[i].off );
                set_cmt( ea, entries[i].cmt, 0 );
                break;

              case I196F_CMT:
                if( entries[i].cmt )
                  add_long_cmt( ea, 1, "%s", entries[i].cmt );
                else
                  describe( ea, 1, "" );
                break;

              case I196F_OFF:
                doWord( ea, 2 );
                set_offset( ea, 0, toEA( inf.baseaddr, 0 ) );

                ea1 = toEA( inf.baseaddr, get_word( ea ) );
                auto_make_proc( ea1 );
//dash: long_cmt здесь не смотрится, так как рисуется до заголовка
//      хорошо бы поставить func_cmt, но к этому моменту функций еще нет
//      как быть?
//ig: воспользоваться простым комментарием
//    при создании функции комментарий перетащится
                set_cmt( ea1, entries[i].cmt, 1 );
            }

            set_name( ea, entries[i].name );
          }
        }

        ea = toEA( inf.baseaddr, 0x2080 );
        if( isEnabled( ea ) )
        {
          inf.beginEA = ea;
          inf.startIP = 0x2080;
        }

        segment_t s;
        s.startEA = toEA( inf.baseaddr, 0 );
        s.endEA   = toEA( inf.baseaddr, 0x400 );
        s.sel     = inf.baseaddr;
        s.type    = SEG_IMEM;                         // internal memory
// ig: лучше искать дырку не от нуля, а от базы загрузки
//      ea_t bottom = toEA( inf.baseaddr, 0 );
//      intmem    = s.startEA = freechunk( bottom, 1024, 0xF );
//      s.endEA   = s.startEA + 1024;
//      s.sel     = ushort(s.startEA >> 4);
// dash: дырку искать не пришлось, но я оставил это как пример на будущее
        add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE);

        predefined_t *ptr;
        for( ptr = iregs; ptr->name != NULL; ptr++ )
        {
          ea_t ea = toEA( inf.baseaddr, ptr->addr );
          ea_t oldea = get_name_ea( BADADDR, ptr->name );
          if( oldea != ea )
          {
            if( oldea != BADADDR )    set_name( oldea, NULL );
            do_unknown( ea, DOUNK_EXPAND );
            set_name( ea, ptr->name );
          }
          if( ptr->cmt != NULL )      set_cmt( ea, ptr->cmt, 1 );
        }
      }
//      do16bit( 0x18, 2 );           // SP always word
      break;

    case processor_t::oldfile:
      for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
      {
        if ( getSRarea(s->startEA) == NULL )
        {
          segreg_t sr;
          sr.startEA = s->startEA;
          sr.endEA   = s->endEA;
          sr.reg(WSR)  = 0;
          sr.reg(WSR1) = 0;
          sr.reg(rVds) = inf.baseaddr;
          sr.settags(SR_autostart);
          SRareas.create_area(&sr);
        }
      }
      break;

    case processor_t::newseg:
                      // default DS is equal to Base Address
      (va_arg(va, segment_t *))->defsr[rVds-ph.regFirstSreg] = inf.baseaddr;
      break;

    case processor_t::newprc:
      extended = va_arg(va,int) != 0;
      if ( !extended )
        ph.flag &= ~PR_SEGS;
      else
        ph.flag |= PR_SEGS;
    default:
      break;
  }
  va_end(va);

  return(1);
}
Beispiel #3
0
static int notify(processor_t::idp_notify msgid, ...) { // Various messages:
  va_list va;
  va_start(va, msgid);

// A well behaving processor module should call invoke_callbacks()
// in his notify() function. If this function returns 0, then
// the processor module should process the notification itself
// Otherwise the code should be returned to the caller:

  int code = invoke_callbacks(HT_IDP, msgid, va);
  if ( code ) return code;


  switch(msgid)
  {
    case processor_t::init:
      inf.mf = 1;                                 // MSB first
    default:
      break;

    case processor_t::newfile:
      {

        segment_t *sptr = get_first_seg();
        if( sptr != NULL )
        {
          if( sptr->startEA - get_segm_base( sptr ) == 0 )
          {
            inf.beginEA = sptr->startEA + 0xC;
            inf.startIP = 0xC;

            for( int i = 0; i < qnumber(entries); i++ )
            {
              ea_t ea = sptr->startEA + entries[i].off;
              if( isEnabled(ea) )
              {
                doWord( ea, 2 );
// ig: set_op_type - внутренняя функция, ее нельзя использовать
//                set_op_type( ea, offflag(), 0 );
                set_offset( ea, 0, sptr->startEA );
                ea_t ea1 = sptr->startEA + get_word( ea );
                auto_make_proc( ea1 );
                set_name( ea, entries[i].name );
// ig: так получше будет?
                set_cmt( sptr->startEA+get_word(ea), entries[i].cmt, 1 );
              }
            }
          }

          set_segm_class( sptr, "CODE" );
        }

        segment_t s;
        ea_t bottom = toEA( inf.baseaddr, 0 );
        intmem       = s.startEA = freechunk( bottom, 256, 0xF );
        s.endEA      = s.startEA + 256;
        s.sel        = allocate_selector( s.startEA >> 4 );
        s.type       = SEG_IMEM;                    // internal memory
        add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE);

        const predefined_t *ptr;
        for( ptr = iregs; ptr->name != NULL; ptr++ )
        {
          ea_t ea = intmem + ptr->addr;
          ea_t oldea = get_name_ea( BADADDR, ptr->name );
          if( oldea != ea )
          {
            if( oldea != BADADDR )    set_name( oldea, NULL );
            do_unknown( ea, DOUNK_EXPAND );
            set_name( ea, ptr->name );
          }
          if( ptr->cmt != NULL )      set_cmt( ea, ptr->cmt, 1 );
        }
      }
      break;

    case processor_t::oldfile:
      sel_t sel;
      if( atos( "INTMEM", &sel) ) intmem = specialSeg(sel);
      break;

    case processor_t::newseg:
      {                 // default DS is equal to CS
        segment_t *sptr = va_arg(va, segment_t *);
        sptr->defsr[rVds-ph.regFirstSreg] = sptr->sel;
      }
  }
  va_end(va);

  return(1);
}
Beispiel #4
0
void find_bios_funcs()
{
	ea_t i;
	make_ascii_string(0x06000200, 16, ASCSTR_C);
	doByte(0x06000210, 36);
	make_vector(0x06000234, NULL);
	make_vector(0x06000238, NULL);
	make_vector(0x0600023C, NULL);
	make_ascii_string(0x06000240, 4, ASCSTR_C);
	make_ascii_string(0x06000244, 4, ASCSTR_C);
	doDwrd(0x06000248, 4);
	doDwrd(0x0600024C, 4);
	make_vector(0x06000250, NULL);
	doDwrd(0x06000264, 4);
	make_vector(0x06000268, NULL);
	make_vector(0x0600026C, "bios_run_cd_player");
	make_vector(0x06000270, NULL);
	make_vector(0x06000274, "bios_is_mpeg_card_present");
	doDwrd(0x06000278, 4);
	doDwrd(0x0600027C, 4);
	make_vector(0x06000280, NULL);
	make_vector(0x06000284, NULL);
	make_vector(0x06000288, NULL);
	make_vector(0x0600028C, NULL);
	doDwrd(0x06000290, 4);
	doDwrd(0x06000294, 4);
	make_vector(0x06000298, "bios_get_mpeg_rom");
	make_vector(0x0600029C, NULL);
	doDwrd(0x060002A0, 4);
	doDwrd(0x060002A4, 4);
	doDwrd(0x060002A8, 4);
	doDwrd(0x060002AC, 4);
	make_vector(0x060002B0, NULL);
	doDwrd(0x060002B4, 4);
	doDwrd(0x060002B8, 4);
	doDwrd(0x060002BC, 4);
	doDwrd(0x060002C0, 4);
	for (i = 0x060002C4; i < 0x06000324; i+=4)
		make_vector(i, NULL);
	set_name(0x06000300, "bios_set_scu_interrupt");
	set_name(0x06000304, "bios_get_scu_interrupt");
	set_name(0x06000310, "bios_set_sh2_interrupt");
	set_name(0x06000314, "bios_get_sh2_interrupt");
	set_name(0x06000320, "bios_set_clock_speed");
	doDwrd(0x06000324, 4);
	set_name(0x06000324, "bios_get_clock_speed");
	for (i = 0x06000328; i < 0x06000348; i+=4)
		make_vector(i, NULL);
	set_name(0x06000340, "bios_set_scu_interrupt_mask");
	set_name(0x06000344, "bios_change_scu_interrupt_mask");
	doDwrd(0x06000348, 4);
	set_name(0x06000348, "bios_get_scu_interrupt_mask");
	make_vector(0x0600034C, NULL);
	doDwrd(0x06000350, 4);
	doDwrd(0x06000354, 4);
	doDwrd(0x06000358, 4);
	doDwrd(0x0600035C, 4);
	for (i = 0x06000360; i < 0x06000380; i+=4)
		make_vector(i, NULL);
	doByte(0x06000380, 16);
	doWord(0x06000390, 16);
	doDwrd(0x060003A0, 32);
	make_ascii_string(0x060003C0, 0x40, ASCSTR_C);
	add_func(0x06000600, BADADDR);
	add_func(0x06000646, BADADDR);
	make_ascii_string(0x0600065C, 0x4, ASCSTR_C);
	add_func(0x06000678, BADADDR);
	add_func(0x0600067C, BADADDR);
	add_func(0x06000690, BADADDR);
	doDwrd(0x06000A80, 0x80);
}
Beispiel #5
0
//------------------------------------------------------------------
static const char *idaapi standard_callback(const ioport_t *, size_t, const char *line)
{
  char word[MAXSTR];
  ea_t ea1;
  int len;
  if ( sscanf(line, "interrupt %s %" FMT_EA "i%n", word, &ea1, &len) == 2 )
  {
    if ( (respect_info & IORESP_INT) != 0 )
    {
      ea_t proc, wrong;
      segment_t *s = getseg(ea1);
      if ( s != NULL && s->use32() )
      {
        doDwrd(ea1, 4);
        proc = get_long(ea1);
        wrong = 0xFFFFFFFF;
      }
      else
      {
        doWord(ea1, 2);
        proc = get_word(ea1);
        wrong = 0xFFFF;
      }
      if ( proc != wrong && isEnabled(proc) )
      {
        set_offset(ea1, 0, 0);
        add_entry(proc, proc, word, true);
      }
      else
      {
        set_name(ea1, word);
      }
      const char *ptr = &line[len];
      ptr = skipSpaces(ptr);
      if ( ptr[0] != '\0' )
        set_cmt(ea1, ptr, true);
    }
    return NULL;
  }
  if ( sscanf(line, "entry %s %" FMT_EA "i%n", word, &ea1, &len) == 2 )
  {
    if ( (respect_info & IORESP_INT) != 0 )
    {
      if ( isEnabled(ea1) )
      {
        const char *ptr = &line[len];
        ptr = skipSpaces(ptr);
#ifdef ENTRY_PROCESSING
        if ( !ENTRY_PROCESSING(ea1, word, ptr) )
#endif
        {
          add_entry(ea1, ea1, word, true);
          if ( ptr[0] != '\0' )
            set_cmt(ea1, ptr, true);
        }
      }
    }
    return NULL;
  }
  return parse_area_line(line, deviceparams, sizeof(deviceparams));
}