+2015-10-21  Antoine Tremblay  <antoine.tremblay@ericsson.com>
+
+       * Makefile.in: Add arm.c/o.
+       * arch/arm.c: New file.
+       * arch/arm.h: (IS_THUMB_ADDR): Move macro from arm-tdep.c.
+       (MAKE_THUMB_ADDR): Likewise.
+       (UNMAKE_THUMB_ADDR): Likewise.
+       * arm-tdep.c (int thumb_insn_size): Move to arm.c.
+       (IS_THUMB_ADDR): Move to arm.h.
+       (MAKE_THUMB_ADDR): Likewise.
+       (UNMAKE_THUMB_ADDR): Likewise.
+       * configure.tgt: Add arm.o to all ARM configs.
+
 2015-10-21  Yao Qi  <yao.qi@linaro.org>
 
        * lib/range-stepping-support.exp (exec_cmd_expect_vCont_count):
 
 
 # All other target-dependent objects files (used with --enable-targets=all).
 ALL_TARGET_OBS = \
-       armbsd-tdep.o arm-linux-tdep.o arm-symbian-tdep.o \
+       armbsd-tdep.o arm.o arm-linux-tdep.o arm-symbian-tdep.o \
        armnbsd-tdep.o armobsd-tdep.o \
        arm-tdep.o arm-wince-tdep.o \
        avr-tdep.o \
        amd64-dicos-tdep.c \
        amd64-linux-nat.c amd64-linux-tdep.c \
        amd64-sol2-tdep.c \
+       arm.c \
        arm-linux-nat.c arm-linux-tdep.c arm-symbian-tdep.c arm-tdep.c \
        armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \
        avr-tdep.c \
        $(COMPILE) $(srcdir)/target/waitstatus.c
        $(POSTCOMPILE)
 
+#
+# gdb/arch/ dependencies
+#
+# Need to explicitly specify the compile rule as make will do nothing
+# or try to compile the object file into the sub-directory.
+
+arm.o: ${srcdir}/arch/arm.c
+       $(COMPILE) $(srcdir)/arch/arm.c
+       $(POSTCOMPILE)
+
 # gdb/nat/ dependencies
 #
 # Need to explicitly specify the compile rule as make will do nothing
 
--- /dev/null
+/* Common target dependent code for GDB on ARM systems.
+
+   Copyright (C) 1988-2015 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 "common-defs.h"
+#include "arm.h"
+
+/* Return the size in bytes of the complete Thumb instruction whose
+   first halfword is INST1.  */
+
+int
+thumb_insn_size (unsigned short inst1)
+{
+  if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
+    return 4;
+  else
+    return 2;
+}
 
 /* Common target dependent code for GDB on ARM systems.
-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
+   Copyright (C) 1988-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
   ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
 };
 
+/* Addresses for calling Thumb functions have the bit 0 set.
+   Here are some macros to test, set, or clear bit 0 of addresses.  */
+#define IS_THUMB_ADDR(addr)    ((addr) & 1)
+#define MAKE_THUMB_ADDR(addr)  ((addr) | 1)
+#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
+
+/* Return the size in bytes of the complete Thumb instruction whose
+   first halfword is INST1.  */
+int thumb_insn_size (unsigned short inst1);
+
 #endif
 
 #include "user-regs.h"
 #include "observer.h"
 
+#include "arch/arm.h"
 #include "arm-tdep.h"
 #include "gdb/sim-arm.h"
 
                                 struct regcache *regcache,
                                 int regnum, const gdb_byte *buf);
 
-static int thumb_insn_size (unsigned short inst1);
-
 struct arm_prologue_cache
 {
   /* The stack pointer at the time this frame was created; i.e. the
 
 #define DISPLACED_STEPPING_ARCH_VERSION                5
 
-/* Addresses for calling Thumb functions have the bit 0 set.
-   Here are some macros to test, set, or clear bit 0 of addresses.  */
-#define IS_THUMB_ADDR(addr)    ((addr) & 1)
-#define MAKE_THUMB_ADDR(addr)  ((addr) | 1)
-#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
-
 /* Set to true if the 32-bit mode is in use.  */
 
 int arm_apcs_32 = 1;
   return nbits;
 }
 
