From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21521 invoked by alias); 5 Jun 2014 08:34:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 21505 invoked by uid 89); 5 Jun 2014 08:34:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ie0-f174.google.com Received: from mail-ie0-f174.google.com (HELO mail-ie0-f174.google.com) (209.85.223.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 05 Jun 2014 08:34:51 +0000 Received: by mail-ie0-f174.google.com with SMTP id lx4so609995iec.33 for ; Thu, 05 Jun 2014 01:34:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=H0lF69qmX6h3lajB71MkytEcPqd+TqJJol9OLsumxa8=; b=UtzKouMbxT5jRFBRc844Za24oO6J473Be+SwWbcgn8UujABoU7PDuIDunGNi0sPTXR i+l7yCCoA7jOmG3504XvMS7EHFcQrjBwT/hzR+K5paotUtmWyzQ4NMf+K58Jp7vyqr4n nJVCAybE+iB3S/paapWeYbrnrHb7DzxEyrts/Dg7biaTYaekuIibuOAMHzl/T0HkYtMD NHcD4uYn5Wdtf/zff/tJ0l2S9FnjvAn/fp5RHivJbD/4nysy+THmGIDPJoj8+JecJS4z tEJ24sjaTBufvTULuDjCGNwyfIkpEhZlRwkkvvaxtCRlt/3K8xB2m44hM2cE6X3KpSbp 1PtQ== X-Gm-Message-State: ALoCoQkG5bTCYLfiHZ3it9Hovl5RNK2s0DYdUA9dSohu287+RQ1MYOv9Zr2L/j8RVc4jrGYkVUR5 MIME-Version: 1.0 X-Received: by 10.50.43.202 with SMTP id y10mr17422525igl.23.1401957289451; Thu, 05 Jun 2014 01:34:49 -0700 (PDT) Received: by 10.64.225.50 with HTTP; Thu, 5 Jun 2014 01:34:49 -0700 (PDT) In-Reply-To: <1401898871-2270-5-git-send-email-omair.javaid@linaro.org> References: <1401898871-2270-1-git-send-email-omair.javaid@linaro.org> <1401898871-2270-5-git-send-email-omair.javaid@linaro.org> Date: Thu, 05 Jun 2014 08:34:00 -0000 Message-ID: Subject: Re: [PATCH 4/7] Implements aarch64 process record and reverse debugging support From: Will Newton To: Omair Javaid Cc: "gdb-patches@sourceware.org" Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2014-06/txt/msg00236.txt.bz2 On 4 June 2014 17:21, Omair Javaid wrote: > This patch defines structures, macros and functions required for process record > and reverse debugging support on aarch64-linux targets. Also implements > support for recording most if not all of instructions from a64 instruction set. > > gdb: > > 2014-06-04 Omair Javaid > > * aarch64-linux-tdep.c (aarch64_linux_init_abi): Updated. > * aarch64-tdep.c (record.h): Include. > (record-full.h): Include. > (aarch64_record_data_proc_reg): New function. > (aarch64_record_data_proc_imm): New function. > (aarch64_record_branch_except_sys): New function. > (aarch64_record_load_store): New function. > (aarch64_record_decode_insn_handler): New function. > (deallocate_reg_mem): New function. > (aarch64_process_record): New function. > * aarch64-tdep.h (submask): New macro. > (bit): New macro. > (bits): New macro. > (REG_ALLOC): New macro. > (MEM_ALLOC): New macro. > (struct aarch64_mem_r): Defined. > (aarch64_record_result): New enum. > (struct insn_decode_record): Defined. > (insn_decode_record): New typedef. > (aarch64_process_record): New extern declaration. > > --- > gdb/aarch64-linux-tdep.c | 3 + > gdb/aarch64-tdep.c | 517 +++++++++++++++++++++++++++++++++++++++++++++++ > gdb/aarch64-tdep.h | 65 ++++++ > 3 files changed, 585 insertions(+) > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c > index b285818..dece0c3 100644 > --- a/gdb/aarch64-linux-tdep.c > +++ b/gdb/aarch64-linux-tdep.c > @@ -468,6 +468,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_stap_is_single_operand (gdbarch, aarch64_stap_is_single_operand); > set_gdbarch_stap_parse_special_token (gdbarch, > aarch64_stap_parse_special_token); > + > + /* Reversible debugging, process record. */ > + set_gdbarch_process_record (gdbarch, aarch64_process_record); > } > > /* Provide a prototype to silence -Wmissing-prototypes. */ > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c > index 4abe36e..bb533b2 100644 > --- a/gdb/aarch64-tdep.c > +++ b/gdb/aarch64-tdep.c > @@ -52,6 +52,9 @@ > #include "gdb_assert.h" > #include "vec.h" > > +#include "record.h" > +#include "record-full.h" > + > #include "features/aarch64.c" > > /* Pseudo register base numbers. */ > @@ -2806,3 +2809,517 @@ When on, AArch64 specific debugging is enabled."), > show_aarch64_debug, > &setdebuglist, &showdebuglist); > } > + > +/* Record handler for data processing - register instructions. */ > +static unsigned int > +aarch64_record_data_proc_reg (insn_decode_record *aarch64_insn_r) > +{ > + uint8_t reg_rd, insn_bits24_27, insn_bits21_23, setflags; > + uint32_t record_buf[4]; > + > + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); > + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); > + insn_bits21_23 = bits (aarch64_insn_r->aarch64_insn, 21, 23); > + > + if (!bit (aarch64_insn_r->aarch64_insn, 28)) > + { > + /* Logical (shifted register). */ > + if (insn_bits24_27 == 0x0a) > + setflags = (bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03); > + /* Add/subtract. */ > + else if (insn_bits24_27 == 0x0b) > + setflags = bit (aarch64_insn_r->aarch64_insn, 29); > + else > + return AARCH64_RECORD_USUPPORTED; > + > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + if (setflags) > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; > + } > + else > + { > + if (insn_bits24_27 == 0x0b) > + { > + /* Data-processing (3 source). */ > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + } > + else if (insn_bits24_27 == 0x0a) > + { > + if (insn_bits21_23 == 0x00) > + { > + /* Add/subtract (with carry). */ > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + if (bit (aarch64_insn_r->aarch64_insn, 29)) > + { > + record_buf[1] = AARCH64_CPSR_REGNUM; > + aarch64_insn_r->reg_rec_count = 2; > + } > + } > + else if (insn_bits21_23 == 0x02) > + { > + /* Conditional compare (register) / Conditional compare (immediate). */ > + record_buf[0] = AARCH64_CPSR_REGNUM; > + aarch64_insn_r->reg_rec_count = 1; > + } > + else if (insn_bits21_23 == 0x04 || insn_bits21_23 == 0x06) > + { > + /* CConditional select. */ > + /* Data-processing (2 source). */ > + /* Data-processing (1 source). */ > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + } > + else > + return AARCH64_RECORD_USUPPORTED; > + } > + } > + > + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, > + record_buf); > + return AARCH64_RECORD_SUCCESS; > +} > + > +/* Record handler for data processing - immediate instructions. */ > +static unsigned int > +aarch64_record_data_proc_imm (insn_decode_record *aarch64_insn_r) > +{ > + uint8_t reg_rd, insn_bit28, insn_bit23, insn_bits24_27, setflags; > + uint32_t record_buf[4]; > + > + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); > + insn_bit28 = bit (aarch64_insn_r->aarch64_insn, 28); > + insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23); > + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); > + > + /*PC rel addressing / Move wide immediate / BitField / Extract. */ Missing space at the start of this comment. > + if (insn_bits24_27 == 0x00 || insn_bits24_27 == 0x03 || > + (insn_bits24_27 == 0x02 && insn_bit23)) > + { > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + } > + else if (insn_bits24_27 == 0x01) > + { > + /* Add/Subtract (immediate). */ > + setflags = bit (aarch64_insn_r->aarch64_insn, 29); > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + if (setflags) > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; > + } > + else if (insn_bits24_27 == 0x02 && !insn_bit23) > + { > + /* Logical (immediate). */ > + setflags = bits (aarch64_insn_r->aarch64_insn, 29, 30) == 0x03; > + record_buf[0] = reg_rd; > + aarch64_insn_r->reg_rec_count = 1; > + if (setflags) > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_CPSR_REGNUM; > + } > + else > + return AARCH64_RECORD_USUPPORTED; > + > + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, > + record_buf); > + return AARCH64_RECORD_SUCCESS; > +} > + > +/* Record handler for branch, exception generation and system instructions. */ > +static unsigned int > +aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r) > +{ > + struct gdbarch_tdep *tdep = gdbarch_tdep (aarch64_insn_r->gdbarch); > + uint8_t insn_bits24_27, insn_bits28_31, insn_bits22_23; > + uint32_t record_buf[4]; > + > + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); > + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31); > + insn_bits22_23 = bits (aarch64_insn_r->aarch64_insn, 22, 23); > + > + if (insn_bits28_31 == 0x0d) > + { > + /* Exception generation instructions. */ > + if (insn_bits24_27 == 0x04) > + return AARCH64_RECORD_USUPPORTED; > + /* System instructions. */ > + else if (insn_bits24_27 == 0x05 && insn_bits22_23 == 0x00) > + { > + record_buf[0] = AARCH64_CPSR_REGNUM; > + record_buf[1] = bits (aarch64_insn_r->aarch64_insn, 0, 4); > + aarch64_insn_r->reg_rec_count = 2; > + } > + else if((insn_bits24_27 & 0x0e) == 0x06) > + { > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; > + if (bits (aarch64_insn_r->aarch64_insn, 21, 22) == 0x01) > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM; > + } > + else > + return AARCH64_RECORD_USUPPORTED; > + } > + else if ((insn_bits28_31 & 0x07) == 0x01 && (insn_bits24_27 & 0x0c) == 0x04) > + { > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; > + if (bit (aarch64_insn_r->aarch64_insn, 31)) > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_LR_REGNUM; > + } > + else > + /* All other types of branch instructions. */ > + record_buf[aarch64_insn_r->reg_rec_count++] = AARCH64_PC_REGNUM; > + > + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, > + record_buf); > + return AARCH64_RECORD_SUCCESS; > +} > + > +/* Record handler for load and store instructions. */ > +static unsigned int > +aarch64_record_load_store (insn_decode_record *aarch64_insn_r) > +{ > + uint8_t insn_bits24_27, insn_bits28_29, insn_bits10_11; > + uint8_t insn_bit23, insn_bit21; > + uint8_t opc, size_bits, ld_flag, vector_flag; > + uint32_t reg_rn, reg_rt, reg_rt2; > + uint64_t datasize, offset; > + uint32_t record_buf[8]; > + uint64_t record_buf_mem[8]; > + CORE_ADDR address; > + > + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11); > + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27); > + insn_bits28_29 = bits (aarch64_insn_r->aarch64_insn, 28, 29); > + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21); > + insn_bit23 = bit (aarch64_insn_r->aarch64_insn, 23); > + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22); > + vector_flag = bit (aarch64_insn_r->aarch64_insn, 26); > + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4); > + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9); > + reg_rt2 = bits (aarch64_insn_r->aarch64_insn, 10, 14); > + size_bits = bits (aarch64_insn_r->aarch64_insn, 30, 31); > + > + /* Load/store exclusive instructions decoding. */ > + if (insn_bits24_27 == 0x08 && insn_bits28_29 == 0x00) > + { > + if (ld_flag) > + { > + record_buf[0] = reg_rt; > + aarch64_insn_r->reg_rec_count = 1; > + if (insn_bit21) > + { > + record_buf[1] = reg_rt2; > + aarch64_insn_r->reg_rec_count = 2; > + } > + } > + else > + { > + if (insn_bit21) > + datasize = (8 << size_bits) * 2; > + else > + datasize = (8 << size_bits); > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, > + &address); > + record_buf_mem[0] = datasize / 8; > + record_buf_mem[1] = address; > + aarch64_insn_r->mem_rec_count = 1; > + if (!insn_bit23) > + { > + /* Save register rs. */ > + record_buf[0] = bits (aarch64_insn_r->aarch64_insn, 16, 20); > + aarch64_insn_r->reg_rec_count = 1; > + } > + } > + } > + /* Load register (literal) instructions decoding. */ > + else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x01) > + { > + if (vector_flag) > + record_buf[0] = reg_rt + AARCH64_V0_REGNUM; > + else > + record_buf[0] = reg_rt; > + aarch64_insn_r->reg_rec_count = 1; > + } > + /* All types of load/store pair instructions decoding. */ > + else if ((insn_bits24_27 & 0x0a) == 0x08 && insn_bits28_29 == 0x02) > + { > + if (ld_flag) > + { > + if (vector_flag) > + { > + record_buf[0] = reg_rt + AARCH64_V0_REGNUM; > + record_buf[1] = reg_rt2 + AARCH64_V0_REGNUM; > + } > + else > + { > + record_buf[0] = reg_rt; > + record_buf[1] = reg_rt2; > + } > + aarch64_insn_r->reg_rec_count = 2; > + } > + else > + { > + uint16_t imm7_off; > + imm7_off = bits (aarch64_insn_r->aarch64_insn, 15, 21); > + if (!vector_flag) > + size_bits = size_bits >> 1; > + datasize = 8 << (2 + size_bits); > + offset = (imm7_off & 0x40) ? (((~imm7_off) & 0x007f) + 1) : imm7_off; The brackets around ~imm7_off are not needed, and also around the parts of the ternary conditional. > + offset = offset << (2 + size_bits); > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, > + &address); > + if (!((insn_bits24_27 & 0x0b) == 0x08 && insn_bit23)) > + { > + if (imm7_off & 0x40) > + address = address - offset; > + else > + address = address + offset; > + } > + > + record_buf_mem[0] = datasize / 8; > + record_buf_mem[1] = address; > + record_buf_mem[2] = datasize / 8; > + record_buf_mem[3] = address + (datasize / 8); > + aarch64_insn_r->mem_rec_count = 2; > + } > + if (bit (aarch64_insn_r->aarch64_insn, 23)) > + record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn; > + } > + /* Load/store register (unsigned immediate) instructions. */ > + else if ((insn_bits24_27 & 0x0b) == 0x09 && insn_bits28_29 == 0x03) > + { > + opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); > + if (!(opc >> 1)) > + if (opc & 0x01) > + ld_flag = 0x01; > + else > + ld_flag = 0x0; > + else > + if (size_bits != 0x03) > + ld_flag = 0x01; > + else > + return AARCH64_RECORD_USUPPORTED; > + > + if (!ld_flag) > + { > + offset = bits (aarch64_insn_r->aarch64_insn, 10, 21); > + datasize = 8 << size_bits; > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, > + &address); > + offset = offset << size_bits; > + address = address + offset; > + > + record_buf_mem[0] = datasize >> 3; > + record_buf_mem[1] = address; > + aarch64_insn_r->mem_rec_count = 1; > + } > + else > + { > + if (vector_flag) > + record_buf[0] = reg_rt + AARCH64_V0_REGNUM; > + else > + record_buf[0] = reg_rt; > + aarch64_insn_r->reg_rec_count = 1; > + } > + } > + /* Load/store register (register offset) instructions. */ > + else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 && > + insn_bits10_11 == 0x02 && insn_bit21) > + { > + opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); > + if (!(opc >> 1)) > + if (opc & 0x01) > + ld_flag = 0x01; > + else > + ld_flag = 0x0; > + else > + if (size_bits != 0x03) > + ld_flag = 0x01; > + else > + return AARCH64_RECORD_USUPPORTED; > + > + if (!ld_flag) > + { > + uint64_t reg_rm_val; > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, > + bits (aarch64_insn_r->aarch64_insn, 16, 20), ®_rm_val); > + if (bit (aarch64_insn_r->aarch64_insn, 12)) > + offset = reg_rm_val << size_bits; > + else > + offset = reg_rm_val; > + datasize = 8 << size_bits; > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, > + &address); > + address = address + offset; > + record_buf_mem[0] = datasize >> 3; > + record_buf_mem[1] = address; > + aarch64_insn_r->mem_rec_count = 1; > + } > + else > + { > + if (vector_flag) > + record_buf[0] = reg_rt + AARCH64_V0_REGNUM; > + else > + record_buf[0] = reg_rt; > + aarch64_insn_r->reg_rec_count = 1; > + } > + } > + /* Load/store register (immediate) instructions. */ > + else if ((insn_bits24_27 & 0x0b) == 0x08 && insn_bits28_29 == 0x03 && > + !insn_bit21) > + { > + opc = bits (aarch64_insn_r->aarch64_insn, 22, 23); > + if (!(opc >> 1)) > + if (opc & 0x01) > + ld_flag = 0x01; > + else > + ld_flag = 0x0; > + else > + if (size_bits != 0x03) > + ld_flag = 0x01; > + else > + return AARCH64_RECORD_USUPPORTED; > + > + if (!ld_flag) > + { > + uint16_t imm9_off; > + imm9_off = bits (aarch64_insn_r->aarch64_insn, 12, 20); > + offset = (imm9_off & 0x0100) ? (((~imm9_off) & 0x01ff) + 1) : imm9_off; > + datasize = 8 << size_bits; > + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, > + &address); > + if (insn_bits10_11 != 0x01) > + { > + if (imm9_off & 0x0100) > + address = address - offset; > + else > + address = address + offset; > + } > + record_buf_mem[0] = datasize >> 3; > + record_buf_mem[1] = address; > + aarch64_insn_r->mem_rec_count = 1; > + } > + else > + { > + if (vector_flag) > + record_buf[0] = reg_rt + AARCH64_V0_REGNUM; > + else > + record_buf[0] = reg_rt; > + aarch64_insn_r->reg_rec_count = 1; > + } > + if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03) > + record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn; > + } > + /* Advanced SIMD load/store instructions. */ > + else > + return AARCH64_RECORD_USUPPORTED; > + > + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, > + record_buf_mem); > + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, > + record_buf); > + return AARCH64_RECORD_SUCCESS; > +} > +/* Decodes thumb2 instruction type and invokes its record handler. */ This comment needs updating. > + > +static unsigned int > +aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r) > +{ > + uint32_t ins_bit25, ins_bit26, ins_bit27, ins_bit28; > + > + ins_bit25 = bit (aarch64_insn_r->aarch64_insn, 25); > + ins_bit26 = bit (aarch64_insn_r->aarch64_insn, 26); > + ins_bit27 = bit (aarch64_insn_r->aarch64_insn, 27); > + ins_bit28 = bit (aarch64_insn_r->aarch64_insn, 28); > + > + /* Data processing - immediate instructions. */ > + if (!ins_bit26 && !ins_bit27 && ins_bit28) > + return aarch64_record_data_proc_imm (aarch64_insn_r); > + > + /* Branch, exception generation and system instructions. */ > + if (ins_bit26 && !ins_bit27 && ins_bit28) > + return aarch64_record_branch_except_sys (aarch64_insn_r); > + > + /* Load and store instructions. */ > + if (!ins_bit25 && ins_bit27) > + return aarch64_record_load_store (aarch64_insn_r); > + > + /* Data processing - register instructions. */ > + if (ins_bit25 && !ins_bit26 && ins_bit27) > + return aarch64_record_data_proc_reg (aarch64_insn_r); > + > + /* Data processing - SIMD and floating point instructions. */ > + if (ins_bit25 && ins_bit26 && ins_bit27) > + return AARCH64_RECORD_USUPPORTED; > + > + return AARCH64_RECORD_USUPPORTED; > +} > + > +/* Cleans up local record registers and memory allocations. */ > + > +static void > +deallocate_reg_mem (insn_decode_record *record) > +{ > + xfree (record->aarch64_regs); > + xfree (record->aarch64_mems); > +} > + > +/* Parse the current instruction and record the values of the registers and > + memory that will be changed in current instruction to record_arch_list". Should the quote after record_arch_list be here? > + Return -1 if something is wrong. */ > + > +int > +aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache, > + CORE_ADDR insn_addr) > +{ > + uint32_t rec_no = 0; > + uint8_t insn_size = 4; > + uint32_t ret = 0; It would probably be cleaner to use int for ret. > + ULONGEST t_bit = 0, insn_id = 0; These two aren't used. > + gdb_byte buf[insn_size]; > + insn_decode_record aarch64_record; > + > + memset (&buf[0], 0, insn_size); > + memset (&aarch64_record, 0, sizeof (insn_decode_record)); > + target_read_memory (insn_addr, &buf[0], insn_size); > + aarch64_record.aarch64_insn = (uint32_t) extract_unsigned_integer (&buf[0], > + insn_size, gdbarch_byte_order (gdbarch)); > + aarch64_record.regcache = regcache; > + aarch64_record.this_addr = insn_addr; > + aarch64_record.gdbarch = gdbarch; > + > + ret = aarch64_record_decode_insn_handler (&aarch64_record); > + if (ret == AARCH64_RECORD_USUPPORTED) > + { > + printf_unfiltered (_("Process record does not support instruction " > + "0x%0x at address %s.\n"),aarch64_record.aarch64_insn, > + paddress (gdbarch, insn_addr)); > + ret = -1; > + } > + > + if (0 == ret) > + { > + /* Record registers. */ > + record_full_arch_list_add_reg (aarch64_record.regcache, AARCH64_PC_REGNUM); > + if (aarch64_record.aarch64_regs) > + for (rec_no = 0; rec_no < aarch64_record.reg_rec_count; rec_no++) > + if (record_full_arch_list_add_reg (aarch64_record.regcache, > + aarch64_record.aarch64_regs[rec_no])) > + ret = -1; > + > + /* Record memories. */ > + if (aarch64_record.aarch64_mems) > + for (rec_no = 0; rec_no < aarch64_record.mem_rec_count; rec_no++) > + if (record_full_arch_list_add_mem > + ((CORE_ADDR)aarch64_record.aarch64_mems[rec_no].addr, > + aarch64_record.aarch64_mems[rec_no].len)) > + ret = -1; > + > + if (record_full_arch_list_add_end ()) > + ret = -1; > + } > + > + deallocate_reg_mem (&aarch64_record); > + return ret; > +} > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h > index 78fb779..8a193f4 100644 > --- a/gdb/aarch64-tdep.h > +++ b/gdb/aarch64-tdep.h > @@ -90,4 +90,69 @@ struct gdbarch_tdep > struct type *vnb_type; > }; > > +/* aarch64 process record-replay related structures, defines etc. */ > + > +#define submask(x) ((1L << ((x) + 1)) - 1) > +#define bit(obj,st) (((obj) >> (st)) & 1) > +#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) > + > +#define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \ > + do \ > + { \ > + unsigned int reg_len = LENGTH; \ > + if (reg_len) \ > + { \ > + REGS = XNEWVEC (uint32_t, reg_len); \ > + memcpy(®S[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \ > + } \ > + } \ > + while (0) > + > +#define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \ > + do \ > + { \ > + unsigned int mem_len = LENGTH; \ > + if (mem_len) \ > + { \ > + MEMS = XNEWVEC (struct aarch64_mem_r, mem_len); \ > + memcpy(&MEMS->len, &RECORD_BUF[0], \ > + sizeof(struct aarch64_mem_r) * LENGTH); \ > + } \ > + } \ > + while (0) > + > +/* ARM memory record structure. */ Comment needs updating. > +struct aarch64_mem_r > +{ > + uint64_t len; /* Record length. */ > + uint64_t addr; /* Memory address. */ > +}; > + > +enum aarch64_record_result > +{ > + AARCH64_RECORD_SUCCESS, > + AARCH64_RECORD_FAILURE, > + AARCH64_RECORD_USUPPORTED Should this be UNSUPPORTED? > +}; > + > +/* ARM instruction record contains opcode of current insn Also needs updating. > + 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; > + uint32_t aarch64_insn; > + uint32_t mem_rec_count; > + uint32_t reg_rec_count; > + uint32_t *aarch64_regs; > + struct aarch64_mem_r *aarch64_mems; > +} insn_decode_record; > + > +extern int aarch64_process_record (struct gdbarch *gdbarch, > + struct regcache *regcache, CORE_ADDR addr); > + > #endif /* aarch64-tdep.h */ > -- > 1.9.1 > -- Will Newton Toolchain Working Group, Linaro