On Mon, 2020-05-18 at 20:28 -0400, k...@intricatesoftware.com wrote: > Fix backtrace across signals on amd64 > > The 'Apply the retpoline transformation to indirect jumps in the > raw ASM' commit in 6.4 added an instruction to the sigcode. > This fixes the offset to look for sigreturn and mantains > backward compat till 5.0. > > okay?
ping > > Index: Makefile > =================================================================== > RCS file: /cvs/ports/devel/gdb/Makefile,v > retrieving revision 1.65 > diff -u -p -u -r1.65 Makefile > --- Makefile 29 Mar 2020 17:23:30 -0000 1.65 > +++ Makefile 18 May 2020 21:44:42 -0000 > @@ -4,7 +4,7 @@ COMMENT= GNU debugger > CATEGORIES= devel > > DISTNAME= gdb-7.12.1 > -REVISION= 10 > +REVISION= 11 > > HOMEPAGE= https://www.gnu.org/software/gdb/ > > Index: patches/patch-gdb_amd64obsd-tdep_c > =================================================================== > RCS file: patches/patch-gdb_amd64obsd-tdep_c > diff -N patches/patch-gdb_amd64obsd-tdep_c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-gdb_amd64obsd-tdep_c 18 May 2020 21:44:42 -0000 > @@ -0,0 +1,107 @@ > +$OpenBSD$ > + > +Index: gdb/amd64obsd-tdep.c > +--- gdb/amd64obsd-tdep.c.orig > ++++ gdb/amd64obsd-tdep.c > +@@ -76,8 +76,40 @@ amd64obsd_iterate_over_regset_sections (struct gdbarch > + /* Support for signal handlers. */ > + > + /* Default page size. */ > +-static const int amd64obsd_page_size = 4096; > ++static const CORE_ADDR amd64obsd_page_size = 4096; > + > ++/* Offset & instructions for sigreturn(2). */ > ++ > ++#define SIGRETURN_INSN_LEN 9 > ++ > ++struct amd64obsd_sigreturn_info_t { > ++ int offset; > ++ gdb_byte sigreturn[SIGRETURN_INSN_LEN]; > ++}; > ++ > ++static const amd64obsd_sigreturn_info_t > ++ amd64obsd_sigreturn_info[] = { > ++ /* OpenBSD 6.4 */ > ++ { 9, { 0x48, 0xc7, 0xc0, > ++ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > ++ 0x0f, 0x05 } }, /* syscall */ > ++ /* OpenBSD 5.1 */ > ++ { 6, { 0x48, 0xc7, 0xc0, > ++ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > ++ 0x0f, 0x05 } }, /* syscall */ > ++ { 7, { 0x48, 0xc7, 0xc0, > ++ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > ++ 0x0f, 0x05 } }, /* syscall */ > ++ /* OpenBSD 5.0 */ > ++ { 6, { 0x48, 0xc7, 0xc0, > ++ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > ++ 0xcd, 0x80 } }, /* int $0x80 */ > ++ { 7, { 0x48, 0xc7, 0xc0, > ++ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > ++ 0xcd, 0x80 } }, /* int $0x80 */ > ++ { -1, {} } > ++}; > ++ > + /* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp > + routine. */ > + > +@@ -86,20 +118,8 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame) > + { > + CORE_ADDR pc = get_frame_pc (this_frame); > + CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1)); > +- const gdb_byte osigreturn[] = > +- { > +- 0x48, 0xc7, 0xc0, > +- 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > +- 0xcd, 0x80 /* int $0x80 */ > +- }; > +- const gdb_byte sigreturn[] = > +- { > +- 0x48, 0xc7, 0xc0, > +- 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ > +- 0x0f, 0x05 /* syscall */ > +- }; > +- size_t buflen = (sizeof sigreturn) + 1; > +- gdb_byte *buf; > ++ const amd64obsd_sigreturn_info_t *info; > ++ gdb_byte buf[SIGRETURN_INSN_LEN]; > + const char *name; > + > + /* If the function has a valid symbol name, it isn't a > +@@ -113,22 +133,22 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame) > + if (find_pc_section (pc) != NULL) > + return 0; > + > +- /* If we can't read the instructions at START_PC, return zero. */ > +- buf = (gdb_byte *) alloca ((sizeof sigreturn) + 1); > +- if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen)) > +- return 0; > ++ for (info = amd64obsd_sigreturn_info; info->offset != -1; info++) > ++ { > + > +- /* Check for sigreturn(2). Depending on how the assembler encoded > +- the `movq %rsp, %rdi' instruction, the code starts at offset 6 or > +- 7. OpenBSD 5.0 and later use the `syscall' instruction. Older > +- versions use `int $0x80'. Check for both. */ > +- if (memcmp (buf, sigreturn, sizeof sigreturn) > +- && memcmp (buf + 1, sigreturn, sizeof sigreturn) > +- && memcmp (buf, osigreturn, sizeof osigreturn) > +- && memcmp (buf + 1, osigreturn, sizeof osigreturn)) > +- return 0; > ++ /* If we can't read the instructions at return zero. */ > ++ if (!safe_frame_unwind_memory (this_frame, > ++ start_pc + info->offset, buf, sizeof buf)) > ++ continue; > + > +- return 1; > ++ /* Check for sigreturn(2). */ > ++ if (memcmp (buf, info->sigreturn, sizeof buf)) > ++ continue; > ++ > ++ return 1; > ++ } > ++ > ++ return 0; > + } > + > + /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the