//-------------------------------------------------------------------------- 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); }
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); }
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); }
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); }
//------------------------------------------------------------------ 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)); }