aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2015-10-12 11:28:38 +0100
committerYao Qi <yao.qi@linaro.org>2015-10-12 11:28:38 +0100
commit246994ce350923199a4c952b38dcee5bcbe8c554 (patch)
tree63dfde48740657187e8e20ba1ce35af5cf4be662
parent0badd99faf8cb1a20ade36e94d3f74b9e6f65cd1 (diff)
downloadgdb-246994ce350923199a4c952b38dcee5bcbe8c554.zip
gdb-246994ce350923199a4c952b38dcee5bcbe8c554.tar.gz
gdb-246994ce350923199a4c952b38dcee5bcbe8c554.tar.bz2
Move aarch64_relocate_instruction to arch/aarch64-insn.c
This patch moves aarch64_relocate_instruction and visitor class to arch/aarch64-insn.c, so that both GDB and GDBserver can use it. gdb: 2015-10-12 Yao Qi <yao.qi@linaro.org> * arch/aarch64-insn.c (aarch64_decode_ldr_literal): Moved from gdbserver/linux-aarch64-low.c. (aarch64_relocate_instruction): Likewise. * arch/aarch64-insn.h (aarch64_decode_ldr_literal): Declare. (struct aarch64_insn_data): Moved from gdbserver/linux-aarch64-low.c. (struct aarch64_insn_visitor): Likewise. (aarch64_relocate_instruction): Declare. gdb/gdbserver: 2015-10-12 Yao Qi <yao.qi@linaro.org> * linux-aarch64-low.c (extract_signed_bitfield): Remove. (aarch64_decode_ldr_literal): Move to gdb/arch/aarch64-insn.c. (aarch64_relocate_instruction): Likewise. (struct aarch64_insn_data): Move to gdb/arch/aarch64-insn.h. (struct aarch64_insn_visitor): Likewise.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/arch/aarch64-insn.c93
-rw-r--r--gdb/arch/aarch64-insn.h50
-rw-r--r--gdb/gdbserver/ChangeLog8
-rw-r--r--gdb/gdbserver/linux-aarch64-low.c155
5 files changed, 162 insertions, 155 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e760bd0..f79c93d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2015-10-12 Yao Qi <yao.qi@linaro.org>
+
+ * arch/aarch64-insn.c (aarch64_decode_ldr_literal): Moved from
+ gdbserver/linux-aarch64-low.c.
+ (aarch64_relocate_instruction): Likewise.
+ * arch/aarch64-insn.h (aarch64_decode_ldr_literal): Declare.
+ (struct aarch64_insn_data): Moved from
+ gdbserver/linux-aarch64-low.c.
+ (struct aarch64_insn_visitor): Likewise.
+ (aarch64_relocate_instruction): Declare.
+
2015-10-12 Pierre-Marie de Rodat <derodat@adacore.com>
* eval.c (evaluate_subexp_standard) <STRUCTOP_STRUCT>: If
diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c
index 13d0013..d0e88fa 100644
--- a/gdb/arch/aarch64-insn.c
+++ b/gdb/arch/aarch64-insn.c
@@ -235,3 +235,96 @@ aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
}
return 0;
}
+
+/* Decode an opcode if it represents an LDR or LDRSW instruction taking a
+ literal offset from the current PC.
+
+ ADDR specifies the address of the opcode.
+ INSN specifies the opcode to test.
+ IS_W is set if the instruction is LDRSW.
+ IS64 receives size field from the decoded instruction.
+ RT receives the 'rt' field from the decoded instruction.
+ OFFSET receives the 'imm' field from the decoded instruction.
+
+ Return 1 if the opcodes matches and is decoded, otherwise 0. */
+
+int
+aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
+ int *is64, unsigned *rt, int32_t *offset)
+{
+ /* LDR 0T01 1000 iiii iiii iiii iiii iiir rrrr */
+ /* LDRSW 1001 1000 iiii iiii iiii iiii iiir rrrr */
+ if ((insn & 0x3f000000) == 0x18000000)
+ {
+ *is_w = (insn >> 31) & 0x1;
+
+ if (*is_w)
+ {
+ /* LDRSW always takes a 64-bit destination registers. */
+ *is64 = 1;
+ }
+ else
+ *is64 = (insn >> 30) & 0x1;
+
+ *rt = (insn >> 0) & 0x1f;
+ *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+
+ if (aarch64_debug)
+ debug_printf ("decode: %s 0x%x %s %s%u, #?\n",
+ core_addr_to_string_nz (addr), insn,
+ *is_w ? "ldrsw" : "ldr",
+ *is64 ? "x" : "w", *rt);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Visit an instruction INSN by VISITOR with all needed information in DATA.
+
+ PC relative instructions need to be handled specifically:
+
+ - B/BL
+ - B.COND
+ - CBZ/CBNZ
+ - TBZ/TBNZ
+ - ADR/ADRP
+ - LDR/LDRSW (literal) */
+
+void
+aarch64_relocate_instruction (uint32_t insn,
+ const struct aarch64_insn_visitor *visitor,
+ struct aarch64_insn_data *data)
+{
+ int is_bl;
+ int is64;
+ int is_sw;
+ int is_cbnz;
+ int is_tbnz;
+ int is_adrp;
+ unsigned rn;
+ unsigned rt;
+ unsigned rd;
+ unsigned cond;
+ unsigned bit;
+ int32_t offset;
+
+ if (aarch64_decode_b (data->insn_addr, insn, &is_bl, &offset))
+ visitor->b (is_bl, offset, data);
+ else if (aarch64_decode_bcond (data->insn_addr, insn, &cond, &offset))
+ visitor->b_cond (cond, offset, data);
+ else if (aarch64_decode_cb (data->insn_addr, insn, &is64, &is_cbnz, &rn,
+ &offset))
+ visitor->cb (offset, is_cbnz, rn, is64, data);
+ else if (aarch64_decode_tb (data->insn_addr, insn, &is_tbnz, &bit, &rt,
+ &offset))
+ visitor->tb (offset, is_tbnz, rt, bit, data);
+ else if (aarch64_decode_adr (data->insn_addr, insn, &is_adrp, &rd, &offset))
+ visitor->adr (offset, rd, is_adrp, data);
+ else if (aarch64_decode_ldr_literal (data->insn_addr, insn, &is_sw, &is64,
+ &rt, &offset))
+ visitor->ldr_literal (offset, is_sw, rt, is64, data);
+ else
+ visitor->others (insn, data);
+}
diff --git a/gdb/arch/aarch64-insn.h b/gdb/arch/aarch64-insn.h
index 2facb44..47f6715 100644
--- a/gdb/arch/aarch64-insn.h
+++ b/gdb/arch/aarch64-insn.h
@@ -36,4 +36,54 @@ int aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64,
int aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
unsigned *bit, unsigned *rt, int32_t *imm);
+int aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
+ int *is64, unsigned *rt, int32_t *offset);
+
+/* Data passed to each method of aarch64_insn_visitor. */
+
+struct aarch64_insn_data
+{
+ /* The instruction address. */
+ CORE_ADDR insn_addr;
+};
+
+/* Visit different instructions by different methods. */
+
+struct aarch64_insn_visitor
+{
+ /* Visit instruction B/BL OFFSET. */
+ void (*b) (const int is_bl, const int32_t offset,
+ struct aarch64_insn_data *data);
+
+ /* Visit instruction B.COND OFFSET. */
+ void (*b_cond) (const unsigned cond, const int32_t offset,
+ struct aarch64_insn_data *data);
+
+ /* Visit instruction CBZ/CBNZ Rn, OFFSET. */
+ void (*cb) (const int32_t offset, const int is_cbnz,
+ const unsigned rn, int is64,
+ struct aarch64_insn_data *data);
+
+ /* Visit instruction TBZ/TBNZ Rt, #BIT, OFFSET. */
+ void (*tb) (const int32_t offset, int is_tbnz,
+ const unsigned rt, unsigned bit,
+ struct aarch64_insn_data *data);
+
+ /* Visit instruction ADR/ADRP Rd, OFFSET. */
+ void (*adr) (const int32_t offset, const unsigned rd,
+ const int is_adrp, struct aarch64_insn_data *data);
+
+ /* Visit instruction LDR/LDRSW Rt, OFFSET. */
+ void (*ldr_literal) (const int32_t offset, const int is_sw,
+ const unsigned rt, const int is64,
+ struct aarch64_insn_data *data);
+
+ /* Visit instruction INSN of other kinds. */
+ void (*others) (const uint32_t insn, struct aarch64_insn_data *data);
+};
+
+void aarch64_relocate_instruction (uint32_t insn,
+ const struct aarch64_insn_visitor *visitor,
+ struct aarch64_insn_data *data);
+
#endif
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index f72a0e2..6d3d66d 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,13 @@
2015-10-12 Yao Qi <yao.qi@linaro.org>
+ * linux-aarch64-low.c (extract_signed_bitfield): Remove.
+ (aarch64_decode_ldr_literal): Move to gdb/arch/aarch64-insn.c.
+ (aarch64_relocate_instruction): Likewise.
+ (struct aarch64_insn_data): Move to gdb/arch/aarch64-insn.h.
+ (struct aarch64_insn_visitor): Likewise.
+
+2015-10-12 Yao Qi <yao.qi@linaro.org>
+
* linux-aarch64-low.c (struct aarch64_insn_data): New.
(struct aarch64_insn_visitor): New.
(struct aarch64_insn_relocation_data): New.
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index b4181ed..1241434 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -584,70 +584,6 @@ aarch64_get_thread_area (int lwpid, CORE_ADDR *addrp)
return 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;
-}
-
-/* Decode an opcode if it represents an LDR or LDRSW instruction taking a
- literal offset from the current PC.
-
- ADDR specifies the address of the opcode.
- INSN specifies the opcode to test.
- IS_W is set if the instruction is LDRSW.
- IS64 receives size field from the decoded instruction.
- RT receives the 'rt' field from the decoded instruction.
- OFFSET receives the 'imm' field from the decoded instruction.
-
- Return 1 if the opcodes matches and is decoded, otherwise 0. */
-
-int
-aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
- int *is64, unsigned *rt, int32_t *offset)
-{
- /* LDR 0T01 1000 iiii iiii iiii iiii iiir rrrr */
- /* LDRSW 1001 1000 iiii iiii iiii iiii iiir rrrr */
- if ((insn & 0x3f000000) == 0x18000000)
- {
- *is_w = (insn >> 31) & 0x1;
-
- if (*is_w)
- {
- /* LDRSW always takes a 64-bit destination registers. */
- *is64 = 1;
- }
- else
- *is64 = (insn >> 30) & 0x1;
-
- *rt = (insn >> 0) & 0x1f;
- *offset = extract_signed_bitfield (insn, 19, 5) << 2;
-
- if (aarch64_debug)
- debug_printf ("decode: %s 0x%x %s %s%u, #?\n",
- core_addr_to_string_nz (addr), insn,
- *is_w ? "ldrsw" : "ldr",
- *is64 ? "x" : "w", *rt);
-
- return 1;
- }
-
- return 0;
-}
-
/* List of opcodes that we need for building the jump pad and relocating
an instruction. */
@@ -1924,49 +1860,6 @@ can_encode_int32 (int32_t val, unsigned bits)
return rest == 0 || rest == -1;
}
-/* Data passed to each method of aarch64_insn_visitor. */
-
-struct aarch64_insn_data
-{
- /* The instruction address. */
- CORE_ADDR insn_addr;
-};
-
-/* Visit different instructions by different methods. */
-
-struct aarch64_insn_visitor
-{
- /* Visit instruction B/BL OFFSET. */
- void (*b) (const int is_bl, const int32_t offset,
- struct aarch64_insn_data *data);
-
- /* Visit instruction B.COND OFFSET. */
- void (*b_cond) (const unsigned cond, const int32_t offset,
- struct aarch64_insn_data *data);
-
- /* Visit instruction CBZ/CBNZ Rn, OFFSET. */
- void (*cb) (const int32_t offset, const int is_cbnz,
- const unsigned rn, int is64,
- struct aarch64_insn_data *data);
-
- /* Visit instruction TBZ/TBNZ Rt, #BIT, OFFSET. */
- void (*tb) (const int32_t offset, int is_tbnz,
- const unsigned rt, unsigned bit,
- struct aarch64_insn_data *data);
-
- /* Visit instruction ADR/ADRP Rd, OFFSET. */
- void (*adr) (const int32_t offset, const unsigned rd,
- const int is_adrp, struct aarch64_insn_data *data);
-
- /* Visit instruction LDR/LDRSW Rt, OFFSET. */
- void (*ldr_literal) (const int32_t offset, const int is_sw,
- const unsigned rt, const int is64,
- struct aarch64_insn_data *data);
-
- /* Visit instruction INSN of other kinds. */
- void (*others) (const uint32_t insn, struct aarch64_insn_data *data);
-};
-
/* Sub-class of struct aarch64_insn_data, store information of
instruction relocation for fast tracepoint. Visitor can
relocate an instruction from BASE.INSN_ADDR to NEW_ADDR and save
@@ -2195,54 +2088,6 @@ static const struct aarch64_insn_visitor visitor =
aarch64_ftrace_insn_reloc_others,
};
-/* Visit an instruction INSN by VISITOR with all needed information in DATA.
-
- PC relative instructions need to be handled specifically:
-
- - B/BL
- - B.COND
- - CBZ/CBNZ
- - TBZ/TBNZ
- - ADR/ADRP
- - LDR/LDRSW (literal) */
-
-static void
-aarch64_relocate_instruction (uint32_t insn,
- const struct aarch64_insn_visitor *visitor,
- struct aarch64_insn_data *data)
-{
- int is_bl;
- int is64;
- int is_sw;
- int is_cbnz;
- int is_tbnz;
- int is_adrp;
- unsigned rn;
- unsigned rt;
- unsigned rd;
- unsigned cond;
- unsigned bit;
- int32_t offset;
-
- if (aarch64_decode_b (data->insn_addr, insn, &is_bl, &offset))
- visitor->b (is_bl, offset, data);
- else if (aarch64_decode_bcond (data->insn_addr, insn, &cond, &offset))
- visitor->b_cond (cond, offset, data);
- else if (aarch64_decode_cb (data->insn_addr, insn, &is64, &is_cbnz, &rn,
- &offset))
- visitor->cb (offset, is_cbnz, rn, is64, data);
- else if (aarch64_decode_tb (data->insn_addr, insn, &is_tbnz, &bit, &rt,
- &offset))
- visitor->tb (offset, is_tbnz, rt, bit, data);
- else if (aarch64_decode_adr (data->insn_addr, insn, &is_adrp, &rd, &offset))
- visitor->adr (offset, rd, is_adrp, data);
- else if (aarch64_decode_ldr_literal (data->insn_addr, insn, &is_sw, &is64,
- &rt, &offset))
- visitor->ldr_literal (offset, is_sw, rt, is64, data);
- else
- visitor->others (insn, data);
-}
-
/* Implementation of linux_target_ops method
"install_fast_tracepoint_jump_pad". */