From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 903 invoked by alias); 3 Mar 2011 04:08:51 -0000 Received: (qmail 32597 invoked by uid 22791); 3 Mar 2011 04:08:42 -0000 X-SWARE-Spam-Status: No, hits=0.1 required=5.0 tests=AWL,BAYES_05,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RFC_ABUSE_POST,TW_EG,TW_NR,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nm4-vm0.bullet.mail.sp2.yahoo.com (HELO nm4-vm0.bullet.mail.sp2.yahoo.com) (98.139.91.190) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Thu, 03 Mar 2011 04:08:30 +0000 Received: from [98.139.91.63] by nm4.bullet.mail.sp2.yahoo.com with NNFMP; 03 Mar 2011 04:08:28 -0000 Received: from [98.139.91.60] by tm3.bullet.mail.sp2.yahoo.com with NNFMP; 03 Mar 2011 04:08:28 -0000 Received: from [127.0.0.1] by omp1060.mail.sp2.yahoo.com with NNFMP; 03 Mar 2011 04:08:28 -0000 Received: (qmail 10471 invoked by uid 60001); 3 Mar 2011 04:08:28 -0000 Message-ID: <341905.10459.qm@web112513.mail.gq1.yahoo.com> Received: from [123.238.92.202] by web112513.mail.gq1.yahoo.com via HTTP; Wed, 02 Mar 2011 20:08:27 PST Date: Thu, 03 Mar 2011 04:08:00 -0000 From: paawan oza Subject: Re: [PATCH] arm reversible : progress To: "gdb@sourceware.org" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2011-03/txt/msg00029.txt.bz2 Hi, I am done with the deisng for both thumb and arm framework. coding guidelines are improved. having some doubts as of now. 1) what is the API to read arm coprocessor registers ? 2) how to read SPSR value ? 3) there are couple of FIX me in code. PS: patch progress is posted below. phase 3 will include thumb insn decoding part.phase 4 will include arm-linux ABI part. PATCH STARTS ------------------------------------ diff -urN arm_new/arm-linux-tdep.c arm_orig/arm-linux-tdep.c --- arm_new/arm-linux-tdep.c 2011-03-03 09:15:59.000000000 +0530 +++ arm_orig/arm-linux-tdep.c 2011-03-03 09:21:13.000000000 +0530 @@ -998,9 +998,6 @@ 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, diff -urN arm_new/arm-tdep.c arm_orig/arm-tdep.c --- arm_new/arm-tdep.c 2011-03-03 09:15:59.000000000 +0530 +++ arm_orig/arm-tdep.c 2011-03-03 09:21:13.000000000 +0530 @@ -54,11 +54,8 @@ #include "gdb_assert.h" #include "vec.h" -#include "record.h" - #include "features/arm-with-m.c" - static int arm_debug; /* Macros for setting and testing a bit in a minimal symbol that marks @@ -7932,1168 +7929,3 @@ NULL, /* FIXME: i18n: "ARM debugging is %s. */ &setdebuglist, &showdebuglist); } - - - -/* arm-reversible process reacord data structures */ - -#define ARM_INSN_SIZE_BYTES 4 -#define THUMB_INSN_SIZE_BYTES 2 -#define NO_OF_TYPE_OF_ARM_INSNS 8 -#define NO_OF_TYPE_OF_THUMB_INSNS 8 - -#define ARM_RECORD_ARCH_LIST_ADD_REG(regnum) \ - record_arch_list_add_reg (arm_record.regcache, regnum) - -#define GET_REG_VAL(REGCACHE,NO,BUF) regcache_raw_read (REGCACHE, NO, BUF); - -#define IS_IT_ARM_INSN(X) ((X & 0x00000010) >> 4) -#define ARM_PARSE_INSN(X,BIT_POS,NO_OF_BITS) \ - ((X >> (BIT_POS-1)) & (0xFFFFFFFF >> ((sizeof(uint32_t)*8) - \ - NO_OF_BITS))) - -#define INSN_S_L_BIT_NUM 21 -#define ARM_BIT_SET(X, NUM) (((X >> (NUM-1)) & 0x00000001) == 1) -#define GET_BIT(X, NUM) (((X >> (NUM-1)) & 0x00000001)) - - - -int arm_handle_data_proc_misc_load_str_insn (void*); -int arm_handle_data_proc_misc_load_str_insn (void*); -int arm_handle_data_proc_imm_insn (void*); -int arm_handle_ld_st_imm_offset_insn (void*); -int arm_handle_ld_st_reg_offset_insn (void*); -int arm_hamdle_ld_st_multiple_insn (void*); -int arm_handle_brn_insn (void*); -int arm_handle_coproc_insn (void*); -int arm_handle_coproc_data_proc_insn (void*); - -int thumb_handle_shift_add_sub_insn (void*); -int thumb_handle_data_proc_load_strbrn_insn (void*); -int thumb_handle_ld_st_reg_offset_insn (void*); -int thumb_handle_ld_st_imm_offset_insn (void*); -int thumb_hamdle_ld_st_stack_insn (void*); -int thumb_handle_misc_insn (void*); -int thumb_handle_swi_insn (void*); -int thumb_handle_branch_insn (void*); - - -/* (starting from numerical 0); bits 25,26,27 decodes type of arm instruction */ -int (*const arm_handle_insn[NO_OF_TYPE_OF_ARM_INSNS]) (void*) = -{ - arm_handle_data_proc_misc_load_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_hamdle_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 */ -int (*const thumb_handle_insn[NO_OF_TYPE_OF_THUMB_INSNS]) (void*) = -{ - thumb_handle_shift_add_sub_insn, /* 000 */ - thumb_handle_data_proc_load_strbrn_insn, /* 001 */ - thumb_handle_ld_st_reg_offset_insn, /* 010 */ - thumb_handle_ld_st_imm_offset_insn, /* 011 */ - thumb_hamdle_ld_st_stack_insn, /* 100 */ - thumb_handle_misc_insn, /* 101 */ - thumb_handle_swi_insn, /* 110 */ - thumb_handle_branch_insn /* 111 */ -}; - - -struct arm_mem_r -{ - uint32_t len; - CORE_ADDR addr; -}; - -typedef struct arm_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 accomodate thumb */ - uint32_t cond; /* condition code */ - uint32_t id; /* type of insn */ - uint32_t opcode; /* insn opcode */ - uint32_t decode; /* insn decode bits */ - uint32_t *arm_regs; /* registers to be saved for this record */ - struct arm_mem_r *arm_mems; /* memory to be saved for this record */ -} arm_insn_decode_record; - - -int -decode_insn (arm_insn_decode_record *arm_record, uint32_t insn_size) -{ - union - { - uint32_t s_word; - gdb_byte buf[insn_size]; - } u_buf; - - 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 = u_buf.s_word; - arm_record->id = ARM_PARSE_INSN (arm_record->arm_insn,26,3); - arm_handle_insn[arm_record->id] ((void*)arm_record); - } - else if(THUMB_INSN_SIZE_BYTES == insn_size) - { - arm_record->arm_insn = u_buf.s_word; - arm_record->id = ARM_PARSE_INSN (arm_record->arm_insn,14,3); - thumb_handle_insn[arm_record->id] ((void*)arm_record); - } - return 0; -} - -/* 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); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int no_of_rec=0; - - union - { - uint32_t s_word; - gdb_byte buf[4]; - } u_buf; - - arm_insn_decode_record arm_record; - - memset (&u_buf, 0, sizeof(u_buf)); - memset (&arm_record, 0, sizeof (arm_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 */ - GET_REG_VAL (arm_record.regcache, ARM_PS_REGNUM, &u_buf.buf[0]); - if (IS_IT_ARM_INSN (u_buf.s_word)) - { - /* we are decoding arm insn */ - decode_insn (&arm_record, 4); - } - else - { - /* we are decoding thumb insn */ - decode_insn (&arm_record, 2); - } - - /* record registers */ - ARM_RECORD_ARCH_LIST_ADD_REG(ARM_PC_REGNUM); - if(arm_record.arm_regs) - { - for(no_of_rec=1;no_of_rec<=arm_record.arm_regs[0];no_of_rec++) - { - if(ARM_RECORD_ARCH_LIST_ADD_REG (arm_record.arm_regs[no_of_rec])) - return -1; - } - } - /* record memories */ - if(arm_record.arm_mems) - { - for(no_of_rec=1;no_of_rec<=arm_record.arm_mems[0].len;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)) - return -1; - } - } - - if (record_arch_list_add_end ()) - return -1; - - xfree (arm_record.arm_regs); - xfree (arm_record.arm_mems); - return 0; -} - -int -arm_handle_data_proc_misc_load_str_insn (void *data) -{ - - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - union - { - uint32_t s_word; - gdb_byte buf[4]; - } u_buf[2]; - - - uint32_t reg_val1=0,reg_val2=0; - 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; - - memset(&u_buf, 0, sizeof(u_buf)); - - arm_insn_r->opcode = ARM_PARSE_INSN (arm_insn_r->arm_insn,22,4); - arm_insn_r->decode = ARM_PARSE_INSN (arm_insn_r->arm_insn,5,4); - - if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) - { - /* data processing insn /multiply sinsn */ - if(9 == arm_insn_r->decode) - { - /* handle multiply instructions */ - /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL */ - if((0 == arm_insn_r->opcode) || (1 == arm_insn_r->opcode)) - { - /* handle MLA and MUL */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN \ - (arm_insn_r->arm_insn,17,4); - arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; - } - else if((4 <= arm_insn_r->opcode) && (7 >= arm_insn_r->opcode)) - { - /* handle SMLAL, SMULL, UMLAL, UMULL */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*4); - arm_insn_r->arm_regs[0] = 3; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - arm_insn_r->arm_regs[2] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - arm_insn_r->arm_regs[3] = ARM_PS_REGNUM; - } - } - else if((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 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. I am not sure this is right - place as opcode = 010 LDR insn make this happen, if R15 was - used. */ - reg_dest = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); - if(15 != reg_dest) - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN \ - (arm_insn_r->arm_insn,13,4); - } - else - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = reg_dest; - arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; - } - } - else - { - /* normal data processing insns */ - /* out of 11 shifter operands mode, all the insn modifies destination - register, which is specified by 13-16 decode */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[0] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - } - } - else - { - /* handle misc, swap insns, and store instructions as 20th bit ((L = 0) */ - if(9 == arm_insn_r->decode) - { - /* Handling SWP, SWPB */ - /* these insns, changes register and memory as well */ - if((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode)) - { - /* SWP or SWPB insn */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - /* get memory address given by Rn */ - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - arm_insn_r->arm_mems[0].len = 1; - /* SWP insn ?, swaps word */ - if (8 == arm_insn_r->opcode) - { - arm_insn_r->arm_mems[1].len = 4; - } - else - { - /* SWPB insn, swaps only byte */ - arm_insn_r->arm_mems[1].len = 1; - } - arm_insn_r->arm_mems[1].addr = u_buf[0].s_word; - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - } - } - else if(3 == arm_insn_r->decode) - { - /* 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 */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - arm_insn_r->arm_regs[2] = ARM_LR_REGNUM; - } - } - else if(7 == arm_insn_r->decode) - { - /* 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 */ - /* Oza: FIX ME ? what if user hit breakpoint and type reverse, in - that case, we need to go back with previous CSPR and - Program Counter. */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[0] = ARM_PS_REGNUM; - } - else if(11 == arm_insn_r->decode) - { - /* handle enhanced store insns and LDRD DSP insn */ - /* 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 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - immed_high = ARM_PARSE_INSN (arm_insn_r->arm_insn,9,4); - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - if(15 == reg_src1) - { - /* if R15 was used as Rn, hence current PC+8 */ - u_buf[0].s_word = u_buf[0].s_word + 8; - } - offset_8 = (immed_high << 4) | immed_low; - /* calculate target store address */ - if(14 == arm_insn_r->opcode) - { - tgt_mem_addr = u_buf[0].s_word + offset_8; - } - else - { - tgt_mem_addr = u_buf[0].s_word - offset_8; - } - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - arm_insn_r->arm_mems[1].len = 2; - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - } - else if((12 == arm_insn_r->opcode) || (8 == arm_insn_r->opcode)) - { - /* 2) store, register offset */ - /* get Rm */ - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - /* get Rn */ - reg_src2 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - GET_REG_VAL (reg_cache,reg_src2,&u_buf[1].buf[0]); - if(15 == reg_src2) - { - /* if R15 was used as Rn, hence current PC+8 */ - u_buf[0].s_word = u_buf[0].s_word + 8; - } - /* calculate target store address, Rn +/- Rm, register offset */ - if(12 == arm_insn_r->opcode) - { - tgt_mem_addr = u_buf[0].s_word + u_buf[1].s_word; - } - else - { - tgt_mem_addr = u_buf[1].s_word - u_buf[0].s_word; - } - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - arm_insn_r->arm_mems[1].len = 2; - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - } - 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 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - immed_high = ARM_PARSE_INSN (arm_insn_r->arm_insn,9,4); - offset_8 = (immed_high << 4) | immed_low; - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); - /* 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].s_word + offset_8; - } - else - { - tgt_mem_addr = u_buf[0].s_word - offset_8; - } - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - arm_insn_r->arm_mems[1].len = 2; - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - /* record Rn also as it changes */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN \ - (arm_insn_r->arm_insn,17,4); - } - 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 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - reg_src2 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - GET_REG_VAL (reg_cache,reg_src2,&u_buf[1].buf[0]); - /* 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].s_word + u_buf[1].s_word; - } - else - { - tgt_mem_addr = u_buf[1].s_word - u_buf[0].s_word; - } - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - arm_insn_r->arm_mems[1].len = 2; - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - /* record Rn also as it changes */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN \ - (arm_insn_r->arm_insn,17,4); - } - /* DSP LDRD TBD */ - } - else if(1 == arm_insn_r->decode) - { - /* handle BLX, branch and link/exchange */ - if(2 == arm_insn_r->opcode) - { - /* branch is chosen by setting T bit of CSPR, bitp[0] of Rm */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - } - else if(11 == arm_insn_r->opcode) - { - /* count leading zeros: CLZ */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN \ - (arm_insn_r->arm_insn,13,4); - } - } - else if((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode)) - { - /* handle MRS insn*/ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - } - else if ((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)) - { - /* handle MSR insn*/ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - if (9 == arm_insn_r->opcode) - { - /*CSPR is going to be changed */ - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - } - else - { - /* SPSR is going to be changed */ - /* Oza: FIX ME ? how to read SPSR value ?*/ - } - } - } - return 0; -} - -int -arm_handle_data_proc_imm_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = \ - gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - uint32_t reg_val1=0,reg_val2=0; - 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; - - arm_insn_r->opcode = ARM_PARSE_INSN (arm_insn_r->arm_insn,22,4); - arm_insn_r->decode = ARM_PARSE_INSN (arm_insn_r->arm_insn,5,4); - - if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) - { - /* data processing insn, e.g. MOV */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; - } - else - { - /* handle MSR insn, status register access */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - /*CSPR is going to be changed */ - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - } - return 0; -} - -int -arm_handle_ld_st_imm_offset_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = \ - gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - uint32_t reg_val1=0,reg_val2=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; - - union - { - uint32_t s_word; - gdb_byte buf[4]; - } u_buf; - - memset(&u_buf, 0, sizeof(u_buf)); - arm_insn_r->opcode = ARM_PARSE_INSN (arm_insn_r->arm_insn,22,4); - arm_insn_r->decode = ARM_PARSE_INSN (arm_insn_r->arm_insn,5,4); - - if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) - { - reg_dest = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); - /* 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) - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - } - else - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = reg_dest; - arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; - } - } - 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-indeed */ - reg_src1= ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - offset_12 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,12); - GET_REG_VAL (reg_cache,reg_src1,&u_buf.buf[0]); - /* U == 1 */ - if (ARM_BIT_SET (arm_insn_r->arm_insn,24)) - { - tgt_mem_addr = u_buf.s_word + offset_12; - } - else - { - tgt_mem_addr = u_buf.s_word - offset_12; - } - - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - - switch(arm_insn_r->opcode) - { - case 8: - case 12: - case 9: - case 13: - case 1: - case 5: - /* STR insn, STRT insn */ - arm_insn_r->arm_mems[1].len = 4; - break; - - case 10: - case 14: - case 11: - case 15: - case 3: - case 7: - /* STRB insn, STRBT insn */ - arm_insn_r->arm_mems[1].len = 1; - break; - - default: - /* rest of the insns are unreachable for this addressing mode */ - break; - } - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - 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 */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = reg_src1; - } - } - } - return 0; -} - -int -arm_handle_ld_st_reg_offset_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = \ - gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - uint32_t reg_val1=0,reg_val2=0,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; - - union - { - int32_t signed_word; - uint32_t s_word; - gdb_byte buf[4]; - } u_buf[2]; - - memset(&u_buf, 0, sizeof(u_buf)); - arm_insn_r->opcode = ARM_PARSE_INSN (arm_insn_r->arm_insn,22,4); - arm_insn_r->decode = ARM_PARSE_INSN (arm_insn_r->arm_insn,5,4); - - /* handle enhanced store insns and LDRD DSP insn */ - /* let us begin according to addressing modes for store insns */ - /* STRH insn */ - - /* LDR or STR ? */ - if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) - { - reg_dest = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - /* 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) - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[1] = ARM_PARSE_INSN (arm_insn_r->arm_insn,13,4); - } - else - { - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = reg_dest; - arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; - } - } - 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(!ARM_PARSE_INSN(arm_insn_r->arm_insn,5,8)) - { - /* store insn, register offset and register pre-indexed, - register post-indexed */ - /* get Rm */ - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - /* get Rn */ - reg_src2 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - GET_REG_VAL (reg_cache,reg_src2,&u_buf[1].buf[0]); - 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].s_word = u_buf[0].s_word + 8; - } - /* calculate target store address, Rn +/- Rm, register offset */ - /* U == 1 */ - if (ARM_BIT_SET (arm_insn_r->arm_insn,24)) - { - tgt_mem_addr = u_buf[0].s_word + u_buf[1].s_word; - } - else - { - tgt_mem_addr = u_buf[1].s_word - u_buf[0].s_word; - } - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - switch(arm_insn_r->opcode) - { - case 8: - case 12: - case 9: - case 13: - case 1: - case 5: - /* STR insn, STRT insn */ - arm_insn_r->arm_mems[1].len = 4; - break; - - case 10: - case 14: - case 11: - case 15: - case 3: - case 7: - /* STRB insn, STRBT insn */ - arm_insn_r->arm_mems[1].len = 1; - break; - - default: - /* rest of the insns are unreachable for this addr mode */ - break; - } - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - - 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)) - { - arm_insn_r->arm_regs = \ - (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - /* Rn is going to be changed in pre-indexed mode and - post-indexed mode as well */ - arm_insn_r->arm_regs[1] = reg_src2; - } - } - else - { - /* store insn, scaled register offset; scaled pre-indexed */ - offset_12 = ARM_PARSE_INSN (arm_insn_r->arm_insn,6,2); - /* get Rm */ - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,4); - /* get Rn */ - reg_src2 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - /* get shift_imm */ - shift_imm = ARM_PARSE_INSN (arm_insn_r->arm_insn,8,5); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - GET_REG_VAL (reg_cache,reg_src2,&u_buf[1].buf[0]); - /* offset_12 used as shift */ - switch(offset_12) - { - case 0: - /* offset_12 used as index */ - offset_12 = u_buf[0].s_word << shift_imm; - break; - - case 1: - offset_12 = (!shift_imm)?0:u_buf[0].s_word >> shift_imm; - break; - - case 2: - if(!shift_imm) - { - if(ARM_BIT_SET (u_buf[0].s_word,32)) - { - 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) - { - GET_REG_VAL (reg_cache,ARM_PS_REGNUM,&u_buf[1].buf[0]); - /* get C flag value and shift it by 31 */ - offset_12 = (((GET_BIT (u_buf[1].s_word,30)) << 31) \ - | (u_buf[0].s_word) >> 1); - } - else - { - offset_12 = (u_buf[0].s_word >> shift_imm) \ - | (u_buf[0].s_word << (sizeof(uint32_t)-shift_imm)); - } - break; - - default: - /* unreachable */ - break; - } - - GET_REG_VAL (reg_cache,reg_src2,&u_buf[1].buf[0]); - /* U == 1 */ - if (ARM_BIT_SET (arm_insn_r->arm_insn,24)) - { - tgt_mem_addr = u_buf[1].s_word + offset_12; - } - else - { - tgt_mem_addr = u_buf[1].s_word - offset_12; - } - switch(arm_insn_r->opcode) - { - case 8: - case 12: - case 9: - case 13: - case 1: - case 5: - /* STR insn, STRT insn */ - arm_insn_r->arm_mems[1].len = 4; - break; - - case 10: - case 14: - case 11: - case 15: - case 3: - case 7: - /* STRB insn, STRBT insn */ - arm_insn_r->arm_mems[1].len = 1; - break; - - default: - /* rest of the insns are unreachable for this addr mode */ - break; - } - arm_insn_r->arm_mems = (struct arm_mem_r *) - xmalloc (sizeof(struct arm_mem_r)*2); - arm_insn_r->arm_mems[0].len = 1; - arm_insn_r->arm_mems[1].addr = tgt_mem_addr; - - 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)) - { - arm_insn_r->arm_regs = \ - (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - /* Rn is going to be changed in register scaled pre-indexed - mode, and scaled post indexed mode */ - arm_insn_r->arm_regs[1] = reg_src2; - } - } - } - } - return 0; -} - -int -arm_hamdle_ld_st_multiple_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = \ - gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - uint32_t register_list[16]={0}, register_count=0, register_bits=0; - uint32_t reg_val1=0, reg_val2=0, shift_imm=0; - uint32_t reg_src1=0, reg_src2=0, addr_mode=0; - uint32_t start_address=0; - - union - { - uint32_t s_word; - gdb_byte buf[4]; - } 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 chaging depending on W bit, but as of now we store Rn too wihtout going for - optmization, */ - - - if (ARM_BIT_SET (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) - { - /* LDR (1,2,3) where LDR (3) changes CPSR too */ - - register_bits = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,16); - /* get Rn */ - reg_src1 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); - while(register_bits) - { - register_list[register_count++] = register_bits & 0x00000001; - register_bits = register_bits >> 1; - } - /* extra space for Base Register and CPSR; wihtout optmization */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc \ - (sizeof(uint32_t)*(register_count+1+1+1)); - arm_insn_r->arm_regs[0] = register_count+1+1; - arm_insn_r->arm_regs[register_count+1] = reg_src1; - arm_insn_r->arm_regs[register_count+2] = ARM_PS_REGNUM; - while(register_count) - { - arm_insn_r->arm_regs[register_count] = \ - register_list[register_count-1]; - register_count--; - } - } - else - { - /* it handles both STM(1) and STM(2) */ - addr_mode = ARM_PARSE_INSN (arm_insn_r->arm_insn,24,2); - - register_bits = ARM_PARSE_INSN (arm_insn_r->arm_insn,1,16); - /* get Rn */ - reg_src1 = ARM_PARSE_INSN (arm_insn_r->arm_insn,17,4); - GET_REG_VAL (reg_cache,reg_src1,&u_buf[0].buf[0]); - 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].s_word) - (register_count * 4) + 4; - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*(register_count+1)); - arm_insn_r->arm_mems[0].len = 1; - while(register_count) - { - arm_insn_r->arm_mems[register_count].addr = start_address; - start_address = start_address + 4; - register_count--; - } - break; - - /* Increment after */ - case 1: - start_address = u_buf[0].s_word; - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*(register_count+1)); - arm_insn_r->arm_mems[0].len = 1; - while(register_count) - { - arm_insn_r->arm_mems[register_count].addr = start_address; - start_address = start_address + 4; - register_count--; - } - break; - - /* Decrement before */ - case 2: - - start_address = (u_buf[0].s_word) - (register_count * 4); - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*(register_count+1)); - arm_insn_r->arm_mems[0].len = 1; - while(register_count) - { - arm_insn_r->arm_mems[register_count].addr = start_address; - start_address = start_address + 4; - register_count--; - } - break; - - /* Increment before */ - case 3: - start_address = u_buf[0].s_word + 4; - arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc (sizeof(struct - arm_mem_r)*(register_count+1)); - arm_insn_r->arm_mems[0].len = 1; - while(register_count) - { - arm_insn_r->arm_mems[register_count].addr = start_address; - start_address = start_address + 4; - register_count--; - } - break; - - default: - /* unreachable */ - break; - } - - /* base register also changes; based on condition and W bit */ - /* we save it anyway without optimization */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*2); - arm_insn_r->arm_regs[0] = 1; - arm_insn_r->arm_regs[register_count+1] = reg_src1; - } - return 0; -} - -int -arm_handle_brn_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - /* handle B, BL, BLX(1) insns */ - /* wihtout optmization we save link register, - CSPR for the insn which changes T bit */ - arm_insn_r->arm_regs = (uint32_t*)xmalloc (sizeof(uint32_t)*3); - arm_insn_r->arm_regs[0] = 2; - arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; - arm_insn_r->arm_regs[2] = ARM_LR_REGNUM; - - return 0; -} - -int -arm_handle_coproc_insn (void *data) -{ - arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; - struct gdbarch_tdep *tdep = \ - gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); - struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; - - uint32_t register_list[16]={0},register_count=0, register_bits=0; - uint32_t reg_val1=0,reg_val2=0,shift_imm=0; - uint32_t reg_src1=0,reg_src2=0,addr_mode=0; - uint32_t start_address=0; - - return 0; -} - -int -arm_handle_coproc_data_proc_insn (void *data) -{ - /* TBD */ - return 0; -} - - -int -thumb_handle_shift_add_sub_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_data_proc_load_strbrn_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_ld_st_reg_offset_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_ld_st_imm_offset_insn (void *data ) -{ - /* TBD */ - return 0; -} - -int -thumb_hamdle_ld_st_stack_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_misc_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_swi_insn (void *data) -{ - /* TBD */ - return 0; -} - -int -thumb_handle_branch_insn (void *data) -{ - /* TBD */ - return 0; -} diff -urN arm_new/arm-tdep.h arm_orig/arm-tdep.h --- arm_new/arm-tdep.h 2011-03-03 09:15:59.000000000 +0530 +++ arm_orig/arm-tdep.h 2011-03-03 09:21:13.000000000 +0530 @@ -310,10 +310,6 @@ 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 ----- Original Message ---- From: paawan oza To: "gdb@sourceware.org" Sent: Wed, February 2, 2011 2:58:44 PM Subject: [PATCH] arm reversible : progress Hi all, As I thought, I would be working on arm insn part first and then linux ABI part first. working with arm and thumb insn, I have come up with patch_1 of my phase 1 activity. which mainly includes design, few insns, and framework on which I will relying on rest of the implementation. few arm insns are implemented and in place, and I am able to debug following samle program too. PS: I am posting this patch, not with the intension of comletion or getting it in mainline. but I thought If I post early I may get some valuable suggestions and inputs regarding design and data structures, or have missed to consider some arch related issues. I will get to know early before I go forward. please also ignore coding guidelines as it will be corrected in due timeline. any inputs and suggestions are welcome. the samle program is as below. #include void main() { int s; s = 10; s = 15; s = 20; s = -30; s = 88; } diff -urN arm_orig/arm-linux-tdep.c arm_new/arm-linux-tdep.c --- arm_orig/arm-linux-tdep.c 2011-02-02 14:22:52.000000000 +0530 +++ arm_new/arm-linux-tdep.c 2011-02-02 14:23:03.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, diff -urN arm_orig/arm-tdep.c arm_new/arm-tdep.c --- arm_orig/arm-tdep.c 2011-02-02 14:22:53.000000000 +0530 +++ arm_new/arm-tdep.c 2011-02-02 14:23:03.000000000 +0530 @@ -54,8 +54,11 @@ #include "gdb_assert.h" #include "vec.h" +#include "record.h" + #include "features/arm-with-m.c" + static int arm_debug; /* Macros for setting and testing a bit in a minimal symbol that marks @@ -7929,3 +7932,576 @@ NULL, /* FIXME: i18n: "ARM debugging is %s. */ &setdebuglist, &showdebuglist); } + + + +/* arm-reversible process reacord data structures */ + +#define NO_OF_TYPE_OF_ARM_INSNS 8 +#define ARM_RECORD_ARCH_LIST_ADD_REG(regnum) \ + record_arch_list_add_reg (arm_record.regcache, regnum) + +#define GET_REG_VAL(REGCACHE,NO,BUF) regcache_raw_read (REGCACHE, NO, BUF); + +#define IS_IT_ARM_INSN(X) ((X & 0x00000010) >> 4) +#define ARM_PARSE_INSN(X,BIT_POS,NO_OF_BITS) \ + ((X >> (BIT_POS-1)) & (0xFFFFFFFF >> ((sizeof(uint32_t)*8) - \ + NO_OF_BITS))) + +/* arm_handle_data_proc_imm_insn */ +#define INSN_S_BIT_NUM 21 +#define ARM_BIT_SET(X, NUM) (((X >> (NUM-1)) & 0x00000001) == 1) + + +int arm_handle_data_proc_misc_load_str_insn (void*); +int arm_handle_data_proc_misc_load_str_insn(void*); +int arm_handle_data_proc_imm_insn(void*); +int arm_handle_ld_st_imm_offset_insn(void*); +int arm_handle_ld_st_reg_offset_insn(void*); +int arm_hamdle_ld_st_multiple_insn(void*); +int arm_handle_brn_insn(void*); +int arm_handle_coproc_insn(void*); +int arm_handle_coproc_data_proc_insn(void*); + +int (*const arm_handle_insn[NO_OF_TYPE_OF_ARM_INSNS]) (void*) = +{ + arm_handle_data_proc_misc_load_str_insn, + arm_handle_data_proc_imm_insn, + arm_handle_ld_st_imm_offset_insn, + arm_handle_ld_st_reg_offset_insn, + arm_hamdle_ld_st_multiple_insn, + arm_handle_brn_insn, + arm_handle_coproc_insn, + arm_handle_coproc_data_proc_insn +}; + +struct arm_mem_r +{ + uint32_t len; + CORE_ADDR addr; +}; + +typedef struct arm_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 accomodate thumb */ + uint32_t cond; /* condition code */ + uint32_t id; /* type of insn */ + uint32_t opcode; /* insn opcode */ + uint32_t decode; /* insn decode bits */ + uint32_t *arm_regs; /* registers to be saved for this record */ + struct arm_mem_r *arm_mems; /* memory to be saved for this record */ +} arm_insn_decode_record; + + +int decode_insn(arm_insn_decode_record *arm_record, uint32_t insn_size) +{ + union + { + uint32_t s_word; + gdb_byte buf[insn_size]; + } 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 + { + arm_record->arm_insn = u_buf.s_word; + arm_record->cond = ARM_PARSE_INSN (arm_record->arm_insn,29,4); + arm_record->id = ARM_PARSE_INSN (arm_record->arm_insn,26,3); + + if (0b1111 == arm_record->cond) + { + /* Version5 and above support this, so handle this as well. */ + } + else + { + arm_handle_insn[arm_record->id]((void*)arm_record); + } + } + return 0; +} + +/* 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); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int no_of_rec=0; + + union + { + uint32_t s_word; + gdb_byte buf[4]; + } u_buf; + + arm_insn_decode_record arm_record; + + memset (&arm_record, 0, sizeof (arm_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 */ + GET_REG_VAL (arm_record.regcache, ARM_PS_REGNUM, &u_buf.buf[0]); + if (IS_IT_ARM_INSN (u_buf.s_word)) + { + /* we are decoding arm insn */ + decode_insn (&arm_record, 4); + } + else + { + /* we are decoding thumb insn */ + decode_insn (&arm_record, 2); + } + + /* record registers */ + ARM_RECORD_ARCH_LIST_ADD_REG(ARM_PC_REGNUM); + if(arm_record.arm_regs) + { + for(no_of_rec=1;no_of_rec<=arm_record.arm_regs[0];no_of_rec++) + { + if(ARM_RECORD_ARCH_LIST_ADD_REG(arm_record.arm_regs[no_of_rec])) + { + return -1; + } + } + } + /* record memories */ + if(arm_record.arm_mems) + { + for(no_of_rec=1;no_of_rec<=arm_record.arm_mems[0].len;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)) + { + return -1; + } + } + } + + if (record_arch_list_add_end ()) + { + return -1; + } + return 0; +} + +int arm_handle_data_proc_misc_load_str_insn(void *data) +{ + + arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; + struct gdbarch_tdep *tdep = gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); + struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; + + union + { + uint32_t s_word; + gdb_byte buf[4]; + }u_buf[2]; + + uint32_t reg_val1=0,reg_val2=0; + 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; + + arm_insn_r->opcode = ARM_PARSE_INSN(arm_insn_r->arm_insn,22,4); + arm_insn_r->decode = ARM_PARSE_INSN(arm_insn_r->arm_insn,5,4); + + if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_BIT_NUM)) + { + /* data processing insn /multiply sinsn */ + if(9 == arm_insn_r->decode) + { + /* handle multiply instructions */ + /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL */ + if((0 == arm_insn_r->opcode) || (1 == arm_insn_r->opcode)) + { + /* handle MLA and MUL */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*3); + arm_insn_r->arm_regs[0] = 2; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; + } + else if((4 <= arm_insn_r->opcode) && (7 >= arm_insn_r->opcode)) + { + /* handle SMLAL, SMULL, UMLAL, UMULL */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*4); + arm_insn_r->arm_regs[0] = 3; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + arm_insn_r->arm_regs[2] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + arm_insn_r->arm_regs[3] = ARM_PS_REGNUM; + + } + } + else if((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 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. */ + reg_dest = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + if(15 != reg_dest) + { + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + } + else + { + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*3); + arm_insn_r->arm_regs[0] = 2; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; + } + } + else + { + /* normal data processing insns */ + /* out of 11 shifter operands mode, all the insn modifies destination + register, which is specified by 13-16 decode */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*3); + arm_insn_r->arm_regs[0] = 2; + arm_insn_r->arm_regs[0] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; + } + } + else + { + /* handle misc, swap insns, and store instructions as 20th bit ((L = 0) */ + if(9 == arm_insn_r->decode) + { + /* Handling SWP, SWPB */ + /* these insns, changes register and memory as well */ + if((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode)) + { + /* SWP or SWPB insn */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + /* get memory address given by Rn */ + reg_src1 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); + arm_insn_r->arm_mems[0].len = 1; + /* SWP insn ?, swaps word */ + if (8 == arm_insn_r->opcode) + { + arm_insn_r->arm_mems[1].len = 4; + } + else + { + /* SWPB insn, swaps only byte */ + arm_insn_r->arm_mems[1].len = 1; + } + arm_insn_r->arm_mems[1].addr = u_buf[0].s_word; + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + } + } + else if(3 == arm_insn_r->decode) + { + /* 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 */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*3); + arm_insn_r->arm_regs[0] = 2; + arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; + arm_insn_r->arm_regs[2] = ARM_LR_REGNUM; + } + } + else if(7 == arm_insn_r->decode) + { + /* 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 */ + /* Oza: FIX ME ? what if user hit breakpoint and type reverse, in + that case, we need to go back with previous CSPR and + Program Counter. */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[0] = ARM_PS_REGNUM; + } + else if(13 == arm_insn_r->decode) + { + /* handle enhanced store insns and LDRD DSP insn and */ + /* let us begin according to addressing modes for store insns */ + + if((14 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode)) + { + /* 1) handle misc store, immediate offset */ + immed_low = ARM_PARSE_INSN(arm_insn_r->arm_insn,1,4); + immed_high = ARM_PARSE_INSN(arm_insn_r->arm_insn,9,4); + reg_src1 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); + if(15 == reg_src1) + { + /* if R15 was used as Rn, hence current PC+8 */ + u_buf[0].s_word = u_buf[0].s_word + 8; + } + offset_8 = (immed_high << 4) | immed_low; + /* calculate target store address */ + if(14 == arm_insn_r->opcode) + { + tgt_mem_addr = u_buf[0].s_word + offset_8; + } + else + { + tgt_mem_addr = u_buf[0].s_word - offset_8; + } + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + arm_insn_r->arm_mems[0].len = 1; + arm_insn_r->arm_mems[1].len = 2; + arm_insn_r->arm_mems[1].addr = tgt_mem_addr; + } + else if((12 == arm_insn_r->opcode) || (8 == arm_insn_r->opcode)) + { + /* 2) store, register offset */ + /* get Rm */ + reg_src1 = ARM_PARSE_INSN(arm_insn_r->arm_insn,1,4); + /* get Rn */ + reg_src2 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); + GET_REG_VAL(reg_cache,reg_src2,&u_buf[1].buf[0]); + if(15 == reg_src2) + { + /* if R15 was used as Rn, hence current PC+8 */ + u_buf[0].s_word = u_buf[0].s_word + 8; + } + /* calculate target store address, Rn +/- Rm, register offset */ + if(12 == arm_insn_r->opcode) + { + tgt_mem_addr = u_buf[0].s_word + u_buf[1].s_word; + } + else + { + tgt_mem_addr = u_buf[1].s_word - u_buf[0].s_word; + } + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + arm_insn_r->arm_mems[0].len = 1; + arm_insn_r->arm_mems[1].len = 2; + arm_insn_r->arm_mems[1].addr = tgt_mem_addr; + } + 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 = ARM_PARSE_INSN(arm_insn_r->arm_insn,1,4); + immed_high = ARM_PARSE_INSN(arm_insn_r->arm_insn,9,4); + offset_8 = (immed_high << 4) | immed_low; + reg_src1 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); + /* 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].s_word + offset_8; + } + else + { + tgt_mem_addr = u_buf[0].s_word - offset_8; + } + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + arm_insn_r->arm_mems[0].len = 1; + arm_insn_r->arm_mems[1].len = 2; + arm_insn_r->arm_mems[1].addr = tgt_mem_addr; + /* record Rn also as it changes */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + + } + 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 = ARM_PARSE_INSN(arm_insn_r->arm_insn,1,4); + reg_src2 = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + GET_REG_VAL(reg_cache,reg_src1,&u_buf[0].buf[0]); + GET_REG_VAL(reg_cache,reg_src2,&u_buf[1].buf[0]); + /* 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].s_word + u_buf[1].s_word; + } + else + { + tgt_mem_addr = u_buf[1].s_word - u_buf[0].s_word; + } + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + arm_insn_r->arm_mems[0].len = 1; + arm_insn_r->arm_mems[1].len = 2; + arm_insn_r->arm_mems[1].addr = tgt_mem_addr; + /* record Rn also as it changes */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + } + /* DSP LDRD TBD */ + } + else if(1 == arm_insn_r->decode) + { + /* handle BLX, branch and link/exchange */ + if(2 == arm_insn_r->opcode) + { + /* branch is chosen by setting T bit of CSPR, bitp[0] of Rm */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; + } + else if(11 == arm_insn_r->opcode) + { + /* count leading zeros: CLZ */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + } + } + else if((0 == arm_insn_r->opcode) || (4 == arm_insn_r->opcode)) + { + /* handle MRS insn*/ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + } + else if ((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)) + { + /* handle MSR insn*/ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*2); + if (9 == arm_insn_r->opcode) + { + /*CSPR is going to be changed */ + arm_insn_r->arm_regs[0] = 1; + arm_insn_r->arm_regs[1] = ARM_PS_REGNUM; + } + else + { + /* SPSR is going to be changed */ + /* OZA FIX ME ? how to read SPSR value ?*/ + } + } + } + return 0; +} + +int arm_handle_data_proc_imm_insn(void *data) +{ + arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; + struct gdbarch_tdep *tdep = \ + gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); + struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; + + uint32_t reg_val1=0,reg_val2=0; + 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; + + arm_insn_r->opcode = ARM_PARSE_INSN(arm_insn_r->arm_insn,22,4); + arm_insn_r->decode = ARM_PARSE_INSN(arm_insn_r->arm_insn,5,4); + + if (ARM_BIT_SET(arm_insn_r->arm_insn, INSN_S_BIT_NUM)) + { + /* data processing insn, e.g. MOV */ + arm_insn_r->arm_regs = (uint32_t*)xmalloc(sizeof(uint32_t)*3); + arm_insn_r->arm_regs[0] = 2; + arm_insn_r->arm_regs[1] = ARM_PARSE_INSN(arm_insn_r->arm_insn,13,4); + arm_insn_r->arm_regs[2] = ARM_PS_REGNUM; + } + return 0; +} + +int arm_handle_ld_st_imm_offset_insn(void *data) +{ + arm_insn_decode_record *arm_insn_r = (arm_insn_decode_record*) data; + struct gdbarch_tdep *tdep = \ + gdbarch_tdep ((struct gdbarch*) arm_insn_r->gdbarch); + struct regcache *reg_cache = (struct regcache*) arm_insn_r->regcache; + + uint32_t reg_val1=0,reg_val2=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; + + union + { + uint32_t s_word; + gdb_byte buf[4]; + }u_buf; + + arm_insn_r->opcode = ARM_PARSE_INSN(arm_insn_r->arm_insn,22,4); + arm_insn_r->decode = ARM_PARSE_INSN(arm_insn_r->arm_insn,5,4); + + /* Oza: as of now only STR is getting implemented for demo */ + reg_src1= ARM_PARSE_INSN(arm_insn_r->arm_insn,17,4); + offset_12 = ARM_PARSE_INSN(arm_insn_r->arm_insn,1,12); + GET_REG_VAL(reg_cache,reg_src1,&u_buf.buf[0]); + if (ARM_BIT_SET(arm_insn_r->arm_insn,24)) + { + tgt_mem_addr = u_buf.s_word + offset_12; + } + else + { + tgt_mem_addr = u_buf.s_word - offset_12; + } + + arm_insn_r->arm_mems = (struct arm_mem_r *)xmalloc(sizeof(struct + arm_mem_r)*2); + arm_insn_r->arm_mems[0].len = 1; + arm_insn_r->arm_mems[1].len = 4; + arm_insn_r->arm_mems[1].addr = tgt_mem_addr; + return 0; +} + +int arm_handle_ld_st_reg_offset_insn(void *data) +{ + /* TBD */ + return 0; +} + +int arm_hamdle_ld_st_multiple_insn(void *data) +{ + /* TBD */ + return 0; +} + +int arm_handle_brn_insn(void *data) +{ + /* TBD */ + return 0; +} + +int arm_handle_coproc_insn(void *data) +{ + /* TBD */ + return 0; +} + +int arm_handle_coproc_data_proc_insn(void *data) +{ + /* TBD */ + return 0; +} Regards, Oza. ----- Original Message ---- From: paawan oza To: Michael Snyder Cc: "gdb@sourceware.org" Sent: Tue, February 1, 2011 8:50:51 AM Subject: Re: arm reversible execution query Hi Michael, thank you for your reply. I think you are referring to below line. in process_record. I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM); if (record_arch_list_add_end ()) return -1; I got it that it has to be saved explicitly by process record arch level. Thanks, Oza. ----- Original Message ---- From: Michael Snyder To: paawan oza Cc: "gdb@sourceware.org" Sent: Tue, February 1, 2011 12:23:14 AM Subject: Re: arm reversible execution query paawan oza wrote: > > Hi all, > > I have been wroking on arm-reversible implementation and doing arm insn part. I > > >am done with framework, and supporting 30-40% on insns till now. > when I simply test on arm board, I find that, > > all the memory and registers are replayed correctly and recording is happening. > but, > do I need to save Program counter explicitly ? > doesnt gdb reversible framework take care of changing pc when I apply >reverse-stepi/nexti command ? > > as i386-tdep.c, does not seem to be saving PC explicitly. > > please clarify. i386-tdep.c does save the PC ($eip), at the end of function i386_process_record. If you don't save the PC, how can you do a reverse jump?