public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 04/11] Set architecture to arm in arm-*.xml files
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
  2015-07-01 13:58 ` [PATCH 01/11] Remove {fetch,store}_fpregister and {fetch,store}_register Yao Qi
  2015-07-01 13:58 ` [PATCH 02/11] New aarch32-linux-nat.c Yao Qi
@ 2015-07-01 13:58 ` Yao Qi
  2015-07-01 13:58 ` [PATCH 07/11] New proc is_aarch32_target Yao Qi
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

This patch is to add the following line to various arm target description
xml files,

<architecture>arm</architecture>

in order to fix problems I've seen on aarch64 multi-arch debugging,

 detach^M
 Detaching from program: build-gdb/gdb/testsuite/gdb.base/attach, process 17145^M
 (gdb) PASS: gdb.base/attach.exp: attach1 detach file^M
 No executable file now.^M
 Architecture of file not recognized.^M
 (gdb) FAIL: gdb.base/attach.exp: attach1, purging symbols after detach

Without this patch, struct target_desc *tdesc_* are not initialised
properly, that is, fields arch and osabi in 'struct target_desc' are
not set properly.  This doesn't cause any problems on single arch
debugging, because arch-utils.c:gdbarch_info_fill will guess correctly.
However, in multi-arch debugging, gdbarch_info_fill gets the aarch64
arch, but the target description is for arm (because the current
inferior is 32-bit arm).

It is a surprise to me we didn't set architecture to "arm" before in *.xml
files, and I didn't find out why didn't do so.  AFAICS,
gdb/features/arm-with-iwmmxt.xml was added firstly (in patch
https://sourceware.org/ml/gdb-patches/2007-01/msg00593.html)
which had <architecture>iwmmxt</architecture>, however, afterwards,
architecture isn't set anymore in features/arm-*.xml files (in patches
https://sourceware.org/ml/gdb-patches/2009-07/msg00689.html and
https://sourceware.org/ml/gdb-patches/2010-08/msg00225.html).

gdb:

2015-06-29  Yao Qi  <yao.qi@linaro.org>

	* features/arm-with-m-fpa-layout.xml: Set architecture to arm.
	* features/arm-with-m-fpa-layout.c: Regenerated.
	* features/arm-with-m-vfp-d16.xml: Likewise.
	* features/arm-with-m-vfp-d16.c: Regenerated.
	* features/arm-with-m.xml: Likewise.
	* features/arm-with-m.c: Regenerated.
	* features/arm-with-neon.xml: Likewise.
	* features/arm-with-neon.c: Regenerated.
	* features/arm-with-vfpv2.xml: Likewise.
	* features/arm-with-vfpv2.c: Regenerated.
	* features/arm-with-vfpv3.xml: Likewise.
	* features/arm-with-vfpv3.c: Regenerated.
---
 gdb/features/arm-with-m-fpa-layout.c   | 2 ++
 gdb/features/arm-with-m-fpa-layout.xml | 1 +
 gdb/features/arm-with-m-vfp-d16.c      | 2 ++
 gdb/features/arm-with-m-vfp-d16.xml    | 1 +
 gdb/features/arm-with-m.c              | 2 ++
 gdb/features/arm-with-m.xml            | 1 +
 gdb/features/arm-with-neon.c           | 2 ++
 gdb/features/arm-with-neon.xml         | 1 +
 gdb/features/arm-with-vfpv2.c          | 2 ++
 gdb/features/arm-with-vfpv2.xml        | 1 +
 gdb/features/arm-with-vfpv3.c          | 2 ++
 gdb/features/arm-with-vfpv3.xml        | 1 +
 12 files changed, 18 insertions(+)

diff --git a/gdb/features/arm-with-m-fpa-layout.c b/gdb/features/arm-with-m-fpa-layout.c
index bc51f05..f720614 100644
--- a/gdb/features/arm-with-m-fpa-layout.c
+++ b/gdb/features/arm-with-m-fpa-layout.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_m_fpa_layout (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
diff --git a/gdb/features/arm-with-m-fpa-layout.xml b/gdb/features/arm-with-m-fpa-layout.xml
index 7700666..aab1806 100644
--- a/gdb/features/arm-with-m-fpa-layout.xml
+++ b/gdb/features/arm-with-m-fpa-layout.xml
@@ -10,6 +10,7 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+<architecture>arm</architecture>
 <feature name="org.gnu.gdb.arm.m-profile">
   <reg name="r0" bitsize="32"/>
   <reg name="r1" bitsize="32"/>
diff --git a/gdb/features/arm-with-m-vfp-d16.c b/gdb/features/arm-with-m-vfp-d16.c
index a0da583..069baac 100644
--- a/gdb/features/arm-with-m-vfp-d16.c
+++ b/gdb/features/arm-with-m-vfp-d16.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_m_vfp_d16 (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
diff --git a/gdb/features/arm-with-m-vfp-d16.xml b/gdb/features/arm-with-m-vfp-d16.xml
index 315d1a8..0586017 100644
--- a/gdb/features/arm-with-m-vfp-d16.xml
+++ b/gdb/features/arm-with-m-vfp-d16.xml
@@ -7,6 +7,7 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+  <architecture>arm</architecture>
   <xi:include href="arm-m-profile.xml"/>
   <!-- Layout of vfpv4-sp-d16 is identical to vfpv2 -->
   <xi:include href="arm-vfpv2.xml"/>
diff --git a/gdb/features/arm-with-m.c b/gdb/features/arm-with-m.c
index 8e27a80..64d31bb 100644
--- a/gdb/features/arm-with-m.c
+++ b/gdb/features/arm-with-m.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_m (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
diff --git a/gdb/features/arm-with-m.xml b/gdb/features/arm-with-m.xml
index 6289472..a7aa2d2 100644
--- a/gdb/features/arm-with-m.xml
+++ b/gdb/features/arm-with-m.xml
@@ -7,5 +7,6 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+  <architecture>arm</architecture>
   <xi:include href="arm-m-profile.xml"/>
 </target>
diff --git a/gdb/features/arm-with-neon.c b/gdb/features/arm-with-neon.c
index 61c9a3a..d365c0f 100644
--- a/gdb/features/arm-with-neon.c
+++ b/gdb/features/arm-with-neon.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_neon (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32");
diff --git a/gdb/features/arm-with-neon.xml b/gdb/features/arm-with-neon.xml
index b537337..777b826 100644
--- a/gdb/features/arm-with-neon.xml
+++ b/gdb/features/arm-with-neon.xml
@@ -7,6 +7,7 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+  <architecture>arm</architecture>
   <xi:include href="arm-core.xml"/>
   <xi:include href="arm-vfpv3.xml"/>
   <feature name="org.gnu.gdb.arm.neon"/>
diff --git a/gdb/features/arm-with-vfpv2.c b/gdb/features/arm-with-vfpv2.c
index 78e3c81..0ebbfef 100644
--- a/gdb/features/arm-with-vfpv2.c
+++ b/gdb/features/arm-with-vfpv2.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_vfpv2 (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32");
diff --git a/gdb/features/arm-with-vfpv2.xml b/gdb/features/arm-with-vfpv2.xml
index 6008124..fe7941a 100644
--- a/gdb/features/arm-with-vfpv2.xml
+++ b/gdb/features/arm-with-vfpv2.xml
@@ -7,6 +7,7 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+  <architecture>arm</architecture>
   <xi:include href="arm-core.xml"/>
   <xi:include href="arm-vfpv2.xml"/>
 </target>
diff --git a/gdb/features/arm-with-vfpv3.c b/gdb/features/arm-with-vfpv3.c
index e48ca79..e235dfa 100644
--- a/gdb/features/arm-with-vfpv3.c
+++ b/gdb/features/arm-with-vfpv3.c
@@ -12,6 +12,8 @@ initialize_tdesc_arm_with_vfpv3 (void)
   struct target_desc *result = allocate_target_description ();
   struct tdesc_feature *feature;
 
+  set_tdesc_architecture (result, bfd_scan_arch ("arm"));
+
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core");
   tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32");
   tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32");
diff --git a/gdb/features/arm-with-vfpv3.xml b/gdb/features/arm-with-vfpv3.xml
index e4eeb6a..66d98ec 100644
--- a/gdb/features/arm-with-vfpv3.xml
+++ b/gdb/features/arm-with-vfpv3.xml
@@ -7,6 +7,7 @@
 
 <!DOCTYPE target SYSTEM "gdb-target.dtd">
 <target>
+  <architecture>arm</architecture>
   <xi:include href="arm-core.xml"/>
   <xi:include href="arm-vfpv3.xml"/>
 </target>
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 08/11] New proc is_aarch64_target
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (3 preceding siblings ...)
  2015-07-01 13:58 ` [PATCH 07/11] New proc is_aarch32_target Yao Qi
@ 2015-07-01 13:58 ` Yao Qi
  2015-07-01 14:10   ` Andreas Schwab
  2015-07-01 13:59 ` [PATCH 10/11] Reply s and S vCont actions if target supports hardware single step Yao Qi
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

Some tests expect the the target is aarch64, but checking target
triplet is not accurate, because target triplet can be aarch64 but
the program is in arm (or aarch32) state.

This patch addes a new proc is_aarch64_target which returns true
if the target is on aarch64 state.

gdb/testsuite:

2015-06-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.arch/aarch64-atomic-inst.exp: Check is_aarch64_target
	instead of istarget "aarch64*-*-*".
	* gdb.arch/aarch64-fp.exp: Likewise.
	* gdb.base/float.exp: Likewise.
	* gdb.reverse/aarch64.exp: Likewise.
	* lib/gdb.exp (is_aarch64_target): New proc.
---
 gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp |  2 +-
 gdb/testsuite/gdb.arch/aarch64-fp.exp          |  2 +-
 gdb/testsuite/gdb.base/float.exp               |  2 +-
 gdb/testsuite/gdb.reverse/aarch64.exp          |  2 +-
 gdb/testsuite/lib/gdb.exp                      | 10 ++++++++++
 5 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp b/gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp
index 885cfb1..19a98cd 100644
--- a/gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp
+++ b/gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp
@@ -19,7 +19,7 @@
 # Test single stepping through atomic sequences beginning with
 # a ldxr instruction and ending with a stxr instruction.
 
-if {![istarget "aarch64*"]} {
+if {![is_aarch64_target]} {
     verbose "Skipping ${gdb_test_file_name}."
     return
 }
diff --git a/gdb/testsuite/gdb.arch/aarch64-fp.exp b/gdb/testsuite/gdb.arch/aarch64-fp.exp
index 0cd734f..aaf5640 100644
--- a/gdb/testsuite/gdb.arch/aarch64-fp.exp
+++ b/gdb/testsuite/gdb.arch/aarch64-fp.exp
@@ -19,7 +19,7 @@
 # PR server/17457
 # Test aarch64 floating point registers q0, q1, v0, v1, fpsr, fpcr
 
-if {![istarget "aarch64*"]} {
+if {![is_aarch64_target]} {
     verbose "Skipping ${gdb_test_file_name}."
     return
 }
diff --git a/gdb/testsuite/gdb.base/float.exp b/gdb/testsuite/gdb.base/float.exp
index a7183cf..91c2d45 100644
--- a/gdb/testsuite/gdb.base/float.exp
+++ b/gdb/testsuite/gdb.base/float.exp
@@ -36,7 +36,7 @@ if ![runto_main] then {
 
 # Test "info float".
 
-if { [istarget "aarch64*-*-*"] } then {
+if { [is_aarch64_target] } then {
     gdb_test "info float" "d0.*d1.*d31.*s0.*s1.*s31.*" "info float"
 } elseif { [istarget "alpha*-*-*"] } then {
     gdb_test "info float" "f0.*" "info float"
diff --git a/gdb/testsuite/gdb.reverse/aarch64.exp b/gdb/testsuite/gdb.reverse/aarch64.exp
index 800645e..1c5f181 100644
--- a/gdb/testsuite/gdb.reverse/aarch64.exp
+++ b/gdb/testsuite/gdb.reverse/aarch64.exp
@@ -19,7 +19,7 @@ if ![supports_reverse] {
 
 # Test aarch64 instruction recording.
 
-if {![istarget "aarch64*-*-*"]} then {
+if {![is_aarch64_target]} then {
     verbose "Skipping aarch64 instruction recording tests."
     return
 }
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index b29b8c4..2e226ad 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -2308,6 +2308,16 @@ gdb_caching_proc is_aarch32_target {
     return 1
 }
 
+# Return 1 if this target is an aarch64, either lp64 or ilp32.
+
+proc is_aarch64_target {} {
+    if { ![istarget "aarch64*-*-*"] } {
+	return 0
+    }
+
+    return [expr ![is_aarch32_target]]
+}
+
 # Return 1 if displaced stepping is supported on target, otherwise, return 0.
 proc support_displaced_stepping {} {
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 01/11] Remove {fetch,store}_fpregister and {fetch,store}_register
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
@ 2015-07-01 13:58 ` Yao Qi
  2015-07-01 13:58 ` [PATCH 02/11] New aarch32-linux-nat.c Yao Qi
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

This patch is to remove fetch_fpregister, fech_register,
store_fpregister and store_register, and use fetch_fpregs,
fetch_regs, store_regs, and store_fpregs instead.

gdb:

2015-06-23  Yao Qi  <yao.qi@linaro.org>

	* arm-linux-nat.c (store_fpregister): Remove.
	(store_register): Likewise.
	(fetch_fpregister): Likewise.
	(fetch_register): Likewise.
	(arm_linux_store_inferior_registers): Call store_regs and
	store_fpregs instead.
	(arm_linux_fetch_inferior_registers): Call fetch_fpregs and
	fetch_regs instead.
---
 gdb/arm-linux-nat.c | 223 +---------------------------------------------------
 1 file changed, 4 insertions(+), 219 deletions(-)

diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index c167bce..5a8880f 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -82,47 +82,6 @@ get_thread_id (ptid_t ptid)
 
 #define GET_THREAD_ID(PTID)	get_thread_id (PTID)
 
-/* Get the value of a particular register from the floating point
-   state of the process and store it into regcache.  */
-
-static void
-fetch_fpregister (struct regcache *regcache, int regno)
-{
-  int ret, tid;
-  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
-
-  /* Get the thread id for the ptrace call.  */
-  tid = GET_THREAD_ID (inferior_ptid);
-
-  /* Read the floating point state.  */
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &fp;
-      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to fetch floating point register."));
-      return;
-    }
-
-  /* Fetch fpsr.  */
-  if (ARM_FPS_REGNUM == regno)
-    regcache_raw_supply (regcache, ARM_FPS_REGNUM,
-			 fp + NWFPE_FPSR_OFFSET);
-
-  /* Fetch the floating point register.  */
-  if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
-    supply_nwfpe_register (regcache, regno, fp);
-}
-
 /* Get the whole floating point state of the process and store it
    into regcache.  */
 
@@ -163,65 +122,6 @@ fetch_fpregs (struct regcache *regcache)
     supply_nwfpe_register (regcache, regno, fp);
 }
 
-/* Save a particular register into the floating point state of the
-   process using the contents from regcache.  */
-
-static void
-store_fpregister (const struct regcache *regcache, int regno)
-{
-  int ret, tid;
-  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
-
-  /* Get the thread id for the ptrace call.  */
-  tid = GET_THREAD_ID (inferior_ptid);
-
-  /* Read the floating point state.  */
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &fp;
-      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to fetch the floating point registers."));
-      return;
-    }
-
-  /* Store fpsr.  */
-  if (ARM_FPS_REGNUM == regno
-      && REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM))
-    regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);
-
-  /* Store the floating point register.  */
-  if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
-    collect_nwfpe_register (regcache, regno, fp);
-
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &fp;
-      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
-
-      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to store floating point register."));
-      return;
-    }
-}
-
 /* Save the whole floating point state of the process using
    the contents from regcache.  */
 
@@ -282,59 +182,6 @@ store_fpregs (const struct regcache *regcache)
     }
 }
 
-/* Fetch a general register of the process and store into
-   regcache.  */
-
-static void
-fetch_register (struct regcache *regcache, int regno)
-{
-  int ret, tid;
-  elf_gregset_t regs;
-
-  /* Get the thread id for the ptrace call.  */
-  tid = GET_THREAD_ID (inferior_ptid);
-
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &regs;
-      iov.iov_len = sizeof (regs);
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
-    }
-  else
-    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to fetch general register."));
-      return;
-    }
-
-  if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM)
-    regcache_raw_supply (regcache, regno, (char *) &regs[regno]);
-
-  if (ARM_PS_REGNUM == regno)
-    {
-      if (arm_apcs_32)
-        regcache_raw_supply (regcache, ARM_PS_REGNUM,
-			     (char *) &regs[ARM_CPSR_GREGNUM]);
-      else
-        regcache_raw_supply (regcache, ARM_PS_REGNUM,
-			     (char *) &regs[ARM_PC_REGNUM]);
-    }
-    
-  if (ARM_PC_REGNUM == regno)
-    { 
-      regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
-			      (get_regcache_arch (regcache),
-			       regs[ARM_PC_REGNUM]);
-      regcache_raw_supply (regcache, ARM_PC_REGNUM,
-			   (char *) &regs[ARM_PC_REGNUM]);
-    }
-}
-
 /* Fetch all general registers of the process and store into
    regcache.  */
 
@@ -381,68 +228,6 @@ fetch_regs (struct regcache *regcache)
 		       (char *) &regs[ARM_PC_REGNUM]);
 }
 
