Move aarch64_relocate_instruction to arch/aarch64-insn.c
authorYao Qi <yao.qi@linaro.org>
Mon, 12 Oct 2015 10:28:38 +0000 (11:28 +0100)
committerYao Qi <yao.qi@linaro.org>
Mon, 12 Oct 2015 10:28:38 +0000 (11:28 +0100)
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.

gdb/ChangeLog
gdb/arch/aarch64-insn.c
gdb/arch/aarch64-insn.h
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-aarch64-low.c

index e760bd0062071f09e8f2e8ea8b24766cffa5485b..f79c93df0fbc4bebc3708be6793287ae7796d26e 100644 (file)
@@ -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
index 13d0013d6e971b728191c29a1a0668f89e5dc855..d0e88fa88d1d0dedd3a91d749d9f99dfe7a3ddc2 100644 (file)
@@ -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);
+}
index 2facb44aea8445331d97b075f5b31b8bab589f1d..47f671565bd874ba7194805d1b53120edb799436 100644 (file)
@@ -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
index f72a0e249e28c865171432763b599c96ceb34ca6..6d3d66de28041686ef46ee37cda8b3b41399f487 100644 (file)
@@ -1,3 +1,11 @@
+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.
index b4181ed53f7041f1d05e259fce6d727b978331aa..1241434f08018ee9bc4e16ac04e380fbc578f940 100644 (file)
@@ -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".  */