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