Exemple #1
0
//------------------------------------------------------------------
static const char *idaapi parse_area_line(const char *line, char *buf, size_t bufsize)
{
  char word[MAXSTR];
  char aclass[MAXSTR];
  ea_t ea1, ea2;
  if ( sscanf(line, "area %s %s %" FMT_EA "i:%" FMT_EA "i", aclass, word, &ea1, &ea2) == 4 )
  {
    int ram = 0;
    int rom = 0;
    int eprom = 0;
    int eeprom = 0;
    static const char format[] = "RAM=%d ROM=%d EPROM=%d " CUSTOM1 "=%d";
    sscanf(buf, format, &ram, &rom, &eprom, &eeprom);
    int size = ea2 - ea1;
         if ( stristr(word, "RAM")    != NULL ) ram    += size;
    else if ( stristr(word, CUSTOM1)  != NULL ) eeprom += size;
    else if ( stristr(word, "EPROM")  != NULL ) eprom  += size;
    else if ( stristr(word, "ROM")    != NULL ) rom    += size;
    if ( ram || rom || eeprom || eeprom )
      qsnprintf(buf, bufsize, format, ram, rom, eprom, eeprom);
    else
      buf[0] = '\0';
    if ( (respect_info & IORESP_AREA) != 0 && get_segm_qty() != 0 )
    {
#ifdef I8051
      if ( ( stristr(word, "FSR") != NULL ) ||( stristr(word, "RAM") != NULL ))
      {
        AdditionalSegment( ea2-ea1, ea1, word );
      }
      else
#endif
      {
        sel_t sel = allocate_selector(0);
        add_segm(sel, ea1, ea2, word, aclass);
      }
      if ( ea2-ea1 > 0xFFFF )
        set_segm_addressing(getseg(ea1), true);
    }
    return NULL;
  }
  return "syntax error";
}
Exemple #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:
      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;
}
Exemple #3
0
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);
}