-/* Store all general registers of the process from the values in
-   regcache.  */
-
-static void
-store_register (const struct regcache *regcache, int regno)
-{
-  int ret, tid;
-  elf_gregset_t regs;
-  
-  if (REG_VALID != regcache_register_status (regcache, regno))
-    return;
-
-  /* Get the thread id for the ptrace call.  */
-  tid = GET_THREAD_ID (inferior_ptid);
-
-  /* Get the general registers from the process.  */
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &regs;
-      iov.iov_len = sizeof (regs);
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
-    }
-  else
-    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to fetch general registers."));
-      return;
-    }
-
-  if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
-    regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
-  else if (arm_apcs_32 && regno == ARM_PS_REGNUM)
-    regcache_raw_collect (regcache, regno,
-			 (char *) &regs[ARM_CPSR_GREGNUM]);
-  else if (!arm_apcs_32 && regno == ARM_PS_REGNUM)
-    regcache_raw_collect (regcache, ARM_PC_REGNUM,
-			 (char *) &regs[ARM_PC_REGNUM]);
-
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &regs;
-      iov.iov_len = sizeof (regs);
-
-      ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iov);
-    }
-  else
-    ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
-
-  if (ret < 0)
-    {
-      warning (_("Unable to store general register."));
-      return;
-    }
-}
-
 static void
 store_regs (const struct regcache *regcache)
 {
@@ -694,9 +479,9 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops,
   else 
     {
       if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
-        fetch_register (regcache, regno);
+	fetch_regs (regcache);
       else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
-        fetch_fpregister (regcache, regno);
+	fetch_fpregs (regcache);
       else if (tdep->have_wmmx_registers
 	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
 	fetch_wmmx_regs (regcache);
@@ -730,9 +515,9 @@ arm_linux_store_inferior_registers (struct target_ops *ops,
   else
     {
       if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
-        store_register (regcache, regno);
+	store_regs (regcache);
       else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
-        store_fpregister (regcache, regno);
+	store_fpregs (regcache);
       else if (tdep->have_wmmx_registers
 	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
 	store_wmmx_regs (regcache);
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 07/11] New proc is_aarch32_target
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (2 preceding siblings ...)
  2015-07-01 13:58 ` [PATCH 04/11] Set architecture to arm in arm-*.xml files Yao Qi
@ 2015-07-01 13:58 ` Yao Qi
  2015-07-01 13:58 ` [PATCH 08/11] New proc is_aarch64_target Yao Qi
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

GDB tests running on arm target should be also run on aarch32
(32-bit mode on aarch64).  There should be no difference.  It is not
precise to check target triplet to decide which tests should be run,
because if I compiler all the test binary in 32-bit (arm program),
but target triplet is still aarch64, so that these arm specific tests
are skipped.

This patch is to add a new proc is_aarch32_target which return true
if target triplet is arm or the test binary is compiled for arm.

gdb/testsuite:

2015-06-19  Yao Qi  <yao.qi@linaro.org>

	* lib/gdb.exp (is_aarch32_target): New proc.
	* gdb.arch/arm-bl-branch-dest.exp: Check is_aarch32_target
	instead of "istarget "arm*-*-*"".
	* gdb.arch/arm-disp-step.exp: Likewise.
	* gdb.arch/thumb-bx-pc.exp: Likewise.
	* gdb.arch/thumb-prologue.exp: Likewise.
	* gdb.arch/thumb-singlestep.exp: Likewise.
	* gdb.base/disp-step-syscall.exp: Likewise.
	* gdb.base/float.exp: Likewise.
---
 gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp |  2 +-
 gdb/testsuite/gdb.arch/arm-disp-step.exp      |  2 +-
 gdb/testsuite/gdb.arch/thumb-bx-pc.exp        |  2 +-
 gdb/testsuite/gdb.arch/thumb-prologue.exp     |  2 +-
 gdb/testsuite/gdb.arch/thumb-singlestep.exp   |  2 +-
 gdb/testsuite/gdb.base/disp-step-syscall.exp  |  2 +-
 gdb/testsuite/gdb.base/float.exp              |  2 +-
 gdb/testsuite/lib/gdb.exp                     | 37 +++++++++++++++++++++++++++
 8 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp b/gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp
index 9a64054..f35548a 100644
--- a/gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp
+++ b/gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-if { ![istarget "arm*-*-*"] } {
+if { ![is_aarch32_target] } {
     verbose "Skipping ${gdb_test_file_name}."
     return
 }
diff --git a/gdb/testsuite/gdb.arch/arm-disp-step.exp b/gdb/testsuite/gdb.arch/arm-disp-step.exp
index e191f73..83858ca 100644
--- a/gdb/testsuite/gdb.arch/arm-disp-step.exp
+++ b/gdb/testsuite/gdb.arch/arm-disp-step.exp
@@ -17,7 +17,7 @@
 
 # Test arm displaced stepping.
 
-if {![istarget "arm*-*-*"]} then {
+if {![is_aarch32_target]} then {
     verbose "Skipping arm displaced stepping tests."
     return
 }
diff --git a/gdb/testsuite/gdb.arch/thumb-bx-pc.exp b/gdb/testsuite/gdb.arch/thumb-bx-pc.exp
index f402339..05be0e1 100644
--- a/gdb/testsuite/gdb.arch/thumb-bx-pc.exp
+++ b/gdb/testsuite/gdb.arch/thumb-bx-pc.exp
@@ -15,7 +15,7 @@
 
 # Test PC adjustment from Thumb-mode "bx pc" instruction.
 
-if {![istarget arm*-*]} then {
+if {![is_aarch32_target]} then {
     verbose "Skipping ARM tests."
     return
 }
diff --git a/gdb/testsuite/gdb.arch/thumb-prologue.exp b/gdb/testsuite/gdb.arch/thumb-prologue.exp
index 8e3d293..a34beb2 100644
--- a/gdb/testsuite/gdb.arch/thumb-prologue.exp
+++ b/gdb/testsuite/gdb.arch/thumb-prologue.exp
@@ -15,7 +15,7 @@
 
 # Test ARM/Thumb prologue analyzer.
 
-if {![istarget arm*-*]} then {
+if {![is_aarch32_target]} then {
     verbose "Skipping ARM prologue tests."
     return
 }
diff --git a/gdb/testsuite/gdb.arch/thumb-singlestep.exp b/gdb/testsuite/gdb.arch/thumb-singlestep.exp
index 07adaaf..ba75570 100644
--- a/gdb/testsuite/gdb.arch/thumb-singlestep.exp
+++ b/gdb/testsuite/gdb.arch/thumb-singlestep.exp
@@ -15,7 +15,7 @@
 
 # Test single-stepping into incorrectly marked Thumb routine
 
-if {![istarget arm*-*]} then {
+if {![is_aarch32_target]} then {
     verbose "Skipping ARM tests."
     return
 }
diff --git a/gdb/testsuite/gdb.base/disp-step-syscall.exp b/gdb/testsuite/gdb.base/disp-step-syscall.exp
index b13dce4..ec3fccc 100644
--- a/gdb/testsuite/gdb.base/disp-step-syscall.exp
+++ b/gdb/testsuite/gdb.base/disp-step-syscall.exp
@@ -26,7 +26,7 @@ set syscall_insn ""
 
 if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
     set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]"
-} elseif [istarget "arm*-*-linux*"] {
+} elseif [is_aarch32_target] {
     set syscall_insn "\[ \t\](swi|svc)\[ \t\]"
 } else {
     return -1
diff --git a/gdb/testsuite/gdb.base/float.exp b/gdb/testsuite/gdb.base/float.exp
index f351795..a7183cf 100644
--- a/gdb/testsuite/gdb.base/float.exp
+++ b/gdb/testsuite/gdb.base/float.exp
@@ -40,7 +40,7 @@ if { [istarget "aarch64*-*-*"] } then {
     gdb_test "info float" "d0.*d1.*d31.*s0.*s1.*s31.*" "info float"
 } elseif { [istarget "alpha*-*-*"] } then {
     gdb_test "info float" "f0.*" "info float"
-} elseif { [istarget "arm*-*-*"] } then {
+} elseif { [is_aarch32_target] } then {
     gdb_test_multiple "info float" "info float" {
 	-re "Software FPU type.*mask:.*flags:.*$gdb_prompt $" {
 	    pass "info float (FPA)"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index c0e0cb1..b29b8c4 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -2271,6 +2271,43 @@ proc is_x86_like_target {} {
     return [expr [is_ilp32_target] && ![is_amd64_regs_target]]
 }
 
+# Return 1 if this target is an arm or aarch32 on aarch64.
+
+gdb_caching_proc is_aarch32_target {
+    if { [istarget "arm*-*-*"] } {
+	return 1
+    }
+
+    if { ![istarget "aarch64*-*-*"] } {
+	return 0
+    }
+
+    set me "is_aarch32_target"
+
+    set src [standard_temp_file aarch32[pid].s]
+    set obj [standard_temp_file aarch32[pid].o]
+
+    set list {}
+    foreach reg \
+	{r0 r1 r2 r3} {
+	    lappend list "\tmov $reg, $reg"
+	}
+    gdb_produce_source $src [join $list \n]
+
+    verbose "$me:  compiling testfile $src" 2
+    set lines [gdb_compile $src $obj object {quiet}]
+    file delete $src
+    file delete $obj
+
+    if ![string match "" $lines] then {
+	verbose "$me:  testfile compilation failed, returning 0" 2
+	return 0
+    }
+
+    verbose "$me:  returning 1" 2
+    return 1
+}
+
 # Return 1 if displaced stepping is supported on target, otherwise, return 0.
 proc support_displaced_stepping {} {
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1)
@ 2015-07-01 13:58 Yao Qi
  2015-07-01 13:58 ` [PATCH 01/11] Remove {fetch,store}_fpregister and {fetch,store}_register Yao Qi
                   ` (11 more replies)
  0 siblings, 12 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

This patch series is to enable Aarch64 GDB (64-bit) debug arm program
(32-bit) rudimentarily, which means with these patches applied, Aarch64
GDB is able to do some basic debugging to arm program .  However, some
features are still missing,

 - Debug multi-threaded program,
 - Use HW watchpoint and breakpoint,

because current linux kernel ptrace doesn't have right requests to get
the TLS area and to set HW watchpoint registers.  I am still working
with kernel hackers to get ptrace requests ready.  Our plan is to be
clear on aarch64 multi-arch debugging requirements to kernel first,
get them upstream to kernel, and then, post the rest of aarch64 gdb
multi-arch patches.  Afterwards, I'll add aarch64 multi-arch support
in gdbserver too.

Patch #1 is to align arm-linux-nat.c to aarch64-linux-nat.c, it is a
refactor patch.  Patch #2 and #3 starts the basic multi-arch debugging
support, in which some code is shared between arm and aarch64.  Patch
#4 is to adjust all arm-*.xml target descriptions to fix some fails
I've seen.  Patch #5 - #8 are various tweaks to gdb testsuite for
aarch64 multi-arch debugging.

Patch #9 - #11 can be regarded as an RFC, which teaches GDB to use
hardware single step in software single step architecture if target
supports hardware single step.  They are useful to aarch64 multi-arch
debugging, because hardware single step is available for arm32 process
on aarch64.

The whole series is tested on aarch64-linux with both aarch64 gcc and
arm gcc.  It is also tested on arm-linux and x86_64-linux.  Since we'll
branch 7.10 soon, I don't like to have such big change at last moment
of branching and releasing.  I plan to push them (or part of them) in
after 7.10 branch is created, if there are no objections.

*** BLURB HERE ***

Yao Qi (11):
  Remove {fetch,store}_fpregister and {fetch,store}_register
  New aarch32-linux-nat.c
  Native debug arm program by aarch64 GDB
  Set architecture to arm in arm-*.xml files
  Adjust gdb.multi tests for aarch64
  Enable multi-arch test in catch-syscall.exp on aarch64
  New proc is_aarch32_target
  New proc is_aarch64_target
  [gdbserver] Rename supports_conditional_breakpoints to
    supports_hardware_single_step
  Reply s and S vCont actions if target supports hardware single step
  New target_ops hook to_can_do_single_step

 gdb/aarch32-linux-nat.c                        |  99 +++++++++
 gdb/aarch32-linux-nat.h                        |  34 +++
 gdb/aarch64-linux-nat.c                        | 209 +++++++++++++++----
 gdb/arm-linux-nat.c                            | 274 ++-----------------------
 gdb/arm-linux-tdep.c                           |   5 +
 gdb/config/aarch64/linux.mh                    |   2 +-
 gdb/config/arm/linux.mh                        |   2 +-
 gdb/configure.tgt                              |   1 +
 gdb/features/arm-with-m-fpa-layout.c           |   2 +
 gdb/features/arm-with-m-fpa-layout.xml         |   1 +
 gdb/features/arm-with-m-vfp-d16.c              |   2 +
 gdb/features/arm-with-m-vfp-d16.xml            |   1 +
 gdb/features/arm-with-m.c                      |   2 +
 gdb/features/arm-with-m.xml                    |   1 +
 gdb/features/arm-with-neon.c                   |   2 +
 gdb/features/arm-with-neon.xml                 |   1 +
 gdb/features/arm-with-vfpv2.c                  |   2 +
 gdb/features/arm-with-vfpv2.xml                |   1 +
 gdb/features/arm-with-vfpv3.c                  |   2 +
 gdb/features/arm-with-vfpv3.xml                |   1 +
 gdb/gdbserver/linux-low.c                      |  11 +-
 gdb/gdbserver/lynx-low.c                       |   5 +-
 gdb/gdbserver/nto-low.c                        |   5 +-
 gdb/gdbserver/server.c                         |  19 +-
 gdb/gdbserver/spu-low.c                        |   2 +-
 gdb/gdbserver/target.c                         |   8 +
 gdb/gdbserver/target.h                         |  13 +-
 gdb/gdbserver/win32-low.c                      |   5 +-
 gdb/remote.c                                   |  33 ++-
 gdb/target-delegates.c                         |  31 +++
 gdb/target.h                                   |   9 +
 gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp |   2 +-
 gdb/testsuite/gdb.arch/aarch64-fp.exp          |   2 +-
 gdb/testsuite/gdb.arch/arm-bl-branch-dest.exp  |   2 +-
 gdb/testsuite/gdb.arch/arm-disp-step.exp       |   2 +-
 gdb/testsuite/gdb.arch/thumb-bx-pc.exp         |   2 +-
 gdb/testsuite/gdb.arch/thumb-prologue.exp      |   2 +-
 gdb/testsuite/gdb.arch/thumb-singlestep.exp    |   2 +-
 gdb/testsuite/gdb.base/catch-syscall.exp       |   7 +-
 gdb/testsuite/gdb.base/disp-step-syscall.exp   |   2 +-
 gdb/testsuite/gdb.base/float.exp               |   4 +-
 gdb/testsuite/gdb.multi/multi-arch-exec.exp    |  18 +-
 gdb/testsuite/gdb.multi/multi-arch.exp         |  18 +-
 gdb/testsuite/gdb.reverse/aarch64.exp          |   2 +-
 gdb/testsuite/lib/gdb.exp                      |  47 +++++
 45 files changed, 546 insertions(+), 351 deletions(-)
 create mode 100644 gdb/aarch32-linux-nat.c
 create mode 100644 gdb/aarch32-linux-nat.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 02/11] New aarch32-linux-nat.c
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
  2015-07-01 13:58 ` [PATCH 01/11] Remove {fetch,store}_fpregister and {fetch,store}_register Yao Qi
@ 2015-07-01 13:58 ` Yao Qi
  2015-07-01 13:58 ` [PATCH 04/11] Set architecture to arm in arm-*.xml files Yao Qi
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:58 UTC (permalink / raw)
  To: gdb-patches

This patch is to move all the code about transferring
regcache <-> byte buffer for arm (aarch32) to a separate file
aarch32-linux-nat.c.  Then, in the following patch, aarch64 code
can use it to do multi-arch debugging.  This is a refactory patch.

gdb:

2015-06-24  Yao Qi  <yao.qi@linaro.org>

	* aarch32-linux-nat.c: New file.
	* aarch32-linux-nat.h: New file.
	* arm-linux-nat.c: Include aarch32-linux-nat.h.
	(fetch_regs): Move code to aarch32-linux-nat.c.  Call
	aarch32_gp_regcache_supply.
	(store_regs): Move code to aarch32-linux-nat.c.  Call
	aarch32_gp_regcache_collect.
	(fetch_vfp_regs): Move code to aarch32-linux-nat.c.  Call
	aarch32_vfp_regcache_supply.
	(store_vfp_regs): Move code to aarch32-linux-nat.c.  Call
	aarch32_vfp_regcache_collect.
	* config/arm/linux.mh (NATDEPFILES): Add aarch32-linux-nat.o.
---
 gdb/aarch32-linux-nat.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/aarch32-linux-nat.h | 29 +++++++++++++++
 gdb/arm-linux-nat.c     | 46 +++++------------------
 gdb/config/arm/linux.mh |  2 +-
 4 files changed, 138 insertions(+), 38 deletions(-)
 create mode 100644 gdb/aarch32-linux-nat.c
 create mode 100644 gdb/aarch32-linux-nat.h

diff --git a/gdb/aarch32-linux-nat.c b/gdb/aarch32-linux-nat.c
new file mode 100644
index 0000000..3147399
--- /dev/null
+++ b/gdb/aarch32-linux-nat.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 1999-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 "defs.h"
+
+#include "regcache.h"
+#include "arm-tdep.h"
+#include "arm-linux-tdep.h"
+
+#include "aarch32-linux-nat.h"
+
+/* Supply GP registers contents, stored in REGS, to REGCACHE.  ARM_APCS_32
+   is true if the 32-bit mode is in use, otherwise, it is false.  */
+
+void
+aarch32_gp_regcache_supply (struct regcache *regcache, uint32_t *regs,
+			    int arm_apcs_32)
+{
+  int regno;
+
+  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
+    regcache_raw_supply (regcache, regno, &regs[regno]);
+
+  if (arm_apcs_32)
+    regcache_raw_supply (regcache, ARM_PS_REGNUM, &regs[ARM_CPSR_GREGNUM]);
+  else
+    regcache_raw_supply (regcache, ARM_PS_REGNUM, &regs[ARM_PC_REGNUM]);
+
+  regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
+			  (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]);
+  regcache_raw_supply (regcache, ARM_PC_REGNUM, &regs[ARM_PC_REGNUM]);
+}
+
+/* Collect GP registers from REGCACHE to buffer REGS.  ARM_APCS_32 is
+   true if the 32-bit mode is in use, otherwise, it is false.  */
+
+void
+aarch32_gp_regcache_collect (const struct regcache *regcache, uint32_t *regs,
+			     int arm_apcs_32)
+{
+  int regno;
+
+  for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
+    {
+      if (REG_VALID == regcache_register_status (regcache, regno))
+	regcache_raw_collect (regcache, regno, &regs[regno]);
+    }
+
+  if (arm_apcs_32
+      && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
+    regcache_raw_collect (regcache, ARM_PS_REGNUM,
+			  &regs[ARM_CPSR_GREGNUM]);
+}
+
+/* Supply VFP registers contents, stored in REGS, to REGCACHE.
+   VFP_REGISTER_COUNT is the number of VFP registers.  */
+
+void
+aarch32_vfp_regcache_supply (struct regcache *regcache, gdb_byte *regs,
+			     const int vfp_register_count)
+{
+  int regno;
+
+  for (regno = 0; regno < vfp_register_count; regno++)
+    regcache_raw_supply (regcache, regno + ARM_D0_REGNUM,
+			 regs + regno * 8);
+
+  regcache_raw_supply (regcache, ARM_FPSCR_REGNUM,
+		       regs + 32 * 8);
+}
+
+/* Collect VFP registers from REGCACHE to buffer REGS.
+   VFP_REGISTER_COUNT is the number VFP registers.  */
+
+void
+aarch32_vfp_regcache_collect (const struct regcache *regcache, gdb_byte *regs,
+			      const int vfp_register_count)
+{
+  int regno;
+
+  for (regno = 0; regno < vfp_register_count; regno++)
+    regcache_raw_collect (regcache, regno + ARM_D0_REGNUM, regs + regno * 8);
+
+  regcache_raw_collect (regcache, ARM_FPSCR_REGNUM, regs + 32 * 8);
+}
diff --git a/gdb/aarch32-linux-nat.h b/gdb/aarch32-linux-nat.h
new file mode 100644
index 0000000..1b7ff83e
--- /dev/null
+++ b/gdb/aarch32-linux-nat.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 1999-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/>.  */
+
+void aarch32_gp_regcache_supply (struct regcache *regcache, uint32_t *regs,
+				 int arm_apcs_32);
+
+void aarch32_gp_regcache_collect (const struct regcache *regcache,
+				  uint32_t *regs, int arm_apcs_32);
+
+void aarch32_vfp_regcache_supply (struct regcache *regcache, gdb_byte *regs,
+				  const int vfp_register_count);
+
+void aarch32_vfp_regcache_collect (const struct regcache *regcache,
+				   gdb_byte *regs,
+				   const int vfp_register_count);
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 5a8880f..aca0461 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -29,6 +29,7 @@
 
 #include "arm-tdep.h"
 #include "arm-linux-tdep.h"
+#include "aarch32-linux-nat.h"
 
 #include <elf/common.h>
 #include <sys/user.h>
@@ -212,20 +213,7 @@ fetch_regs (struct regcache *regcache)
       return;
     }
 
-  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno, (char *) &regs[regno]);
-
-  if (arm_apcs_32)
-    regcache_raw_supply (regcache, ARM_PS_REGNUM,
-			 (char *) &regs[ARM_CPSR_GREGNUM]);
-  else
-    regcache_raw_supply (regcache, ARM_PS_REGNUM,
-			 (char *) &regs[ARM_PC_REGNUM]);
-
-  regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
-			  (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]);
-  regcache_raw_supply (regcache, ARM_PC_REGNUM,
-		       (char *) &regs[ARM_PC_REGNUM]);
+  aarch32_gp_regcache_supply (regcache, (uint32_t *) regs, arm_apcs_32);
 }
 
 static void
@@ -256,15 +244,7 @@ store_regs (const struct regcache *regcache)
       return;
     }
 
