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)));
> }
>