[RFC][PATCH 11/15] gdbserver: Add helper functions to create arm instructions
henrik.wallin@windriver.com
henrik.wallin@windriver.com
Wed Oct 14 15:08:00 GMT 2015
From: Henrik Wallin <henrik.wallin@windriver.com>
This adds the function. No users yet.
gdb/gdbserver/ChangeLog:
* linux-arm-low.c : Add code generation helpers
Signed-off-by: Henrik Wallin <henrik.wallin@windriver.com>
---
gdb/gdbserver/linux-arm-low.c | 135 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index 81d23d953434..044e7527a3b0 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -20,6 +20,7 @@
#include "linux-low.h"
#include "arch/arm.h"
#include "linux-aarch32-low.h"
+#include <inttypes.h>
#include <sys/uio.h>
/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
@@ -916,6 +917,140 @@ arm_regs_info (void)
return ®s_info_arm;
}
+static uint32_t
+mk_t_b_rel (CORE_ADDR from, CORE_ADDR to)
+{
+ uint32_t from_ = ((uint32_t) from) & ~1;
+ uint32_t to_ = ((uint32_t) to) & ~1;
+ return to_ - from_ - 4;
+}
+
+static int
+mk_t_b_isreachable (CORE_ADDR from, CORE_ADDR to)
+{
+ int32_t rel = mk_t_b_rel (from, to);
+ rel >>= 24;
+ return !rel || !(rel + 1);
+}
+
+static uint16_t *
+mk_t_b_instr (uint16_t *mem, CORE_ADDR from, CORE_ADDR to)
+{
+ uint32_t imm10, imm11;
+ uint32_t s, j1, j2;
+ uint32_t rel;
+
+ rel = mk_t_b_rel (from, to);
+ rel >>= 1;
+
+ imm11 = rel & 0x7ff;
+ rel >>= 11;
+ imm10 = rel & 0x3ff;
+ rel >>= 10;
+ s = (rel > 3);
+ j1 = s ^ !(rel & 2);
+ j2 = s ^ !(rel & 1);
+
+ *mem++ = 0xF000 | (s << 10) | imm10;
+ *mem++ = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
+
+ return mem;
+}
+
+static uint16_t *
+mk_t_blx_instr (uint16_t *mem, int reg)
+{
+ reg &= 0xF;
+ *mem++ = 0x4780 | (reg << 3);
+ return mem;
+}
+
+static uint16_t *
+mk_t_load_instr (uint16_t *mem, int reg, uint32_t val)
+{
+ uint32_t imm4, imm3, imm8;
+ uint32_t i;
+
+ imm8 = val & 0x00FF;
+ val >>= 8;
+ imm3 = val & 0x0007;
+ val >>= 3;
+ i = val & 0x0001;
+ val >>= 1;
+ imm4 = val & 0x000F;
+ val >>= 4;
+
+ *mem++ = 0xF240 | (i << 10) | imm4;
+ *mem++ = 0x0000 | (imm3 << 12) | (reg << 8) | imm8;
+
+ imm8 = val & 0x00FF;
+ val >>= 8;
+ imm3 = val & 0x0007;
+ val >>= 3;
+ i = val & 0x0001;
+ val >>= 1;
+ imm4 = val & 0x000F;
+
+ *mem++ = 0xF2C0 | (i << 10) | imm4;
+ *mem++ = 0x0000 | (imm3 << 12) | (reg << 8) | imm8;
+
+ return mem;
+}
+
+static uint32_t
+mk_a_b_rel (CORE_ADDR from, CORE_ADDR to)
+{
+ return (uint32_t) to - (uint32_t) from - 8;
+}
+
+static int
+mk_a_b_isreachable (CORE_ADDR from, CORE_ADDR to)
+{
+ int32_t rel = mk_a_b_rel (from, to);
+ rel >>= 25;
+ return !rel || !(rel + 1);
+}
+
+static uint32_t *
+mk_a_b_instr (uint32_t *mem, CORE_ADDR from, CORE_ADDR to)
+{
+ uint32_t imm24 = mk_a_b_rel (from, to);
+
+ imm24 >>= 2;
+ imm24 &= 0x00FFFFFF;
+ *mem++ = 0xEA000000 | imm24;
+
+ return mem;
+}
+
+static uint32_t *
+mk_a_blx_instr (uint32_t *mem, int reg)
+{
+ *mem++ = 0xE12FFF30 | (reg & 0xF);
+ return mem;
+}
+
+static uint32_t *
+mk_a_load_instr (uint32_t *mem, int reg, uint32_t val)
+{
+ uint32_t imm4, imm12;
+
+ imm12 = val & 0x0FFF;
+ val >>= 12;
+ imm4 = val & 0xF;
+ val >>= 4;
+
+ *mem++ = 0xE3000000 | ((reg & 0xF) << 12) | (imm4 << 16) | imm12;
+
+ imm12 = val & 0x0FFF;
+ val >>= 12;
+ imm4 = val & 0xF;
+
+ *mem++ = 0xE3400000 | ((reg & 0xF) << 12) | (imm4 << 16) | imm12;
+
+ return mem;
+}
+
struct linux_target_ops the_low_target = {
arm_arch_setup,
arm_regs_info,
--
2.1.4
More information about the Gdb-patches
mailing list