[PATCH] arm reversible : <phase_2_complete>
oza Pawandeep
oza.pawandeep@gmail.com
Tue Jul 5 08:47:00 GMT 2011
Hi all,
can anybody from ARM background review the code with functional perspective ?
Chandra K, is assisting for gdb automated testsuite for arm
reversible, but review is equally important specially if ARM folk
could have a look at the patch at functional perspective.
Thanks & Regards,
Oza.
>
> --- On Fri, 3/6/11, "paawan oza" <paawan1982@yahoo.com> wrote:
>> From: paawan oza <paawan1982@yahoo.com>
>> Date: Fri, Jun 3, 2011 at 1:21 PM
>> Subject: Re: [PATCH] arm reversible :
>> <phase_2_complete>
>> To: Tom Tromey <tromey@redhat.com>
>> Cc: gdb-patches@sourceware.org,
>> Petr Hluzín <petr.hluzin@gmail.com>
>>
>>
>> Hi Tom,
>>
>> Fixed almost all comments.
>> any more comments are welcome make this patch ok, if ARM
>> person can have a look
>> at it it would be great.
>>
>> PATCH STARTS
>> ------------------------------------diff -urN
>> arm_orig/arm-linux-tdep.c
>> arm_new/arm-linux-tdep.c
>> --- arm_orig/arm-linux-tdep.c 2011-03-03
>> 09:21:13.000000000 +0530
>> +++ arm_new/arm-linux-tdep.c 2011-05-07
>> 14:20:31.000000000 +0530
>> @@ -998,6 +998,9 @@
>> set_gdbarch_fetch_tls_load_module_address (gdbarch,
>>
>> svr4_fetch_objfile_link_map);
>>
>> + /* Enable process record. */
>> + set_gdbarch_process_record (gdbarch,
>> arm_process_record);
>> +
>> tramp_frame_prepend_unwinder (gdbarch,
>>
>> &arm_linux_sigreturn_tramp_frame);
>> tramp_frame_prepend_unwinder (gdbarch,
>> @@ -1025,6 +1028,8 @@
>>
>>
>> tdep->syscall_next_pc = arm_linux_syscall_next_pc;
>> +
>> + tdep->arm_swi_record = NULL;
>> }
>>
>> /* Provide a prototype to silence -Wmissing-prototypes.
>> */
>> diff -urN arm_orig/arm-tdep.c arm_new/arm-tdep.c
>> --- arm_orig/arm-tdep.c 2011-03-03 09:21:13.000000000
>> +0530
>> +++ arm_new/arm-tdep.c 2011-06-03 13:16:35.000000000
>> +0530
>> @@ -54,6 +54,8 @@
>> #include "gdb_assert.h"
>> #include "vec.h"
>>
>> +#include "record.h"
>> +
>> #include "features/arm-with-m.c"
>>
>> static int arm_debug;
>> @@ -7929,3 +7931,1763 @@
>> NULL, /* FIXME: i18n: "ARM debugging
>> is %s. */
>> &setdebuglist,
>> &showdebuglist);
>> }
>> +
>> +
>> +
>> +/* ARM-reversible process record data structures. */
>> +
>> +#define ARM_INSN_SIZE_BYTES 4
>> +#define THUMB_INSN_SIZE_BYTES 2
>> +#define THUMB2_INSN_SIZE_BYTES 4
>> +
>> +#define INSN_S_L_BIT_NUM 20
>> +
>> +#define REG_ALLOC(REGS,LENGTH,RECORD_BUF) \
>> +do \
>> + { \
>> + unsigned int reg_len = 0; reg_len = LENGTH; \
>> + if (reg_len) \
>> + { \
>> + REGS = (uint32_t*) xmalloc (sizeof(uint32_t) *
>> (reg_len)); \
>> + while (reg_len) \
>> + { \
>> + REGS[reg_len - 1] = RECORD_BUF[reg_len -
>> 1]; \
>> + reg_len--; \
>> + } \
>> + } \
>> + } \
>> +while (0)
>> +
>> +#define MEM_ALLOC(MEMS,LENGTH,RECORD_BUF) \
>> +do \
>> + { \
>> + unsigned int mem_len = 0; mem_len = LENGTH; \
>> + if (mem_len) \
>> + { \
>> + MEMS = (struct arm_mem_r *)xmalloc \
>> + (sizeof(struct arm_mem_r) *
>> (mem_len)); \
>> + while (mem_len) \
>> + { \
>> + MEMS[mem_len - 1].addr =
>> RECORD_BUF[(mem_len * 2) - 1]; \
>> + MEMS[mem_len - 1].len =
>> RECORD_BUF[(mem_len * 2) - 2]; \
>> + mem_len--; \
>> + } \
>> + } \
>> + } \
>> +while (0)
>> +
>> +
>> +/* ARM memory record structure. */
>> +struct arm_mem_r
>> +{
>> + uint32_t len; /* Record length. */
>> + CORE_ADDR addr; /* Memory address. */
>> +};
>> +
>> +/* ARM instruction record contains opcode of current insn
>> and execution state
>> (before entry to
>>
>> +decode_insn() ), contains list of to-be-modified registers
>> and memory blocks
>> (on return from
>>
>> +decode_insn() ). */
>> +typedef struct insn_decode_record_t
>> +{
>> + struct gdbarch *gdbarch;
>> + struct regcache *regcache;
>> + CORE_ADDR this_addr; /* Address of the
>> insn being decoded. */
>> + uint32_t arm_insn; /* Should
>> accommodate thumb. */
>> + uint32_t cond; /* Condition
>> code. */
>> + uint32_t opcode; /* Insn opcode.
>> */
>> + uint32_t decode; /* Insn decode
>> bits. */
>> + uint32_t mem_rec_count; /* No of mem recors
>> */
>> + uint32_t reg_rec_count; /* No of reg records
>> */
>> + uint32_t *arm_regs; /* Registers to be
>> saved for this record. */
>> + struct arm_mem_r *arm_mems; /* Memory to be saved
>> for this record. */
>> +} insn_decode_record;
>> +
>> +
>> +/* Checks ARM SBZ and SBO mendatory fields. */
>> +
>> +static int
>> +sbo_sbz (uint32_t insn, uint32_t bit_num, uint32_t len,
>> uint32_t sbo)
>> +{
>> + uint32_t ones = bits (insn, bit_num - 1, (bit_num -1) +
>> (len - 1));
>> +
>> + if (!len)
>> + return 1;
>> +
>> + if(!sbo)
>> + ones = ~ones;
>> +
>> + while (ones)
>> + {
>> + if (!(ones & sbo))
>> + {
>> + return 0;
>> + }
>> + ones = ones >> 1;
>> + }
>> + return 1;
>> +}
>> +
>> +/* Handling ARM extension space insns. */
>> +
>> +static int
>> +handle_extension_space (insn_decode_record *arm_insn_r)
>> +{
>> + uint32_t ret = 0;
>> + uint32_t opcode1 = 0, opcode2 = 0;
>> +
>> + opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
>> + if ((3 == opcode1) && (bit
>> (arm_insn_r->arm_insn, 4)))
>> + {
>> + ret = -1;
>> + /* Undefined instruction on ARM V5; need to
>> handle if later versions
>> + define it. */
>> + }
>> +
>> + opcode2 = bits (arm_insn_r->arm_insn, 4, 7);
>> +
>> + if ((!opcode1) && (9 == opcode2))
>> + {
>> + ret = -1;
>> + /* Handle arithmetic insn extension space. */
>> + }
>> +
>> + opcode1 = bits (arm_insn_r->arm_insn, 26, 27);
>> + opcode2 = bits (arm_insn_r->arm_insn, 23, 24);
>> +
>> + if ((!opcode1) && (2 == opcode2) &&
>> (!bit (arm_insn_r->arm_insn, 20)))
>> + {
>> + ret = -1;
>> + /* Handle control insn extension space. */
>> + }
>> +
>> + opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
>> + if ((!opcode1) && (bit
>> (arm_insn_r->arm_insn, 7)) \
>> + &&
>> (bit(arm_insn_r->arm_insn, 4)))
>> + {
>> + ret = -1;
>> + /* Handle load/store insn extension space. */
>> + }
>> +
>> + opcode1 = bits (arm_insn_r->arm_insn, 23, 27);
>> + if ((24 == opcode1) && (bit
>> (arm_insn_r->arm_insn, 21)))
>> + {
>> + ret = -1;
>> + /* Handle coprocessor insn extension space. */
>> + }
>> +
>> + /* To be done for ARMv5 and later; as of now we return
>> -1. */
>> + if (-1 == ret)
>> + printf_unfiltered (_("Process record does not
>> support instruction 0x%0x "
>> + "at address %s.\n"),
>> +
>> arm_insn_r->arm_insn,
>> + paddress
>> (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> + return ret;
>> +}
>> +
>> +/* Handling opcode 000 insns. */
>> +
>> +static int
>> +arm_handle_data_proc_misc_ld_str_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + struct regcache *reg_cache = arm_insn_r->regcache;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf[2];
>> +
>> +
>> + uint32_t reg_src1 = 0, reg_src2 = 0, reg_dest = 0;
>> + uint32_t immed_high = 0, immed_low = 0,offset_8 = 0,
>> tgt_mem_addr = 0;
>> + uint32_t opcode1 = 0;
>> +
>> + memset(&u_buf, 0, sizeof (u_buf));
>> +
>> + arm_insn_r->opcode = bits (arm_insn_r->arm_insn,
>> 21, 24);
>> + arm_insn_r->decode = bits (arm_insn_r->arm_insn,
>> 4, 7);
>> + opcode1 = bits (arm_insn_r->arm_insn, 20, 24);
>> +
>> + /* Data processing insn /multiply insn. */
>> + if ((9 == arm_insn_r->decode)
>> + && (((4 <= arm_insn_r->opcode)
>> && (7 >= arm_insn_r->opcode))
>> + || ((0 == arm_insn_r->opcode) || (1 ==
>> arm_insn_r->opcode))))
>> + {
>> + /* Handle multiply instructions. */
>> + /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL. */
>> + if ((0 == arm_insn_r->opcode) || (1 ==
>> arm_insn_r->opcode))
>> + {
>> + /* Handle MLA and MUL. */
>> + record_buf[0] = bits
>> (arm_insn_r->arm_insn, 16, 19);
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + else if ((4 <= arm_insn_r->opcode)
>> && (7 >= arm_insn_r->opcode))
>> + {
>> + /* Handle SMLAL, SMULL, UMLAL, UMULL. */
>> + record_buf[0] = bits
>> (arm_insn_r->arm_insn, 16, 19);
>> + record_buf[1] = bits
>> (arm_insn_r->arm_insn, 12, 15);
>> + record_buf[2] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 3;
>> + }
>> + }
>> + else if ((bit (arm_insn_r->arm_insn,
>> INSN_S_L_BIT_NUM))
>> + && ((11 == arm_insn_r->decode) ||
>> (13 == arm_insn_r->decode)))
>> + {
>> + /* Handle misc load insns, as 20th bit (L =
>> 1). */
>> + /* LDR insn has a capability to do branching,
>> if
>> + MOV LR, PC is preccedded by LDR
>> insn having Rn as R15
>> + in that case, it emulates
>> branch and link insn, and hence we
>> + need to save CSPR and PC as
>> well. I am not sure this is right
>>
>> + place as opcode = 010 LDR insn
>> make this happen, if R15 was
>> + used. */
>> + reg_dest = bits (arm_insn_r->arm_insn, 12,
>> 15);
>> + if (15 != reg_dest)
>> + {
>> + record_buf[0] = bits
>> (arm_insn_r->arm_insn, 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + record_buf[0] = reg_dest;
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + }
>> + else if (((9 == arm_insn_r->opcode) || (11 ==
>> arm_insn_r->opcode))
>> + && (sbo_sbz (arm_insn_r->arm_insn, 5,
>> 12, 0))
>> + && (sbo_sbz (arm_insn_r->arm_insn, 13,
>> 4, 1))
>> + && (2 == bits (arm_insn_r->arm_insn,
>> 20, 21)))
>> + {
>> + /* Handle MSR insn. */
>> + if (9 == arm_insn_r->opcode)
>> + {
>> + /* CSPR is going to be changed. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + /* SPSR is going to be changed. */
>> + /* How to read SPSR value ? */
>> + printf_unfiltered (_("Process record does
>> not support instruction "
>> + "0x%0x at
>> address %s.\n"),
>> +
>> arm_insn_r->arm_insn,
>> + paddress
>> (arm_insn_r->gdbarch,
>> arm_insn_r->this_addr));
>> + return -1;
>> + }
>> + }
>> + else if ((9 == arm_insn_r->decode)
>> + && ((8 == arm_insn_r->opcode)
>> || (10 == arm_insn_r->opcode))
>> + && (!bit (arm_insn_r->arm_insn,
>> INSN_S_L_BIT_NUM)))
>> + {
>> + /* Handling SWP, SWPB. */
>> + /* These insns, changes register and memory as
>> well. */
>> + /* SWP or SWPB insn. */
>> + /* Get memory address given by Rn. */
>> + reg_src1 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + regcache_raw_read_unsigned (reg_cache, reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + /* SWP insn ?, swaps word. */
>> + if (8 == arm_insn_r->opcode)
>> + {
>> + record_buf_mem[0] = 4;
>> + }
>> + else
>> + {
>> + /* SWPB insn, swaps only byte. */
>> + record_buf_mem[0] = 1;
>> + }
>> + record_buf_mem[1] = u_buf[0].unsigned_regval;
>> + arm_insn_r->mem_rec_count = 1;
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else if ((3 == arm_insn_r->decode) && (0x12
>> == opcode1)
>> + && (sbo_sbz
>> (arm_insn_r->arm_insn, 9, 12, 1)))
>> + {
>> + /* Handle BLX, branch and link/exchange. */
>> + if (9 == arm_insn_r->opcode)
>> + {
>> + /* Branch is chosen by setting T bit of CSPR,
>> bitp[0] of Rm,
>> + and R14 stores the return
>> address. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = ARM_LR_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + }
>> + else if ((7 == arm_insn_r->decode) && (0x12
>> == opcode1))
>> + {
>> + /* Handle enhanced software breakpoint insn, BKPT
>> */
>> + /* CPSR is changed to be executed in ARM state,
>> disabling normal
>> + interrupts, entering abort mode.
>> */
>> + /* Accorindly to high vector configuration PC is
>> set accordingly */
>> + /* What if user hit breakpoint and type reverse,
>> in
>> + that case, we need to go back with
>> previous CPSR and
>> + Program Counter. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = ARM_LR_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> +
>> + /* Save SPSR also; how? */
>> + printf_unfiltered (_("Process record does not
>> support instruction "
>> + "0x%0x at address
>> %s.\n"),
>> +
>> arm_insn_r->arm_insn,
>> + paddress
>> (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> + return -1;
>> + }
>> + else if ((11 == arm_insn_r->decode)
>> + && (!bit (arm_insn_r->arm_insn,
>> INSN_S_L_BIT_NUM)))
>> + {
>> + /* Handle enhanced store insns and DSP insns (e.g.
>> LDRD)
>> + let us begin according to addressing modes
>> for store insns
>> + STRH insn, addresing modes are taken
>> following. */
>> + if ((14 == arm_insn_r->opcode) || (10 ==
>> arm_insn_r->opcode))
>> + {
>> + /* 1) Handle misc store, immediate offset.
>> */
>> + immed_low = bits (arm_insn_r->arm_insn, 0,
>> 3);
>> + immed_high = bits (arm_insn_r->arm_insn, 8,
>> 11);
>> + reg_src1 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + if (15 == reg_src1)
>> + {
>> + /* If R15 was used as Rn, hence current
>> PC+8. */
>> + u_buf[0].unsigned_regval =
>> u_buf[0].unsigned_regval + 8;
>> + }
>> + offset_8 = (immed_high << 4) |
>> immed_low;
>> + /* Calculate target store address. */
>> + if (14 == arm_insn_r->opcode)
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> + offset_8;
>> + }
>> + else
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> - offset_8;
>> + }
>> + record_buf_mem[0] = 2;
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> + }
>> + else if ((12 == arm_insn_r->opcode) || (8 ==
>> arm_insn_r->opcode))
>> + {
>> + /* 2) Store, register offset. */
>> + /* Get Rm. */
>> + reg_src1 = bits (arm_insn_r->arm_insn, 0,
>> 3);
>> + /* Get Rn. */
>> + reg_src2 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> + ,
>> &u_buf[1].unsigned_regval);
>>
>> + if (15 == reg_src2)
>> + {
>> + /* If R15 was used as Rn, hence current
>> PC+8. */
>> + u_buf[0].unsigned_regval =
>> u_buf[0].unsigned_regval + 8;
>> + }
>> + /* Calculate target store address, Rn +/- Rm,
>> register offset. */
>> + if (12 == arm_insn_r->opcode)
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> + u_buf[1].unsigned_regval;
>> + }
>> + else
>> + {
>> + tgt_mem_addr = u_buf[1].unsigned_regval
>> - u_buf[0].unsigned_regval;
>> + }
>> + record_buf_mem[0] = 2;
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> + }
>> + else if ((11 == arm_insn_r->opcode) || (15 ==
>> arm_insn_r->opcode)
>> + || (2 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode))
>> + {
>> + /* 3) Store, immediate pre-indexed. */
>> + /* 5) Store, immediate post-indexed. */
>> + immed_low = bits (arm_insn_r->arm_insn, 0,
>> 3);
>> + immed_high = bits (arm_insn_r->arm_insn, 8,
>> 11);
>> + offset_8 = (immed_high << 4) |
>> immed_low;
>> + reg_src1 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + regcache_raw_read_unsigned(reg_cache,
>> reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + /* Calculate target store address, Rn +/- Rm,
>> register offset. */
>> + if ((15 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode))
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> + offset_8;
>> + }
>> + else
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> - offset_8;
>> + }
>> + record_buf_mem[0] = 2;
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> + /* Record Rn also as it changes. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 16, 19);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else if ((9 == arm_insn_r->opcode) || (13 ==
>> arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (4 ==
>> arm_insn_r->opcode))
>> + {
>> + /* 4) Store, register pre-indexed. */
>> + /* 6) Store, register post -indexed. */
>> + reg_src1 = bits (arm_insn_r->arm_insn, 0,
>> 3);
>> + reg_src2 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> + ,
>> &u_buf[1].unsigned_regval);
>> + /* Calculate target store address, Rn +/- Rm,
>> register offset. */
>> + if ((13 == arm_insn_r->opcode) || (4 ==
>> arm_insn_r->opcode))
>> + {
>> + tgt_mem_addr = u_buf[0].unsigned_regval
>> + u_buf[1].unsigned_regval;
>> + }
>> + else
>> + {
>> + tgt_mem_addr = u_buf[1].unsigned_regval
>> - u_buf[0].unsigned_regval;
>> + }
>> + record_buf_mem[0] = 2;
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> + /* Record Rn also as it changes. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 16, 19);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + /* DSP insns (e.g. LDRD) TBD. */
>> + }
>> + else if ((1 == arm_insn_r->decode) && (0x12
>> == opcode1)
>> + && sbo_sbz
>> (arm_insn_r->arm_insn, 9, 12, 1))
>> + {
>> + /* Handle BX, branch and link/exchange. */
>> + /* Branch is chosen by setting T bit of CSPR,
>> bitp[0] of Rm. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else if ((1 == arm_insn_r->decode) && (0x16
>> == opcode1)
>> + && (sbo_sbz
>> (arm_insn_r->arm_insn, 9, 4, 1))
>> + && (sbo_sbz
>> (arm_insn_r->arm_insn, 17, 4, 1)))
>> + {
>> + /* Count leading zeros: CLZ. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else if ((!bit (arm_insn_r->arm_insn,
>> INSN_S_L_BIT_NUM))
>> + && ((8 == arm_insn_r->opcode) ||
>> (10 == arm_insn_r->opcode))
>> + && (sbo_sbz
>> (arm_insn_r->arm_insn, 17, 4, 1))
>> + && (sbo_sbz
>> (arm_insn_r->arm_insn, 1, 12, 0))
>> + )
>> + {
>> + /* Handle MRS insn. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else if (arm_insn_r->opcode <= 15)
>> + {
>> + /* Normal data processing insns. */
>> + /* Out of 11 shifter operands mode, all the insn
>> modifies destination
>> + register, which is specified by
>> 13-16 decode. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 12, 15);
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + else
>> + {
>> + gdb_assert_not_reached ("no decoding pattern
>> found");
>> + }
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (arm_insn_r->arm_mems,
>> arm_insn_r->mem_rec_count, record_buf_mem);
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 001 insns. */
>> +
>> +static int
>> +arm_handle_data_proc_imm_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + arm_insn_r->opcode = bits (arm_insn_r->arm_insn,
>> 21, 24);
>> + arm_insn_r->decode = bits (arm_insn_r->arm_insn,
>> 4, 7);
>> +
>> + if (((9 == arm_insn_r->opcode) || (11 ==
>> arm_insn_r->opcode))
>> + && (2 == bits (arm_insn_r->arm_insn,
>> 20, 21))
>> + && (sbo_sbz (arm_insn_r->arm_insn,
>> 13, 4, 1))
>> + )
>> + {
>> + /* Handle MSR insn. */
>> + if (9 == arm_insn_r->opcode)
>> + {
>> + /*CSPR is going to be changed. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + /* SPSR is going to be changed. */
>> + }
>> + }
>> + else if (arm_insn_r->opcode <= 15)
>> + {
>> + /* Normal data processing insns. */
>> + /* Out of 11 shifter operands mode, all the insn
>> modifies destination
>> + register, which is specified by
>> 13-16 decode. */
>> + record_buf[0] = bits (arm_insn_r->arm_insn,
>> 12, 15);
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + else
>> + {
>> + gdb_assert_not_reached ("no decoding pattern
>> found");
>> + }
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (arm_insn_r->arm_mems,
>> arm_insn_r->mem_rec_count, record_buf_mem);
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 010 insns. */
>> +
>> +static int
>> +arm_handle_ld_st_imm_offset_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> + uint32_t reg_src1 = 0 , reg_dest = 0;
>> + uint32_t offset_12 = 0, tgt_mem_addr = 0;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + memset(&u_buf, 0, sizeof (u_buf));
>> + arm_insn_r->opcode = bits (arm_insn_r->arm_insn,
>> 21, 24);
>> + arm_insn_r->decode = bits (arm_insn_r->arm_insn,
>> 4, 7);
>> +
>> + if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> + {
>> + reg_dest = bits (arm_insn_r->arm_insn, 12,
>> 15);
>> + /* LDR insn has a capability to do branching, if
>> + MOV LR, PC is precedded by LDR insn
>> having Rn as R15
>> + in that case, it emulates branch and
>> link insn, and hence we
>> + need to save CSPR and PC as well.
>> */
>> + if (15 != reg_dest)
>> + {
>> + record_buf[0] = bits
>> (arm_insn_r->arm_insn, 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + record_buf[0] = reg_dest;
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + }
>> + else
>> + {
>> + if ((8 == arm_insn_r->opcode) || (10 ==
>> arm_insn_r->opcode)
>> + || (12 == arm_insn_r->opcode) || (14 ==
>> arm_insn_r->opcode)
>> + || (9 == arm_insn_r->opcode) || (11 ==
>> arm_insn_r->opcode)
>> + || (13 == arm_insn_r->opcode) || (15 ==
>> arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (2 ==
>> arm_insn_r->opcode)
>> + || (4 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode)
>> + || (1 == arm_insn_r->opcode) || (3 ==
>> arm_insn_r->opcode)
>> + || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> + {
>> + /* Store, immediate offset, immediate
>> pre-indexed,
>> + immediate post-indexed.
>> */
>> + reg_src1 = bits (arm_insn_r->arm_insn,
>> 16, 19);
>> + offset_12 = bits (arm_insn_r->arm_insn,
>> 0, 11);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> + ,
>> &u_buf.unsigned_regval);
>> + /* U == 1 */
>> + if (bit (arm_insn_r->arm_insn, 23))
>> + {
>> + tgt_mem_addr = u_buf.unsigned_regval
>> + offset_12;
>> + }
>> + else
>> + {
>> + tgt_mem_addr = u_buf.unsigned_regval -
>> offset_12;
>> + }
>> +
>> + switch(arm_insn_r->opcode)
>> + {
>> + case 8:
>> + case 12:
>> + case 9:
>> + case 13:
>> + case 1:
>> + case 5:
>> + /* STR insn, STRT insn. */
>> + record_buf_mem[0] = 4;
>> + break;
>> +
>> + case 10:
>> + case 14:
>> + case 11:
>> + case 15:
>> + case 3:
>> + case 7:
>> + /* STRB insn, STRBT insn. */
>> + record_buf_mem[0] = 1;
>> + break;
>> +
>> + default:
>> + gdb_assert_not_reached ("Invalid
>> addressing mode for insn");
>> + break;
>> + }
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> +
>> + if ((9 == arm_insn_r->opcode) || (11 ==
>> arm_insn_r->opcode)
>> + || (13 == arm_insn_r->opcode) || (15 ==
>> arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (2 ==
>> arm_insn_r->opcode)
>> + || (4 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode)
>> + || (1 == arm_insn_r->opcode) || (3 ==
>> arm_insn_r->opcode)
>> + || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> + {
>> + /* We are handling pre-indexed mode;
>> post-indexed mode;
>> + where Rn is
>> going to be changed. */
>> + record_buf[0] = reg_src1;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + }
>> + }
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (arm_insn_r->arm_mems,
>> arm_insn_r->mem_rec_count, record_buf_mem);
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 011 insns. */
>> +
>> +static int
>> +arm_handle_ld_st_reg_offset_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> + uint32_t shift_imm = 0;
>> + uint32_t reg_src1 = 0, reg_src2 = 0, reg_dest = 0;
>> + uint32_t immed_high = 0, immed_low = 0, offset_12 = 0,
>> tgt_mem_addr = 0;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + struct
>> + {
>> + LONGEST signed_word;
>> + ULONGEST unsigned_regval;
>> + } u_buf[2];
>> +
>> + memset(&u_buf, 0, sizeof (u_buf));
>> + arm_insn_r->opcode = bits (arm_insn_r->arm_insn,
>> 21, 24);
>> + arm_insn_r->decode = bits (arm_insn_r->arm_insn,
>> 4, 7);
>> +
>> + /* Handle enhanced store insns and LDRD DSP insn,
>> + let us begin according to addressing modes for
>> store insns
>> + STRH insn. */
>> +
>> + /* LDR or STR? */
>> + if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> + {
>> + reg_dest = bits (arm_insn_r->arm_insn, 12,
>> 15);
>> + /* LDR insn has a capability to do branching, if
>> + MOV LR, PC is precedded by LDR insn
>> having Rn as R15
>> + in that case, it emulates branch and
>> link insn, and hence we
>> + need to save CSPR and PC as well.
>> */
>> + if (15 != reg_dest)
>> + {
>> + record_buf[0] = bits
>> (arm_insn_r->arm_insn, 12, 15);
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + record_buf[0] = reg_dest;
>> + record_buf[1] = ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> + }
>> + }
>> + else
>> + {
>> + if ((8 == arm_insn_r->opcode) || (10 ==
>> arm_insn_r->opcode)
>> + || (12 == arm_insn_r->opcode) || (14 ==
>> arm_insn_r->opcode)
>> + || (9 == arm_insn_r->opcode) || (11 ==
>> arm_insn_r->opcode)
>> + || (13 == arm_insn_r->opcode) || (15 ==
>> arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (2 ==
>> arm_insn_r->opcode)
>> + || (4 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode)
>> + || (1 == arm_insn_r->opcode) || (3 ==
>> arm_insn_r->opcode)
>> + || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> + {
>> + if (! bits (arm_insn_r->arm_insn, 4, 11))
>> + {
>> + /* Store insn, register offset and
>> register pre-indexed,
>> + register
>> post-indexed. */
>> + /* Get Rm. */
>> + reg_src1 = bits
>> (arm_insn_r->arm_insn, 0, 3);
>> + /* Get Rn. */
>> + reg_src2 = bits
>> (arm_insn_r->arm_insn, 16, 19);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> +
>> , &u_buf[0].unsigned_regval);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> +
>> ,
>> &u_buf[1].unsigned_regval);
>>
>> + if (15 == reg_src2)
>> + {
>> + /* If R15 was used as Rn, hence
>> current PC+8. */
>> + /* Pre-indexed mode doesnt reach
>> here ; illegal insn. */
>> + u_buf[0].unsigned_regval =
>> u_buf[0].unsigned_regval + 8;
>> + }
>> + /* Calculate target store address, Rn
>> +/- Rm, register offset. */
>> + /* U == 1. */
>> + if (bit (arm_insn_r->arm_insn, 23))
>> + {
>> + tgt_mem_addr =
>> u_buf[0].unsigned_regval +
>> u_buf[1].unsigned_regval;
>> + }
>> + else
>> + {
>> + tgt_mem_addr =
>> u_buf[1].unsigned_regval -
>> u_buf[0].unsigned_regval;
>> + }
>> +
>> + switch(arm_insn_r->opcode)
>> + {
>> + case 8:
>> + case 12:
>> + case 9:
>> + case 13:
>> + case 1:
>> + case 5:
>> + /* STR insn, STRT insn. */
>> + record_buf_mem[0] = 4;
>> + break;
>> +
>> + case 10:
>> + case 14:
>> + case 11:
>> + case 15:
>> + case 3:
>> + case 7:
>> + /* STRB insn, STRBT insn. */
>> + record_buf_mem[0] = 1;
>> + break;
>> +
>> + default:
>> + gdb_assert_not_reached
>> ("Invalid addressing mode for insn");
>> + break;
>> + }
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> +
>> + if ((9 == arm_insn_r->opcode) || (11
>> == arm_insn_r->opcode)
>> + || (13 == arm_insn_r->opcode) || (15
>> == arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (2 ==
>> arm_insn_r->opcode)
>> + || (4 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode)
>> + || (1 == arm_insn_r->opcode) || (3 ==
>> arm_insn_r->opcode)
>> + || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> + {
>> + /* Rn is going to be changed in
>> pre-indexed mode and
>> +
>> post-indexed mode as well. */
>> + record_buf[0] = reg_src2;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + }
>> + else
>> + {
>> + /* Store insn, scaled register offset;
>> scaled pre-indexed. */
>> + offset_12 = bits
>> (arm_insn_r->arm_insn, 5, 6);
>> + /* Get Rm. */
>> + reg_src1 = bits
>> (arm_insn_r->arm_insn, 0, 3);
>> + /* Get Rn. */
>> + reg_src2 = bits
>> (arm_insn_r->arm_insn, 16, 19);
>> + /* Get shift_imm. */
>> + shift_imm = bits
>> (arm_insn_r->arm_insn, 7, 11);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> +
>> , &u_buf[0].unsigned_regval);
>> + regcache_raw_read_signed (reg_cache,
>> reg_src1
>> +
>> , &u_buf[0].signed_word);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> +
>> , &u_buf[1].unsigned_regval);
>> + /* Offset_12 used as shift. */
>> + switch(offset_12)
>> + {
>> + case 0:
>> + /* Offset_12 used as index.
>> */
>> + offset_12 =
>> u_buf[0].unsigned_regval << shift_imm;
>> + break;
>> +
>> + case 1:
>> + offset_12 =
>> (!shift_imm)?0:u_buf[0].unsigned_regval >>
>> shift_imm;
>>
>> + break;
>> +
>> + case 2:
>> + if (!shift_imm)
>> + {
>> + if (bit
>> (u_buf[0].unsigned_regval, 31))
>> + {
>> + offset_12 =
>> 0xFFFFFFFF;
>> + }
>> + else
>> + {
>> + offset_12 = 0;
>> + }
>> + }
>> + else
>> + {
>> + /* This is arithmetic
>> shift. */
>> + offset_12 =
>> u_buf[0].signed_word >> shift_imm;
>> + }
>> + break;
>> +
>> + case 3:
>> + if (!shift_imm)
>> + {
>> +
>> regcache_raw_read_unsigned (reg_cache, ARM_PS_REGNUM
>> +
>> , &u_buf[1].unsigned_regval);
>> + /* Get C flag value and
>> shift it by 31. */
>> + offset_12 = (((bit
>> (u_buf[1].unsigned_regval, 29)) << 31)
>> \
>> + |
>> (u_buf[0].unsigned_regval) >> 1);
>> + }
>> + else
>> + {
>> + offset_12 =
>> (u_buf[0].unsigned_regval >> shift_imm) \
>> + |
>> (u_buf[0].unsigned_regval << (sizeof(uint32_t) -
>> shift_imm));
>> + }
>> + break;
>> +
>> + default:
>> + gdb_assert_not_reached
>> ("Invalid addressing mode for insn");
>> + break;
>> + }
>> +
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> +
>> , &u_buf[1].unsigned_regval);
>> + /* U == 1 */
>> + if (bit (arm_insn_r->arm_insn, 23))
>> + {
>> + tgt_mem_addr =
>> u_buf[1].unsigned_regval + offset_12;
>> + }
>> + else
>> + {
>> + tgt_mem_addr =
>> u_buf[1].unsigned_regval - offset_12;
>> + }
>> +
>> + switch (arm_insn_r->opcode)
>> + {
>> + case 8:
>> + case 12:
>> + case 9:
>> + case 13:
>> + case 1:
>> + case 5:
>> + /* STR insn, STRT insn. */
>> + record_buf_mem[0] = 4;
>> + break;
>> +
>> + case 10:
>> + case 14:
>> + case 11:
>> + case 15:
>> + case 3:
>> + case 7:
>> + /* STRB insn, STRBT insn. */
>> + record_buf_mem[0] = 1;
>> + break;
>> +
>> + default:
>> + gdb_assert_not_reached
>> ("Invalid addressing mode for insn");
>> + break;
>> + }
>> + record_buf_mem[1] = tgt_mem_addr;
>> + arm_insn_r->mem_rec_count = 1;
>> +
>> + if ((9 == arm_insn_r->opcode) || (11
>> == arm_insn_r->opcode)
>> + || (13 == arm_insn_r->opcode) || (15
>> == arm_insn_r->opcode)
>> + || (0 == arm_insn_r->opcode) || (2 ==
>> arm_insn_r->opcode)
>> + || (4 == arm_insn_r->opcode) || (6 ==
>> arm_insn_r->opcode)
>> + || (1 == arm_insn_r->opcode) || (3 ==
>> arm_insn_r->opcode)
>> + || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> + {
>> + /* Rn is going to be changed in
>> register scaled pre-indexed
>> + mode, and
>> scaled post indexed mode. */
>> + record_buf[0] = reg_src2;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> + }
>> + }
>> + }
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (arm_insn_r->arm_mems,
>> arm_insn_r->mem_rec_count, record_buf_mem);
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 100 insns. */
>> +
>> +static int
>> +arm_handle_ld_st_multiple_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> + uint32_t register_list[16] = {0}, register_count = 0,
>> register_bits = 0;
>>
>>
>> + uint32_t shift_imm = 0;
>> + uint32_t reg_src1 = 0, reg_src2 = 0, addr_mode = 0,
>> no_of_regs = 0;
>> + uint32_t start_address = 0, index = 0;
>> + uint32_t record_buf[24], record_buf_mem[48];
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf[2];
>> +
>> + memset (&u_buf, 0, sizeof(u_buf));
>> +
>> + /* This mode is exclusively for load and store
>> multiple. */
>> + /* Handle incremenrt after/before and decrment
>> after.before mode;
>> + Rn is changing depending on W bit, but as of
>> now we store Rn too
>> without optmization. */
>> +
>> + if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> + {
>> + /* LDM (1,2,3) where LDM (3) changes CPSR too.
>> */
>> +
>> + if ((bit (arm_insn_r->arm_insn,20)) &&
>> !(bit (arm_insn_r->arm_insn,22)))
>> + {
>> + register_bits = bits
>> (arm_insn_r->arm_insn, 0, 15);
>> + no_of_regs = 15;
>> + }
>> + else
>> + {
>> + register_bits = bits
>> (arm_insn_r->arm_insn, 0, 14);
>> + no_of_regs = 14;
>> + }
>> + /* Get Rn. */
>> + reg_src1 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_list[register_count++] = 1;
>> + register_bits = register_bits >> 1;
>> + }
>> +
>> + /* Extra space for Base Register and CPSR;
>> wihtout optmization. */
>> + record_buf[register_count] = reg_src1;
>> + record_buf[register_count + 1] =
>> ARM_PS_REGNUM;
>> + arm_insn_r->reg_rec_count = register_count
>> + 2;
>> +
>> + for (register_count = 0; register_count <
>> no_of_regs; register_count++)
>> + {
>> + if (register_list[register_count])
>> + {
>> + /* Register_count gives total no of
>> registers and dually working
>> + as reg number.
>> */
>> + record_buf[index] =
>> register_count;
>> + index++;
>> + }
>> + }
>> +
>> + }
>> + else
>> + {
>> + /* It handles both STM(1) and STM(2). */
>> + addr_mode = bits (arm_insn_r->arm_insn, 23, 24);
>> +
>> + register_bits = bits (arm_insn_r->arm_insn, 0,
>> 15);
>> + /* Get Rn. */
>> + reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> + regcache_raw_read_unsigned (reg_cache, reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_count++;
>> + register_bits = register_bits >> 1;
>> + }
>> +
>> + switch(addr_mode)
>> + {
>> + /* Decrement after. */
>> + case 0:
>> + start_address = (u_buf[0].unsigned_regval)
>> - (register_count * 4) +
>> 4;
>> + arm_insn_r->mem_rec_count =
>> register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) -
>> 1] = start_address;
>> + record_buf_mem[(register_count * 2) -
>> 2] = 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + break;
>> +
>> + /* Increment after. */
>> + case 1:
>> + start_address = u_buf[0].unsigned_regval;
>> + arm_insn_r->mem_rec_count =
>> register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) -
>> 1] = start_address;
>> + record_buf_mem[(register_count * 2) -
>> 2] = 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + break;
>> +
>> + /* Decrement before. */
>> + case 2:
>> +
>> + start_address = (u_buf[0].unsigned_regval)
>> - (register_count * 4);
>> + arm_insn_r->mem_rec_count =
>> register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) -
>> 1] = start_address;
>> + record_buf_mem[(register_count * 2) -
>> 2] = 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + break;
>> +
>> + /* Increment before. */
>> + case 3:
>> + start_address = u_buf[0].unsigned_regval +
>> 4;
>> + arm_insn_r->mem_rec_count =
>> register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) -
>> 1] = start_address;
>> + record_buf_mem[(register_count * 2) -
>> 2] = 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + break;
>> +
>> + default:
>> + gdb_assert_not_reached ("Invalid addressing
>> mode for insn");
>> + break;
>> + }
>> +
>> + /* Base register also changes; based on condition
>> and W bit. */
>> + /* We save it anyway without optimization. */
>> + record_buf[0] = reg_src1;
>> + arm_insn_r->reg_rec_count = 1;
>> + }
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (arm_insn_r->arm_mems,
>> arm_insn_r->mem_rec_count, record_buf_mem);
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 101 insns. */
>> +
>> +static int
>> +arm_handle_brn_insn (insn_decode_record *arm_insn_r)
>> +{
>> +
>> + uint32_t record_buf[8];
>> +
>> + /* Handle B, BL, BLX(1) insns. */
>> + /* Wihtout optmization we save link register,
>> + CSPR for the insn which changes T bit. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = ARM_LR_REGNUM;
>> + arm_insn_r->reg_rec_count = 2;
>> +
>> + REG_ALLOC (arm_insn_r->arm_regs,
>> arm_insn_r->reg_rec_count, record_buf);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 110 insns. */
>> +
>> +static int
>> +arm_handle_coproc_insn (insn_decode_record *arm_insn_r)
>> +{
>> + printf_unfiltered (_("Process record does not support
>> instruction "
>> + "0x%0x at address %s.\n"),
>> + arm_insn_r->arm_insn,
>> + paddress
>> (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +
>> + return -1;
>> +}
>> +
>> +/* Handling opcode 111 insns. */
>> +
>> +static int
>> +arm_handle_coproc_data_proc_insn (insn_decode_record
>> *arm_insn_r)
>> +{
>> + struct gdbarch_tdep *tdep = gdbarch_tdep
>> (arm_insn_r->gdbarch);
>> + struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> + uint32_t shift_imm = 0;
>> + uint32_t reg_src1 = 0, reg_src2 = 0, addr_mode = 0;
>> + uint32_t start_address = 0;
>> +
>> + /* Handle SWI insn; system call would be handled over
>> here. */
>> +
>> + arm_insn_r->opcode = bits (arm_insn_r->arm_insn,
>> 24, 27);
>> + if (15 == arm_insn_r->opcode)
>> + {
>> + /* Handle arm syscall insn. */
>> + if (tdep->arm_swi_record != NULL)
>> + {
>> + tdep->arm_swi_record(reg_cache);
>> + }
>> + else
>> + {
>> + printf_unfiltered (_("no syscall record
>> support\n"));
>> + return -1;
>> + }
>> + }
>> +
>> + printf_unfiltered (_("Process record does not support
>> instruction "
>> + "0x%0x at address
>> %s.\n"),
>> +
>> arm_insn_r->arm_insn,
>> + paddress
>> (arm_insn_r->gdbarch,
>> arm_insn_r->this_addr));
>> + return -1;
>> +}
>> +
>> +/* Handling opcode 000 insns. */
>> +
>> +static int
>> +thumb_handle_shift_add_sub_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + uint32_t record_buf[8];
>> + uint32_t reg_src1 = 0;
>> +
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 2;
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> +
>> + return 0;
>> +}
>> +
>> +
>> +/* Handling opcode 001 insns. */
>> +
>> +static int
>> +thumb_handle_add_sub_cmp_mov_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + uint32_t record_buf[8];
>> + uint32_t reg_src1 = 0;
>> +
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 2;
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 010 insns. */
>> +
>> +static int
>> +thumb_handle_ld_st_reg_offset_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + struct regcache *reg_cache =
>> thumb_insn_r->regcache;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + uint32_t reg_src1 = 0, reg_src2 = 0;
>> + uint32_t opcode1 = 0, opcode2 = 0, opcode3 = 0;
>> +
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + gdb_byte buf[4];
>> + } u_buf[2];
>> +
>> + opcode1 = bits (thumb_insn_r->arm_insn, 10, 12);
>> +
>> + if (bit (thumb_insn_r->arm_insn, 12))
>> + {
>> + /* Handle load/store register offset. */
>> + opcode2 = bits (thumb_insn_r->arm_insn, 9,
>> 10);
>> + if ((opcode2 >= 12) && (opcode2 <=
>> 15))
>> + {
>> + /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH.
>> */
>> + reg_src1 = bits
>> (thumb_insn_r->arm_insn,0, 2);
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if ((opcode2 >= 8) && (opcode2
>> <= 10))
>> + {
>> + /* STR(2), STRB(2), STRH(2) . */
>> + reg_src1 = bits (thumb_insn_r->arm_insn,
>> 3, 5);
>> + reg_src2 = bits (thumb_insn_r->arm_insn,
>> 6, 8);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> + ,
>> &u_buf[0].unsigned_regval);
>> + regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> + ,
>> &u_buf[1].unsigned_regval);
>> + if (8 == opcode2)
>> + record_buf_mem[0] = 4; /* STR (2).
>> */
>> + else if (10 == opcode2)
>> + record_buf_mem[0] = 1; /* STRB
>> (2). */
>> + else if (9 == opcode2)
>> + record_buf_mem[0] = 2; /* STRH (2).
>> */
>> + record_buf_mem[1] =
>> u_buf[0].unsigned_regval+u_buf[1].unsigned_regval;
>>
>> + thumb_insn_r->mem_rec_count = 1;
>> + }
>> + }
>> + else if (bit (thumb_insn_r->arm_insn, 11))
>> + {
>> + /* Handle load from literal pool. */
>> + /* LDR(3). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>>
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if (opcode1)
>> + {
>> + opcode2 = bits (thumb_insn_r->arm_insn, 8,
>> 9);
>> + opcode3 = bits (thumb_insn_r->arm_insn, 0,
>> 2);
>> + if ((3 == opcode2) && (!opcode3))
>> + {
>> + /* Branch with exchange. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + /* Format 8; special data processing insns.
>> */
>> + reg_src1 = bits (thumb_insn_r->arm_insn,
>> 0, 2);
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 2;
>> + }
>> + }
>> + else
>> + {
>> + /* Format 5; data processing insns. */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 0,
>> 2);
>> + if (bit (thumb_insn_r->arm_insn, 7))
>> + {
>> + reg_src1 = reg_src1 + 8;
>> + }
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 2;
>> + }
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (thumb_insn_r->arm_mems,
>> thumb_insn_r->mem_rec_count,
>> record_buf_mem);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 001 insns. */
>> +
>> +static int
>> +thumb_handle_ld_st_imm_offset_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + struct regcache *reg_cache =
>> thumb_insn_r->regcache;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + uint32_t reg_val1 = 0;
>> + uint32_t reg_src1 = 0;
>> + uint32_t opcode = 0, immed_5 = 0;
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> + if (opcode)
>> + {
>> + /* LDR(1). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 0,
>> 2);
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else
>> + {
>> + /* STR(1). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 3,
>> 5);
>> + immed_5 = bits (thumb_insn_r->arm_insn, 6,
>> 10);
>> + regcache_raw_read_unsigned (reg_cache, reg_src1
>> + ,
>> &u_buf.unsigned_regval);
>> + record_buf_mem[0] = 4;
>> + record_buf_mem[1] = u_buf.unsigned_regval +
>> (immed_5 * 4);
>> + thumb_insn_r->mem_rec_count = 1;
>> + }
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (thumb_insn_r->arm_mems,
>> thumb_insn_r->mem_rec_count,
>> record_buf_mem);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 100 insns. */
>> +
>> +static int
>> +thumb_handle_ld_st_stack_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + struct regcache *reg_cache =
>> thumb_insn_r->regcache;
>> + uint32_t record_buf[8], record_buf_mem[8];
>> +
>> + uint32_t reg_val1 = 0;
>> + uint32_t reg_src1 = 0;
>> + uint32_t opcode = 0, immed_8 = 0, immed_5 = 0;
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> + if (3 == opcode)
>> + {
>> + /* LDR(4). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if (1 == opcode)
>> + {
>> + /* LDRH(1). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 0,
>> 2);
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if (2 == opcode)
>> + {
>> + /* STR(3). */
>> + immed_8 = bits (thumb_insn_r->arm_insn, 0,
>> 7);
>> + regcache_raw_read_unsigned (reg_cache,
>> ARM_SP_REGNUM
>> + ,
>> &u_buf.unsigned_regval);
>> + record_buf_mem[0] = 4;
>> + record_buf_mem[1] = u_buf.unsigned_regval +
>> (immed_8 * 4);
>> + thumb_insn_r->mem_rec_count = 1;
>> + }
>> + else if (0 == opcode)
>> + {
>> + /* STRH(1). */
>> + immed_5 = bits (thumb_insn_r->arm_insn, 6,
>> 10);
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 3,
>> 5);
>> + regcache_raw_read_unsigned (reg_cache, reg_src1
>> + ,
>> &u_buf.unsigned_regval);
>> + record_buf_mem[0] = 2;
>> + record_buf_mem[1] = u_buf.unsigned_regval +
>> (immed_5 * 2);
>> + thumb_insn_r->mem_rec_count = 1;
>> + }
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (thumb_insn_r->arm_mems,
>> thumb_insn_r->mem_rec_count,
>> record_buf_mem);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 101 insns. */
>> +
>> +static int
>> +thumb_handle_misc_insn (insn_decode_record *thumb_insn_r)
>> +{
>> + struct regcache *reg_cache =
>> thumb_insn_r->regcache;
>> +
>> + uint32_t reg_val1 = 0;
>> + uint32_t reg_src1 = 0;
>> + uint32_t opcode = 0, opcode1 = 0, opcode2 = 0, immed_8
>> = 0, immed_5 = 0;
>> + uint32_t register_bits = 0, register_count = 0;
>> + uint32_t register_list[8] = {0}, index = 0,
>> start_address = 0;
>> + uint32_t record_buf[24], record_buf_mem[48];
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> + opcode1 = bits (thumb_insn_r->arm_insn, 8, 12);
>> + opcode2 = bits (thumb_insn_r->arm_insn, 9, 12);
>> +
>> + if (14 == opcode2)
>> + {
>> + /* POP. */
>> + register_bits = bits (thumb_insn_r->arm_insn,
>> 0, 7);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_list[register_count++] = 1;
>> + register_bits = register_bits >> 1;
>> + }
>> + record_buf[register_count] = ARM_PS_REGNUM;
>> + record_buf[register_count + 1] = ARM_SP_REGNUM;
>> + thumb_insn_r->reg_rec_count = register_count +
>> 2;
>> + for (register_count = 0; register_count < 8;
>> register_count++)
>> + {
>> + if (register_list[register_count])
>> + {
>> + record_buf[index] = register_count;
>> + index++;
>> + }
>> + }
>> + }
>> + else if (10 == opcode2)
>> + {
>> + /* PUSH. */
>> + register_bits = bits (thumb_insn_r->arm_insn,
>> 0, 7);
>> + regcache_raw_read_unsigned (reg_cache,
>> ARM_PC_REGNUM
>> + ,
>> &u_buf.unsigned_regval);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_count++;
>> + register_bits = register_bits >> 1;
>> + }
>> + start_address = u_buf.unsigned_regval - \
>> + (4 * (bit
>> (thumb_insn_r->arm_insn, 8) + register_count)) ;
>> + thumb_insn_r->mem_rec_count = register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) - 1] =
>> start_address;
>> + record_buf_mem[(register_count * 2) - 2] =
>> 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + record_buf[0] = ARM_SP_REGNUM;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if (0x1E == opcode1)
>> + {
>> + /* BKPT insn. */
>> + /* Handle enhanced software breakpoint insn,
>> BKPT. */
>> + /* CPSR is changed to be executed in ARM state,
>> disabling normal
>> + interrupts, entering abort mode.
>> */
>> + /* Accorindly to high vector configuration PC is
>> set accordingly. */
>> + /* FIX ME ? what if user hit breakpoint and
>> type reverse, in
>> + that case, we need to go back with
>> previous CPSR and
>> + Program Counter.. */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = ARM_LR_REGNUM;
>> + thumb_insn_r->reg_rec_count = 2;
>> + /* Save SPSR also; how?. */
>> + printf_unfiltered (_("Process record does not
>> support instruction "
>> + "0x%0x at address
>> %s.\n"),
>> +
>> thumb_insn_r->arm_insn,
>> + paddress
>> (thumb_insn_r->gdbarch,
>> thumb_insn_r->this_addr));
>> + return -1;
>> + }
>> + else if ((0 == opcode) || (1 == opcode))
>> + {
>> + /* ADD(5), ADD(6). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>> + record_buf[0] = reg_src1;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> + else if (2 == opcode)
>> + {
>> + /* ADD(7), SUB(4). */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>> + record_buf[0] = ARM_SP_REGNUM;
>> + thumb_insn_r->reg_rec_count = 1;
>> + }
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (thumb_insn_r->arm_mems,
>> thumb_insn_r->mem_rec_count,
>> record_buf_mem);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 110 insns. */
>> +
>> +static int
>> +thumb_handle_swi_insn (insn_decode_record *thumb_insn_r)
>> +{
>> + struct gdbarch_tdep *tdep = gdbarch_tdep
>> (thumb_insn_r->gdbarch);
>> + struct regcache *reg_cache =
>> thumb_insn_r->regcache;
>> +
>> + uint32_t reg_val1 = 0;
>> + uint32_t reg_src1 = 0;
>> + uint32_t opcode1 = 0, opcode2 = 0, register_bits = 0,
>> register_count = 0;
>> + uint32_t register_list[8] = {0}, index = 0,
>> start_address = 0;
>> + uint32_t record_buf[24], record_buf_mem[48];
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + opcode1 = bits (thumb_insn_r->arm_insn, 8, 12);
>> + opcode2 = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> + if (1 == opcode2)
>> + {
>> +
>> + /* LDMIA. */
>> + register_bits = bits (thumb_insn_r->arm_insn,
>> 0, 7);
>> + /* Get Rn. */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_list[register_count++] = 1;
>> + register_bits = register_bits >> 1;
>> + }
>> + record_buf[register_count] = reg_src1;
>> + thumb_insn_r->reg_rec_count = register_count +
>> 1;
>> + for (register_count = 0; register_count < 8;
>> register_count++)
>> + {
>> + if (register_list[register_count])
>> + {
>> + record_buf[index] = register_count;
>> + index++;
>> + }
>> + }
>> + }
>> + else if (0 == opcode2)
>> + {
>> + /* It handles both STMIA. */
>> + register_bits = bits (thumb_insn_r->arm_insn,
>> 0, 7);
>> + /* Get Rn. */
>> + reg_src1 = bits (thumb_insn_r->arm_insn, 8,
>> 10);
>> + regcache_raw_read_unsigned (reg_cache, reg_src1,
>> &u_buf.unsigned_regval);
>> + while (register_bits)
>> + {
>> + if (register_bits & 0x00000001)
>> + register_count++;
>> + register_bits = register_bits >> 1;
>> + }
>> + start_address = u_buf.unsigned_regval;
>> + thumb_insn_r->mem_rec_count = register_count;
>> + while (register_count)
>> + {
>> + record_buf_mem[(register_count * 2) - 1] =
>> start_address;
>> + record_buf_mem[(register_count * 2) - 2] =
>> 4;
>> + start_address = start_address + 4;
>> + register_count--;
>> + }
>> + }
>> + else if (0x1F == opcode1)
>> + {
>> + /* Handle arm syscall insn. */
>> + if (tdep->arm_swi_record != NULL)
>> + {
>> + tdep->arm_swi_record(reg_cache);
>> + }
>> + else
>> + {
>> + printf_unfiltered (_("no syscall record
>> support\n"));
>> + return -1;
>> + }
>> + }
>> +
>> + /* B(1), conditional branch is automatically taken care
>> in process_record,
>> + as PC is saved there. */
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> + MEM_ALLOC (thumb_insn_r->arm_mems,
>> thumb_insn_r->mem_rec_count,
>> record_buf_mem);
>> +
>> + return 0;
>> +}
>> +
>> +/* Handling opcode 111 insns. */
>> +
>> +static int
>> +thumb_handle_branch_insn (insn_decode_record
>> *thumb_insn_r)
>> +{
>> + uint32_t record_buf[8];
>> + uint32_t reg_val1 = 0;
>> + uint32_t reg_src1 = 0;
>> + uint32_t opcode = 0, immed_5 = 0;
>> +
>> +
>> + /* BL , BLX(1). */
>> + record_buf[0] = ARM_PS_REGNUM;
>> + record_buf[1] = ARM_LR_REGNUM;
>> + thumb_insn_r->reg_rec_count = 2;
>> +
>> + /* B(2) is automatically taken care in process_record,
>> as PC is saved
>> + there. */
>> +
>> + REG_ALLOC (thumb_insn_r->arm_regs,
>> thumb_insn_r->reg_rec_count, record_buf);
>> +
>> + return 0;
>> +}
>> +
>> +
>> +/* Decode arm/thumb insn depending on condition cods and
>> opcodes; and dispatch
>> it. */
>> +
>> +static int
>> +decode_insn (insn_decode_record *arm_record, uint32_t
>> insn_size)
>> +{
>> +
>> + /* (Starting from numerical 0); bits 25, 26, 27 decodes
>> type of arm
>> instruction. */
>> + static int (*const arm_handle_insn[8])
>> +
>> (insn_decode_record*) =
>> + {
>> + arm_handle_data_proc_misc_ld_str_insn, /*
>> 000. */
>> + arm_handle_data_proc_imm_insn,
>> /* 001. */
>> + arm_handle_ld_st_imm_offset_insn, /*
>> 010. */
>> + arm_handle_ld_st_reg_offset_insn, /*
>> 011. */
>> + arm_handle_ld_st_multiple_insn, /*
>> 100. */
>> + arm_handle_brn_insn,
>> /* 101. */
>> + arm_handle_coproc_insn,
>> /* 110. */
>> + arm_handle_coproc_data_proc_insn /*
>> 111. */
>> + };
>> +
>> + /* (Starting from numerical 0); bits 13,14,15 decodes
>> type of thumb
>> instruction. */
>> + static int (*const thumb_handle_insn[8])
>> +
>> (insn_decode_record*) =
>> + { \
>> + thumb_handle_shift_add_sub_insn, /*
>> 000. */
>> + thumb_handle_add_sub_cmp_mov_insn, /*
>> 001. */
>> + thumb_handle_ld_st_reg_offset_insn, /*
>> 010. */
>> + thumb_handle_ld_st_imm_offset_insn, /*
>> 011. */
>> + thumb_handle_ld_st_stack_insn, /*
>> 100. */
>> + thumb_handle_misc_insn,
>> /* 101. */
>> + thumb_handle_swi_insn,
>> /* 110. */
>> + thumb_handle_branch_insn
>> /* 111. */
>> + };
>> +
>> + struct
>> + {
>> + gdb_byte buf[insn_size];
>> + } u_buf;
>> +
>> + uint32_t ret=0, insn_id = 0;
>> +
>> + memset (&u_buf, 0, sizeof(u_buf));
>> + if (target_read_memory (arm_record->this_addr,
>> &u_buf.buf[0], insn_size))
>> + {
>> + if (record_debug)
>> + {
>> + printf_unfiltered (_("Process record: error
>> reading memory at "
>> + "addr %s len
>> = %d.\n"),
>> + paddress (arm_record->gdbarch,
>> arm_record->this_addr), insn_size);
>> + return -1;
>> + }
>> + }
>> + else if (ARM_INSN_SIZE_BYTES == insn_size)
>> + {
>> + arm_record->arm_insn = (uint32_t)
>> extract_unsigned_integer (&u_buf.buf[0]
>> + , ARM_INSN_SIZE_BYTES ,
>> gdbarch_byte_order (arm_record->gdbarch));
>>
>> + arm_record->cond = bits
>> (arm_record->arm_insn, 28, 31);
>> + insn_id = bits (arm_record->arm_insn, 25,
>> 27);
>> + ret = (0x0F != arm_record->cond)
>> + ? arm_handle_insn[insn_id] (arm_record)
>> + : handle_extension_space (arm_record);
>> + }
>> + else if (THUMB_INSN_SIZE_BYTES == insn_size)
>> + {
>> + /* As thumb does not have condition codes,
>> following field is useless.
>> */
>> + arm_record->cond = -1;
>> + arm_record->arm_insn = (uint32_t)
>> extract_unsigned_integer (&u_buf.buf[0]
>> + , THUMB_INSN_SIZE_BYTES ,
>> gdbarch_byte_order (arm_record->gdbarch));
>> +
>> + insn_id = bits (arm_record->arm_insn, 13,
>> 15);
>> + ret = thumb_handle_insn[insn_id] (arm_record);
>> + }
>> + else if (THUMB2_INSN_SIZE_BYTES == insn_size)
>> + {
>> + /* Yet to be implemented; handle thumb2 part
>> here. */
>> + printf_unfiltered (_("Process record does not
>> support instruction 0x%0x "
>> + "at address %s.\n"),
>> +
>> arm_record->arm_insn,
>> + paddress
>> (arm_record->gdbarch,
>> arm_record->this_addr));
>> + ret = -1;
>> + }
>> + else
>> + {
>> + /* Throw assertion. */
>> + gdb_assert(0);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +/* Parse the current instruction and record the values of
>> the registers and
>> + memory that will be changed in current instruction to
>> "record_arch_list".
>> + Return -1 if something is wrong.. */
>> +
>> +int
>> +arm_process_record (struct gdbarch *gdbarch, struct
>> regcache *regcache,
>> + CORE_ADDR
>> insn_addr)
>> +{
>> +
>> + enum bfd_endian byte_order = gdbarch_byte_order
>> (gdbarch);
>> + uint32_t no_of_rec = 0;
>> + uint32_t ret = 0;
>> + ULONGEST t_bit = 0;
>> +
>> + struct
>> + {
>> + ULONGEST unsigned_regval;
>> + } u_buf;
>> +
>> + insn_decode_record arm_record;
>> + memset (&u_buf, 0, sizeof(u_buf));
>> +
>> + memset (&arm_record, 0, sizeof
>> (insn_decode_record));
>> + arm_record.regcache = regcache;
>> + arm_record.this_addr = insn_addr;
>> + arm_record.gdbarch = gdbarch;
>> +
>> +
>> + if (record_debug > 1)
>> + {
>> + fprintf_unfiltered (gdb_stdlog, "Process record:
>> arm_process_record "
>> +
>> "addr = %s\n",
>> + paddress (gdbarch, arm_record.this_addr));
>> + }
>> +
>> + /* Check the insn, whether it is thumb or arm one.
>> */
>> +
>> + t_bit = arm_psr_thumb_bit (arm_record.gdbarch);
>> + regcache_raw_read_unsigned (arm_record.regcache,
>> ARM_PS_REGNUM
>> + ,
>> &u_buf.unsigned_regval);
>> +
>> + if (!(u_buf.unsigned_regval & t_bit))
>> + {
>> + /* We are decoding arm insn. */
>> + ret = decode_insn (&arm_record,
>> ARM_INSN_SIZE_BYTES);
>> + }
>> + else
>> + {
>> + /* We are decoding thumb insn. */
>> + ret = decode_insn (&arm_record,
>> THUMB_INSN_SIZE_BYTES);
>> + }
>> +
>> + if (0 == ret)
>> + {
>> + /* Record registers. */
>> + record_arch_list_add_reg (arm_record.regcache,
>> ARM_PC_REGNUM);
>> + if (arm_record.arm_regs)
>> + {
>> + for (no_of_rec = 0; no_of_rec <
>> arm_record.reg_rec_count;
>> no_of_rec++)
>> + {
>> + if (record_arch_list_add_reg
>> (arm_record.regcache \
>> +
>> , (arm_record.arm_regs[no_of_rec])))
>> + ret = -1;
>> + }
>> + }
>> + /* Record memories. */
>> + if (arm_record.arm_mems)
>> + {
>> + for (no_of_rec = 0; no_of_rec <
>> arm_record.mem_rec_count;
>> no_of_rec++)
>> + {
>> + if (record_arch_list_add_mem \
>> +
>> ((CORE_ADDR)arm_record.arm_mems[no_of_rec].addr,
>> +
>> arm_record.arm_mems[no_of_rec].len))
>> + ret = -1;
>> + }
>> + }
>> +
>> + if (record_arch_list_add_end ())
>> + ret = -1;
>> + }
>> +
>> + if (arm_record.arm_regs)
>> + xfree (arm_record.arm_regs);
>> + if (arm_record.arm_mems)
>> + xfree (arm_record.arm_mems);
>> +
>> + return ret;
>> +}
>> diff -urN arm_orig/arm-tdep.h arm_new/arm-tdep.h
>> --- arm_orig/arm-tdep.h 2011-03-03 09:21:13.000000000
>> +0530
>> +++ arm_new/arm-tdep.h 2011-05-07 14:20:31.000000000
>> +0530
>> @@ -200,6 +200,9 @@
>> /* Return the expected next PC if FRAME is stopped at a
>> syscall
>> instruction. */
>> CORE_ADDR (*syscall_next_pc) (struct frame_info
>> *frame);
>> +
>> + /* Parse swi insn args, sycall record. */
>> + int (*arm_swi_record) (struct regcache *regcache);
>> };
>>
>> /* Structures used for displaced stepping. */
>> @@ -310,6 +313,10 @@
>> struct
>> displaced_step_closure *,
>> CORE_ADDR, CORE_ADDR,
>> struct regcache *);
>>
>> +extern int arm_process_record (struct gdbarch *gdbarch,
>> + struct
>> regcache *regcache, CORE_ADDR addr);
>> +
>> +
>> /* Functions exported from armbsd-tdep.h. */
>>
>> /* Return the appropriate register set for the core
>> section identified
>>
>
More information about the Gdb-patches
mailing list