Re: Fix gdb "target kvm" on amd64

2019-01-30 Thread Todd Mortimer
On Tue, Jan 22, 2019 at 02:47:10PM +0900, YASUOKA Masahiko wrote:
> Hi,
>
> Currently gdb "target kvm bsd.0.core" on amd64 doesn't work.  It can't
> read the registers and can't follow the stack frames.  The diff
> follows fixes those problems.
>
> ok? comment?

Sorry for the delay getting to this.

This looks ok to me. The checks look complete, so you'll see the
prologue instructions no matter which register we're using.

ok mortimer@

Now I'll have to go look at egdb and lldb to see if they need the same
treatment. :-)

Thanks!


>
> Fix gdb can handle prologues which has the retguard.  Also teach gdb
> that alltraps_kern() is a trap function.  Original diff from IIJ.
>
> Index: gnu/usr.bin/binutils/gdb/amd64-tdep.c
> ===
> RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/amd64-tdep.c,v
> retrieving revision 1.1.1.2
> diff -u -p -r1.1.1.2 amd64-tdep.c
> --- gnu/usr.bin/binutils/gdb/amd64-tdep.c 27 Dec 2004 13:05:33 -  
> 1.1.1.2
> +++ gnu/usr.bin/binutils/gdb/amd64-tdep.c 22 Jan 2019 05:28:15 -
> @@ -741,13 +741,31 @@ amd64_analyze_prologue (CORE_ADDR pc, CO
>   struct amd64_frame_cache *cache)
>  {
>static unsigned char proto[3] = { 0x48, 0x89, 0xe5 };
> -  unsigned char buf[3];
> +  unsigned char buf[10];
>unsigned char op;
> +  CORE_ADDR pc0 = pc;
>
>if (current_pc <= pc)
>  return current_pc;
>
> -  op = read_memory_unsigned_integer (pc, 1);
> +  op = read_memory_unsigned_integer (pc0, 1);
> +
> +  /* Check for retguard */
> +  if ((op == 0x4c || op == 0x48) && (current_pc <= pc + 11))
> +{
> +  read_memory (pc0 + 1, buf, 10);
> +  pc0 += 11;
> +
> +  /* Check for `movq (__retguard_ ## x)(%rip), %reg;'. */
> +  if (buf[0] != 0x8b)
> + return pc;
> +
> +  /* Check for `xorq off(%rsp), %reg'. */
> +  if ((buf[6] != 0x4c && buf[6] != 0x48)
> +   || buf[7] != 0x33 || buf[9] != 0x24)
> + return pc;
> +  op = read_memory_unsigned_integer (pc0, 1);
> +}
>
>if (op == 0x55)/* pushq %rbp */
>  {
> @@ -757,17 +775,17 @@ amd64_analyze_prologue (CORE_ADDR pc, CO
>cache->sp_offset += 8;
>
>/* If that's all, return now.  */
> -  if (current_pc <= pc + 1)
> +  if (current_pc <= pc0 + 1)
>  return current_pc;
>
>/* Check for `movq %rsp, %rbp'.  */
> -  read_memory (pc + 1, buf, 3);
> +  read_memory (pc0 + 1, buf, 3);
>if (memcmp (buf, proto, 3) != 0)
> - return pc + 1;
> + return pc0 + 1;
>
>/* OK, we actually have a frame.  */
>cache->frameless_p = 0;
> -  return pc + 4;
> +  return pc0 + 4;
>  }
>
>return pc;
> Index: gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c
> ===
> RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 amd64obsd-tdep.c
> --- gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c 10 Jul 2018 08:57:44 -  
> 1.11
> +++ gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c 22 Jan 2019 05:28:15 -
> @@ -452,6 +452,7 @@ amd64obsd_trapframe_sniffer (const struc
>return (name && ((strcmp (name, "calltrap") == 0)
>  || (name[0] == 'X' && strncmp(name, "Xipi_", 5) != 0)
>  || (strcmp (name, "alltraps") == 0)
> +|| (strcmp (name, "alltraps_kern") == 0)
>  || (strcmp (name, "intr_fast_exit") == 0)
>  || (strcmp (name, "intr_exit_recurse") == 0)));
>  }
>



Fix gdb "target kvm" on amd64

2019-01-21 Thread YASUOKA Masahiko
Hi,

Currently gdb "target kvm bsd.0.core" on amd64 doesn't work.  It can't
read the registers and can't follow the stack frames.  The diff
follows fixes those problems.

ok? comment?

Fix gdb can handle prologues which has the retguard.  Also teach gdb
that alltraps_kern() is a trap function.  Original diff from IIJ.

Index: gnu/usr.bin/binutils/gdb/amd64-tdep.c
===
RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/amd64-tdep.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 amd64-tdep.c
--- gnu/usr.bin/binutils/gdb/amd64-tdep.c   27 Dec 2004 13:05:33 -  
1.1.1.2
+++ gnu/usr.bin/binutils/gdb/amd64-tdep.c   22 Jan 2019 05:28:15 -
@@ -741,13 +741,31 @@ amd64_analyze_prologue (CORE_ADDR pc, CO
struct amd64_frame_cache *cache)
 {
   static unsigned char proto[3] = { 0x48, 0x89, 0xe5 };
-  unsigned char buf[3];
+  unsigned char buf[10];
   unsigned char op;
+  CORE_ADDR pc0 = pc;
 
   if (current_pc <= pc)
 return current_pc;
 
-  op = read_memory_unsigned_integer (pc, 1);
+  op = read_memory_unsigned_integer (pc0, 1);
+
+  /* Check for retguard */
+  if ((op == 0x4c || op == 0x48) && (current_pc <= pc + 11))
+{
+  read_memory (pc0 + 1, buf, 10);
+  pc0 += 11;
+
+  /* Check for `movq (__retguard_ ## x)(%rip), %reg;'. */
+  if (buf[0] != 0x8b)
+   return pc;
+
+  /* Check for `xorq off(%rsp), %reg'. */
+  if ((buf[6] != 0x4c && buf[6] != 0x48)
+ || buf[7] != 0x33 || buf[9] != 0x24)
+   return pc;
+  op = read_memory_unsigned_integer (pc0, 1);
+}
 
   if (op == 0x55)  /* pushq %rbp */
 {
@@ -757,17 +775,17 @@ amd64_analyze_prologue (CORE_ADDR pc, CO
   cache->sp_offset += 8;
 
   /* If that's all, return now.  */
-  if (current_pc <= pc + 1)
+  if (current_pc <= pc0 + 1)
 return current_pc;
 
   /* Check for `movq %rsp, %rbp'.  */
-  read_memory (pc + 1, buf, 3);
+  read_memory (pc0 + 1, buf, 3);
   if (memcmp (buf, proto, 3) != 0)
-   return pc + 1;
+   return pc0 + 1;
 
   /* OK, we actually have a frame.  */
   cache->frameless_p = 0;
-  return pc + 4;
+  return pc0 + 4;
 }
 
   return pc;
Index: gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c
===
RCS file: /cvs/src/gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c,v
retrieving revision 1.11
diff -u -p -r1.11 amd64obsd-tdep.c
--- gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c   10 Jul 2018 08:57:44 -  
1.11
+++ gnu/usr.bin/binutils/gdb/amd64obsd-tdep.c   22 Jan 2019 05:28:15 -
@@ -452,6 +452,7 @@ amd64obsd_trapframe_sniffer (const struc
   return (name && ((strcmp (name, "calltrap") == 0)
   || (name[0] == 'X' && strncmp(name, "Xipi_", 5) != 0)
   || (strcmp (name, "alltraps") == 0)
+  || (strcmp (name, "alltraps_kern") == 0)
   || (strcmp (name, "intr_fast_exit") == 0)
   || (strcmp (name, "intr_exit_recurse") == 0)));
 }