//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { 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 = 0; inf.s_genflags |= INFFL_LZERO; helper.create("$ CR16"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: // ask for a processor from the config file // use it to handle ports and registers { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if (helper.supval(-1, buf, sizeof(buf)) > 0) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } break; } va_end(va); return 1; }
//-------------------------------------------------------------------------- static int notify(processor_t::idp_notify msgid, ...) { // Various messages: va_list va; va_start(va, msgid); int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::newfile: case processor_t::oldfile: tnode.create("$ tms node"); default: break; case processor_t::move_segm:// A segment is moved // Fix processor dependent address sensitive information // args: ea_t from - old segment address // segment_t - moved segment { ea_t from = va_arg(va, ea_t); segment_t *s = va_arg(va, segment_t *); asize_t size = s->size(); tnode.altshift(from, s->startEA, size); tnode.altadjust(from, s->startEA, size, skip_12); } break; } return(1); }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { 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 != 0 ) return code; switch ( msgid ) { case processor_t::init: inf.mf = 0; inf.s_genflags |= INFFL_LZERO; helper.create("$ C39"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: //Выводит длг. окно процессоров, и позволяет выбрать нужный, считывает для выбраного //процессора информацию из cfg. По считаной информации подписывает порты и регстры { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } 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: helper.create("$ z80"); break; case processor_t::newprc: { int np = va_arg(va, int); pflag = features[np]; ph.assemblers = i8085asms; if ( isZ80() ) ph.assemblers = Z80asms; if ( is64180() ) ph.assemblers = HD64180asms; if ( isGB() ) ph.assemblers = GBasms; { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } } break; case processor_t::newfile: if ( strcmp(inf.procName, "z180") == 0 ) { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_AREA); } break; default: break; } va_end(va); return(1); }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior 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; helper.create("$ fr"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: choose_device(); set_device_name(device, IORESP_ALL); break; case processor_t::oldfile: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.supset(-1, device); break; } va_end(va); return(1); }
static int idaapi notify(processor_t::idp_notify msgid, ...) { 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: helper.create("$ st20"); helper.supval(0, device, sizeof(device)); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded case processor_t::oldfile: // old file loaded load_symbols(); break; case processor_t::savebase: case processor_t::closebase: helper.supset(0, device); break; case processor_t::newprc: // new processor type procnum = va_arg(va, int); if ( isc4() ) ph.retcodes = retcodes4; break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { 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: // __emit__(0xCC); // debugger trap helper.create("$ hppa"); inf.mf = 1; // always big endian syscalls = read_ioports(&nsyscalls, "hpux.cfg", NULL, 0, NULL); break; case processor_t::term: free_ioports(syscalls, nsyscalls); break; case processor_t::newfile: // new file loaded handle_new_flags(); setup_got(); break; case processor_t::oldfile: // old file loaded idpflags = helper.altval(-1); handle_new_flags(); setup_got(); break; case processor_t::newprc: // new processor type break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment { segment_t *sptr = va_arg(va, segment_t *); sptr->defsr[ rVds-ph.regFirstSreg] = find_selector(sptr->sel); sptr->defsr[DPSEG-ph.regFirstSreg] = 0; } break; case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); case processor_t::is_basic_block_end: return is_basic_block_end() ? 2 : 0; // +++ TYPE CALLBACKS (only 32-bit programs for the moment) case processor_t::decorate_name: { const til_t *ti = va_arg(va, const til_t *); const char *name = va_arg(va, const char *); const type_t *type = va_arg(va, const type_t *); char *outbuf = va_arg(va, char *); size_t bufsize = va_arg(va, size_t); bool mangle = va_argi(va, bool); cm_t real_cc = va_argi(va, cm_t); return gen_decorate_name(ti, name, type, outbuf, bufsize, mangle, real_cc); } case processor_t::max_ptr_size: return 4+1; case processor_t::based_ptr: { /*unsigned int ptrt =*/ va_arg(va, unsigned int); char **ptrname = va_arg(va, char **); *ptrname = NULL; return 0; // returns: size of type } case processor_t::get_default_enum_size: // get default enum size // args: cm_t cm // returns: sizeof(enum) { // cm_t cm = va_arg(va, cm_t); return inf.cc.size_e; } case processor_t::calc_arglocs: { const type_t **type = va_arg(va, const type_t **); ulong *arglocs = va_arg(va, ulong *); int maxn = va_arg(va, int); return hppa_calc_arglocs(*type, arglocs, maxn); } // this callback is never used because the stack pointer does not // change for each argument // we use ph.use_arg_types instead case processor_t::use_stkarg_type: // use information about a stack argument { return false; // say failed all the time // so that the kernel attaches a comment } case processor_t::use_regarg_type: { ea_t ea = va_arg(va, ea_t); const type_t * const *types = va_arg(va, const type_t * const *); const char * const *names = va_arg(va, const char * const *); const ulong *regs = va_arg(va, const ulong *); int n = va_arg(va, int); return hppa_use_regvar_type(ea, types, names, regs, n); } case processor_t::use_arg_types: { ea_t ea = va_arg(va, ea_t); const type_t * const *types = va_arg(va, const type_t * const *); const char * const *names = va_arg(va, const char * const *); const ulong *arglocs = va_arg(va, const ulong *); int n = va_arg(va, int); const type_t **rtypes = va_arg(va, const type_t **); const char **rnames = va_arg(va, const char **); ulong *regs = va_arg(va, ulong *); int rn = va_arg(va, int); return hppa_use_arg_types(ea, types, names, arglocs, n, rtypes, rnames, regs, rn); } case processor_t::get_fastcall_regs: { const int **regs = va_arg(va, const int **); static const int fregs[] = { R26, R25, R24, R23, -1 }; *regs = fregs; return qnumber(fregs) - 1; } case processor_t::get_thiscall_regs: { const int **regs = va_arg(va, const int **); *regs = NULL; return 0; } case processor_t::calc_cdecl_purged_bytes: // calculate number of purged bytes after call { // ea_t ea = va_arg(va, ea_t); return 0; } case processor_t::get_stkarg_offset: // get offset from SP to the first stack argument // args: none // returns: the offset return -0x34; // --- TYPE CALLBACKS case processor_t::loader: break; } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { 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: helper.create("$ tms320c3x"); inf.mf = 1; // MSB first inf.wide_high_byte_first = 1; init_analyzer(); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded inf.wide_high_byte_first = 0; { segment_t *s0 = get_first_seg(); if ( s0 != NULL ) { set_segm_name(s0, "CODE"); segment_t *s1 = get_next_seg(s0->startEA); for (int i = dp; i <= rVds; i++) { SetDefaultRegisterValue(s0, i, BADSEL); SetDefaultRegisterValue(s1, i, BADSEL); } } } select_device(IORESP_ALL); break; case processor_t::oldfile: // old file loaded inf.wide_high_byte_first = 0; idpflags = (ushort)helper.altval(-1); { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags); break; case processor_t::is_basic_block_end: return is_basic_block_end() ? 2 : 0; } va_end(va); return 1; }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { 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 = 0; helper.create("$ 78k0s"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: { //функция "выбирает" из указанного файла *.cfg все записи(процессора) //и отображает их в диалоговом окне, в котором пользователь может выбрать //нужный ему процессор. После выбора имя процессора заносится в переменную device //Поумолчанию в DLG выделен процессор который указан в переменной .default //которая распологается в начале файла *.cfg inf.s_genflags |= INFFL_LZERO; char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) //Устанавливает в ядре иды имя выбранного процессора //Вычитывает все "записи"(порты) относящиеся к этому процессору //И подписывает в файле все байты вычитанные из *.cfg файла set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: // new segment { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } break; } va_end(va); return 1; }
static int idaapi notify(processor_t::idp_notify msgid, ...) { 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: // __emit__(0xCC); // debugger trap helper.create("$ h8"); helper.supval(0, device, sizeof(device)); inf.mf = 1; default: break; /* +++ START TYPEINFO CALLBACKS +++ */ // see module/{i960,hppa}/reg.cpp starting on line 253 // Decorate/undecorate a C symbol name // Arguments: // const til_t *ti - pointer to til // const char *name - name of symbol // const type_t *type - type of symbol. If NULL then it will try to guess. // char *outbuf - output buffer // size_t bufsize - size of the output buffer // bool mangle - true-mangle, false-unmangle // cm_t cc - real calling convention for VOIDARG functions // returns: true if success case processor_t::decorate_name: { const til_t *ti = va_arg(va, const til_t *); const char *name = va_arg(va, const char *); const type_t *type = va_arg(va, const type_t *); char *outbuf = va_arg(va, char *); size_t bufsize = va_arg(va, size_t); bool mangle = va_argi(va, bool); cm_t real_cc = va_argi(va, cm_t); return gen_decorate_name(ti, name, type, outbuf, bufsize, mangle, real_cc); } // Setup default type libraries (called after loading a new file into the database) // The processor module may load tils, setup memory model and perform other actions // required to set up the type system. // args: none // returns: nothing case processor_t::setup_til: { } // Purpose: get prefix and size of 'segment based' ptr type (something like // char _ss *ptr). See description in typeinf.hpp. // Other modules simply set the pointer to NULL and return 0 // Ilfak confirmed that this approach is correct for the H8. // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8. // Arguments: // unsigned int ptrt - ... // const char **ptrname - output arg // returns: size of type case processor_t::based_ptr: { /*unsigned int ptrt =*/ va_arg(va, unsigned int); char **ptrname = va_arg(va, char **); *ptrname = NULL; return 0; } // The H8 supports normal (64KB addressing, 16 bits) and advanced mode // (16MB addressing, 24 bits). However, according to the Renesas technical // documentation, certain instructions accept 32-bit pointer values where // the upper 8 bits are "reserved". Ilfak confirms that "4+1" is fine. // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8. case processor_t::max_ptr_size: { return 4+1; } // get default enum size // args: cm_t cm // returns: sizeof(enum) case processor_t::get_default_enum_size: { // cm_t cm = va_argi(va, cm_t); return inf.cc.size_e; } case processor_t::use_stkarg_type: { ea_t ea = va_arg(va, ea_t); const type_t *type = va_arg(va, const type_t *); const char *name = va_arg(va, const char *); return h8_use_stkvar_type(ea, type, name); } // calculate number of purged bytes by the given function type // For cdecl functions, 'purged bytes' is always zero // See the IDA Pro Book, 2e, at the end of pp. 107 for details // args: type_t *type - must be function type // returns: number of bytes purged from the stack + 2 case processor_t::calc_purged_bytes: { //e.g. const type_t t_int[] = { BT_INT, 0 }; //const type_t *type = va_arg(va, const type_t *); // must be BT_FUNC return 0+2; } case processor_t::calc_arglocs2: { const type_t *type = va_arg(va, const type_t *); cm_t cc = va_argi(va, cm_t); varloc_t *arglocs = va_arg(va, varloc_t *); return h8_calc_arglocs(type, cc, arglocs); } /* +++ END TYPEINFO CALLBACKS +++ */ case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: // new file loaded load_symbols(); break; case processor_t::oldfile: // old file loaded load_symbols(); break; case processor_t::closebase: case processor_t::savebase: helper.supset(0, device); break; case processor_t::newprc: // new processor type ptype = ptypes[va_arg(va, int)]; setflag(ph.flag, PR_DEFSEG32, ptype & ADV); break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { static int first_time = 1; 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: helper.create("$ intel 8051"); inf.mf = 1; // Set a big endian mode of the IDA kernel default: break; case processor_t::term: free_ioports(ports, numports); 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; inf.startIP = 0; for ( int i=0; i < qnumber(entries); i++ ) { if ( entries[i].proc > ptype ) continue; ea_t ea = inf.beginEA+entries[i].off; if ( isEnabled(ea) && get_byte(ea) != 0xFF ) { add_entry(ea, ea, entries[i].name, 1); set_cmt(ea, entries[i].cmt, 1); } } } } segment_t *scode = get_first_seg(); set_segm_class(scode, "CODE"); if ( ptype > prc_51 ) { AdditionalSegment(0x10000-256-128, 256+128, "RAM"); if ( scode != NULL ) { ea_t align = (scode->endEA + 0xFFF) & ~0xFFF; if ( getseg(align-7) == scode ) // the code segment size is { // multiple of 4K or near it uchar b0 = get_byte(align-8); // 251: // 0 : 1-source, 0-binary mode // 6,7: must be 1s // 82930: // 0 : 1-source, 0-binary mode // 7 : must be 1s // uchar b1 = get_byte(align-7); // 251 // 0: eprommap 0 - FE2000..FE4000 is mapped into 00E000..100000 // 1 - .............. is not mapped ............... // 1: must be 1 // 3: // 2: must be 1 // 4: intr 1 - upon interrupt PC,PSW are pushed into stack // 0 - upon interrupt only PC is pushed into stack // 5: must be 1 // 6: must be 1 // 7: must be 1 // 82930: // 3: must be 1 // 5: must be 1 // 6: must be 1 // 7: must be 1 // msg("b0=%x b1=%x\n", b0, b1); // if ( (b0 & 0x80) == 0x80 && (b1 & 0xEA) == 0xEA ) { // the init bits are correct char pname[sizeof(inf.procName)+1]; inf.get_proc_name(pname); char ntype = (b0 & 1) ? 's' : 'b'; char *ptr = tail(pname)-1; if ( ntype != *ptr && askyn_c(1, "HIDECANCEL\n" "The input file seems to be for the %s mode of the processor. " "Do you want to change the current processor type?", ntype == 's' ? "source" : "binary") > 0 ) { *ptr = ntype; first_time = 1; set_processor_type(pname, SETPROC_COMPAT); } } } } } // the default data segment will be INTMEM { segment_t *s = getseg(intmem); if ( s != NULL ) set_default_dataseg(s->sel); } if ( choose_ioport_device(cfgname, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); if ( get_segm_by_name("RAM") == NULL ) AdditionalSegment(256, 0, "RAM"); if ( get_segm_by_name("FSR") == NULL ) AdditionalSegment(128, 128, "FSR"); setup_data_segment_pointers(); } break; case processor_t::oldfile: setup_data_segment_pointers(); break; case processor_t::newseg: // make the default DS point to INTMEM // (8051 specific issue) { segment_t *newseg = va_arg(va, segment_t *); segment_t *intseg = getseg(intmem); if ( intseg != NULL ) newseg->defsr[rVds-ph.regFirstSreg] = intseg->sel; } break; case processor_t::newprc: { processor_subtype_t prcnum = processor_subtype_t(va_arg(va, int)); if ( !first_time && prcnum != ptype ) { warning("Sorry, it is not possible to change" // (this is 8051 specific) " the processor mode on the fly." " Please reload the input file" " if you want to change the processor."); return 0; } first_time = 0; ptype = prcnum; } break; case processor_t::newasm: // new assembler type { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::move_segm:// A segment is moved // Fix processor dependent address sensitive information // args: ea_t from - old segment address // segment_t - moved segment { // ea_t from = va_arg(va, ea_t); // segment_t *s = va_arg(va, segment_t *); // Add commands to adjust your internal variables here // Most of the time this callback will be empty // // If you keep information in a netnode's altval array, you can use // node.altshift(from, s->startEA, s->endEA - s->startEA); // // If you have a variables pointing to somewhere in the disassembled program memory, // you can adjust it like this: // // asize_t size = s->endEA - s->startEA; // if ( var >= from && var < from+size ) // var += s->startEA - from; } break; case processor_t::is_sane_insn: // is the instruction sane for the current file type? // arg: int no_crefs // 1: the instruction has no code refs to it. // ida just tries to convert unexplored bytes // to an instruction (but there is no other // reason to convert them into an instruction) // 0: the instruction is created because // of some coderef, user request or another // weighty reason. // The instruction is in 'cmd' // returns: 1-ok, <=0-no, the instruction isn't // likely to appear in the program { int no_crefs = va_arg(va, int); return is_sane_insn(no_crefs); } } va_end(va); return(1); }
static int notify(processor_t::idp_notify msgid, ...) { 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: // __emit__(0xCC); // debugger trap helper.create("$ f2mc"); { char buf[MAXSTR]; if ( helper.supval(0, buf, sizeof(buf)) > 0 ) f2mc_set_device_name(buf, IORESP_NONE); } inf.wide_high_byte_first = 1; break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded set_segm_name(get_first_seg(), "CODE"); if ( choose_ioport_device(cfgname, device, sizeof(device), parse_area_line0) ) f2mc_set_device_name(device, IORESP_ALL); for ( int i = DTB; i <= rVds; i++ ) { for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) SetDefaultRegisterValue(s, i, 0); } break; case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags); break; case processor_t::newprc: // new processor type { ptype = ptypes[va_arg(va, int)]; switch ( ptype ) { case F2MC16L: cfgname = "f2mc16l.cfg"; break; case F2MC16LX: cfgname = "f2mc16lx.cfg"; break; default: error("interr: setprc"); break; } device[0] = '\0'; if ( get_first_seg() != NULL ) choose_device(NULL, 0); } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; } va_end(va); return 1; }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior 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: helper.create("$ m7700"); if ( choose_device() ) set_device_name(device, IORESP_ALL); // Set the default segment register values : // -1 (badsel) for DR // 0 for fM and fX for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { SetDefaultRegisterValue(s, rDR, BADSEL); SetDefaultRegisterValue(s, rfM, 0); SetDefaultRegisterValue(s, rfX, 0); } info(m7700_help_message); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newprc: ptype = processor_subtype_t(va_arg(va, int)); break; case processor_t::setsgr: { ea_t ea1 = va_arg(va, ea_t); ea_t ea2 = va_arg(va, ea_t); int reg = va_arg(va, int); sel_t v = va_arg(va, sel_t); sel_t ov = va_arg(va, sel_t); if ( (reg == rfM || reg == rfX) && v != ov ) set_sreg_at_next_code(ea1, ea2, reg, ov); } break; case processor_t::oldfile: helper.create("$ m7700"); { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_ALL); } break; case processor_t::savebase: case processor_t::closebase: helper.supset(-1, device); break; } va_end(va); return(1); }
static int notify(processor_t::idp_notify msgid, ...) { 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: // __emit__(0xCC); // debugger trap helper.create("$ h8/500"); inf.mf = 1; default: break; case processor_t::term: free_syms(); break; case processor_t::oldfile: // old file loaded idpflags = ushort(helper.altval(-1) + 1); create_segment_registers(); // no break case processor_t::newfile: // new file loaded load_symbols("h8500.cfg"); inf.mf = 1; break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags - 1); break; case processor_t::newseg: // new segment { segment_t *sptr = va_arg(va, segment_t *); sptr->defsr[BR-ph.regFirstSreg] = 0; sptr->defsr[DP-ph.regFirstSreg] = 0; } break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { 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: helper.create("$ pic"); helper.supval(0, device, sizeof(device)); default: break; case processor_t::term: free_mappings(); free_ioports(ports, numports); break; case processor_t::newfile: // new file loaded { segment_t *s0 = get_first_seg(); if ( s0 != NULL ) { set_segm_name(s0, "CODE"); dataseg = AdditionalSegment(0x200, 0, "DATA"); segment_t *s1 = get_next_seg(s0->startEA); SetDefaultRegisterValue(s0, BANK, 0); SetDefaultRegisterValue(s1, BANK, 0); SetDefaultRegisterValue(s0, PCLATH, 0); SetDefaultRegisterValue(s1, PCLATH, 0); SetDefaultRegisterValue(s0, PCLATU, 0); SetDefaultRegisterValue(s1, PCLATU, 0); setup_device(IORESP_INT); apply_symbols(); } } break; case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); dataseg = helper.altval(0); create_mappings(); for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( s->defsr[PCLATH-ph.regFirstSreg] == BADSEL ) s->defsr[PCLATH-ph.regFirstSreg] = 0; } break; case processor_t::closebase: case processor_t::savebase: helper.altset(0, dataseg); helper.altset(-1, idpflags); helper.supset(0, device); break; case processor_t::newprc: // new processor type { int n = va_arg(va, int); static bool set = false; if ( set ) return 0; set = true; if ( ptypes[n] != ptype ) { ptype = ptypes[n]; ph.cnbits = 12 + 2*n; } switch ( ptype ) { case PIC12: register_names[PCLATH] = "status"; cfgname = "pic12.cfg"; break; case PIC14: cfgname = "pic14.cfg"; break; case PIC16: register_names[BANK] = "bsr"; cfgname = "pic16.cfg"; idpflags = 0; ph.cnbits = 8; ph.regLastSreg = PCLATU; break; default: error("interr in setprc"); break; } } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment 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; int retcode = 1; segment_t *sptr; static uchar first = 0; switch(msgid) { case processor_t::newseg: sptr = va_arg(va, segment_t *); sptr->defsr[rVds-ph.regFirstSreg] = find_selector(inf.start_cs); //sptr->sel; break; case processor_t::init: ovrtrans.create(ovrtrans_name); // it makes no harm to create it again default: break; case processor_t::oldfile: m.asect_top = (ushort)ovrtrans.altval(n_asect); m.ovrcallbeg = (ushort)ovrtrans.altval(n_ovrbeg); m.ovrcallend = (ushort)ovrtrans.altval(n_ovrend); if(ovrtrans.altval(n_asciiX)) ash.XlatAsciiOutput = macro11.XlatAsciiOutput = NULL; m.ovrtbl_base = (uint32)ovrtrans.altval(n_ovrbas); case processor_t::newfile: first = 1; break; case processor_t::loader: { pdp_ml_t **ml = va_arg(va, pdp_ml_t **); netnode **mn = va_arg(va, netnode **); if(ml && mn) { *ml = &m; *mn = &ovrtrans; retcode = 0; } } break; case processor_t::move_segm: // A segment is moved // Fix processor dependent address sensitive information // args: ea_t from - old segment address // segment_t - moved segment { ea_t from = va_arg(va, ea_t); segment_t *s = va_arg(va, segment_t *); ovrtrans.altshift(from, s->startEA, s->size()); // i'm not sure about this } break; } va_end(va); return(retcode); }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior 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; helper.create("$ fr"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: choose_device(); set_device_name(device, IORESP_ALL); break; case processor_t::oldfile: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.supset(-1, device); break; case processor_t::is_basic_block_end: return is_basic_block_end() ? 2 : 0; #ifdef FR_TYPEINFO_SUPPORT // +++ TYPE CALLBACKS case processor_t::max_ptr_size: return 4+1; case processor_t::get_default_enum_size: // get default enum size // args: cm_t cm // returns: sizeof(enum) { // cm_t cm = va_argi(va, cm_t); return 1; // inf.cc.size_e; } case processor_t::based_ptr: { uint ptrt = va_arg(va, unsigned int); qnotused(ptrt); char **ptrname = va_arg(va, char **); *ptrname = NULL; return 0; // returns: size of type } case processor_t::get_stkarg_offset2: // get offset from SP to the first stack argument // args: none // returns: the offset+2 return 0x00 + 2; case processor_t::calc_cdecl_purged_bytes2: // calculate number of purged bytes after call { //ea_t ea = va_arg(va, ea_t); return 0x00 + 2; } #endif // FR_TYPEINFO_SUPPORT #ifdef FR_TINFO_SUPPORT case processor_t::decorate_name3: { qstring *outbuf = va_arg(va, qstring *); const char *name = va_arg(va, const char *); bool mangle = va_argi(va, bool); cm_t cc = va_argi(va, cm_t); return gen_decorate_name3(outbuf, name, mangle, cc) ? 2 : 0; } case processor_t::calc_retloc3: //msg("calc_retloc3\n"); { const tinfo_t *type = va_arg(va, const tinfo_t *); cm_t cc = va_argi(va, cm_t); argloc_t *retloc = va_arg(va, argloc_t *); return calc_fr_retloc(*type, cc, retloc) ? 2 : -1; } break; case processor_t::calc_varglocs3: return 1; // not implemented break; case processor_t::calc_arglocs3: { //msg("calc_arglocs3\n"); func_type_data_t *fti = va_arg(va, func_type_data_t *); return calc_fr_arglocs(fti) ? 2 : -1; } case processor_t::use_stkarg_type3: { //msg("use_stkarg_type3\n"); ea_t ea = va_arg(va, ea_t); const funcarg_t *arg = va_arg(va, const funcarg_t* ); } return false; break; case processor_t::use_regarg_type3: //msg("use_regarg_type3\n"); { int *used = va_arg(va, int *); ea_t ea = va_arg(va, ea_t); const funcargvec_t *rargs = va_arg(va, const funcargvec_t *); *used = use_fr_regarg_type(ea, *rargs); return 2; } break; case processor_t::use_arg_types3: { ea_t ea = va_arg(va, ea_t); func_type_data_t *fti = va_arg(va, func_type_data_t *); funcargvec_t *rargs = va_arg(va, funcargvec_t *); use_fr_arg_types(ea, fti, rargs); return 2; } #ifdef IDA65 case processor_t::get_fastcall_regs2: case processor_t::get_varcall_regs2: { const int **regs = va_arg(va, const int **); return get_fr_fastcall_regs(regs) + 2; } case processor_t::get_thiscall_regs2: { const int **regs = va_arg(va, const int **); *regs = NULL; return 2; } #else case processor_t::get_fastcall_regs3: case processor_t::get_varcall_regs3: { const int *regs; get_fr_fastcall_regs(®s); callregs_t *callregs = va_arg(va, callregs_t *); callregs->set(ARGREGS_INDEPENDENT, regs, NULL); return callregs->nregs + 2; } case processor_t::get_thiscall_regs3: { callregs_t *callregs = va_arg(va, callregs_t *); callregs->reset(); return 2; } #endif IDA65 #endif // FR_TINFO_SUPPORT } va_end(va); return(1); }
// create the netnode helper and fetch idpflags value inline static uint32 refresh_idpflags(void) { helper.create("$ m32r"); idpflags = (uint32)helper.altval(-1); return idpflags; }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) // Various messages: { va_list va; va_start(va, msgid); // A well behaved 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; int retcode = 1; switch ( msgid ) { case processor_t::init: helper.create("$ spc700"); break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::oldfile: case processor_t::newfile: { char buf[MAXSTR]; const char *device_ptr = buf; ssize_t len = helper.hashstr("device", buf, sizeof(buf)); if ( len <= 0 ) device_ptr = "spc700"; if ( msgid == processor_t::newfile ) { set_device_name(device_ptr, IORESP_ALL); set_dsp_regs_enum(); set_default_segreg_value(NULL, rDs, 0); set_default_segreg_value(NULL, rFp, 0); } } break; case processor_t::may_be_func: retcode = 0; ea_t cref_addr; for( cref_addr = get_first_cref_to(cmd.ea); cref_addr != BADADDR; cref_addr = get_next_cref_to(cmd.ea, cref_addr) ) { uint8 opcode = get_byte(cref_addr); const struct opcode_info_t &opinfo = get_opcode_info(opcode); if ( opinfo.itype == SPC_call || opinfo.itype == SPC_jmp ) { retcode = 100; break; } } break; case processor_t::is_call_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_call ) retcode = 2; else retcode = 0; } break; case processor_t::is_ret_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_ret || opinfo.itype == SPC_reti ) retcode = 2; else retcode = 0; } break; case processor_t::is_indirect_jump: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_jmp ) { if ( opinfo.addr == ABS_IX_INDIR ) retcode = 3; else retcode = 2; } else retcode = 1; } break; default: break; } va_end(va); return retcode; }
static int notify(processor_t::idp_notify msgid, ...) { 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: helper.create("$ tms320c54"); { char buf[MAXSTR]; if ( helper.supval(0, buf, sizeof(buf)) > 0 ) set_device_name(buf); } inf.mf = 1; // MSB first break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded { { SetDefaultRegisterValue(NULL, ARMS, 0); SetDefaultRegisterValue(NULL, CPL, 1); for (int i = DP; i <= rVds; i++) SetDefaultRegisterValue(NULL, i, 0); } static const char informations[] = { "AUTOHIDE REGISTRY\n" "Default values of flags and registers:\n" "\n" "ARMS bit = 0 (DSP mode operands).\n" "CPL bit = 1 (SP direct addressing mode).\n" "DP register = 0 (Data Page register)\n" "DPH register = 0 (High part of EXTENDED Data Page Register)\n" "PDP register = 0 (Peripheral Data Page register)\n" "\n" "You can change the register values by pressing Alt-G\n" "(Edit, Segments, Change segment register value)\n" }; info(informations); break; } case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags); helper.supset(0, device); break; case processor_t::newprc: // new processor type { ptype = ptypes[va_arg(va, int)]; switch ( ptype ) { case TMS320C55: break; default: error("interr: setprc"); break; } device[0] = '\0'; load_symbols(); } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; case processor_t::get_stkvar_scale_factor: return 2; } va_end(va); return 1; }
//---------------------------------------------------------------------- static int idaapi nec850_notify(processor_t::idp_notify msgid, ...) { 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 = 0; prog_pointers.create("$ prog pointers"); break; case processor_t::is_sane_insn: { int no_crefs = va_arg(va, int); return nec850_is_sane_insn(no_crefs); } case processor_t::newprc: { int procnum = va_arg(va, int); is_v850e = procnum == 0; break; } case processor_t::term: break; // save database case processor_t::closebase: case processor_t::savebase: prog_pointers.altset(GP_EA_IDX, g_gp_ea); break; // old file loaded case processor_t::oldfile: g_gp_ea = prog_pointers.altval(GP_EA_IDX); break; case processor_t::newseg: { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } // A segment is moved //case processor_t::move_segm: // // Fix processor dependent address sensitive information // // args: ea_t from - old segment address // // segment_t - moved segment // { // ea_t from = va_arg(va, ea_t); // segment_t *s = va_arg(va, segment_t *); // // adjust gp_ea // } // break; default: break; } va_end(va); return 1; }