update to ida 7.6, add builds
This commit is contained in:
263
idasdk76/module/tms320c1/emu.cpp
Normal file
263
idasdk76/module/tms320c1/emu.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user