summaryrefslogtreecommitdiff
path: root/gdb/aarch64-linux-tdep.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-10-23 14:52:28 +0100
committerChristoph Muellner <christoph.muellner@theobroma-systems.com>2018-04-27 14:38:50 +0200
commit3adb5fee9ee3d784d8547029be2cb07a4802ace8 (patch)
tree1773005896589d4f3183f7c0764d865d90b26342 /gdb/aarch64-linux-tdep.c
parent4e556d512fa9014a7c68d33310171f18301236e4 (diff)
Rebased 5e5a2a68c772d59c41d4e536949ce4ba3dc9b3ea from linaro's gdb-aarch64-ilp32 branch on GDB 8.1-release. gdb: 2017-03-06 Andrew Pinski <apinski@cavium.com> Steve Ellcey <sellcey@cavium.com> Yao Qi <yao.qi@linaro.org> * aarch64-linux-nat.c (IS_ARM32): New macro. (fetch_gregs_from_thread): Use IS_ARM32 macro. (store_gregs_to_thread): Ditto. (fetch_fpregs_from_thread): Ditto. (store_fpregs_to_thread): Ditto. (ps_get_thread_area): Ditto. (aarch64_linux_siginfo_fixup): Ditto. * aarch64-linux-tdep.c (aarch64_linux_init_abi): Set link map offsets to 32 or 64 bits. * aarch64-tdep.c (aarch64_ilp32_register_type): New function. (aarch64_gdbarch_init): Setup ILP32 support. Make sure the gdbarches have compatible ilp32 flags. Set long and ptr sizes correctly for ilp32. * aarch64-tdep.h (gdbarch_tdep) <ilp32>: New field. gdb/gdbserver: 2017-03-06 Andrew Pinski <apinski@cavium.com> Steve Ellcey <sellcey@cavium.com> * linux-aarch64-low.c (aarch64_linux_read_description):
Diffstat (limited to 'gdb/aarch64-linux-tdep.c')
-rw-r--r--gdb/aarch64-linux-tdep.c73
1 files changed, 68 insertions, 5 deletions
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 1f3e888e40..e6be93ded2 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -131,13 +131,13 @@
ucontext.uc_mcontext. */
/* These magic numbers need to reflect the layout of the kernel
- defined struct rt_sigframe and ucontext. */
+ defined struct rt_sigframe and ucontext in LP64 mode. */
#define AARCH64_SIGCONTEXT_REG_SIZE 8
#define AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET 128
#define AARCH64_UCONTEXT_SIGCONTEXT_OFFSET 176
#define AARCH64_SIGCONTEXT_XO_OFFSET 8
-/* Implement the "init" method of struct tramp_frame. */
+/* Implement the "init" method of struct tramp_frame for LP64. */
static void
aarch64_linux_sigframe_init (const struct tramp_frame *self,
@@ -186,6 +186,62 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
aarch64_linux_sigframe_init
};
+/* These magic numbers need to reflect the layout of the kernel
+ defined struct rt_sigframe and ucontext in LP64 mode. */
+#define AARCH64_ILP32_SIGCONTEXT_REG_SIZE 8
+#define AARCH64_ILP32_RT_SIGFRAME_UCONTEXT_OFFSET 128
+#define AARCH64_ILP32_UCONTEXT_SIGCONTEXT_OFFSET 160
+#define AARCH64_ILP32_SIGCONTEXT_XO_OFFSET 8
+
+/* Implement the "init" method of struct tramp_frame for ILP32. */
+
+static void
+aarch64_ilp32_linux_sigframe_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ CORE_ADDR sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
+ CORE_ADDR sigcontext_addr =
+ sp
+ + AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET
+ + AARCH64_ILP32_UCONTEXT_SIGCONTEXT_OFFSET;
+ int i;
+
+ for (i = 0; i < 31; i++)
+ {
+ trad_frame_set_reg_addr (this_cache,
+ AARCH64_X0_REGNUM + i,
+ sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
+ + i * AARCH64_SIGCONTEXT_REG_SIZE);
+ }
+ trad_frame_set_reg_addr (this_cache, AARCH64_SP_REGNUM,
+ sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
+ + 31 * AARCH64_SIGCONTEXT_REG_SIZE);
+ trad_frame_set_reg_addr (this_cache, AARCH64_PC_REGNUM,
+ sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
+ + 32 * AARCH64_SIGCONTEXT_REG_SIZE);
+
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
+static const struct tramp_frame aarch64_ilp32_linux_rt_sigframe =
+{
+ SIGTRAMP_FRAME,
+ 4,
+ {
+ /* movz x8, 0x8b (S=1,o=10,h=0,i=0x8b,r=8)
+ Soo1 0010 1hhi iiii iiii iiii iiir rrrr */
+ {0xd2801168, -1},
+
+ /* svc 0x0 (o=0, l=1)
+ 1101 0100 oooi iiii iiii iiii iii0 00ll */
+ {0xd4000001, -1},
+ {TRAMP_SENTINEL_INSN, -1}
+ },
+ aarch64_ilp32_linux_sigframe_init
+};
+
/* Register maps. */
static const struct regcache_map_entry aarch64_linux_gregmap[] =
@@ -1025,8 +1081,12 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
+ if (tdep->ilp32)
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_ilp32_fetch_link_map_offsets);
+ else
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ svr4_lp64_fetch_link_map_offsets);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -1036,7 +1096,10 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
- tramp_frame_prepend_unwinder (gdbarch, &aarch64_linux_rt_sigframe);
+ if (tdep->ilp32)
+ tramp_frame_prepend_unwinder (gdbarch, &aarch64_ilp32_linux_rt_sigframe);
+ else
+ tramp_frame_prepend_unwinder (gdbarch, &aarch64_linux_rt_sigframe);
/* Enable longjmp. */
tdep->jb_pc = 11;