-  for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
-    {
-      if (REG_VALID == regcache_register_status (regcache, regno))
-	regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
-    }
-
-  if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
-    regcache_raw_collect (regcache, ARM_PS_REGNUM,
-			 (char *) &regs[ARM_CPSR_GREGNUM]);
+  aarch32_gp_regcache_collect (regcache, (uint32_t *) regs, arm_apcs_32);
 
   if (have_ptrace_getregset == TRIBOOL_TRUE)
     {
@@ -370,7 +350,7 @@ store_wmmx_regs (const struct regcache *regcache)
 static void
 fetch_vfp_regs (struct regcache *regcache)
 {
-  char regbuf[VFP_REGS_SIZE];
+  gdb_byte regbuf[VFP_REGS_SIZE];
   int ret, regno, tid;
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -395,18 +375,14 @@ fetch_vfp_regs (struct regcache *regcache)
       return;
     }
 
-  for (regno = 0; regno < tdep->vfp_register_count; regno++)
-    regcache_raw_supply (regcache, regno + ARM_D0_REGNUM,
-			 (char *) regbuf + regno * 8);
-
-  regcache_raw_supply (regcache, ARM_FPSCR_REGNUM,
-		       (char *) regbuf + 32 * 8);
+  aarch32_vfp_regcache_supply (regcache, regbuf,
+			       tdep->vfp_register_count);
 }
 
 static void
 store_vfp_regs (const struct regcache *regcache)
 {
-  char regbuf[VFP_REGS_SIZE];
+  gdb_byte regbuf[VFP_REGS_SIZE];
   int ret, regno, tid;
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -431,12 +407,8 @@ store_vfp_regs (const struct regcache *regcache)
       return;
     }
 
