@@ -633,6 +633,7 @@ TARGET_OBS = @TARGET_OBS@
ALL_64_TARGET_OBS = \
aarch64-fbsd-tdep.o \
aarch64-linux-tdep.o \
+ aarch64-lk-tdep.o \
aarch64-newlib-tdep.o \
aarch64-ravenscar-thread.o \
aarch64-tdep.o \
@@ -2161,6 +2162,7 @@ ALLDEPFILES = \
aarch64-fbsd-tdep.c \
aarch64-linux-nat.c \
aarch64-linux-tdep.c \
+ aarch64-lk-tdep.c \
aarch64-newlib-tdep.c \
aarch64-ravenscar-thread.c \
aarch64-tdep.c \
new file mode 100644
@@ -0,0 +1,135 @@
+/* Target-dependent code for linux-kernel target on AArch64 architecture.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ 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 "defs.h"
+#include "osabi.h"
+#include "regset.h"
+#include "gdbcore.h"
+
+#include "arch/aarch64.h"
+#include "lk-low.h"
+
+/* Define register map and set. */
+
+/* From linux kernel source arch/arm64/include/asm/processor.h
+ struct cpu_context. */
+
+static const struct regcache_map_entry aarch64_gregmap_lk[] =
+ {
+ { 11, AARCH64_X0_REGNUM + 19, 8 },
+ { 1, AARCH64_SP_REGNUM, 8 },
+ { 1, AARCH64_PC_REGNUM, 8 },
+ { 0 }
+ };
+
+const struct regset aarch64_gregset_lk =
+ {
+ aarch64_gregmap_lk,
+ regcache_supply_regset,
+ regcache_collect_regset
+ };
+
+/* AArch64 specific implementation for linux_kernel_ops. */
+
+class aarch64_linux_kernel_ops : public linux_kernel_ops
+{
+public:
+ aarch64_linux_kernel_ops ()
+ {}
+
+ void get_registers (CORE_ADDR task, struct regcache *regcache,
+ int regnum) override;
+protected:
+ void arch_read_symbols () override;
+};
+
+/* Implement linux_kernel_ops->arch_read_symbols virtual method. */
+
+void
+aarch64_linux_kernel_ops::arch_read_symbols ()
+{
+ declare_field ("task_struct->thread", LK_CONFIG_ALWAYS);
+ declare_field ("thread_struct->cpu_context", LK_CONFIG_ALWAYS);
+}
+
+/* Implement linux_kernel_ops->get_registers virtual method. */
+
+void
+aarch64_linux_kernel_ops::get_registers (CORE_ADDR task,
+ struct regcache *regcache, int regnum)
+{
+ CORE_ADDR cpu_context;
+ gdb_byte buf[104];
+ size_t size;
+
+ /* Calculate cpu_context address from task_struct address. */
+ cpu_context = task + offset ("task_struct->thread")
+ + offset ("thread_struct->cpu_context");
+
+ size = FIELD_SIZE (field ("thread_struct->cpu_context"));
+
+ gdb_assert (size <= sizeof (buf));
+
+ read_memory (cpu_context, buf, size);
+
+ regcache->supply_regset (&aarch64_gregset_lk, -1, buf, size);
+}
+
+/* Implement gdbarch get_new_lk_ops hook. */
+
+static linux_kernel_ops *
+aarch64_get_new_lk_ops (struct gdbarch *gdbarch)
+{
+ return new aarch64_linux_kernel_ops;
+}
+
+/* Initialize Linux kernel specific gdbarch hooks. */
+
+static void
+aarch64_lk_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Support linux kernel debugging. */
+ set_gdbarch_get_new_lk_ops (gdbarch, aarch64_get_new_lk_ops);
+}
+
+/* From the ELF-headers point of view Linux kernel- and user-space binaries
+ are the same. So we have to rely on some heuristics to distinguish them.
+
+ For the heuristic we check for __ksymtab section in the vmlinux and
+ modules .ko files. */
+
+static enum gdb_osabi
+aarch64_lk_osabi_sniffer (bfd *abfd)
+{
+ if (bfd_get_section_by_name (abfd, "__ksymtab"))
+ return GDB_OSABI_LINUX_KERNEL;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+void
+_initialize_aarch64_lk_tdep (void)
+{
+ /* Hook us into the OSABI mechanism. */
+ gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_LINUX_KERNEL,
+ aarch64_lk_init_abi);
+
+ /* Add OSABI sniffer. */
+ gdbarch_register_osabi_sniffer (bfd_arch_aarch64, bfd_target_elf_flavour,
+ aarch64_lk_osabi_sniffer);
+}
@@ -128,7 +128,7 @@ aarch64*-*-linux*)
arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
arm-tdep.o arm-linux-tdep.o \
glibc-tdep.o linux-tdep.o solib-svr4.o \
- symfile-mem.o linux-record.o"
+ symfile-mem.o linux-record.o aarch64-lk-tdep.o ${lk_tobjs}"
build_gdbserver=yes
;;