update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

View File

@@ -0,0 +1,650 @@
// $Id: ana.cpp,v 1.13 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// TMS320C1X Processor module
// Instruction decode.
//
#include "../idaidp.hpp"
#include "tms320c1.hpp"
#include "ins.hpp"
#include "reg.hpp"
//
// After determining an instruction's opcode, ana() calls one of the
// functions below to decode its operands.
//
static int ana_di(insn_t &insn, uint16); // direct/indirect instruction
static int ana_di_shift(insn_t &insn, uint16); // direct/indirect w/ shift instruction
static int ana_di_port(insn_t &insn, uint16); // direct/indirect to/from I/O port
static int ana_di_aux(insn_t &insn, uint16); // direct/indirect to AR register
static int ana_imm_1(insn_t &insn, uint16); // immediate 1 bit
static int ana_imm_8(insn_t &insn, uint16); // immediate 8 bits
static int ana_imm_13(insn_t &insn, uint16); // immediate 13 bits
static int ana_imm_8_aux(insn_t &insn, uint16); // immediate 8 bits into AR register
static int ana_flow(insn_t &insn); // flow control
inline int ana_empty(const insn_t &insn); // no operands
//
// These functions in turn may call one of the functions below to help
// decode the individual operands within the instruction.
//
static int ana_op_di(const insn_t &insn, op_t &, op_t &, uint16); // direct/indirect operand
static int ana_op_narp(const insn_t &insn, op_t &, uint16); // new ARP operand
//
// Due to limitations that IDA's some of IDA's helper functions have,
// they don't work well with processors whose byte size is greater
// than 8 bits. (This processor has a 16-bit byte). Therefore we
// have to make our own replacements for these functions.
//
// Simulates the effect of the IDA kernel helper function insn.get_next_byte(),
// but works with our 16-bit byte environment.
//
static uint16 tms320c1x_get_next_insn_byte(insn_t &insn)
{
//
// Fetch a 16 bit value from the (global) current instruction decode
// pointer.
//
uint16 value = get_wide_byte(insn.ea+insn.size);
//
// Increment the size of the current instruction, to reflect the fact
// that it contains the byte that we just read.
//
insn.size++;
return value;
}
//lint -esym(714,ana)
int idaapi ana(insn_t *_insn)
{
insn_t &insn = *_insn;
//
// Fetch the first 16 bits of the instruction.
// (All instructions are at least 16 bits long).
//
uint16 opcode = tms320c1x_get_next_insn_byte(insn);
//
// Decode the instruction in the opcode by sifting through the
// various instruction bit masks.
//
//
// 3-bit mask instructions:
// MPYK
//
switch ( opcode & ISN_3_BIT_MASK )
{
case ISN3_MPYK : insn.itype = I_MPYK; return ana_imm_13(insn, opcode);
}
//
// 4-bit mask instructions:
// ADD, LAC, SUB
//
switch ( opcode & ISN_4_BIT_MASK )
{
case ISN4_ADD : insn.itype = I_ADD; return ana_di_shift(insn, opcode);
case ISN4_LAC : insn.itype = I_LAC; return ana_di_shift(insn, opcode);
case ISN4_SUB : insn.itype = I_SUB; return ana_di_shift(insn, opcode);
}
//
// 5-bit mask instructions:
// SACH, IN, OUT
//
switch ( opcode & ISN_5_BIT_MASK )
{
case ISN5_SACH : insn.itype = I_SACH; return ana_di(insn, opcode);
case ISN5_IN : insn.itype = I_IN; return ana_di_port(insn, opcode);
case ISN5_OUT : insn.itype = I_OUT; return ana_di_port(insn, opcode);
}
//
// 7-bit mask instructions:
// LAR, LARK, SAR
//
switch ( opcode & ISN_7_BIT_MASK )
{
case ISN7_LAR : insn.itype = I_LAR; return ana_di_aux(insn, opcode);
case ISN7_LARK : insn.itype = I_LARK; return ana_imm_8_aux(insn, opcode);
case ISN7_SAR : insn.itype = I_SAR; return ana_di_aux(insn, opcode);
}
//
// 8-bit mask instructions:
// ADDH, ADDS, AND, LACK, OR, SACL, SUBC, SUBH, XOR, ZALH, LDP, MAR,
// LT, LTA, LTD, MPY, LST, SST, DMOV, TBLR, TBLW
//
switch ( opcode & ISN_8_BIT_MASK )
{
case ISN8_ADDH : insn.itype = I_ADDH; return ana_di(insn, opcode);
case ISN8_ADDS : insn.itype = I_ADDS; return ana_di(insn, opcode);
case ISN8_AND : insn.itype = I_AND; return ana_di(insn, opcode);
case ISN8_LACK : insn.itype = I_LACK; return ana_imm_8(insn, opcode);
case ISN8_OR : insn.itype = I_OR; return ana_di(insn, opcode);
case ISN8_SACL : insn.itype = I_SACL; return ana_di(insn, opcode);
case ISN8_SUBC : insn.itype = I_SUBC; return ana_di(insn, opcode);
case ISN8_SUBH : insn.itype = I_SUBH; return ana_di(insn, opcode);
case ISN8_SUBS : insn.itype = I_SUBS; return ana_di(insn, opcode);
case ISN8_XOR : insn.itype = I_XOR; return ana_di(insn, opcode);
case ISN8_ZALH : insn.itype = I_ZALH; return ana_di(insn, opcode);
case ISN8_ZALS : insn.itype = I_ZALS; return ana_di(insn, opcode);
case ISN8_LDP : insn.itype = I_LDP; return ana_di(insn, opcode);
case ISN8_MAR : insn.itype = I_MAR; return ana_di(insn, opcode);
case ISN8_LT : insn.itype = I_LT; return ana_di(insn, opcode);
case ISN8_LTA : insn.itype = I_LTA; return ana_di(insn, opcode);
case ISN8_LTD : insn.itype = I_LTD; return ana_di(insn, opcode);
case ISN8_MPY : insn.itype = I_MPY; return ana_di(insn, opcode);
case ISN8_LST : insn.itype = I_LST; return ana_di(insn, opcode);
case ISN8_SST : insn.itype = I_SST; return ana_di(insn, opcode);
case ISN8_DMOV : insn.itype = I_DMOV; return ana_di(insn, opcode);
case ISN8_TBLR : insn.itype = I_TBLR; return ana_di(insn, opcode);
case ISN8_TBLW : insn.itype = I_TBLW; return ana_di(insn, opcode);
}
//
// 15-bit mask instructions:
// LARP, LDPK
//
switch ( opcode & ISN_15_BIT_MASK )
{
// LARP is a synonym for a special case of MAR
// case ISN15_LARP: insn.itype = I_LARP; return ana_ar(opcode);
case ISN15_LDPK: insn.itype = I_LDPK; return ana_imm_1(insn, opcode);
}
//
// 16-bit mask instructions:
// ABS, ZAC, APAC, PAC, SPAC, B, BANZ, BGEZ, BGZ, BIOZ, BLEZ, BLZ,
// BNZ, BV, BZ, CALA, CALL, RET, DINT, EINT, NOP, POP, PUSH, ROVM,
// SOVM
//
switch ( opcode & ISN_16_BIT_MASK )
{
case ISN16_ABS: insn.itype = I_ABS; return ana_empty(insn);
case ISN16_ZAC: insn.itype = I_ZAC; return ana_empty(insn);
case ISN16_APAC: insn.itype = I_APAC; return ana_empty(insn);
case ISN16_PAC: insn.itype = I_PAC; return ana_empty(insn);
case ISN16_SPAC: insn.itype = I_SPAC; return ana_empty(insn);
case ISN16_B: insn.itype = I_B; return ana_flow(insn);
case ISN16_BANZ: insn.itype = I_BANZ; return ana_flow(insn);
case ISN16_BGEZ: insn.itype = I_BGEZ; return ana_flow(insn);
case ISN16_BGZ: insn.itype = I_BGZ; return ana_flow(insn);
case ISN16_BIOZ: insn.itype = I_BIOZ; return ana_flow(insn);
case ISN16_BLEZ: insn.itype = I_BLEZ; return ana_flow(insn);
case ISN16_BLZ: insn.itype = I_BLZ; return ana_flow(insn);
case ISN16_BNZ: insn.itype = I_BNZ; return ana_flow(insn);
case ISN16_BV: insn.itype = I_BV; return ana_flow(insn);
case ISN16_BZ: insn.itype = I_BZ; return ana_flow(insn);
case ISN16_CALA: insn.itype = I_CALA; return ana_empty(insn);
case ISN16_CALL: insn.itype = I_CALL; return ana_flow(insn);
case ISN16_RET: insn.itype = I_RET; return ana_empty(insn);
case ISN16_DINT: insn.itype = I_DINT; return ana_empty(insn);
case ISN16_EINT: insn.itype = I_EINT; return ana_empty(insn);
case ISN16_NOP: insn.itype = I_NOP; return ana_empty(insn);
case ISN16_POP: insn.itype = I_POP; return ana_empty(insn);
case ISN16_PUSH: insn.itype = I_PUSH; return ana_empty(insn);
case ISN16_ROVM: insn.itype = I_ROVM; return ana_empty(insn);
case ISN16_SOVM: insn.itype = I_SOVM; return ana_empty(insn);
}
//
// If control reaches this point, then the opcode does not represent
// any known instruction.
//
return 0;
}
//
// ana_empty()
//
// Called to decode an 'empty' instruction's operands.
// (Very trivial, because an empty instruction has no operands).
//
inline int ana_empty(const insn_t &insn)
{
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_flow()
//
// Called to decode a flow control instruction's operands.
// Decodes the branch address of the instruction.
//
// (Some flow control instructions have no arguments and are thus
// decoded by calling ana_empty()).
//
static int ana_flow(insn_t &insn)
{
//
// Fetch the next 16 bits from the instruction; they
// constitute the branch address.
//
uint16 addr = tms320c1x_get_next_insn_byte(insn);
//
// Fill in the insn structure to reflect the first (and only)
// operand of this instruction as being a reference to the CODE segment.
//
insn.Op1.type = o_near;
insn.Op1.addr = addr;
//
// Set the operand type to reflect the size of the address
// in the instruction. Technically this instructions address
// value is one processor byte (16 bits), but when it comes to defining
// operand value sizes, IDA thinks in terms of 8-bit bytes.
// Therefore, we specify this value as a word.
//
insn.Op1.dtype = dt_word;
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_di(opcode)
//
// Called to decode a direct/indirect memory reference instruction's
// operands.
//
static int ana_di(insn_t &insn, uint16 opcode)
{
//
// Decode the direct or indirect memory reference made
// by the instruction as its first operand and the new arp value
// (if it exists) as its second operand.
//
if ( ana_op_di(insn, insn.Op1, insn.Op2, opcode) == 0 )
{
//
// The operand was invalid.
//
return 0;
}
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_di_shift(opcode)
//
// Called to decode a direct/indirect memory reference plus shift
// instruction's operands.
//
static int ana_di_shift(insn_t &insn, uint16 opcode)
{
//
// First, decode the direct or indirect memory reference made
// by the instruction as its first operand, and the new arp
// value (if it exists) as its third operand.
//
if ( ana_op_di(insn, insn.Op1, insn.Op3, opcode) == 0 )
{
//
// The operand was invalid.
//
return 0;
}
//
// Finally, decode the shift value as the instruction's second operand.
//
insn.Op2.type = o_imm;
insn.Op2.value = ISN_SHIFT(opcode);
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_di_port(opcode)
//
// Called to decode a direct/indirect memory reference to/from I/O port
// instruction's operands.
//
static int ana_di_port(insn_t &insn, uint16 opcode)
{
//
// First, decode the direct or indirect memory reference made
// by the instruction as its first operand and the new arp value
// (if it exists) as its third operand.
//
if ( ana_op_di(insn, insn.Op1, insn.Op3, opcode) == 0 )
{
//
// The operand was invalid.
//
return 0;
}
//
// Next, decode the port number as the instruction's second operand.
//
insn.Op2.type = o_imm;
insn.Op2.value = ISN_PORT(opcode);
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_di_aux(opcode)
//
// Called to decode a direct/indirect memory reference to/from auxiliary
// register instruction's operands.
//
static int ana_di_aux(insn_t &insn, uint16 opcode)
{
//
// First, decode the auxiliary register number as the instruction's
// first operand.
//
insn.Op1.type = o_reg;
insn.Op1.reg = (ISN_AUX_AR(opcode) ? IREG_AR1 : IREG_AR0);
//
// Finally, decode the direct or indirect memory reference made
// by the instruction as its second operand and the new arp
// value (if it exists) as its third operand.
//
if ( ana_op_di(insn, insn.Op2, insn.Op3, opcode) == 0 )
{
//
// The operand was invalid.
//
return 0;
}
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_imm_1(opcode)
//
// Called to decode a 1 bit immediate value instruction's operands.
//
static int ana_imm_1(insn_t &insn, uint16 opcode)
{
//
// Decode the 1 bit immediate value in this instruction's opcode
// and make an immediate value operand out of it.
//
insn.Op1.type = o_imm;
insn.Op1.value = ISN_IMM1(opcode);
insn.Op1.dtype = dt_byte; // This means an 8 bit value, rather than 16.
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_imm_8(opcode)
//
// Called to decode an 8 bit immediate value instruction's operands.
//
static int ana_imm_8(insn_t &insn, uint16 opcode)
{
//
// Decode the 8 bit immediate value in this instruction's opcode
// and make an immediate value operand out of it.
//
insn.Op1.type = o_imm;
insn.Op1.value = ISN_IMM8(opcode);
insn.Op1.dtype = dt_byte; // This means an 8 bit value, rather than 16.
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_imm_13(opcode)
//
// Called to decode a 13 bit immediate value instruction's operands.
//
static int ana_imm_13(insn_t &insn, uint16 opcode)
{
//
// Decode the 13 bit immediate value in this instruction's opcode
// and make an immediate value operand out of it.
//
insn.Op1.type = o_imm;
insn.Op1.value = ISN_IMM13(opcode);
insn.Op1.dtype = dt_word; // This means an 8 bit value, rather than 16.
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_imm_8_aux(opcode)
//
// Called upon to decode an immediate 8 bit to aux register instruction's
// operands.
//
static int ana_imm_8_aux(insn_t &insn, uint16 opcode)
{
//
// Decode the AR bit of the instruction to determine which auxiliary
// register is being loaded. Make this register the first operand.
//
insn.Op1.type = o_reg;
insn.Op1.reg = (ISN_AUX_AR(opcode) ? IREG_AR1 : IREG_AR0);
//
// Next, decode the 8 bit immediate value in the instruction and
// make it the second operand.
//
insn.Op2.type = o_imm;
insn.Op2.value = ISN_IMM8(opcode);
insn.Op2.dtype = dt_word; // This means an 8 bit value, rather than 16.
//
// Successful decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_op_di(addr_op, narp_op, opcode)
//
// Decodes the direct or indirect memory reference made in the instruction
// contained in 'opcode' and places the decoded information into the operand
// address operand 'operand' and the new ARP operand 'narp_op'.
//
// Returns instruction size on successful decode, 0 on illegal condition.
//
static int ana_op_di(const insn_t &insn, op_t &addr_op, op_t &narp_op, uint16 opcode)
{
//
// Check the direct/indirect bit. This determines whether the
// opcode makes a direct memory reference via an immediate value,
// or an indirect memory reference via the current auxiliary
// register.
//
if ( ISN_DIRECT(opcode) )
{
//
// The direct bit is set. This instruction makes a direct
// memory reference to the memory location specified in its
// immediate operand.
//
addr_op.type = o_mem;
addr_op.dtype = dt_byte; // This means an 8 bit value, rather than 16.
addr_op.addr = ISN_DIR_ADDR(opcode);
}
else
{
//
// The direct bit is reset. This instruction makes an
// indirect memory reference.
//
// Determine whether this is an AR post-increment,
// post-decrement, or no change reference.
//
if ( ISN_INDIR_INCR(opcode) && ISN_INDIR_DECR(opcode) )
{
//
// Both the AR increment and AR decrement flags are
// set. This is an illegal instruction.
//
return 0;
}
else if ( ISN_INDIR_INCR(opcode) )
{
//
// The AR increment flag is set.
// This is an AR increment reference.
//
addr_op.type = o_phrase;
addr_op.phrase = IPH_AR_INCR;
}
else if ( ISN_INDIR_DECR(opcode) )
{
//
// The AR decrement flag is set.
// This is an AR decrement reference.
//
addr_op.type = o_phrase;
addr_op.phrase = IPH_AR_DECR;
}
else
{
//
// Neither the AR auto-increment or auto-decrement
// flags is set. That makes this a regular AR
// indirect reference.
//
addr_op.type = o_phrase;
addr_op.phrase = IPH_AR;
}
//
// Next, decode the auxiliary register pointer change command,
// if present, as the instruction's second operand. If no
// change is requested in this instruction, then the second operand
// will not be filled in.
//
if ( ana_op_narp(insn, narp_op, opcode) == 0 )
{
//
// The operand was invalid.
//
return 0;
}
}
//
// Successful operand decode.
// Return the instruction size.
//
return insn.size;
}
//
// ana_op_narp(operand, opcode)
//
// Decodes the 'auxiliary-register-pointer-change' command that may
// be embededded in the opcode 'opcode' and places the information
// about the change in the operand 'operand'. If the instruction does
// not have a pointer change request, then 'operand' is left alone.
//
// Returns instruction size on successful decode, 0 on illegal condition.
//
static int ana_op_narp(const insn_t &insn, op_t &op, uint16 opcode)
{
//
// Determine if the instruction contains a request
// to change the ARP register after execution.
//
if ( ISN_INDIR_NARP(opcode) )
{
//
// The instruction contains the request.
// Reflect the request in the operand provided.
//
op.type = o_reg;
if ( ISN_INDIR_ARP(opcode) )
{
// Change to AR1
op.reg = IREG_AR1;
}
else
{
// Change to AR0
op.reg = IREG_AR0;
}
}
//
// Successful operand decode.
// Return the instruction size.
//
return insn.size;
}

View File

@@ -0,0 +1,45 @@
// $Id: ana.hpp,v 1.3 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// TMS320C1X Processor module
// Instruction decode.
//
#ifndef _IDP_TMS320C1X_ANA_H
#define _IDP_TMS320C1X_ANA_H
int idaapi ana(insn_t *insn);
#endif // _IDP_TMS320C1X_ANA_H

View File

@@ -0,0 +1,101 @@
// $Id: asms.cpp,v 1.2 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// TMS320C1X assembler types and implementations
//
#include "../idaidp.hpp"
#include "asms.hpp"
//////////////////////////////////////////////////////////////////////////////
// TI Assembler
//////////////////////////////////////////////////////////////////////////////
const asm_t tiAssembler =
{
// Assembler features:
AS_ASCIIC // ASCII directive support C escape sequences
|AS_ASCIIZ // ASCII directive appends implicit null character
|ASH_HEXF3 // Hexidecimal constant format: 0x<nn...>
|ASD_DECF0 // Decimal constant format : 34
|ASO_OCTF1 // Octal format : 0<nn..>
|ASB_BINF0 // Binary format : <nn...>b
|AS_ONEDUP, // One array directive per line
0, // Assembler-defined flags (for local use)
"TI", // Assembler name
0, // Help screen number
NULL, // Array of automatically generated header lines
".org", // Origin directive
NULL, // End directive
";", // Comment string
'"', // ASCII string delimiter
'\'', // ASCII character constant delimiter
"\"", // Characters that cannot appear inside a string
".asciiz", // ASCII string directive
".byte", // Byte (8-bit) directive
".short", // Word (16-bit) directive
".word", // Dword (32-bit) directive
".quad", // Qword (64-bit) directive
NULL, // Oword (128-bit) directive
".float", // IEEE single directive
".double", // IEEE double directive
NULL, // IEEE tbyte directive
NULL, // IEEE packed-real directive
".fill #d, #sb, #v",// Array (dup) directive
".bss", // BSS directive
NULL, // EQU directive to use if AS_UNEQU is set
NULL, // Segment operand keyword
".", // Symbol for current assembly location
NULL, // Function header generating function
NULL, // Function footer generating function
".global", // Public name keyword
NULL, // Weak keyword
".extern", // Extern keyword
".comm", // Communal keyword
NULL, // 'get_type_name()' function
".align", // Align keyword
'(', // Left delimiter for complex expressions
')', // Right delimiter for complex expressions
"%", // Remainder (MOD) operator
"&", // Bit-wise AND operator
"|", // Bit-wise OR operator
"^", // Bit-wise XOR operator
"~", // Bit-wise NOT operator
"<<", // Left shift operator
">>", // Right shift operator
NULL, // Sizeof() keyword
};
const asm_t *const tms320c1x_Assemblers[] =
{
&tiAssembler,
NULL
};

View File

@@ -0,0 +1,41 @@
// $Id: asms.hpp,v 1.2 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// TMS320C1X assembler types
//
#ifndef _IDP_TMS320C1X_ASMS_HPP
#define _IDP_TMS320C1X_ASMS_HPP
extern const asm_t *const tms320c1x_Assemblers[];
#endif // _IDP_TMS320C1X_ASMS_HPP

View File

@@ -0,0 +1,263 @@
// $Id: emu.cpp,v 1.6 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// TMS320C1X Processor module
// Instruction emulation.
//
#include "../idaidp.hpp"
#include <segregs.hpp>
#include "tms320c1.hpp"
#include "ins.hpp"
#include "reg.hpp"
int tms320c1_t::emu(const insn_t &insn) const
{
//
// Determine the current instruction's features.
//
int features = insn.get_canon_feature(ph);
bool flow = (features & CF_STOP) == 0;
//
// Examine each operand and determine what effect, if any,
// it makes on the environment.
//
// Operands that are read
if ( features & CF_USE1 )
flow &= handle_operand(insn, insn.Op1, hop_READ);
if ( features & CF_USE2 )
flow &= handle_operand(insn, insn.Op2, hop_READ);
if ( features & CF_USE3 )
flow &= handle_operand(insn, insn.Op3, hop_READ);
// Operands that are written
if ( features & CF_CHG1 )
flow &= handle_operand(insn, insn.Op1, hop_WRITE);
if ( features & CF_CHG2 )
flow &= handle_operand(insn, insn.Op2, hop_WRITE);
if ( features & CF_CHG3 )
flow &= handle_operand(insn, insn.Op3, hop_WRITE);
//
// Determine whether the instruction stops the execution flow.
//
if ( flow )
{
//
// This instruction doesn't stop execution flow.
// Add a cross reference to the next instrction.
//
add_cref(insn.ea, insn.ea+insn.size, fl_F);
}
//
// If the instruction makes a branch, let the IDA kernel
// know.
//
if ( features & CF_JUMP )
remember_problem(PR_JUMP, insn.ea);
return 1;
}
bool tms320c1_t::handle_operand(const insn_t &insn, const op_t &op, opRefType ref_type) const
{
ea_t ea;
sel_t data_selector;
bool flow = true;
switch ( op.type )
{
case o_reg:
//
// Register operand.
//
//
// Nothing needs to be calculated or examined for this
// operand.
//
break;
case o_imm:
//
// Immediate operand.
//
// Make sure that this operand reference isn't a write reference.
// (Writing to an immediate value is not allowed and is a sure
// sign of a badly decoded instruction).
//
if ( ref_type == hop_WRITE )
{
//
// Attempt to write to an immediate value.
// Error.
//
warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), op.n, op.type);
break;
}
//
// SPECIAL INSTRUCTION CASE:
//
// The LDPK instruction is decoded by ana() to have an immediate
// value as an operand. However, this immediate value is to be
// the new data page pointer, which we must track for proper
// memory referencing.
//
if ( insn.itype == I_LDPK )
{
//
// This is an LDPK instruction. Let the kernel know that
// we are changing the current data page pointer. We track
// this bit as though it were a virtual segment register named
// I_VDS, although it is not a true register in the CPU.
//
// Determine into which data page the instruction is attempting
// to point.
//
if ( op.value == 0 )
{
//
// Data page 0 is being loaded.
//
data_selector = tms320c1x_dpage0;
}
else
{
//
// Data page 1 is being loaded.
//
data_selector = tms320c1x_dpage1;
}
//
// Notify the IDA kernel of the change.
//
split_sreg_range(
insn.ea, // The current instruction's address
IREG_VDS, // The segment register being modified
data_selector, // The new selector value being loaded
SR_auto); // How the new value was determined
}
//
// Let the kernel know that the instruction's address should
// be marked with a 'has immediate value' flag.
// (Useful during search?)
//
set_immd(insn.ea);
break;
case o_phrase:
//
// Processor-specific phrase.
//
// These operands have no currently trackable side effect.
//
break;
case o_mem:
//
// Direct memory reference.
//
//
// Ask the IDA kernel for the current data page pointer selector.
//
data_selector = get_sreg(insn.ea, IREG_VDS);
//
// Is it known?
//
if ( data_selector == BADSEL )
{
//
// The current data page pointer is unknown.
// There is nothing to do.
//
}
else
{
//
// The current data page pointer is known.
// Calculate the full effective address being referenced
// by this operand.
//
ea = sel2ea(data_selector) + op.addr;
//
// Generate a data cross reference from this instruction
// to the target address.
//
insn.add_dref(ea, op.offb, ref_type == hop_READ ? dr_R : dr_W);
}
//
// TODO: DMOV, ...
// These instructions read from the address in their operands
// and write to the address ADJACENT to it.
//
break;
case o_near:
//
// Code reference in current segment.
//
//
// Determine the effective address of the reference.
//
ea = to_ea(insn.cs, op.addr);
//
// Is this a 'CALL' type reference, or a branch type reference?
//
if ( has_insn_feature(insn.itype, CF_CALL) )
{
//
// This is a CALL type reference. Make a cross reference
// that notes it.
//
insn.add_cref(ea, op.offb, fl_CN);
if ( !func_does_return(ea) )
flow = false;
}
else
{
//
// This is a branch type reference. Make a cross reference
// that notes it.
//
insn.add_cref(ea, op.offb, fl_JN);
}
break;
default:
//
// Unhandled operand type.
// Error.
//
warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), op.n, op.type);
break;
}
return flow;
}

View File

@@ -0,0 +1,40 @@
// $Id: emu.hpp,v 1.2 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// Instruction emulation/flow routines.
//
#ifndef _IDP_TMS320C1X_EMU_CPP
#define _IDP_TMS320C1X_EMU_CPP
extern int idaapi emu(const insn_t &insn);
#endif // _IDP_TMS320C1X_EMU_CPP

View File

@@ -0,0 +1,330 @@
// $Id: idp.cpp,v 1.9 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// IDP module entry structure
//
#include "../idaidp.hpp"
#include "tms320c1.hpp"
#include "ana.hpp"
#include "reg.hpp"
#include "out.hpp"
#include "ins.hpp"
#include "asms.hpp"
//----------------------------------------------------------------------
// This old-style callback only returns the processor module object.
static ssize_t idaapi notify(void *, int msgid, va_list)
{
if ( msgid == processor_t::ev_get_procmod )
return size_t(new tms320c1_t);
return 0;
}
//
// This function is the entry point that is called to notify the processor
// module of an important event.
//
ssize_t idaapi tms320c1_t::on_event(ssize_t msgid, va_list va)
{
int code = 1;
switch ( msgid )
{
case processor_t::ev_init:
//
// Initialize the processor module.
//
tms320c1x_Init();
break;
case processor_t::ev_newfile:
//
// Prepare for decoding of the file that has just been
// loaded.
//
tms320c1x_NewFile();
break;
case processor_t::ev_out_header:
{
outctx_t *ctx = va_arg(va, outctx_t *);
outHeader(*ctx);
return 1;
}
case processor_t::ev_out_footer:
{
outctx_t *ctx = va_arg(va, outctx_t *);
outFooter(*ctx);
return 1;
}
case processor_t::ev_out_segstart:
{
outctx_t *ctx = va_arg(va, outctx_t *);
segment_t *seg = va_arg(va, segment_t *);
outSegStart(*ctx, seg);
return 1;
}
case processor_t::ev_ana_insn:
{
insn_t *out_ins = va_arg(va, insn_t *);
return ana(out_ins);
}
case processor_t::ev_emu_insn:
{
const insn_t *insn = va_arg(va, const insn_t *);
return emu(*insn) ? 1 : -1;
}
case processor_t::ev_out_insn:
{
outctx_t *ctx = va_arg(va, outctx_t *);
out_insn(*ctx);
return 1;
}
case processor_t::ev_out_operand:
{
outctx_t *ctx = va_arg(va, outctx_t *);
const op_t *op = va_arg(va, const op_t *);
return out_opnd(*ctx, *op) ? 1 : -1;
}
default:
code = 0;
break;
}
return code;
}
//
// tms320c1x_Init()
//
// Initialize the processor module.
//
// (Called from on_event()).
//
void tms320c1_t::tms320c1x_Init() const
{
//
// Have the IDA kernel interpret the data within the virtual
// address space in a big-endian manner.
//
inf_set_be(true);
}
//
// tms320c1x_NewFile()
//
// Make any preparations needed to interpret the file that has
// just been loaded.
//
// (Called from on_event()).
//
void tms320c1_t::tms320c1x_NewFile()
{
ea_t data_start;
segment_t dpage0, dpage1;
//
// There are no known executable file formats for TMS320C1X executables.
// Therefore, we will assume in this processor module that the user
// has loaded a program ROM image into IDA. This image lacks any
// definitions for data RAM, so we must create an area in IDA's virtual
// address space to represent this RAM, thus enabling us to make
// and track cross-references made to data RAM by TMS320C1X instructions.
//
// The TMS320C1X accesses data RAM in two discrete ways, the first of
// which has a major impact on the strategy we must use to represent
// data RAM.
//
// The first kind of access occurs during the execution of instructions
// with immediate address operands. The 7-bit immediate address operand
// is combined with the current data page pointer bit in the processor
// status register to give an 8-bit final address. We will simulate this
// behavior by keeping track of the data page pointer bit from instruction
// to instruction, in effect acting as though it were a segment register.
// We will then treat the 7-bit immediate address operand in each
// instruction as though it were an offset into one of two data RAM
// segments, depending on the current value of the data page pointer bit.
// To do this, we need to create and define those two data segments here.
//
// The second manner in which the TMS320C1X access data RAM is during the
// execution of instructions with indirect address operands. An indirect
// address operand is one which identifies a location in data RAM
// indirectly through the current value in one of the accumulator or
// auxiliary registers. These memory references are fully qualified
// since all three of these registers are spacious enough to hold all
// 8-bits of addressing information. Therefore, we needn't do anything
// special here to accomodate these instructions.
//
//
// Find a suitable place in IDA's virtual address space to place
// the TMS320C1X's data RAM. Make sure it is aligned on a 16 byte
// boundary.
//
data_start = free_chunk(0, TMS320C1X_DATA_RAM_SIZE, 15);
////
//// Create the first data segment, otherwise known as 'data page 0'.
////
//
// Define its start and ending virtual address.
//
dpage0.start_ea = data_start;
dpage0.end_ea = data_start + (TMS320C1X_DATA_RAM_SIZE / 2);
//
// Assign it a unique selector value.
//
dpage0.sel = allocate_selector(dpage0.start_ea >> 4);
//
// Let the kernel know that it is a DATA segment.
//
dpage0.type = SEG_DATA;
//
// Create the segment in the address space.
//
add_segm_ex(&dpage0, "dp0", NULL, ADDSEG_OR_DIE);
////
//// Create the second data segment, otherwise known as 'data page 1'.
////
//
// Define its start and ending virtual address.
//
dpage1.start_ea = data_start + (TMS320C1X_DATA_RAM_SIZE / 2);
dpage1.end_ea = data_start + TMS320C1X_DATA_RAM_SIZE;
//
// Assign it a unique selector value.
//
dpage1.sel = allocate_selector(dpage1.start_ea >> 4);
//
// Let the kernel know that it is a DATA segment.
//
dpage1.type = SEG_DATA;
//
// Create the segment in the address space.
//
add_segm_ex(&dpage1, "dp1", NULL, ADDSEG_OR_DIE);
//
// Store the selectors of these two data segments in the global
// variables tms320c1x_dpage0 and tms320c1x_dpage1.
//
tms320c1x_dpage0 = dpage0.sel;
tms320c1x_dpage1 = dpage1.sel;
}
//
// Short supported processor names.
//
// [ This array is named in our processor_t.psnames member ]
//
static const char *const shnames[] =
{
"tms320c1x",
NULL
};
//
// Descriptive supported processor names.
//
// [ This array is named in our processor_t.plnames member ]
//
#define FAMILY "TMS320C1X Series:"
static const char *const lnames[] =
{
FAMILY"Texas Instruments TMS320C1X DSP",
NULL
};
//
// Array of opcode streams that represent a function return
// instruction.
//
// [ This array is named in our processor_t.retcodes member ]
//
const bytes_t tms320c1x_retCodes[] =
{
{ 0, 0 }
};
//////////////////////////////////////////////////////////////////////////////
// PROCESSOR MODULE DEFINITION
//////////////////////////////////////////////////////////////////////////////
processor_t LPH =
{
IDP_INTERFACE_VERSION,// version
PLFM_TMS320C1X, // id
// flag
//
// processor module capablilty flags:
//
PR_RNAMESOK // A register name can be used to name a location
| PR_BINMEM // The module creates segments for binary files
| PR_SEGS, // We'd like to use the segment register tracking
// features of IDA.
// flag2
0,
//
16, // Bits in a byte for code segments
16, // Bits in a byte for other segments
shnames, // Array of short processor names
// the short names are used to specify the processor
// with the -p command line switch)
lnames, // array of long processor names
// the long names are used to build the processor
// selection menu type
tms320c1x_Assemblers, // array of target assemblers
notify, // Callback function for kernel event notification
registerNames, // Regsiter names
nregisterNames, // Number of registers
IREG_VCS, // First segment-register number
IREG_VDS, // Last segment-register number
1, // size of a segment register
IREG_VCS, // CS segment-register number
IREG_VDS, // DS segment-register number
NULL, // Known code start sequences
tms320c1x_retCodes, // Known return opcodes
I__FIRST, // First instruction number
I__LAST, // Last instruction number
Instructions, // instruc
};

View File

@@ -0,0 +1,114 @@
// $Id: ins.cpp,v 1.2 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// TMS320C1X processor module.
// Software representation of TMS320C1X instructions.
//
#include "../idaidp.hpp"
#include "ins.hpp"
//
// Names and side-effect features of all instructions.
// Used by the emu() function to determine instruction side effects
// and report them to the kernel.
//
const instruc_t Instructions[] =
{
// Accumulator Memory Reference Instructions
{ "ABS", 0 },
{ "ADD", CF_USE1 },
{ "ADDH", CF_USE1 },
{ "ADDS", CF_USE1 },
{ "AND", CF_USE1 },
{ "LAC", CF_USE1 },
{ "LACK", CF_USE1 },
{ "OR", CF_USE1 },
{ "SACH", CF_CHG1 },
{ "SACL", CF_CHG1 },
{ "SUB", CF_USE1 },
{ "SUBC", CF_USE1 },
{ "SUBH", CF_USE1 },
{ "SUBS", CF_USE1 },
{ "XOR", CF_USE1 },
{ "ZAC", 0 },
{ "ZALH", CF_USE1 },
{ "ZALS", CF_USE1 },
// Auxiliary Register and Data Page Pointer Instructions
{ "LAR", CF_USE1 },
{ "LARK", CF_USE1 },
{ "LARP", CF_USE1 },
{ "LDP", CF_USE1 },
{ "LDPK", CF_USE1 },
{ "MAR", 0 }, // no memory access occurs, just ARP and AR change
{ "SAR", CF_CHG1 },
// T Register, P Register, and Multiply Instructions
{ "APAC", 0 },
{ "LT", CF_USE1 },
{ "LTA", CF_USE1 },
{ "LTD", CF_USE1|CF_CHG1 }, // changes [Op1 + 1]!
{ "MPY", CF_USE1 },
{ "MPYK", CF_USE1 },
{ "PAC", 0 },
{ "SPAC", 0 },
// Branch/Call Instructions
{ "B", CF_USE1|CF_JUMP|CF_STOP },
{ "BANZ", CF_USE1|CF_JUMP },
{ "BGEZ", CF_USE1|CF_JUMP },
{ "BGZ", CF_USE1|CF_JUMP },
{ "BIOZ", CF_USE1|CF_JUMP },
{ "BLEZ", CF_USE1|CF_JUMP },
{ "BLZ", CF_USE1|CF_JUMP },
{ "BNZ", CF_USE1|CF_JUMP },
{ "BV", CF_USE1|CF_JUMP },
{ "BZ", CF_USE1|CF_JUMP },
{ "CALA", CF_CALL },
{ "CALL", CF_USE1|CF_CALL },
{ "RET", CF_STOP },
// Control Instructions
{ "DINT", 0 },
{ "EINT", 0 },
{ "LST", CF_USE1 },
{ "NOP", 0 },
{ "POP", 0 },
{ "PUSH", 0 },
{ "ROVM", 0 },
{ "SOVM", 0 },
{ "SST", CF_CHG1 }, // Operates in page 1 ONLY if direct
// I/O and Data Memory Instructions
{ "DMOV", CF_CHG1 }, // changes [Op1 + 1]!
{ "IN", CF_CHG1 },
{ "OUT", CF_USE1 },
{ "TBLR", CF_CHG1 },
{ "TBLW", CF_USE1 },
};
CASSERT(qnumber(Instructions) == I__LAST);

View File

@@ -0,0 +1,134 @@
// $Id: ins.hpp,v 1.6 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// Software representation of TMS320C1X instructions.
//
#ifndef _IDP_TMS320C1X_INS_H
#define _IDP_TMS320C1X_INS_H
enum nameNum
{
// Accumulator Memory Reference Instructions
I__FIRST = 0,
I_ABS = 0,
I_ADD,
I_ADDH,
I_ADDS,
I_AND,
I_LAC,
I_LACK,
I_OR,
I_SACH,
I_SACL,
I_SUB,
I_SUBC,
I_SUBH,
I_SUBS,
I_XOR,
I_ZAC,
I_ZALH,
I_ZALS,
// Auxiliary Register and Data Page Pointer Instructions
I_LAR,
I_LARK,
I_LARP,
I_LDP,
I_LDPK,
I_MAR,
I_SAR,
// T Register, P Register, and Multiply Instructions
I_APAC,
I_LT,
I_LTA,
I_LTD,
I_MPY,
I_MPYK,
I_PAC,
I_SPAC,
// Branch/Call Instructions
I_B,
I_BANZ,
I_BGEZ,
I_BGZ,
I_BIOZ,
I_BLEZ,
I_BLZ,
I_BNZ,
I_BV,
I_BZ,
I_CALA,
I_CALL,
I_RET,
// Control Instructions
I_DINT,
I_EINT,
I_LST,
I_NOP,
I_POP,
I_PUSH,
I_ROVM,
I_SOVM,
I_SST,
// I/O and Data Memory Instructions
I_DMOV,
I_IN,
I_OUT,
I_TBLR,
I_TBLW,
I__LAST
};
//
// TMS320C1X register phrases.
// These are used to represent instruction operands that are not either
// immediate values or registers.
//
enum regPhrase
{
IPH_AR, // Dereference current aux register
IPH_AR_INCR, // Dereference current aux register and post-increment
IPH_AR_DECR, // Dereference current aux register and post-decrement
};
//
// Auxilliary instruction information.
// This is information that this processor module can add to the instruction,
// only to be examined and consumed by the processor module itself.
//
#define IX_DATA_PAGE_KNOWN 0x8000 // The current data page is known
#define IX_DATA_PAGE(x) ((x) & 0x1) // Retrieves the known data page
extern const instruc_t Instructions[];
#endif // _IDP_TMS320C1X_INS_H

View File

@@ -0,0 +1,60 @@
PROC=tms320c1
O1=idp
O2=asms
include ../module.mak
# MAKEDEP dependency list ------------------
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ana.cpp ins.hpp \
reg.hpp tms320c1.hpp
$(F)asms$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp asms.cpp asms.hpp
$(F)emu$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
emu.cpp ins.hpp reg.hpp tms320c1.hpp
$(F)idp$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ana.hpp asms.hpp \
idp.cpp ins.hpp out.hpp reg.hpp tms320c1.hpp
$(F)ins$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ins.cpp ins.hpp
$(F)out$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
ins.hpp out.cpp out.hpp reg.hpp
$(F)reg$(O) : reg.cpp reg.hpp

View File

@@ -0,0 +1,333 @@
// $Id: out.cpp,v 1.7 2000/11/06 22:11:16 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// Instruction display routines
//
#include "../idaidp.hpp"
#include <segregs.hpp>
#include "ins.hpp"
#include "out.hpp"
#include "reg.hpp"
//
// outSegStart()
//
// [ This function is named in our processor_t.segstart member ]
//
// Generate assembly text before the start of a segment.
//
void idaapi outSegStart(outctx_t &ctx, segment_t *)
{
ctx.gen_cmt_line("A segment starts here.");
}
//
// outSegEnd()
//
// [ This function is named in our processor_t.segend member ]
//
// Generate assembly text after the end of a segment.
//
void idaapi outSegEnd(outctx_t &ctx, segment_t *)
{
ctx.gen_cmt_line("A segment ends here.");
}
//
// outHeader()
//
// [ This function is named in our processor_t.header member ]
//
// Generate an assembly header for the top of the file.
//
void idaapi outHeader(outctx_t &ctx)
{
ctx.gen_header(GH_PRINT_PROC_AND_ASM);
}
//
// outFooter()
//
// [ This function is named in our processor_t.footer member ]
//
// Generate an assembly footer for the bottom of the file.
//
void idaapi outFooter(outctx_t &ctx)
{
ctx.gen_cmt_line("End of file");
}
////////////////////////////////////////////////////////////////////////////
//
// DISASSEMBLY OPERAND HELPER FUNCTIONS
//
////////////////////////////////////////////////////////////////////////////
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_tms320c1_t)
//
// outPhrase(phrase)
// Output a TMS320C1X-specific operand phrase.
//
void out_tms320c1_t::outPhrase(int phrase)
{
//
// Complex phrase operand.
// (Processor specific)
//
switch ( phrase )
{
case IPH_AR:
//
// Current address register, indirect.
//
out_symbol('*');
break;
case IPH_AR_INCR:
//
// Current address register, indirect, post-increment.
//
out_symbol('*');
out_symbol('+');
break;
case IPH_AR_DECR:
//
// Current address register, indirect, post-decrement.
//
out_symbol('*');
out_symbol('-');
break;
}
}
//
// outNear(operand)
//
// Display an operand that is known to reference another piece of
// of code.
//
void out_tms320c1_t::outNear(const op_t &op)
{
//
// Calculate the effective address of this code reference.
//
ea_t ea = to_ea(insn.cs, op.addr);
//
// Find or create a name for the code address that this operand
// references so that we can output that name in the operand's
// place.
//
if ( !out_name_expr(op, ea, op.addr) )
//
// The code address didn't have a name. Default to
// displaying the address as a number.
//
out_value(op, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN);
//
// Let the user know that he or she should look at this
// instruction and attempt to name the address that it
// references.
//
remember_problem(PR_NONAME, insn.ea);
}
//
// outNear(operand)
//
// Display an operand that is known to reference data RAM.
//
void out_tms320c1_t::outMem(const op_t &op)
{
//
// Ask the IDA kernel for the value of the current data page
// pointer for execution of this instruction.
//
sel_t data_selector = get_sreg(insn.ea, IREG_VDS);
//
// Is it known?
//
if ( data_selector == BADSEL )
{
//
// The current data page pointer is not known.
//
//
// Display the current operand as a regular number and
// return.
//
out_value(op, OOF_ADDR);
return;
}
//
// The current data page pointer is known. Use it to calculate the
// effective address of the memory being referenced by this
// operand.
//
ea_t ea = sel2ea(data_selector) + op.addr;
//
// Find or create a name for the data address that this operand
// references so that we can output that name in the operand's
// place.
//
if ( !out_name_expr(op, ea, op.addr) )
{
//
// No name was found and no name was created.
// Display the current operand as a regular number.
//
out_value(op, OOF_ADDR);
//
// Let the user know that he or she should look at this
// instruction and attempt to name the address that it
// references.
//
remember_problem(PR_NONAME, insn.ea);
}
}
bool out_tms320c1_t::out_operand(const op_t &op)
{
switch ( op.type )
{
case o_reg:
//
// Register operand.
//
outreg(op.reg);
break;
case o_phrase:
//
// Complex phrase.
// (Processor specific)
//
outPhrase(op.phrase);
break;
case o_imm:
//
// Immediate value.
//
out_value(op, 0);
break;
case o_near:
//
// Code reference.
//
outNear(op);
break;
case o_mem:
//
// Data memory reference.
//
outMem(op);
break;
default:
break;
}
return 1;
}
void out_tms320c1_t::out_insn()
{
//
// An unseen parameter to this function is the 'insn' structure
// which holds all the information about the instruction that we
// are being asked to display.
//
// This call to out_mnemonic() is a helper function in the IDA kernel that
// displays an instruction mnemonic for the current instruction.
// It does so by taking the integer value in insn.itype and using it
// as an index into the array that we named in this processor module's
// processor_t.instruc member. From this indexed element comes the
// instruction mnemonic to be displayed.
//
out_mnemonic();
//
// If the current instruction has a non-empty first operand,
// then display it.
//
if ( insn.Op1.type != o_void )
{
//
// This call to out_one_operand() is another IDA kernel function that
// is mandatory for a properly behaved processor module.
//
// Normally, this helper function turns around and calls the function
// named in our processor_t.u_outop member with a reference to
// the current instruction's operand numbered in the first argument.
// However, if through the course of interacting with the
// disassembly the user chooses to manually override the specified
// operand in this instruction, the IDA kernel will forego the call
// to u_outop() -- instead calling an internal IDA routine to
// display the user's manually entered operand.
//
out_one_operand(0);
}
//
// Display the second operand, if non-empty.
//
if ( insn.Op2.type != o_void )
{
//
// This call to out_symbol() is another helper function in the
// IDA kernel. It writes the specified character to the current
// buffer, using the user-configurable 'symbol' color.
//
out_symbol(',');
out_char(' ');
out_one_operand(1);
}
//
// Finally, display the third operand, if non-empty.
//
if ( insn.Op3.type != o_void )
{
out_symbol(',');
out_char(' ');
out_one_operand(2);
}
//
// Tell IDA to display our constructed line.
//
flush_outbuf();
}

View File

@@ -0,0 +1,67 @@
// $Id: out.hpp,v 1.4 2000/11/06 22:11:17 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// Instruction display routines
//
#ifndef _IDP_TMS320C1X_OUT_H
#define _IDP_TMS320C1X_OUT_H
void idaapi outSegStart(outctx_t &, segment_t *);
void idaapi outSegEnd(outctx_t &, segment_t *);
void idaapi outHeader(outctx_t &);
void idaapi outFooter(outctx_t &);
bool idaapi outOp(outctx_t &ctx, const op_t &op);
void idaapi out(outctx_t &ctx);
// simple wrapper class for syntactic sugar of member functions
// this class may have only simple member functions.
// virtual functions and data fields are forbidden, otherwise the class
// layout may change
class out_tms320c1_t : public outctx_t
{
out_tms320c1_t(void) = delete; // not used
public:
bool out_operand(const op_t &x);
void out_insn(void);
void outreg(int r) { out_register(ph.reg_names[r]); }
void outPhrase(int phrase);
void outNear(const op_t &op);
void outMem(const op_t &op);
};
CASSERT(sizeof(out_tms320c1_t) == sizeof(outctx_t));
#endif // _IDP_TMS320C1X_OUT_H

View File

@@ -0,0 +1,52 @@
// $Id: reg.cpp,v 1.3 2000/11/06 22:11:17 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// TMS320C1X register names.
//
#include "reg.hpp"
//
// The following doesn't represent all of the TMS320C1X's registers.
// It only represents those registers that are explicitly specified
// in instruction mnemonics.
//
const char *const registerNames[] =
{
"AR0", // Address register zero
"AR1", // Address register one.
//
// Special registers required by IDA kernel.
//
"VCS",
"VDS"
};
const int nregisterNames = sizeof(registerNames) / sizeof(*registerNames);

View File

@@ -0,0 +1,58 @@
// $Id: reg.hpp,v 1.2 2000/11/06 22:11:17 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// Constants used for representing TMS320C1X registers in instructions.
//
#ifndef _IDP_TMS320C1X_REG_H
#define _IDP_TMS320C1X_REG_H
#ifdef _MSC_VER
#define ENUM8BIT : unsigned char
#else
#define ENUM8BIT
#endif
enum tms320c1x_register ENUM8BIT
{
IREG_AR0, // Address register zero
IREG_AR1, // Address register one
//
// Virtual registers required by IDA kernel
//
IREG_VCS,
IREG_VDS,
IREG__LAST
};
extern const char *const registerNames[];
extern const int nregisterNames;
#endif // _IDP_TMS320C1X_REG_H

View File

@@ -0,0 +1,210 @@
// $Id: tms320c1.hpp,v 1.8 2000/11/06 22:11:17 jeremy Exp $
//
// Copyright (c) 2000 Jeremy Cooper. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by Jeremy Cooper.
// 4. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// IDA TMS320C1X processor module.
// TMS320C1X constants, etc.
//
#ifndef _IDP_TMS320C1X_H
#define _IDP_TMS320C1X_H
//////////////////////////////////////////////////////////////////////////////
// TMS320C1X Instruction Opcodes
//
// To ease decoding requirements, we have classified each TMS320C1X
// instruction by the number of significant bits that need to be scanned in
// the instruction opcode in order to uniquely identify it.
//
//
// Bit scanning masks
//
#define ISN_3_BIT_MASK 0xe000 // 111x xxxx xxxx xxxx
#define ISN_4_BIT_MASK 0xf000 // 1111 xxxx xxxx xxxx
#define ISN_5_BIT_MASK 0xf800 // 1111 1xxx xxxx xxxx
#define ISN_7_BIT_MASK 0xfe00 // 1111 111x xxxx xxxx
#define ISN_8_BIT_MASK 0xff00 // 1111 1111 xxxx xxxx
#define ISN_15_BIT_MASK 0xfffe // 1111 1111 1111 111x
#define ISN_16_BIT_MASK 0xffff // 1111 1111 1111 1111
//
// 3 bit Opcodes
//
enum isn_3bit
{
ISN3_MPYK = 0x8000, // 100...
};
//
// 4 bit Opcodes
//
enum isn_4bit
{
ISN4_ADD = 0x0000, // 0000...
ISN4_LAC = 0x2000, // 0100...
ISN4_SUB = 0x1000, // 0001...
};
//
// 5 bit Opcodes
//
enum isn_5bit
{
ISN5_SACH = 0x5800, // 0101 1...
ISN5_IN = 0x4000, // 0100 0...
ISN5_OUT = 0x4800, // 0100 1...
};
//
// 7 bit Opcodes
//
enum isn_7bit
{
ISN7_LAR = 0x3800, // 0011 100...
ISN7_LARK = 0x7000, // 0111 000...
ISN7_SAR = 0x3000, // 0011 000...
};
//
// 8 bit Opcodes
//
enum isn_8bit
{
ISN8_ADDH = 0x6000, // 0110 0000 ...
ISN8_ADDS = 0x6100, // 0110 0001 ...
ISN8_AND = 0x7900, // 0111 1001 ...
ISN8_LACK = 0x7e00, // 0111 1110 ...
ISN8_OR = 0x7a00, // 0111 1010 ...
ISN8_SACL = 0x5000, // 0101 0000 ...
ISN8_SUBC = 0x6400, // 0110 0100 ...
ISN8_SUBH = 0x6200, // 0110 0010 ...
ISN8_SUBS = 0x6300, // 0110 0011 ...
ISN8_XOR = 0x7800, // 0111 1000 ...
ISN8_ZALH = 0x6500, // 0110 0101 ...
ISN8_ZALS = 0x6600, // 0110 0110 ...
ISN8_LDP = 0x6f00, // 0110 1111 ...
ISN8_MAR = 0x6800, // 0110 1000 ...
ISN8_LT = 0x6a00, // 0110 1010 ...
ISN8_LTA = 0x6c00, // 0110 1100 ...
ISN8_LTD = 0x6b00, // 0110 1011 ...
ISN8_MPY = 0x6d00, // 0110 1101 ...
ISN8_LST = 0x7b00, // 0111 1101 ...
ISN8_SST = 0x7c00, // 0111 1100 ...
ISN8_DMOV = 0x6900, // 0110 1001 ...
ISN8_TBLR = 0x6700, // 0110 0111 ...
ISN8_TBLW = 0x7d00, // 0111 1101 ...
};
//
// 15 bit Opcodes
//
enum isn_15bit
{
// LARP is a synonym for a special case of MAR
// ISN15_LARP = 0x6880, // 0110 1000 1000 000.
ISN15_LDPK = 0x6e00, // 0110 1110 0000 000.
};
//
// 16 bit Opcodes
//
enum isn_16bit
{
ISN16_ABS = 0x7f88, // 0111 1111 1000 1000
ISN16_ZAC = 0x7f89, // 0111 1111 1000 0101
ISN16_APAC = 0x7f8f, // 0111 1111 1000 1111
ISN16_PAC = 0x7f8e, // 0111 1111 1000 1110
ISN16_SPAC = 0x7f90, // 0111 1111 1001 0000
ISN16_B = 0xf900, // 1111 1001 0000 0000
ISN16_BANZ = 0xf400, // 1111 0100 0000 0000
ISN16_BGEZ = 0xfd00, // 1111 1101 0000 0000
ISN16_BGZ = 0xfc00, // 1111 1100 0000 0000
ISN16_BIOZ = 0xf600, // 1111 0110 0000 0000
ISN16_BLEZ = 0xfb00, // 1111 1011 0000 0000
ISN16_BLZ = 0xfa00, // 1111 1010 0000 0000
ISN16_BNZ = 0xfe00, // 1111 1110 0000 0000
ISN16_BV = 0xf500, // 1111 0101 0000 0000
ISN16_BZ = 0xff00, // 1111 1111 0000 0000
ISN16_CALA = 0x7f8c, // 0111 1111 1000 1100
ISN16_CALL = 0xf800, // 1111 1000 0000 0000
ISN16_RET = 0x7f8d, // 0111 1111 1000 1101
ISN16_DINT = 0x7f81, // 0111 1111 1000 0001
ISN16_EINT = 0x7f82, // 0111 1111 1000 0010
ISN16_NOP = 0x7f80, // 0111 1111 1000 0000
ISN16_POP = 0x7f9d, // 0111 1111 1001 1101
ISN16_PUSH = 0x7f9c, // 0111 1111 1001 1100
ISN16_ROVM = 0x7f8a, // 0111 1111 1000 1010
ISN16_SOVM = 0x7f8b, // 0111 1111 1000 1011
};
//
// Instruction property macros.
// These macros deduce certain facts about the instruction.
//
#define ISN_IMM1(op) ((op) & 0x0001) // Immediate 1 bit value
#define ISN_IMM8(op) ((op) & 0x00ff) // Immediate 8 bit value
#define ISN_IMM13(op) ((op) & 0x1fff) // Immediate 13 bit value
#define ISN_DIRECT(op) (!((op) & 0x0080)) // Direct/Indirect reference flag
#define ISN_DIR_ADDR(op) ((op) & 0x007f) // Direct memory location
#define ISN_INDIR_INCR(op) ((op) & 0x0020) // Aux reg. post-increment flag
#define ISN_INDIR_DECR(op) ((op) & 0x0010) // Aux reg. post-decrement flag
#define ISN_INDIR_NARP(op) ((op) & 0x0008) // Aux reg. change flag
#define ISN_INDIR_ARP(op) ((op) & 0x0001) // New aux reg. pointer value
#define ISN_AUX_AR(op) ((op) & 0x0100) // Aux register index
#define ISN_SHIFT(o) (((o)&0x0f00)>>8) // Data bit shift amount
#define ISN_PORT(o) (((o)&0x0700)>>8) // I/O port number
//
// TMS320C1X environment facts.
// These macros define the size of the TMS320C1X's addressable
// data RAM.
//
#define TMS320C1X_DATA_RAM_SIZE 256 // 256 bytes
//
// Reference type. Used between emu() and handle_operand() to
// flag whether an operand is written to or read from.
//
enum opRefType
{
hop_READ,
hop_WRITE,
};
struct tms320c1_t : public procmod_t
{
sel_t tms320c1x_dpage0; // Data page 0 selector
sel_t tms320c1x_dpage1; // Data page 1 selector
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
// Kernel message handlers.
void tms320c1x_Init() const;
void tms320c1x_NewFile();
int emu(const insn_t &insn) const;
bool handle_operand(const insn_t &insn, const op_t &op, opRefType ref_type) const;
};
#endif // IDP_TMS320C1X_H