-/* Return the size in bytes of the complete Thumb instruction whose
-   first halfword is INST1.  */
-
-static int
-thumb_insn_size (unsigned short inst1)
-{
-  if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
-    return 4;
-  else
-    return 2;
-}
-
 static int
 thumb_advance_itstate (unsigned int itstate)
 {
 
 aarch64*-*-linux*)
        # Target: AArch64 linux
        gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o aarch64-insn.o \
-                       arm-tdep.o arm-linux-tdep.o \
+                       arm.o arm-tdep.o arm-linux-tdep.o \
                        glibc-tdep.o linux-tdep.o solib-svr4.o \
                        symfile-mem.o linux-record.o"
        build_gdbserver=yes
 
 arm*-wince-pe | arm*-*-mingw32ce*)
        # Target: ARM based machine running Windows CE (win32)
-       gdb_target_obs="arm-tdep.o arm-wince-tdep.o windows-tdep.o"
+       gdb_target_obs="arm.o arm-tdep.o arm-wince-tdep.o windows-tdep.o"
        build_gdbserver=yes
        ;;
 arm*-*-linux*)
        # Target: ARM based machine running GNU/Linux
-       gdb_target_obs="arm-tdep.o arm-linux-tdep.o glibc-tdep.o \
+       gdb_target_obs="arm.o arm-tdep.o arm-linux-tdep.o glibc-tdep.o \
                        solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
        build_gdbserver=yes
        ;;
 arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
        # Target: NetBSD/arm
-       gdb_target_obs="arm-tdep.o armnbsd-tdep.o solib-svr4.o"
+       gdb_target_obs="arm.o arm-tdep.o armnbsd-tdep.o solib-svr4.o"
        ;;
 arm*-*-openbsd*)
        # Target: OpenBSD/arm
-       gdb_target_obs="arm-tdep.o armbsd-tdep.o armobsd-tdep.o obsd-tdep.o \
-                       solib-svr4.o"
+       gdb_target_obs="arm.o arm-tdep.o armbsd-tdep.o armobsd-tdep.o \
+                       obsd-tdep.o solib-svr4.o"
        ;;
 arm*-*-symbianelf*)
        # Target: SymbianOS/arm
-       gdb_target_obs="arm-tdep.o arm-symbian-tdep.o"
+       gdb_target_obs="arm.o arm-tdep.o arm-symbian-tdep.o"
        ;;
 arm*-*-*)
        # Target: ARM embedded system
-       gdb_target_obs="arm-tdep.o"
+       gdb_target_obs="arm.o arm-tdep.o"
        gdb_sim=../sim/arm/libsim.a
        ;;
 
 