-  for (regno = 0; regno < tdep->vfp_register_count; regno++)
-    regcache_raw_collect (regcache, regno + ARM_D0_REGNUM,
-			  (char *) regbuf + regno * 8);
-
-  regcache_raw_collect (regcache, ARM_FPSCR_REGNUM,
-			(char *) regbuf + 32 * 8);
+  aarch32_vfp_regcache_collect (regcache, regbuf,
+				tdep->vfp_register_count);
 
   if (have_ptrace_getregset == TRIBOOL_TRUE)
     {
diff --git a/gdb/config/arm/linux.mh b/gdb/config/arm/linux.mh
index f0c5967..003ca1f 100644
--- a/gdb/config/arm/linux.mh
+++ b/gdb/config/arm/linux.mh
@@ -2,7 +2,7 @@
 
 NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
-	proc-service.o linux-thread-db.o \
+	aarch32-linux-nat.o proc-service.o linux-thread-db.o \
 	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
 	linux-waitpid.o linux-personality.o linux-namespaces.o
 NAT_CDEPS = $(srcdir)/proc-service.list
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 11/11] New target_ops hook to_can_do_single_step
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (6 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 05/11] Adjust gdb.multi tests for aarch64 Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 16:43   ` Pedro Alves
  2015-07-01 13:59 ` [PATCH 03/11] Native debug arm program by aarch64 GDB Yao Qi
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

Nowadays, GDB only knows whether architecture supports hardware single
step or software single step (through gdbarch hook software_single_step),
and for a given instruction or instruction sequence, GDB knows how to
do single step (hardware or software).  However, GDB doesn't know whether
the target supports hardware single step.  It is possible that the
architecture doesn't support hardware single step, such as arm, but
the target supports, such as simulator.  This was discussed in this
thread https://www.sourceware.org/ml/gdb/2009-12/msg00033.html before.

I encounter this problem for aarch64 multi-arch support.  When aarch64
debugs arm program, gdbarch is arm, so software single step is still
used.  However, the underneath linux kernel does support hardware
single step, so IWBN to use it.

This patch is to add a new target_ops hook to_can_do_single_step, and
only use it in arm_linux_software_single_step to decide whether or not
to use hardware single step.  On the remote target, if the target
supports s and S actions in the vCont? reply, then target can do single
step.  On the native aarch64 linux target, 1 is returned.  On other
targets, -1 is returned.

gdb:

2015-06-30  Yao Qi  <yao.qi@linaro.org>

	* aarch64-linux-nat.c (aarch64_linux_can_do_single_step): New function.
	(_initialize_aarch64_linux_nat): Install it to to_can_do_single_step.
	* arm-linux-tdep.c (arm_linux_software_single_step): Return 0
	if target_can_do_single_step returns 1.
	* remote.c (struct vCont_action_support) <s>: New field.
	(remote_vcont_probe): Remove support_s and use
	rs->supports_vCont.s instead.
	(remote_can_do_single_step): New function.
	(init_remote_ops): Install it to to_can_do_single_step.
	* target.h (struct target_ops) <to_can_do_single_step>: New field.
	(target_can_do_single_step): New macro.
	* target-delegates.c: Re-generated.
---
 gdb/aarch64-linux-nat.c |  9 +++++++++
 gdb/arm-linux-tdep.c    |  5 +++++
 gdb/remote.c            | 33 +++++++++++++++++++++++++++------
 gdb/target-delegates.c  | 31 +++++++++++++++++++++++++++++++
 gdb/target.h            |  9 +++++++++
 5 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 9814dce..be9a91a 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -1607,6 +1607,14 @@ aarch64_linux_watchpoint_addr_within_range (struct target_ops *target,
   return start <= addr && start + length - 1 >= addr;
 }
 
+/* Implement the "to_can_do_single_step" target_ops method.  */
+
+static int
+aarch64_linux_can_do_single_step (struct target_ops *target)
+{
+  return 1;
+}
+
 /* Define AArch64 maintenance commands.  */
 
 static void
@@ -1658,6 +1666,7 @@ _initialize_aarch64_linux_nat (void)
   t->to_stopped_data_address = aarch64_linux_stopped_data_address;
   t->to_watchpoint_addr_within_range =
     aarch64_linux_watchpoint_addr_within_range;
+  t->to_can_do_single_step = aarch64_linux_can_do_single_step;
 
   /* Override the GNU/Linux inferior startup hook.  */
   super_post_startup_inferior = t->to_post_startup_inferior;
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 6273027..84afdd4 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -917,6 +917,11 @@ arm_linux_software_single_step (struct frame_info *frame)
   if (arm_deal_with_atomic_sequence (frame))
     return 1;
 
+  /* If the target does have hardware single step, GDB doesn't have
+     to bother software single step.  */
+  if (target_can_do_single_step () == 1)
+    return 0;
+
   next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
 
   /* The Linux kernel offers some user-mode helpers in a high page.  We can
diff --git a/gdb/remote.c b/gdb/remote.c
index 68dd99d..16f74c9 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -245,6 +245,12 @@ struct vCont_action_support
 
   /* vCont;r */
   int r;
+
+  /* vCont;s */
+  int s;
+
+  /* vCont;S */
+  int S;
 };
 
 /* Controls whether GDB is willing to use range stepping.  */
@@ -4818,10 +4824,10 @@ remote_vcont_probe (struct remote_state *rs)
   if (startswith (buf, "vCont"))
     {
       char *p = &buf[5];
-      int support_s, support_S, support_c, support_C;
+      int support_c, support_C;
 
-      support_s = 0;
-      support_S = 0;
+      rs->supports_vCont.s = 0;
+      rs->supports_vCont.S = 0;
       support_c = 0;
       support_C = 0;
       rs->supports_vCont.t = 0;
@@ -4830,9 +4836,9 @@ remote_vcont_probe (struct remote_state *rs)
 	{
 	  p++;
 	  if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0))
