Add support for Intel PKRU register to GDB and GDBserver.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-aarch32-low.c
index 7379350b05acb1702e76e92d814045b9efd75e85..2b710ba7d614b5f35152c3e174fbf7c7bb057f61 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -17,6 +17,7 @@
 
 #include "server.h"
 #include "arch/arm.h"
+#include "arch/arm-linux.h"
 #include "linux-low.h"
 #include "linux-aarch32-low.h"
 
 #include <elf.h>
 #endif
 
+/* Correct in either endianness.  */
+#define arm_abi_breakpoint 0xef9f0001UL
+
+/* For new EABI binaries.  We recognize it regardless of which ABI
+   is used for gdbserver, so single threaded debugging should work
+   OK, but for multi-threaded debugging we only insert the current
+   ABI's breakpoint instruction.  For now at least.  */
+#define arm_eabi_breakpoint 0xe7f001f0UL
+
+#if (defined __ARM_EABI__ || defined __aarch64__)
+static const unsigned long arm_breakpoint = arm_eabi_breakpoint;
+#else
+static const unsigned long arm_breakpoint = arm_abi_breakpoint;
+#endif
+
+#define arm_breakpoint_len 4
+static const unsigned short thumb_breakpoint = 0xde01;
+#define thumb_breakpoint_len 2
+static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
+#define thumb2_breakpoint_len 4
+
 /* Some older versions of GNU/Linux and Android do not define
    the following macros.  */
 #ifndef NT_ARM_VFP
@@ -40,11 +62,15 @@ arm_fill_gregset (struct regcache *regcache, void *buf)
 {
   int i;
   uint32_t *regs = (uint32_t *) buf;
+  uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
 
   for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
     collect_register (regcache, i, &regs[i]);
 
-  collect_register (regcache, ARM_PS_REGNUM, &regs[16]);
+  collect_register (regcache, ARM_PS_REGNUM, &regs[ARM_CPSR_GREGNUM]);
+  /* Keep reserved bits bit 20 to bit 23.  */
+  regs[ARM_CPSR_GREGNUM] = ((regs[ARM_CPSR_GREGNUM] & 0xff0fffff)
+                           | (cpsr & 0x00f00000));
 }
 
 /* Supply GP registers contents, stored in BUF, to REGCACHE.  */
@@ -55,6 +81,7 @@ arm_store_gregset (struct regcache *regcache, const void *buf)
   int i;
   char zerobuf[8];
   const uint32_t *regs = (const uint32_t *) buf;
+  uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
 
   memset (zerobuf, 0, 8);
   for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
@@ -63,7 +90,9 @@ arm_store_gregset (struct regcache *regcache, const void *buf)
   for (; i < ARM_PS_REGNUM; i++)
     supply_register (regcache, i, zerobuf);
 
-  supply_register (regcache, ARM_PS_REGNUM, &regs[16]);
+  /* Clear reserved bits bit 20 to bit 23.  */
+  cpsr &= 0xff0fffff;
+  supply_register (regcache, ARM_PS_REGNUM, &cpsr);
 }
 
 /* Collect NUM number of VFP registers from REGCACHE to buffer BUF.  */
@@ -137,30 +166,9 @@ struct regs_info regs_info_aarch32 =
     &aarch32_regsets_info
   };
 
-/* Correct in either endianness.  */
-#define arm_abi_breakpoint 0xef9f0001UL
-
-/* For new EABI binaries.  We recognize it regardless of which ABI
-   is used for gdbserver, so single threaded debugging should work
-   OK, but for multi-threaded debugging we only insert the current
-   ABI's breakpoint instruction.  For now at least.  */
-#define arm_eabi_breakpoint 0xe7f001f0UL
-
-#ifndef __ARM_EABI__
-static const unsigned long arm_breakpoint = arm_abi_breakpoint;
-#else
-static const unsigned long arm_breakpoint = arm_eabi_breakpoint;
-#endif
-
-#define arm_breakpoint_len 4
-static const unsigned short thumb_breakpoint = 0xde01;
-#define thumb_breakpoint_len 2
-static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
-#define thumb2_breakpoint_len 4
-
 /* Returns 1 if the current instruction set is thumb, 0 otherwise.  */
 
-static int
+int
 arm_is_thumb_mode (void)
 {
   struct regcache *regcache = get_thread_regcache (current_thread, 1);
@@ -211,14 +219,6 @@ arm_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
-/* Enum describing the different kinds of breakpoints.  */
-enum arm_breakpoint_kinds
-{
-   ARM_BP_KIND_THUMB = 2,
-   ARM_BP_KIND_THUMB2 = 3,
-   ARM_BP_KIND_ARM = 4,
-};
-
 /* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
 
    Determine the type and size of breakpoint to insert at PCPTR.  Uses the
@@ -237,11 +237,11 @@ arm_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
       *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
 
       /* Check whether we are replacing a thumb2 32-bit instruction.  */
-      if ((*the_target->read_memory) (*pcptr, buf, 2) == 0)
+      if (target_read_memory (*pcptr, buf, 2) == 0)
        {
          unsigned short inst1 = 0;
 
-         (*the_target->read_memory) (*pcptr, (gdb_byte *) &inst1, 2);
+         target_read_memory (*pcptr, (gdb_byte *) &inst1, 2);
          if (thumb_insn_size (inst1) == 4)
            return ARM_BP_KIND_THUMB2;
        }
This page took 0.026198 seconds and 4 git commands to generate.