+2015-10-21  Antoine Tremblay  <antoine.tremblay@ericsson.com>
+
+       * Makefile.in: Add arm.c/o.
+       * configure.srv: Likewise.
+       * linux-arm-low.c (arm_breakpoint_kinds): New enum.
+       (arm_breakpoint_kind_from_pc): New function.
+       (arm_sw_breakpoint_from_kind): Return proper kind.
+       (struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize.
+
 2015-10-21  Antoine Tremblay  <antoine.tremblay@ericsson.com>
 
        * linux-low.c (initialize_low): Ajdust for breakpoint global variables
 
        $(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c \
        $(srcdir)/common/common-exceptions.c $(srcdir)/symbol.c \
        $(srcdir)/common/btrace-common.c \
-       $(srcdir)/common/fileio.c $(srcdir)/nat/linux-namespaces.c
+       $(srcdir)/common/fileio.c $(srcdir)/nat/linux-namespaces.c \
+       $(srcdir)/arch/arm.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
        $(COMPILE) $<
        $(POSTCOMPILE)
 
+# Arch object files rules form ../arch
+
+arm.o: ../arch/arm.c
+       $(COMPILE) $<
+       $(POSTCOMPILE)
+
 # Native object files rules from ../nat
 
 x86-dregs.o: ../nat/x86-dregs.c
 
                        srv_regobj="${srv_regobj} arm-with-neon.o"
                        srv_tgtobj="$srv_linux_obj linux-arm-low.o"
                        srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
+                       srv_tgtobj="${srv_tgtobj} arm.o"
                        srv_xmlfiles="arm-with-iwmmxt.xml"
                        srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
                        srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
 
 #include "nat/gdb_ptrace.h"
 #include <signal.h>
 
+#include "arch/arm.h"
+
 /* Defined in auto-generated files.  */
 void init_registers_arm (void);
 extern const struct target_desc *tdesc_arm;
   arm_hwbp_access = 3
 } arm_hwbp_type;
 
+/* 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,
+};
+
 /* Type describing an ARM Hardware Breakpoint Control register value.  */
 typedef unsigned int arm_hwbp_control_t;
 
 static const unsigned long arm_breakpoint = 0xef9f0001;
 #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
 
 /* For new EABI binaries.  We recognize it regardless of which ABI
    is used for gdbserver, so single threaded debugging should work
     return ®s_info_arm;
 }
 
-/* Implementation of linux_target_ops method "sw_breakpoint_from_kind".  */
+/* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
+
+   Determine the type and size of breakpoint to insert at PCPTR.  Uses the
+   program counter value to determine whether a 16-bit or 32-bit breakpoint
+   should be used.  It returns the breakpoint's kind, and adjusts the program
+   counter (if necessary) to point to the actual memory location where the
+   breakpoint should be inserted.  */
+
+static int
+arm_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
+{
+  if (IS_THUMB_ADDR (*pcptr))
+    {
+      gdb_byte buf[2];
+
+      *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
+
+      /* Check whether we are replacing a thumb2 32-bit instruction.  */
+      if ((*the_target->read_memory) (*pcptr, buf, 2) == 0)
+       {
+         unsigned short inst1 = 0;
+
+         (*the_target->read_memory) (*pcptr, (gdb_byte *) &inst1, 2);
+         if (thumb_insn_size (inst1) == 4)
+           return ARM_BP_KIND_THUMB2;
+       }
+      return ARM_BP_KIND_THUMB;
+    }
+  else
+    return ARM_BP_KIND_ARM;
+}
+
+/*  Implementation of the linux_target_ops method "sw_breakpoint_from_kind".  */
 
 static const gdb_byte *
 arm_sw_breakpoint_from_kind (int kind , int *size)
      clone events, we will never insert a breakpoint, so even a Thumb
      C library will work; so will mixing EABI/non-EABI gdbserver and
      application.  */
+  switch (kind)
+    {
+      case ARM_BP_KIND_THUMB:
+       *size = thumb_breakpoint_len;
+       return (gdb_byte *) &thumb_breakpoint;
+      case ARM_BP_KIND_THUMB2:
+       *size = thumb2_breakpoint_len;
+       return (gdb_byte *) &thumb2_breakpoint;
+      case ARM_BP_KIND_ARM:
+       *size = arm_breakpoint_len;
 #ifndef __ARM_EABI__
-  return (const gdb_byte *) &arm_breakpoint;
+       return (const gdb_byte *) &arm_breakpoint;
 #else
-  return (const gdb_byte *) &arm_eabi_breakpoint;
+       return (const gdb_byte *) &arm_eabi_breakpoint;
 #endif
+      default:
+       return NULL;
+    }
+  return NULL;
 }
 
 struct linux_target_ops the_low_target = {
   NULL, /* fetch_register */
   arm_get_pc,
   arm_set_pc,
-  NULL, /* breakpoint_kind_from_pc */
+  arm_breakpoint_kind_from_pc,
   arm_sw_breakpoint_from_kind,
   arm_reinsert_addr,
   0,