-	    support_s = 1;
+	    rs->supports_vCont.s = 1;
 	  else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0))
-	    support_S = 1;
+	    rs->supports_vCont.S = 1;
 	  else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0))
 	    support_c = 1;
 	  else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0))
@@ -4847,7 +4853,8 @@ remote_vcont_probe (struct remote_state *rs)
 
       /* If s, S, c, and C are not all supported, we can't use vCont.  Clearing
          BUF will make packet_ok disable the packet.  */
-      if (!support_s || !support_S || !support_c || !support_C)
+      if (!rs->supports_vCont.s || !rs->supports_vCont.S
+	  || !support_c || !support_C)
 	buf[0] = 0;
     }
 
@@ -12147,6 +12154,19 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
   return filename;
 }
 
+/* Implement the to_can_do_single_step target_ops method.  */
+
+static int
+remote_can_do_single_step (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
+    remote_vcont_probe (rs);
+
+  return rs->supports_vCont.s && rs->supports_vCont.S;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -12216,6 +12236,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_can_async_p = remote_can_async_p;
   remote_ops.to_is_async_p = remote_is_async_p;
   remote_ops.to_async = remote_async;
+  remote_ops.to_can_do_single_step = remote_can_do_single_step;
   remote_ops.to_terminal_inferior = remote_terminal_inferior;
   remote_ops.to_terminal_ours = remote_terminal_ours;
   remote_ops.to_supports_non_stop = remote_supports_non_stop;
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 36eacbf..b55a1b1 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -832,6 +832,33 @@ debug_masked_watch_num_registers (struct target_ops *self, CORE_ADDR arg1, CORE_
   return result;
 }
 
+static int
+delegate_can_do_single_step (struct target_ops *self)
+{
+  self = self->beneath;
+  return self->to_can_do_single_step (self);
+}
+
+static int
+tdefault_can_do_single_step (struct target_ops *self)
+{
+  return -1;
+}
+
+static int
+debug_can_do_single_step (struct target_ops *self)
+{
+  int result;
+  fprintf_unfiltered (gdb_stdlog, "-> %s->to_can_do_single_step (...)\n", debug_target.to_shortname);
+  result = debug_target.to_can_do_single_step (&debug_target);
+  fprintf_unfiltered (gdb_stdlog, "<- %s->to_can_do_single_step (", debug_target.to_shortname);
+  target_debug_print_struct_target_ops_p (&debug_target);
+  fputs_unfiltered (") = ", gdb_stdlog);
+  target_debug_print_int (result);
+  fputs_unfiltered ("\n", gdb_stdlog);
+  return result;
+}
+
 static void
 delegate_terminal_init (struct target_ops *self)
 {
@@ -3935,6 +3962,8 @@ install_delegators (struct target_ops *ops)
     ops->to_can_accel_watchpoint_condition = delegate_can_accel_watchpoint_condition;
   if (ops->to_masked_watch_num_registers == NULL)
     ops->to_masked_watch_num_registers = delegate_masked_watch_num_registers;
+  if (ops->to_can_do_single_step == NULL)
+    ops->to_can_do_single_step = delegate_can_do_single_step;
   if (ops->to_terminal_init == NULL)
     ops->to_terminal_init = delegate_terminal_init;
   if (ops->to_terminal_inferior == NULL)
@@ -4197,6 +4226,7 @@ install_dummy_methods (struct target_ops *ops)
   ops->to_region_ok_for_hw_watchpoint = default_region_ok_for_hw_watchpoint;
   ops->to_can_accel_watchpoint_condition = tdefault_can_accel_watchpoint_condition;
   ops->to_masked_watch_num_registers = tdefault_masked_watch_num_registers;
+  ops->to_can_do_single_step = tdefault_can_do_single_step;
   ops->to_terminal_init = tdefault_terminal_init;
   ops->to_terminal_inferior = tdefault_terminal_inferior;
   ops->to_terminal_ours_for_output = tdefault_terminal_ours_for_output;
@@ -4345,6 +4375,7 @@ init_debug_target (struct target_ops *ops)
   ops->to_region_ok_for_hw_watchpoint = debug_region_ok_for_hw_watchpoint;
   ops->to_can_accel_watchpoint_condition = debug_can_accel_watchpoint_condition;
   ops->to_masked_watch_num_registers = debug_masked_watch_num_registers;
+  ops->to_can_do_single_step = debug_can_do_single_step;
   ops->to_terminal_init = debug_terminal_init;
   ops->to_terminal_inferior = debug_terminal_inferior;
   ops->to_terminal_ours_for_output = debug_terminal_ours_for_output;
diff --git a/gdb/target.h b/gdb/target.h
index 32234f7..a312664 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -557,6 +557,12 @@ struct target_ops
     int (*to_masked_watch_num_registers) (struct target_ops *,
 					  CORE_ADDR, CORE_ADDR)
       TARGET_DEFAULT_RETURN (-1);
+
+    /* Return 1 for sure target can do single step.  Return -1 for
+       unknown.  Return 0 for target can't do.  */
+    int (*to_can_do_single_step) (struct target_ops *)
+      TARGET_DEFAULT_RETURN (-1);
+
     void (*to_terminal_init) (struct target_ops *)
       TARGET_DEFAULT_IGNORE ();
     void (*to_terminal_inferior) (struct target_ops *)
@@ -1861,6 +1867,9 @@ extern char *target_thread_name (struct thread_info *);
 						      addr, len)
 
 
+#define target_can_do_single_step() \
+  (*current_target.to_can_do_single_step) (&current_target)
+
 /* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes.
    TYPE is 0 for write, 1 for read, and 2 for read/write accesses.
    COND is the expression for its condition, or NULL if there's none.
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 09/11] [gdbserver] Rename supports_conditional_breakpoints to supports_hardware_single_step
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (8 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 03/11] Native debug arm program by aarch64 GDB Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 13:59 ` [PATCH 06/11] Enable multi-arch test in catch-syscall.exp on aarch64 Yao Qi
  2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

In my patch https://sourceware.org/ml/gdb-patches/2015-04/msg01110.html
a new target_ops hook supports_conditional_breakpoints was added to
disable conditional breakpoints if target doesn't have hardware single
step.  This patch is to generalize this hook from
supports_conditional_breakpoints to supports_hardware_single_step,
so that the following patch can use it.

gdb/gdbserver:

2015-06-30  Yao Qi  <yao.qi@linaro.org>

	* linux-low.c (linux_supports_conditional_breakpoints): Rename
	it to ...
	(linux_supports_hardware_single_step): ... New function.
	(linux_target_ops): Update.
	* lynx-low.c (lynx_target_ops): Set field
	supports_hardware_single_step to target_can_do_hardware_single_step.
	* nto-low.c (nto_target_ops): Likewise.
	* spu-low.c (spu_target_ops): Likewise.
	* win32-low.c (win32_target_ops): Likewise.
	* target.c (target_can_do_hardware_single_step): New function.
	* target.h (struct target_ops) <supports_conditional_breakpoints>:
	Remove.  <supports_hardware_single_step>: New field.
	(target_supports_conditional_breakpoints): Remove.
	(target_supports_hardware_single_step): New macro.
	(target_can_do_hardware_single_step): Declare.
	* server.c (handle_query): Use target_supports_hardware_single_step
	instead of target_supports_conditional_breakpoints.
---
 gdb/gdbserver/linux-low.c | 11 +++--------
 gdb/gdbserver/lynx-low.c  |  5 +----
 gdb/gdbserver/nto-low.c   |  5 +----
 gdb/gdbserver/server.c    | 10 ++++++++--
 gdb/gdbserver/spu-low.c   |  2 +-
 gdb/gdbserver/target.c    |  8 ++++++++
 gdb/gdbserver/target.h    | 13 +++++++------
 gdb/gdbserver/win32-low.c |  5 +----
 8 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3774d17..6467ca8 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -5313,16 +5313,11 @@ linux_supports_stopped_by_hw_breakpoint (void)
   return USE_SIGTRAP_SIGINFO;
 }
 
-/* Implement the supports_conditional_breakpoints target_ops
-   method.  */
+/* Implement the supports_hardware_single_step target_ops method.  */
 
 static int
-linux_supports_conditional_breakpoints (void)
+linux_supports_hardware_single_step (void)
 {
-  /* GDBserver needs to step over the breakpoint if the condition is
-     false.  GDBserver software single step is too simple, so disable
-     conditional breakpoints if the target doesn't have hardware single
-     step.  */
   return can_hardware_single_step ();
 }
 
@@ -6582,7 +6577,7 @@ static struct target_ops linux_target_ops = {
   linux_supports_stopped_by_sw_breakpoint,
   linux_stopped_by_hw_breakpoint,
   linux_supports_stopped_by_hw_breakpoint,
-  linux_supports_conditional_breakpoints,
+  linux_supports_hardware_single_step,
   linux_stopped_by_watchpoint,
   linux_stopped_data_address,
 #if defined(__UCLIBC__) && defined(HAS_NOMMU)	      \
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index ee7b28a..f636377 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -746,10 +746,7 @@ static struct target_ops lynx_target_ops = {
   NULL,  /* supports_stopped_by_sw_breakpoint */
   NULL,  /* stopped_by_hw_breakpoint */
   NULL,  /* supports_stopped_by_hw_breakpoint */
-  /* Although lynx has hardware single step, still disable this
-     feature for lynx, because it is implemented in linux-low.c instead
-     of in generic code.  */
-  NULL,  /* supports_conditional_breakpoints */
+  target_can_do_hardware_single_step,
   NULL,  /* stopped_by_watchpoint */
   NULL,  /* stopped_data_address */
   NULL,  /* read_offsets */
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index 9276736..6c50e95 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -949,10 +949,7 @@ static struct target_ops nto_target_ops = {
   NULL, /* supports_stopped_by_sw_breakpoint */
   NULL, /* stopped_by_hw_breakpoint */
   NULL, /* supports_stopped_by_hw_breakpoint */
-  /* Although nto has hardware single step, still disable this
-     feature for not, because it is implemented in linux-low.c instead
-     of in generic code.  */
-  NULL, /* supports_conditional_breakpoints */
+  target_can_do_hardware_single_step,
   nto_stopped_by_watchpoint,
   nto_stopped_data_address,
   NULL, /* nto_read_offsets */
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index c9effc2..858fbe5 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2142,8 +2142,14 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 	}
 
       /* Support target-side breakpoint conditions and commands.  */
-      if (target_supports_conditional_breakpoints ())
-	strcat (own_buf, ";ConditionalBreakpoints+");
+      if (target_supports_hardware_single_step ())
+	{
+	  /* GDBserver needs to step over the breakpoint if the condition
+	     is false.  GDBserver software single step is too simple, so
+	     disable conditional breakpoints if the target doesn't have
+	     hardware single step.  */
+	  strcat (own_buf, ";ConditionalBreakpoints+");
+	}
       strcat (own_buf, ";BreakpointCommands+");
 
       if (target_supports_agent ())
diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c
index a56a889..b5501c4 100644
--- a/gdb/gdbserver/spu-low.c
+++ b/gdb/gdbserver/spu-low.c
@@ -662,7 +662,7 @@ static struct target_ops spu_target_ops = {
   NULL, /* supports_stopped_by_sw_breakpoint */
   NULL, /* stopped_by_hw_breakpoint */
   NULL, /* supports_stopped_by_hw_breakpoint */
-  NULL, /* supports_conditional_breakpoints */
+  NULL, /* supports_hardware_single_step */
   NULL,
   NULL,
   NULL,
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 14999e6..dd04642 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -218,3 +218,11 @@ kill_inferior (int pid)
 
   return (*the_target->kill) (pid);
 }
+
+/* Target can do hardware single step.  */
+
+int
+target_can_do_hardware_single_step (void)
+{
+  return 1;
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 9a40867..c16f55b 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -222,9 +222,8 @@ struct target_ops
      HW breakpoint triggering.  */
   int (*supports_stopped_by_hw_breakpoint) (void);
 
-  /* Returns true if the target can evaluate conditions of
-     breakpoints.  */
-  int (*supports_conditional_breakpoints) (void);
+  /* Returns true if the target can do hardware single step.  */
+  int (*supports_hardware_single_step) (void);
 
   /* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise.  */
 
@@ -599,9 +598,9 @@ int kill_inferior (int);
   (the_target->supports_stopped_by_hw_breakpoint ? \
    (*the_target->supports_stopped_by_hw_breakpoint) () : 0)
 
-#define target_supports_conditional_breakpoints() \
-  (the_target->supports_conditional_breakpoints ? \
-   (*the_target->supports_conditional_breakpoints) () : 0)
+#define target_supports_hardware_single_step() \
+  (the_target->supports_hardware_single_step ? \
+   (*the_target->supports_hardware_single_step) () : 0)
 
 #define target_stopped_by_hw_breakpoint() \
   (the_target->stopped_by_hw_breakpoint ? \
@@ -639,4 +638,6 @@ void set_desired_thread (int id);
 
 const char *target_pid_to_str (ptid_t);
 
+int target_can_do_hardware_single_step (void);
+
 #endif /* TARGET_H */
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 64caf24..ff3feff 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -1809,10 +1809,7 @@ static struct target_ops win32_target_ops = {
   NULL, /* supports_stopped_by_sw_breakpoint */
   NULL, /* stopped_by_hw_breakpoint */
   NULL, /* supports_stopped_by_hw_breakpoint */
-  /* Although win32-i386 has hardware single step, still disable this
-     feature for win32, because it is implemented in linux-low.c instead
-     of in generic code.  */
-  NULL, /* supports_conditional_breakpoints */
+  target_can_do_hardware_single_step,
   win32_stopped_by_watchpoint,
   win32_stopped_data_address,
   NULL, /* read_offsets */
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 06/11] Enable multi-arch test in catch-syscall.exp on aarch64
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (9 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 09/11] [gdbserver] Rename supports_conditional_breakpoints to supports_hardware_single_step Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

This patch is to enable test_catch_syscall_multi_arch on aarch64.

gdb/testsuite:

2015-06-19  Yao Qi  <yao.qi@linaro.org>

	* gdb.base/catch-syscall.exp (test_catch_syscall_multi_arch):
	Set arch1, arch2, syscall1_name, syscall2_name and syscall_number.
---
 gdb/testsuite/gdb.base/catch-syscall.exp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp
index df0004a..40ca148 100644
--- a/gdb/testsuite/gdb.base/catch-syscall.exp
+++ b/gdb/testsuite/gdb.base/catch-syscall.exp
@@ -403,8 +403,11 @@ proc test_catch_syscall_multi_arch {} {
 	verbose "Not testing ARM for multi-arch syscall support"
 	return
     } elseif { [istarget "aarch64*-linux*"] } {
-	verbose "Not testing AARCH64 for multi-arch syscall support"
-	return
+	set arch1 "aarch64"
+	set arch2 "arm"
+	set syscall1_name "reboot"
+	set syscall2_name "_newselect"
+	set syscall_number 142
     } elseif { [istarget "s390*-linux*"] } {
 	set arch1 "s390:31-bit"
 	set arch2 "s390:64-bit"
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 03/11] Native debug arm program by aarch64 GDB
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (7 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 11/11] New target_ops hook to_can_do_single_step Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 13:59 ` [PATCH 09/11] [gdbserver] Rename supports_conditional_breakpoints to supports_hardware_single_step Yao Qi
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

This patch is to let aarch64 GDB debug 32-bit arm program natively.  In
each function for fetching and storing registers, GDB will check
gdbarch_bfd_arch_info (gdbarch)->bits_per_word, if it is 32, call
the corresponding aarch32 functions in aarch32-linux-nat.c, otherwise
fall back to aarch64 code to fetch and store registers.

aarch64_linux_read_description has to return the right target description,
but we don't have gdbarch available there, so GDB fetches auxv and gets
AT_PHENT, in order to determine whether the target is 32-bit or 64-bit.
I learned this trick from solib-svr4.c.

gdb:

2015-06-24  Yao Qi  <yao.qi@linaro.org>

	* aarch32-linux-nat.h (VFP_REGS_SIZE): New macro, moved from
	arm-linux-nat.c.
	* aarch64-linux-nat.c: Include aarch32-linux-nat.h and
	elf/external.h.
	(fetch_gregs_from_thread): Call aarch32_gp_regcache_supply
	if target is 32-bit.
	(store_gregs_to_thread): Call aarch32_gp_regcache_collect
	if target is 32-bit.
	(fetch_fpregs_from_thread): Call aarch32_vfp_regcache_supply
	if target is 32-bit.
	(store_fpregs_to_thread): Call aarch32_vfp_regcache_collect
	if target is 32-bit.
	(tdesc_arm_with_vfpv3, tdesc_arm_with_neon): Declare.
	(aarch64_linux_read_description): Return the right target
	description.
	* arm-linux-nat.c (VFP_REGS_SIZE): Moved to aarch32-linux-nat.h.
	* config/aarch64/linux.mh (NATDEPFILES): Add aarch32-linux-nat.o.
	* configure.tgt (aarch64*-*-linux*): Add arm-tdep.o and
	arm-linux-tdep.o
---
 gdb/aarch32-linux-nat.h     |   5 ++
 gdb/aarch64-linux-nat.c     | 200 ++++++++++++++++++++++++++++++++++++--------
 gdb/arm-linux-nat.c         |   5 --
 gdb/config/aarch64/linux.mh |   2 +-
 gdb/configure.tgt           |   1 +
 5 files changed, 170 insertions(+), 43 deletions(-)

diff --git a/gdb/aarch32-linux-nat.h b/gdb/aarch32-linux-nat.h
index 1b7ff83e..d7b5e16 100644
--- a/gdb/aarch32-linux-nat.h
+++ b/gdb/aarch32-linux-nat.h
@@ -15,6 +15,11 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+/* Fetch and store VFP Registers.  The kernel object has space for 32
+   64-bit registers, and the FPSCR.  This is even when on a VFPv2 or
+   VFPv3D16 target.  */
+#define VFP_REGS_SIZE (32 * 8 + 4)
+
 void aarch32_gp_regcache_supply (struct regcache *regcache, uint32_t *regs,
 				 int arm_apcs_32);
 
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index aae4853..9814dce 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -29,6 +29,9 @@
 #include "gdbcmd.h"
 #include "aarch64-tdep.h"
 #include "aarch64-linux-tdep.h"
+#include "aarch32-linux-nat.h"
+
+#include "elf/external.h"
 #include "elf/common.h"
 
 #include <sys/ptrace.h>
@@ -458,22 +461,36 @@ aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state,
 static void
 fetch_gregs_from_thread (struct regcache *regcache)
 {
-  int ret, regno, tid;
+  int ret, tid;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   elf_gregset_t regs;
   struct iovec iovec;
 
+  /* Make sure REGS can hold all registers contents on both aarch64
+     and arm.  */
+  gdb_static_assert (sizeof (regs) >= 18 * 4);
+
   tid = get_thread_id (inferior_ptid);
 
   iovec.iov_base = &regs;
-  iovec.iov_len = sizeof (regs);
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    iovec.iov_len = 18 * 4;
+  else
+    iovec.iov_len = sizeof (regs);
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
     perror_with_name (_("Unable to fetch general registers."));
 
-  for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno,
-			 (char *) &regs[regno - AARCH64_X0_REGNUM]);
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    aarch32_gp_regcache_supply (regcache, (uint32_t *) regs, 1);
+  else
+    {
+      int regno;
+
+      for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
+	regcache_raw_supply (regcache, regno, &regs[regno - AARCH64_X0_REGNUM]);
+    }
 }
 
 /* Store to the current thread the valid general-purpose register
@@ -482,23 +499,37 @@ fetch_gregs_from_thread (struct regcache *regcache)
 static void
 store_gregs_to_thread (const struct regcache *regcache)
 {
-  int ret, regno, tid;
+  int ret, tid;
   elf_gregset_t regs;
   struct iovec iovec;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
+  /* Make sure REGS can hold all registers contents on both aarch64
+     and arm.  */
+  gdb_static_assert (sizeof (regs) >= 18 * 4);
   tid = get_thread_id (inferior_ptid);
 
   iovec.iov_base = &regs;
-  iovec.iov_len = sizeof (regs);
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    iovec.iov_len = 18 * 4;
+  else
+    iovec.iov_len = sizeof (regs);
 
   ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
     perror_with_name (_("Unable to fetch general registers."));
 
-  for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
-    if (REG_VALID == regcache_register_status (regcache, regno))
-      regcache_raw_collect (regcache, regno,
-			    (char *) &regs[regno - AARCH64_X0_REGNUM]);
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    aarch32_gp_regcache_collect (regcache, (uint32_t *) regs, 1);
+  else
+    {
+      int regno;
+
+      for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
+	if (REG_VALID == regcache_register_status (regcache, regno))
+	  regcache_raw_collect (regcache, regno,
+				&regs[regno - AARCH64_X0_REGNUM]);
+    }
 
   ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iovec);
   if (ret < 0)
@@ -511,25 +542,46 @@ store_gregs_to_thread (const struct regcache *regcache)
 static void
 fetch_fpregs_from_thread (struct regcache *regcache)
 {
-  int ret, regno, tid;
+  int ret, tid;
   elf_fpregset_t regs;
   struct iovec iovec;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+  /* Make sure REGS can hold all VFP registers contents on both aarch64
+     and arm.  */
+  gdb_static_assert (sizeof regs >= VFP_REGS_SIZE);
 
   tid = get_thread_id (inferior_ptid);
 
   iovec.iov_base = &regs;
-  iovec.iov_len = sizeof (regs);
 
-  ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
-  if (ret < 0)
-    perror_with_name (_("Unable to fetch FP/SIMD registers."));
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    {
+      iovec.iov_len = VFP_REGS_SIZE;
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to fetch VFP registers."));
+
+      aarch32_vfp_regcache_supply (regcache, (gdb_byte *) &regs, 32);
+    }
+  else
+    {
+      int regno;
+
+      iovec.iov_len = sizeof (regs);
 
-  for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno,
-			 (char *) &regs.vregs[regno - AARCH64_V0_REGNUM]);
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to fetch vFP/SIMD registers."));
 
-  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM, (char *) &regs.fpsr);
-  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM, (char *) &regs.fpcr);
+      for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
+	regcache_raw_supply (regcache, regno,
+			     &regs.vregs[regno - AARCH64_V0_REGNUM]);
+
+      regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM, &regs.fpsr);
+      regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM, &regs.fpcr);
+    }
 }
 
 /* Store to the current thread the valid fp/simd register
@@ -538,32 +590,63 @@ fetch_fpregs_from_thread (struct regcache *regcache)
 static void
 store_fpregs_to_thread (const struct regcache *regcache)
 {
-  int ret, regno, tid;
+  int ret, tid;
   elf_fpregset_t regs;
   struct iovec iovec;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
+  /* Make sure REGS can hold all VFP registers contents on both aarch64
+     and arm.  */
+  gdb_static_assert (sizeof regs >= VFP_REGS_SIZE);
   tid = get_thread_id (inferior_ptid);
 
   iovec.iov_base = &regs;
-  iovec.iov_len = sizeof (regs);
 
-  ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
-  if (ret < 0)
-    perror_with_name (_("Unable to fetch FP/SIMD registers."));
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    {
+      iovec.iov_len = VFP_REGS_SIZE;
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to fetch VFP registers."));
+
+      aarch32_vfp_regcache_collect (regcache, (gdb_byte *) &regs, 32);
+    }
+  else
+    {
+      int regno;
 
-  for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
-    if (REG_VALID == regcache_register_status (regcache, regno))
-      regcache_raw_collect (regcache, regno,
-			    (char *) &regs.vregs[regno - AARCH64_V0_REGNUM]);
+      iovec.iov_len = sizeof (regs);
 
-  if (REG_VALID == regcache_register_status (regcache, AARCH64_FPSR_REGNUM))
-    regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM, (char *) &regs.fpsr);
-  if (REG_VALID == regcache_register_status (regcache, AARCH64_FPCR_REGNUM))
-    regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM, (char *) &regs.fpcr);
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to fetch FP/SIMD registers."));
 
-  ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iovec);
-  if (ret < 0)
-    perror_with_name (_("Unable to store FP/SIMD registers."));
+      for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
+	if (REG_VALID == regcache_register_status (regcache, regno))
+	  regcache_raw_collect (regcache, regno,
+				(char *) &regs.vregs[regno - AARCH64_V0_REGNUM]);
+
+      if (REG_VALID == regcache_register_status (regcache, AARCH64_FPSR_REGNUM))
+	regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM,
+			      (char *) &regs.fpsr);
+      if (REG_VALID == regcache_register_status (regcache, AARCH64_FPCR_REGNUM))
+	regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM,
+			      (char *) &regs.fpcr);
+    }
+
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    {
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_VFP, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to store VFP registers."));
+    }
+  else
+    {
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iovec);
+      if (ret < 0)
+	perror_with_name (_("Unable to store FP/SIMD registers."));
+    }
 }
 
 /* Implement the "to_fetch_register" target_ops method.  */
@@ -823,11 +906,54 @@ aarch64_linux_child_post_startup_inferior (struct target_ops *self,
   super_post_startup_inferior (self, ptid);
 }
 
+extern struct target_desc *tdesc_arm_with_vfpv3;
+extern struct target_desc *tdesc_arm_with_neon;
+
 /* Implement the "to_read_description" target_ops method.  */
 
 static const struct target_desc *
 aarch64_linux_read_description (struct target_ops *ops)
 {
+  CORE_ADDR at_phent;
+
+  if (target_auxv_search (ops, AT_PHENT, &at_phent) == 1)
+    {
+      if (at_phent == sizeof (Elf64_External_Phdr))
+	return tdesc_aarch64;
+      else
+	{
+	  CORE_ADDR arm_hwcap = 0;
+
+	  if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
+	    return ops->beneath->to_read_description (ops->beneath);
+
+#ifndef COMPAT_HWCAP_VFP
+#define COMPAT_HWCAP_VFP        (1 << 6)
+#endif
+#ifndef COMPAT_HWCAP_NEON
+#define COMPAT_HWCAP_NEON       (1 << 12)
+#endif
+#ifndef COMPAT_HWCAP_VFPv3
+#define COMPAT_HWCAP_VFPv3      (1 << 13)
+#endif
+
+	  if (arm_hwcap & COMPAT_HWCAP_VFP)
+	    {
+	      char *buf;
+	      const struct target_desc *result = NULL;
+
+	      if (arm_hwcap & COMPAT_HWCAP_NEON)
+		result = tdesc_arm_with_neon;
+	      else if (arm_hwcap & COMPAT_HWCAP_VFPv3)
+		result = tdesc_arm_with_vfpv3;
+
+	      return result;
+	    }
+
+	  return NULL;
+	}
+    }
+
   return tdesc_aarch64;
 }
 
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index aca0461..f0ab98c 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -342,11 +342,6 @@ store_wmmx_regs (const struct regcache *regcache)
     }
 }
 
-/* Fetch and store VFP Registers.  The kernel object has space for 32
-   64-bit registers, and the FPSCR.  This is even when on a VFPv2 or
-   VFPv3D16 target.  */
-#define VFP_REGS_SIZE (32 * 8 + 4)
-
 static void
 fetch_vfp_regs (struct regcache *regcache)
 {
diff --git a/gdb/config/aarch64/linux.mh b/gdb/config/aarch64/linux.mh
index 6a8aa7d..cbe322f 100644
--- a/gdb/config/aarch64/linux.mh
+++ b/gdb/config/aarch64/linux.mh
@@ -19,7 +19,7 @@
 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 NAT_FILE= config/nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o aarch64-linux-nat.o \
+NATDEPFILES= inf-ptrace.o fork-child.o aarch64-linux-nat.o aarch32-linux-nat.o \
 	proc-service.o linux-thread-db.o linux-nat.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-osdata.o linux-waitpid.o \
 	linux-personality.o linux-namespaces.o
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 4e4d6a9..f2c1a2d 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -44,6 +44,7 @@ aarch64*-*-elf)
 aarch64*-*-linux*)
 	# Target: AArch64 linux
 	gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.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
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 10/11] Reply s and S vCont actions if target supports hardware single step
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (4 preceding siblings ...)
  2015-07-01 13:58 ` [PATCH 08/11] New proc is_aarch64_target Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 13:59 ` [PATCH 05/11] Adjust gdb.multi tests for aarch64 Yao Qi
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

Nowadays, GDBserver reports vCont s and S actions are supported
unconditionally in vCont? reply, which isn't accurate.

This patch is to teach GDBserver to tell GDB that whether GDBserver can
do hardware single step by reporting s and S in the vCont? reply, if
GDBserver knows it supports hardware single step.

gdb/gdbserver:

2015-06-30  Yao Qi  <yao.qi@linaro.org>

	* server.c (handle_v_requests): Append ";s;S" to own_buf if
	target_supports_hardware_single_step returns true.
---
 gdb/gdbserver/server.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 858fbe5..e5a8f06 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2766,7 +2766,14 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 
       if (startswith (own_buf, "vCont?"))
 	{
-	  strcpy (own_buf, "vCont;c;C;s;S;t");
+	  strcpy (own_buf, "vCont;c;C;t");
+	  if (target_supports_hardware_single_step ())
+	    {
+	      /* Only return s;S if target supports hardware single
+		 step.  */
+	      own_buf = own_buf + strlen (own_buf);
+	      strcpy (own_buf, ";s;S");
+	    }
 	  if (target_supports_range_stepping ())
 	    {
 	      own_buf = own_buf + strlen (own_buf);
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 05/11] Adjust gdb.multi tests for aarch64
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (5 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 10/11] Reply s and S vCont actions if target supports hardware single step Yao Qi
@ 2015-07-01 13:59 ` Yao Qi
  2015-07-01 13:59 ` [PATCH 11/11] New target_ops hook to_can_do_single_step Yao Qi
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-01 13:59 UTC (permalink / raw)
  To: gdb-patches

Multi-arch related tests under gdb.multi are to compile programs with
the same compiler but different compiler options (-m64 vs -m32).  However,
different compilers are needed to compile both aarch64 program and
arm (aarch32) program.  This patch is to adjust these test cases to
compile programs in different modes with different compiler.

When we use gcc for arm-linux target, its file name can be different,
arm-linux-gnueabihf-gcc, arm-linux-gnueabi-gcc, or arm-none-linux-gnueabi-gcc,
so I add a variable ARM_CC_FOR_TARGET, so that user can set the name
of gcc for arm-linux target on aarch64, like:

 $ make check RUNTESTFLAGS='ARM_CC_FOR_TARGET=arm-linux-gnueabihf-gcc multi-arch.exp'

gdb/testsuite:

2015-06-24  Yao Qi  <yao.qi@linaro.org>

	* gdb.multi/multi-arch-exec.exp: Set march1 and march2 to "" if target
	is aarch64.  If target is aarch64, set compiler=${ARM_CC_FOR_TARGET}
	if it exists.
	* gdb.multi/multi-arch.exp: Likewise.
---
 gdb/testsuite/gdb.multi/multi-arch-exec.exp | 18 +++++++++++++++++-
 gdb/testsuite/gdb.multi/multi-arch.exp      | 18 +++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.multi/multi-arch-exec.exp b/gdb/testsuite/gdb.multi/multi-arch-exec.exp
index 4532108..67020d9 100644
--- a/gdb/testsuite/gdb.multi/multi-arch-exec.exp
+++ b/gdb/testsuite/gdb.multi/multi-arch-exec.exp
@@ -44,6 +44,9 @@ set binfile2 [standard_output_file ${exec2}]
 if [istarget "s390*-*-*"] {
     set march1 "-m64"
     set march2 "-m31"
+} elseif { [istarget "aarch64*-*-*"] } {
+    set march1 ""
+    set march2 ""
 } else {
     set march1 "-m64"
     set march2 "-m32"
@@ -57,8 +60,21 @@ if { [prepare_for_testing ${testfile}.exp ${exec1} "${srcfile1}" \
     return -1
 }
 
+set options [list debug nowarnings]
+
+if { [istarget "aarch64*-*-*"] } {
+    if {[info exists ARM_CC_FOR_TARGET]} {
+	lappend options "compiler=${ARM_CC_FOR_TARGET}"
+    } else {
+	unsupported "ARM compiler is not known"
+	return -1
+    }
+} else {
+    lappend options "additional_flags=${march2}"
+}
+
 if { [prepare_for_testing ${testfile}.exp ${exec2} "${srcfile2}" \
-	  [list debug nowarnings additional_flags=${march2}]] } {
+	  $options] } {
     return -1
 }
 
diff --git a/gdb/testsuite/gdb.multi/multi-arch.exp b/gdb/testsuite/gdb.multi/multi-arch.exp
index 22ad4da..4b255ee 100644
--- a/gdb/testsuite/gdb.multi/multi-arch.exp
+++ b/gdb/testsuite/gdb.multi/multi-arch.exp
@@ -44,6 +44,9 @@ set binfile2 [standard_output_file ${exec2}]
 if [istarget "s390*-*-*"] {
     set march1 "-m64"
     set march2 "-m31"
+} elseif { [istarget "aarch64*-*-*"] } {
+    set march1 ""
+    set march2 ""
 } else {
     set march1 "-m64"
     set march2 "-m32"
@@ -54,8 +57,21 @@ if { [prepare_for_testing ${testfile}.exp ${exec1} "${srcfile1}" \
     return -1
 }
 
+set options [list debug nowarnings]
+
+if [istarget "aarch64*-*-*"] {
+    if {[info exists ARM_CC_FOR_TARGET]} {
+	lappend options "compiler=${ARM_CC_FOR_TARGET}"
+    } else {
+	unsupported "ARM compiler is not known"
+	return -1
+    }
+} else {
+    lappend options "additional_flags=${march2}"
+}
+
 if { [prepare_for_testing ${testfile}.exp ${exec2} "${srcfile2}" \
-	  [list debug nowarnings additional_flags=${march2}]] } {
+	 $options]} {
     return -1
 }
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 08/11] New proc is_aarch64_target
  2015-07-01 13:58 ` [PATCH 08/11] New proc is_aarch64_target Yao Qi
@ 2015-07-01 14:10   ` Andreas Schwab
  2015-07-01 14:19     ` Yao Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Andreas Schwab @ 2015-07-01 14:10 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi <qiyaoltc@gmail.com> writes:

> +    return [expr ![is_aarch32_target]]

[expr] is redundant.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 08/11] New proc is_aarch64_target
  2015-07-01 14:10   ` Andreas Schwab
@ 2015-07-01 14:19     ` Yao Qi
  2015-07-01 14:39       ` Andreas Schwab
  0 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2015-07-01 14:19 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: gdb-patches

On 01/07/15 15:10, Andreas Schwab wrote:
>> +    return [expr ![is_aarch32_target]]
> [expr] is redundant.

If I write "return ![is_aarch32_target]", I'll get a tcl error,

ERROR: tcl error sourcing 
../../../binutils-gdb/gdb/testsuite/gdb.arch/aarch64-atomic-inst.exp.
ERROR: expected boolean value but got "!1"
     while executing
"if {![is_aarch64_target]} {
     verbose "Skipping ${gdb_test_file_name}."
     return
}"

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 08/11] New proc is_aarch64_target
  2015-07-01 14:19     ` Yao Qi
@ 2015-07-01 14:39       ` Andreas Schwab
  0 siblings, 0 replies; 22+ messages in thread
From: Andreas Schwab @ 2015-07-01 14:39 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi <qiyaoltc@gmail.com> writes:

> On 01/07/15 15:10, Andreas Schwab wrote:
>>> +    return [expr ![is_aarch32_target]]
>> [expr] is redundant.
>
> If I write "return ![is_aarch32_target]", I'll get a tcl error,

Sorry, you are right of course, I've missed the !.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 11/11] New target_ops hook to_can_do_single_step
  2015-07-01 13:59 ` [PATCH 11/11] New target_ops hook to_can_do_single_step Yao Qi
@ 2015-07-01 16:43   ` Pedro Alves
  2015-07-02  8:56     ` Yao Qi
  0 siblings, 1 reply; 22+ messages in thread
From: Pedro Alves @ 2015-07-01 16:43 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 07/01/2015 02:58 PM, Yao Qi wrote:
> Nowadays, GDB only knows whether architecture supports hardware single
> step or software single step (through gdbarch hook software_single_step),
> and for a given instruction or instruction sequence, GDB knows how to
> do single step (hardware or software).  However, GDB doesn't know whether
> the target supports hardware single step.  It is possible that the
> architecture doesn't support hardware single step, such as arm, but
> the target supports, such as simulator.  This was discussed in this
> thread https://www.sourceware.org/ml/gdb/2009-12/msg00033.html before.
> 
> I encounter this problem for aarch64 multi-arch support.  When aarch64
> debugs arm program, gdbarch is arm, so software single step is still
> used.  However, the underneath linux kernel does support hardware
> single step, so IWBN to use it.
> 
> This patch is to add a new target_ops hook to_can_do_single_step, and
> only use it in arm_linux_software_single_step to decide whether or not
> to use hardware single step.  On the remote target, if the target
> supports s and S actions in the vCont? reply, then target can do single
> step.  On the native aarch64 linux target, 1 is returned.  On other
> targets, -1 is returned.

Yeah, I've wanted to do this before too.

But my issue with it is that this breaks gdb/gdbserver compatibility.

Old GDB has:

      /* If s, S, c, and C are not all supported, we can't use vCont.  Clearing
         BUF will make packet_ok disable the packet.  */
      if (!support_s || !support_S || !support_c || !support_C)
	buf[0] = 0;

Which means that new x86-86 gdbserver with old gdb will just
stop using vCont after this change.

And old arm gdbserver will still claim support for vCont;s packets,
which means that new gdb with old gdbserver will be broken.

I think this needs to be addressed somehow.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1)
  2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
                   ` (10 preceding siblings ...)
  2015-07-01 13:59 ` [PATCH 06/11] Enable multi-arch test in catch-syscall.exp on aarch64 Yao Qi
@ 2015-07-01 17:00 ` Pedro Alves
  2015-07-01 18:54   ` Pedro Alves
                     ` (2 more replies)
  11 siblings, 3 replies; 22+ messages in thread
From: Pedro Alves @ 2015-07-01 17:00 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 07/01/2015 02:58 PM, Yao Qi wrote:
> This patch series is to enable Aarch64 GDB (64-bit) debug arm program
> (32-bit) rudimentarily, which means with these patches applied, Aarch64
> GDB is able to do some basic debugging to arm program .  However, some
> features are still missing,
> 
>  - Debug multi-threaded program,
>  - Use HW watchpoint and breakpoint,
> 
> because current linux kernel ptrace doesn't have right requests to get
> the TLS area and to set HW watchpoint registers.  I am still working
> with kernel hackers to get ptrace requests ready.  Our plan is to be
> clear on aarch64 multi-arch debugging requirements to kernel first,
> get them upstream to kernel, and then, post the rest of aarch64 gdb
> multi-arch patches.  Afterwards, I'll add aarch64 multi-arch support
> in gdbserver too.

I'd be fantastic if you managed to merge the gdb and gdbserver
arm/aarch64 files, like we did for x86.

> 
> Patch #1 is to align arm-linux-nat.c to aarch64-linux-nat.c, it is a
> refactor patch.  Patch #2 and #3 starts the basic multi-arch debugging
> support, in which some code is shared between arm and aarch64.  Patch
> #4 is to adjust all arm-*.xml target descriptions to fix some fails
> I've seen.  Patch #5 - #8 are various tweaks to gdb testsuite for
> aarch64 multi-arch debugging.

I skimmed these and they looked fine to me.

> 
> Patch #9 - #11 can be regarded as an RFC, which teaches GDB to use
> hardware single step in software single step architecture if target
> supports hardware single step.  They are useful to aarch64 multi-arch
> debugging, because hardware single step is available for arm32 process
> on aarch64.

These I think are problematic as is.

> 
> The whole series is tested on aarch64-linux with both aarch64 gcc and
> arm gcc.  It is also tested on arm-linux and x86_64-linux.  Since we'll
> branch 7.10 soon, I don't like to have such big change at last moment
> of branching and releasing.  I plan to push them (or part of them) in
> after 7.10 branch is created, if there are no objections.
> 

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1)
  2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
@ 2015-07-01 18:54   ` Pedro Alves
  2015-07-02  9:05   ` Yao Qi
  2015-07-07 16:13   ` Yao Qi
  2 siblings, 0 replies; 22+ messages in thread
From: Pedro Alves @ 2015-07-01 18:54 UTC (permalink / raw)
  To: Yao Qi, gdb-patches

On 07/01/2015 06:00 PM, Pedro Alves wrote:
>> > Patch #9 - #11 can be regarded as an RFC, which teaches GDB to use
>> > hardware single step in software single step architecture if target
>> > supports hardware single step.  They are useful to aarch64 multi-arch
>> > debugging, because hardware single step is available for arm32 process
>> > on aarch64.
> These I think are problematic as is.

I didn't say it out loud, but I think the natural solution would be
to replace vCont? with new qSupported features.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 11/11] New target_ops hook to_can_do_single_step
  2015-07-01 16:43   ` Pedro Alves
@ 2015-07-02  8:56     ` Yao Qi
  2015-07-02  9:09       ` Pedro Alves
  0 siblings, 1 reply; 22+ messages in thread
From: Yao Qi @ 2015-07-02  8:56 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, gdb-patches

Pedro Alves <palves@redhat.com> writes:

> But my issue with it is that this breaks gdb/gdbserver compatibility.
>
> Old GDB has:
>
>       /* If s, S, c, and C are not all supported, we can't use vCont.  Clearing
>          BUF will make packet_ok disable the packet.  */
>       if (!support_s || !support_S || !support_c || !support_C)
> 	buf[0] = 0;
>
> Which means that new x86-86 gdbserver with old gdb will just
> stop using vCont after this change.

I think you meant new arm gdbserver, which doesn't return s and S in the
reply, old gdb will stop using vCont.

>
> And old arm gdbserver will still claim support for vCont;s packets,
> which means that new gdb with old gdbserver will be broken.

That is right.  I'll do it in qSupported features.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1)
  2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
  2015-07-01 18:54   ` Pedro Alves
@ 2015-07-02  9:05   ` Yao Qi
  2015-07-07 16:13   ` Yao Qi
  2 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-02  9:05 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, gdb-patches

Pedro Alves <palves@redhat.com> writes:

> I'd be fantastic if you managed to merge the gdb and gdbserver
> arm/aarch64 files, like we did for x86.

Yes, That is a good point.  I want to merge gdb and gdbserver code for
arm and aarch64 respectively, especially on inserting and removing
watchpoint.  However, arm vs. aarch64 are very different, unlike x86
vs. x86_64, in terms of different instruction set, software single step
vs hardware single step, different ptrace requests to access watchpoint
registers, etc.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 11/11] New target_ops hook to_can_do_single_step
  2015-07-02  8:56     ` Yao Qi
@ 2015-07-02  9:09       ` Pedro Alves
  0 siblings, 0 replies; 22+ messages in thread
From: Pedro Alves @ 2015-07-02  9:09 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On 07/02/2015 09:56 AM, Yao Qi wrote:
> Pedro Alves <palves@redhat.com> writes:
> 
>> But my issue with it is that this breaks gdb/gdbserver compatibility.
>>
>> Old GDB has:
>>
>>       /* If s, S, c, and C are not all supported, we can't use vCont.  Clearing
>>          BUF will make packet_ok disable the packet.  */
>>       if (!support_s || !support_S || !support_c || !support_C)
>> 	buf[0] = 0;
>>
>> Which means that new x86-86 gdbserver with old gdb will just
>> stop using vCont after this change.
> 
> I think you meant new arm gdbserver, which doesn't return s and S in the
> reply, old gdb will stop using vCont.

Yeah.

> 
>>
>> And old arm gdbserver will still claim support for vCont;s packets,
>> which means that new gdb with old gdbserver will be broken.
> 
> That is right.  I'll do it in qSupported features.

Thanks.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1)
  2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
  2015-07-01 18:54   ` Pedro Alves
  2015-07-02  9:05   ` Yao Qi
