aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPierre Langlois <pierre.langlois@arm.com>2015-09-21 15:01:04 +0100
committerYao Qi <yao.qi@linaro.org>2015-09-21 15:01:04 +0100
commit787749ead66eee8c20754c160bd79404b2109553 (patch)
treea39692b0cfaae08eab2caecf8b43e4c0d03ab7e0 /gdb
parent9812b2e60750cc7bbfa252d9ae8d85a72a399e01 (diff)
downloadgdb-787749ead66eee8c20754c160bd79404b2109553.zip
gdb-787749ead66eee8c20754c160bd79404b2109553.tar.gz
gdb-787749ead66eee8c20754c160bd79404b2109553.tar.bz2
Move instruction decoding into new arch/ directory
This patch moves the following functions into the arch/ common directory, in new files arch/aarch64-insn.{h,c}. They are prefixed with 'aarch64_': - aarch64_decode_adrp - aarch64_decode_b - aarch64_decode_cb - aarch64_decode_tb We will need them to implement fast tracepoints in GDBserver. For consistency, this patch also adds the 'aarch64_' prefix to static decoding functions that do not need to be shared right now. V2: make sure the formatting issues propagated fix `gdbserver/configure.srv'. gdb/ChangeLog: * Makefile.in (ALL_64_TARGET_OBS): Add aarch64-insn.o. (HFILES_NO_SRCDIR): Add arch/aarch64-insn.h. (aarch64-insn.o): New rule. * configure.tgt (aarch64*-*-elf): Add aarch64-insn.o. (aarch64*-*-linux*): Likewise. * arch/aarch64-insn.c: New file. * arch/aarch64-insn.h: New file. * aarch64-tdep.c: Include arch/aarch64-insn.h. (aarch64_debug): Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (decode_add_sub_imm): Rename to ... (aarch64_decode_add_sub_imm): ... this. (decode_adrp): Rename to ... (aarch64_decode_adrp): ... this. Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (decode_b): Rename to ... (aarch64_decode_b): ... this. Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (decode_bcond): Rename to ... (aarch64_decode_bcond): ... this. Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (decode_br): Rename to ... (aarch64_decode_br): ... this. (decode_cb): Rename to ... (aarch64_decode_cb): ... this. Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (decode_eret): Rename to ... (aarch64_decode_eret): ... this. (decode_movz): Rename to ... (aarch64_decode_movz): ... this. (decode_orr_shifted_register_x): Rename to ... (aarch64_decode_orr_shifted_register_x): ... this. (decode_ret): Rename to ... (aarch64_decode_ret): ... this. (decode_stp_offset): Rename to ... (aarch64_decode_stp_offset): ... this. (decode_stp_offset_wb): Rename to ... (aarch64_decode_stp_offset_wb): ... this. (decode_stur): Rename to ... (aarch64_decode_stur): ... this. (decode_tb): Rename to ... (aarch64_decode_tb): ... this. Move to arch/aarch64-insn.c. Declare in arch/aarch64-insn.h. (aarch64_analyze_prologue): Adjust calls to renamed functions. gdb/gdbserver/ChangeLog: * Makefile.in (aarch64-insn.o): New rule. * configure.srv (aarch64*-*-linux*): Add aarch64-insn.o.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog47
-rw-r--r--gdb/Makefile.in13
-rw-r--r--gdb/aarch64-tdep.c235
-rw-r--r--gdb/arch/aarch64-insn.c218
-rw-r--r--gdb/arch/aarch64-insn.h38
-rw-r--r--gdb/configure.tgt4
-rw-r--r--gdb/gdbserver/ChangeLog5
-rw-r--r--gdb/gdbserver/Makefile.in6
-rw-r--r--gdb/gdbserver/configure.srv1
9 files changed, 366 insertions, 201 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fe56b75..7d8feeb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,50 @@
+2015-09-21 Pierre Langlois <pierre.langlois@arm.com>
+
+ * Makefile.in (ALL_64_TARGET_OBS): Add aarch64-insn.o.
+ (HFILES_NO_SRCDIR): Add arch/aarch64-insn.h.
+ (aarch64-insn.o): New rule.
+ * configure.tgt (aarch64*-*-elf): Add aarch64-insn.o.
+ (aarch64*-*-linux*): Likewise.
+ * arch/aarch64-insn.c: New file.
+ * arch/aarch64-insn.h: New file.
+ * aarch64-tdep.c: Include arch/aarch64-insn.h.
+ (aarch64_debug): Move to arch/aarch64-insn.c. Declare in
+ arch/aarch64-insn.h.
+ (decode_add_sub_imm): Rename to ...
+ (aarch64_decode_add_sub_imm): ... this.
+ (decode_adrp): Rename to ...
+ (aarch64_decode_adrp): ... this. Move to arch/aarch64-insn.c.
+ Declare in arch/aarch64-insn.h.
+ (decode_b): Rename to ...
+ (aarch64_decode_b): ... this. Move to arch/aarch64-insn.c.
+ Declare in arch/aarch64-insn.h.
+ (decode_bcond): Rename to ...
+ (aarch64_decode_bcond): ... this. Move to arch/aarch64-insn.c.
+ Declare in arch/aarch64-insn.h.
+ (decode_br): Rename to ...
+ (aarch64_decode_br): ... this.
+ (decode_cb): Rename to ...
+ (aarch64_decode_cb): ... this. Move to arch/aarch64-insn.c.
+ Declare in arch/aarch64-insn.h.
+ (decode_eret): Rename to ...
+ (aarch64_decode_eret): ... this.
+ (decode_movz): Rename to ...
+ (aarch64_decode_movz): ... this.
+ (decode_orr_shifted_register_x): Rename to ...
+ (aarch64_decode_orr_shifted_register_x): ... this.
+ (decode_ret): Rename to ...
+ (aarch64_decode_ret): ... this.
+ (decode_stp_offset): Rename to ...
+ (aarch64_decode_stp_offset): ... this.
+ (decode_stp_offset_wb): Rename to ...
+ (aarch64_decode_stp_offset_wb): ... this.
+ (decode_stur): Rename to ...
+ (aarch64_decode_stur): ... this.
+ (decode_tb): Rename to ...
+ (aarch64_decode_tb): ... this. Move to arch/aarch64-insn.c.
+ Declare in arch/aarch64-insn.h.
+ (aarch64_analyze_prologue): Adjust calls to renamed functions.
+
2015-09-20 Doug Evans <xdje42@gmail.com>
* dwarf2read.c (add_partial_symbol): Remove outdated comments.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 5659116..d5ca2ee 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -644,7 +644,7 @@ TARGET_OBS = @TARGET_OBS@
# All target-dependent objects files that require 64-bit CORE_ADDR
# (used with --enable-targets=all --enable-64-bit-bfd).
ALL_64_TARGET_OBS = \
- aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o \
+ aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o aarch64-insn.o \
alphabsd-tdep.o alphafbsd-tdep.o alpha-linux-tdep.o alpha-mdebug-tdep.o \
alphanbsd-tdep.o alphaobsd-tdep.o alpha-tdep.o \
amd64fbsd-tdep.o amd64-darwin-tdep.o amd64-dicos-tdep.o \
@@ -986,7 +986,7 @@ common/common-debug.h common/cleanups.h common/gdb_setjmp.h \
common/common-exceptions.h target/target.h common/symbol.h \
common/common-regcache.h fbsd-tdep.h nat/linux-personality.h \
common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h \
-nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h
+nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -2336,6 +2336,15 @@ aarch64-linux.o: ${srcdir}/nat/aarch64-linux.c
$(COMPILE) $(srcdir)/nat/aarch64-linux.c
$(POSTCOMPILE)
+# gdb/arch/ dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the sub-directory.
+
+aarch64-insn.o: ${srcdir}/arch/aarch64-insn.c
+ $(COMPILE) $(srcdir)/arch/aarch64-insn.c
+ $(POSTCOMPILE)
+
#
# gdb/tui/ dependencies
#
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 9a4eda2..92e2404 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -57,6 +57,8 @@
#include "features/aarch64.c"
+#include "arch/aarch64-insn.h"
+
/* Pseudo register base numbers. */
#define AARCH64_Q0_REGNUM 0
#define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + 32)
@@ -179,9 +181,6 @@ struct aarch64_prologue_cache
struct trad_frame_saved_reg *saved_regs;
};
-/* Toggle this file's internal debugging dump. */
-static int aarch64_debug;
-
static void
show_aarch64_debug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
@@ -231,8 +230,8 @@ decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd, unsigned *rn,
- int32_t *imm)
+aarch64_decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd,
+ unsigned *rn, int32_t *imm)
{
if ((insn & 0x9f000000) == 0x91000000)
{
@@ -271,94 +270,6 @@ decode_add_sub_imm (CORE_ADDR addr, uint32_t insn, unsigned *rd, unsigned *rn,
return 0;
}
-/* Decode an opcode if it represents an ADRP instruction.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- RD receives the 'rd' field from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-static int
-decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
-{
- if (decode_masked_match (insn, 0x9f000000, 0x90000000))
- {
- *rd = (insn >> 0) & 0x1f;
-
- if (aarch64_debug)
- {
- debug_printf ("decode: 0x%s 0x%x adrp x%u, #?\n",
- core_addr_to_string_nz (addr), insn, *rd);
- }
- return 1;
- }
- return 0;
-}
-
-/* Decode an opcode if it represents an branch immediate or branch
- and link immediate instruction.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- IS_BL receives the 'op' bit from the decoded instruction.
- OFFSET receives the immediate offset from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-static int
-decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl, int32_t *offset)
-{
- /* b 0001 01ii iiii iiii iiii iiii iiii iiii */
- /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
- if (decode_masked_match (insn, 0x7c000000, 0x14000000))
- {
- *is_bl = (insn >> 31) & 0x1;
- *offset = extract_signed_bitfield (insn, 26, 0) << 2;
-
- if (aarch64_debug)
- {
- debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *is_bl ? "bl" : "b",
- core_addr_to_string_nz (addr + *offset));
- }
-
- return 1;
- }
- return 0;
-}
-
-/* Decode an opcode if it represents a conditional branch instruction.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- COND receives the branch condition field from the decoded
- instruction.
- OFFSET receives the immediate offset from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-static int
-decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond, int32_t *offset)
-{
- /* b.cond 0101 0100 iiii iiii iiii iiii iii0 cccc */
- if (decode_masked_match (insn, 0xff000010, 0x54000000))
- {
- *cond = (insn >> 0) & 0xf;
- *offset = extract_signed_bitfield (insn, 19, 5) << 2;
-
- if (aarch64_debug)
- {
- debug_printf ("decode: 0x%s 0x%x b<%u> 0x%s\n",
- core_addr_to_string_nz (addr), insn, *cond,
- core_addr_to_string_nz (addr + *offset));
- }
- return 1;
- }
- return 0;
-}
-
/* Decode an opcode if it represents a branch via register instruction.
ADDR specifies the address of the opcode.
@@ -369,7 +280,8 @@ decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond, int32_t *offset)
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr, unsigned *rn)
+aarch64_decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr,
+ unsigned *rn)
{
/* 8 4 0 6 2 8 4 0 */
/* blr 110101100011111100000000000rrrrr */
@@ -391,42 +303,6 @@ decode_br (CORE_ADDR addr, uint32_t insn, int *is_blr, unsigned *rn)
return 0;
}
-/* Decode an opcode if it represents a CBZ or CBNZ instruction.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- IS64 receives the 'sf' field from the decoded instruction.
- IS_CBNZ receives the 'op' field from the decoded instruction.
- RN receives the 'rn' field from the decoded instruction.
- OFFSET receives the 'imm19' field from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-static int
-decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
- unsigned *rn, int32_t *offset)
-{
- /* cbz T011 010o iiii iiii iiii iiii iiir rrrr */
- /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
- if (decode_masked_match (insn, 0x7e000000, 0x34000000))
- {
- *rn = (insn >> 0) & 0x1f;
- *is64 = (insn >> 31) & 0x1;
- *is_cbnz = (insn >> 24) & 0x1;
- *offset = extract_signed_bitfield (insn, 19, 5) << 2;
-
- if (aarch64_debug)
- {
- debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *is_cbnz ? "cbnz" : "cbz",
- core_addr_to_string_nz (addr + *offset));
- }
- return 1;
- }
- return 0;
-}
-
/* Decode an opcode if it represents a ERET instruction.
ADDR specifies the address of the opcode.
@@ -435,7 +311,7 @@ decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_eret (CORE_ADDR addr, uint32_t insn)
+aarch64_decode_eret (CORE_ADDR addr, uint32_t insn)
{
/* eret 1101 0110 1001 1111 0000 0011 1110 0000 */
if (insn == 0xd69f03e0)
@@ -459,7 +335,7 @@ decode_eret (CORE_ADDR addr, uint32_t insn)
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
+aarch64_decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
{
if (decode_masked_match (insn, 0xff800000, 0x52800000))
{
@@ -488,9 +364,9 @@ decode_movz (CORE_ADDR addr, uint32_t insn, unsigned *rd)
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_orr_shifted_register_x (CORE_ADDR addr,
- uint32_t insn, unsigned *rd, unsigned *rn,
- unsigned *rm, int32_t *imm)
+aarch64_decode_orr_shifted_register_x (CORE_ADDR addr, uint32_t insn,
+ unsigned *rd, unsigned *rn,
+ unsigned *rm, int32_t *imm)
{
if (decode_masked_match (insn, 0xff200000, 0xaa000000))
{
@@ -519,7 +395,7 @@ decode_orr_shifted_register_x (CORE_ADDR addr,
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
+aarch64_decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
{
if (decode_masked_match (insn, 0xfffffc1f, 0xd65f0000))
{
@@ -547,9 +423,8 @@ decode_ret (CORE_ADDR addr, uint32_t insn, unsigned *rn)
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_stp_offset (CORE_ADDR addr,
- uint32_t insn,
- unsigned *rt1, unsigned *rt2, unsigned *rn, int32_t *imm)
+aarch64_decode_stp_offset (CORE_ADDR addr, uint32_t insn, unsigned *rt1,
+ unsigned *rt2, unsigned *rn, int32_t *imm)
{
if (decode_masked_match (insn, 0xffc00000, 0xa9000000))
{
@@ -583,10 +458,8 @@ decode_stp_offset (CORE_ADDR addr,
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_stp_offset_wb (CORE_ADDR addr,
- uint32_t insn,
- unsigned *rt1, unsigned *rt2, unsigned *rn,
- int32_t *imm)
+aarch64_decode_stp_offset_wb (CORE_ADDR addr, uint32_t insn, unsigned *rt1,
+ unsigned *rt2, unsigned *rn, int32_t *imm)
{
if (decode_masked_match (insn, 0xffc00000, 0xa9800000))
{
@@ -620,8 +493,8 @@ decode_stp_offset_wb (CORE_ADDR addr,
Return 1 if the opcodes matches and is decoded, otherwise 0. */
static int
-decode_stur (CORE_ADDR addr, uint32_t insn, int *is64, unsigned *rt,
- unsigned *rn, int32_t *imm)
+aarch64_decode_stur (CORE_ADDR addr, uint32_t insn, int *is64,
+ unsigned *rt, unsigned *rn, int32_t *imm)
{
if (decode_masked_match (insn, 0xbfe00c00, 0xb8000000))
{
@@ -641,42 +514,6 @@ decode_stur (CORE_ADDR addr, uint32_t insn, int *is64, unsigned *rt,
return 0;
}
-/* Decode an opcode if it represents a TBZ or TBNZ instruction.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- IS_TBNZ receives the 'op' field from the decoded instruction.
- BIT receives the bit position field from the decoded instruction.
- RT receives 'rt' field from the decoded instruction.
- IMM receives 'imm' field from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-static int
-decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz, unsigned *bit,
- unsigned *rt, int32_t *imm)
-{
- /* tbz b011 0110 bbbb biii iiii iiii iiir rrrr */
- /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
- if (decode_masked_match (insn, 0x7e000000, 0x36000000))
- {
- *rt = (insn >> 0) & 0x1f;
- *is_tbnz = (insn >> 24) & 0x1;
- *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
- *imm = extract_signed_bitfield (insn, 14, 5) << 2;
-
- if (aarch64_debug)
- {
- debug_printf ("decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
- core_addr_to_string_nz (addr), insn,
- *is_tbnz ? "tbnz" : "tbz", *rt, *bit,
- core_addr_to_string_nz (addr + *imm));
- }
- return 1;
- }
- return 0;
-}
-
/* Analyze a prologue, looking for a recognizable stack frame
and frame pointer. Scan until we encounter a store that could
clobber the stack frame unexpectedly, or an unknown instruction. */
@@ -718,39 +555,40 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
insn = read_memory_unsigned_integer (start, 4, byte_order_for_code);
- if (decode_add_sub_imm (start, insn, &rd, &rn, &imm))
+ if (aarch64_decode_add_sub_imm (start, insn, &rd, &rn, &imm))
regs[rd] = pv_add_constant (regs[rn], imm);
- else if (decode_adrp (start, insn, &rd))
+ else if (aarch64_decode_adrp (start, insn, &rd))
regs[rd] = pv_unknown ();
- else if (decode_b (start, insn, &is_link, &offset))
+ else if (aarch64_decode_b (start, insn, &is_link, &offset))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_bcond (start, insn, &cond, &offset))
+ else if (aarch64_decode_bcond (start, insn, &cond, &offset))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_br (start, insn, &is_link, &rn))
+ else if (aarch64_decode_br (start, insn, &is_link, &rn))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_cb (start, insn, &is64, &is_cbnz, &rn, &offset))
+ else if (aarch64_decode_cb (start, insn, &is64, &is_cbnz, &rn,
+ &offset))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_eret (start, insn))
+ else if (aarch64_decode_eret (start, insn))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_movz (start, insn, &rd))
+ else if (aarch64_decode_movz (start, insn, &rd))
regs[rd] = pv_unknown ();
- else
- if (decode_orr_shifted_register_x (start, insn, &rd, &rn, &rm, &imm))
+ else if (aarch64_decode_orr_shifted_register_x (start, insn, &rd,
+ &rn, &rm, &imm))
{
if (imm == 0 && rn == 31)
regs[rd] = regs[rm];
@@ -765,17 +603,18 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
break;
}
}
- else if (decode_ret (start, insn, &rn))
+ else if (aarch64_decode_ret (start, insn, &rn))
{
/* Stop analysis on branch. */
break;
}
- else if (decode_stur (start, insn, &is64, &rt, &rn, &offset))
+ else if (aarch64_decode_stur (start, insn, &is64, &rt, &rn, &offset))
{
pv_area_store (stack, pv_add_constant (regs[rn], offset),
is64 ? 8 : 4, regs[rt]);
}
- else if (decode_stp_offset (start, insn, &rt1, &rt2, &rn, &imm))
+ else if (aarch64_decode_stp_offset (start, insn, &rt1, &rt2, &rn,
+ &imm))
{
/* If recording this store would invalidate the store area
(perhaps because rn is not known) then we should abandon
@@ -793,7 +632,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
regs[rt2]);
}
- else if (decode_stp_offset_wb (start, insn, &rt1, &rt2, &rn, &imm))
+ else if (aarch64_decode_stp_offset_wb (start, insn, &rt1, &rt2, &rn,
+ &imm))
{
/* If recording this store would invalidate the store area
(perhaps because rn is not known) then we should abandon
@@ -812,7 +652,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
regs[rt2]);
regs[rn] = pv_add_constant (regs[rn], imm);
}
- else if (decode_tb (start, insn, &is_tbnz, &bit, &rn, &offset))
+ else if (aarch64_decode_tb (start, insn, &is_tbnz, &bit, &rn,
+ &offset))
{
/* Stop analysis on branch. */
break;
@@ -2663,7 +2504,7 @@ aarch64_software_single_step (struct frame_info *frame)
byte_order_for_code);
/* Check if the instruction is a conditional branch. */
- if (decode_bcond (loc, insn, &cond, &offset))
+ if (aarch64_decode_bcond (loc, insn, &cond, &offset))
{
if (bc_insn_count >= 1)
return 0;
diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c
new file mode 100644
index 0000000..3a289a2
--- /dev/null
+++ b/gdb/arch/aarch64-insn.c
@@ -0,0 +1,218 @@
+/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "aarch64-insn.h"
+
+/* Toggle this file's internal debugging dump. */
+int aarch64_debug = 0;
+
+/* Extract a signed value from a bit field within an instruction
+ encoding.
+
+ INSN is the instruction opcode.
+
+ WIDTH specifies the width of the bit field to extract (in bits).
+
+ OFFSET specifies the least significant bit of the field where bits
+ are numbered zero counting from least to most significant. */
+
+static int32_t
+extract_signed_bitfield (uint32_t insn, unsigned width, unsigned offset)
+{
+ unsigned shift_l = sizeof (int32_t) * 8 - (offset + width);
+ unsigned shift_r = sizeof (int32_t) * 8 - width;
+
+ return ((int32_t) insn << shift_l) >> shift_r;
+}
+
+/* Determine if specified bits within an instruction opcode matches a
+ specific pattern.
+
+ INSN is the instruction opcode.
+
+ MASK specifies the bits within the opcode that are to be tested
+ agsinst for a match with PATTERN. */
+
+static int
+decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
+{
+ return (insn & mask) == pattern;
+}
+
+/* Decode an opcode if it represents an ADRP instruction.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ RD receives the 'rd' field from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
+{
+ if (decode_masked_match (insn, 0x9f000000, 0x90000000))
+ {
+ *rd = (insn >> 0) & 0x1f;
+
+ if (aarch64_debug)
+ {
+ debug_printf ("decode: 0x%s 0x%x adrp x%u, #?\n",
+ core_addr_to_string_nz (addr), insn, *rd);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Decode an opcode if it represents an branch immediate or branch
+ and link immediate instruction.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ IS_BL receives the 'op' bit from the decoded instruction.
+ OFFSET receives the immediate offset from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
+ int32_t *offset)
+{
+ /* b 0001 01ii iiii iiii iiii iiii iiii iiii */
+ /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
+ if (decode_masked_match (insn, 0x7c000000, 0x14000000))
+ {
+ *is_bl = (insn >> 31) & 0x1;
+ *offset = extract_signed_bitfield (insn, 26, 0) << 2;
+
+ if (aarch64_debug)
+ {
+ debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
+ core_addr_to_string_nz (addr), insn,
+ *is_bl ? "bl" : "b",
+ core_addr_to_string_nz (addr + *offset));
+ }
+
+ return 1;
+ }
+ return 0;
+}
+
+/* Decode an opcode if it represents a conditional branch instruction.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ COND receives the branch condition field from the decoded
+ instruction.
+ OFFSET receives the immediate offset from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
+ int32_t *offset)
+{
+ /* b.cond 0101 0100 iiii iiii iiii iiii iii0 cccc */
+ if (decode_masked_match (insn, 0xff000010, 0x54000000))
+ {
+ *cond = (insn >> 0) & 0xf;
+ *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+
+ if (aarch64_debug)
+ {
+ debug_printf ("decode: 0x%s 0x%x b<%u> 0x%s\n",
+ core_addr_to_string_nz (addr), insn, *cond,
+ core_addr_to_string_nz (addr + *offset));
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Decode an opcode if it represents a CBZ or CBNZ instruction.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ IS64 receives the 'sf' field from the decoded instruction.
+ IS_CBNZ receives the 'op' field from the decoded instruction.
+ RN receives the 'rn' field from the decoded instruction.
+ OFFSET receives the 'imm19' field from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
+ unsigned *rn, int32_t *offset)
+{
+ /* cbz T011 010o iiii iiii iiii iiii iiir rrrr */
+ /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
+ if (decode_masked_match (insn, 0x7e000000, 0x34000000))
+ {
+ *rn = (insn >> 0) & 0x1f;
+ *is64 = (insn >> 31) & 0x1;
+ *is_cbnz = (insn >> 24) & 0x1;
+ *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+
+ if (aarch64_debug)
+ {
+ debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
+ core_addr_to_string_nz (addr), insn,
+ *is_cbnz ? "cbnz" : "cbz",
+ core_addr_to_string_nz (addr + *offset));
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Decode an opcode if it represents a TBZ or TBNZ instruction.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ IS_TBNZ receives the 'op' field from the decoded instruction.
+ BIT receives the bit position field from the decoded instruction.
+ RT receives 'rt' field from the decoded instruction.
+ IMM receives 'imm' field from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
+ unsigned *bit, unsigned *rt, int32_t *imm)
+{
+ /* tbz b011 0110 bbbb biii iiii iiii iiir rrrr */
+ /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
+ if (decode_masked_match (insn, 0x7e000000, 0x36000000))
+ {
+ *rt = (insn >> 0) & 0x1f;
+ *is_tbnz = (insn >> 24) & 0x1;
+ *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
+ *imm = extract_signed_bitfield (insn, 14, 5) << 2;
+
+ if (aarch64_debug)
+ {
+ debug_printf ("decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
+ core_addr_to_string_nz (addr), insn,
+ *is_tbnz ? "tbnz" : "tbz", *rt, *bit,
+ core_addr_to_string_nz (addr + *imm));
+ }
+ return 1;
+ }
+ return 0;
+}
diff --git a/gdb/arch/aarch64-insn.h b/gdb/arch/aarch64-insn.h
new file mode 100644
index 0000000..7775a34
--- /dev/null
+++ b/gdb/arch/aarch64-insn.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef AARCH64_INSN_H
+#define AARCH64_INSN_H 1
+
+extern int aarch64_debug;
+
+int aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd);
+
+int aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
+ int32_t *offset);
+
+int aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
+ int32_t *offset);
+
+int aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64,
+ int *is_cbnz, unsigned *rn, int32_t *offset);
+
+int aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
+ unsigned *bit, unsigned *rt, int32_t *imm);
+
+#endif
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index c42b4df..33d4cfc 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -38,12 +38,12 @@ esac
case "${targ}" in
aarch64*-*-elf)
# Target: AArch64 embedded system
- gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o"
+ gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o aarch64-insn.o"
;;
aarch64*-*-linux*)
# Target: AArch64 linux
- gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o \
+ gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o aarch64-insn.o \
arm-tdep.o arm-linux-tdep.o \
glibc-tdep.o linux-tdep.o solib-svr4.o \
symfile-mem.o linux-record.o"
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 16b02ca..83a7848 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-21 Pierre Langlois <pierre.langlois@arm.com>
+
+ * Makefile.in (aarch64-insn.o): New rule.
+ * configure.srv (aarch64*-*-linux*): Add aarch64-insn.o.
+
2015-09-21 Yao Qi <yao.qi@linaro.org>
* ax.c [!IN_PROCESS_AGENT] (gdb_agent_op_sizes): Define it.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index b715a32..d096663 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -625,6 +625,12 @@ linux-namespaces.o: ../nat/linux-namespaces.c
$(COMPILE) $<
$(POSTCOMPILE)
+# Architecture specific object files rules from ../arch
+
+aarch64-insn.o: ../arch/aarch64-insn.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c
reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index aa232f8..a62df83 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -53,6 +53,7 @@ case "${target}" in
srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o"
srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
srv_tgtobj="$srv_tgtobj aarch64-linux.o"
+ srv_tgtobj="$srv_tgtobj aarch64-insn.o"
srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
srv_xmlfiles="aarch64.xml"
srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"