Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}