@ 2015-07-07 16:13   ` Yao Qi
  2 siblings, 0 replies; 22+ messages in thread
From: Yao Qi @ 2015-07-07 16:13 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, gdb-patches

Pedro Alves <palves@redhat.com> writes:

> I skimmed these and they looked fine to me.

I pushed patches #1 - #8 in, and ...

>
>> 
>> Patch #9 - #11 can be regarded as an RFC, which teaches GDB to use
>> hardware single step in software single step architecture if target
>> supports hardware single step.  They are useful to aarch64 multi-arch
>> debugging, because hardware single step is available for arm32 process
>> on aarch64.
>
> These I think are problematic as is.

... will update patch #9 - #11 soon.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2015-07-07 16:13 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-01 13:58 [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Yao Qi
2015-07-01 13:58 ` [PATCH 01/11] Remove {fetch,store}_fpregister and {fetch,store}_register Yao Qi
2015-07-01 13:58 ` [PATCH 02/11] New aarch32-linux-nat.c Yao Qi
2015-07-01 13:58 ` [PATCH 04/11] Set architecture to arm in arm-*.xml files Yao Qi
2015-07-01 13:58 ` [PATCH 07/11] New proc is_aarch32_target Yao Qi
2015-07-01 13:58 ` [PATCH 08/11] New proc is_aarch64_target Yao Qi
2015-07-01 14:10   ` Andreas Schwab
2015-07-01 14:19     ` Yao Qi
2015-07-01 14:39       ` Andreas Schwab
2015-07-01 13:59 ` [PATCH 10/11] Reply s and S vCont actions if target supports hardware single step Yao Qi
2015-07-01 13:59 ` [PATCH 05/11] Adjust gdb.multi tests for aarch64 Yao Qi
2015-07-01 13:59 ` [PATCH 11/11] New target_ops hook to_can_do_single_step Yao Qi
2015-07-01 16:43   ` Pedro Alves
2015-07-02  8:56     ` Yao Qi
2015-07-02  9:09       ` Pedro Alves
2015-07-01 13:59 ` [PATCH 03/11] Native debug arm program by aarch64 GDB Yao Qi
2015-07-01 13:59 ` [PATCH 09/11] [gdbserver] Rename supports_conditional_breakpoints to supports_hardware_single_step Yao Qi
2015-07-01 13:59 ` [PATCH 06/11] Enable multi-arch test in catch-syscall.exp on aarch64 Yao Qi
2015-07-01 17:00 ` [PATCH 00/11] Aarch64 linux GDB native multi-arch debugging (part 1) Pedro Alves
2015-07-01 18:54   ` Pedro Alves
2015-07-02  9:05   ` Yao Qi
2015-07-07 16:13   ` Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).