2023-08-16 22:26:55 +00:00
|
|
|
|
Index: gdb/amd64-obsd-tdep.c
|
|
|
|
|
--- gdb/amd64-obsd-tdep.c.orig
|
|
|
|
|
+++ gdb/amd64-obsd-tdep.c
|
2024-05-26 03:08:12 +00:00
|
|
|
|
@@ -39,8 +39,44 @@
|
2023-08-16 22:26:55 +00:00
|
|
|
|
/* 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[] = {
|
2024-05-26 03:08:12 +00:00
|
|
|
|
+ /* OpenBSD 7.4 */
|
|
|
|
|
+ { 13, { 0x48, 0xc7, 0xc0,
|
|
|
|
|
+ 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
|
|
|
|
|
+ 0x0f, 0x05 } }, /* syscall */
|
2023-08-16 22:26:55 +00:00
|
|
|
|
+ /* 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. */
|
|
|
|
|
|
2024-05-26 03:08:12 +00:00
|
|
|
|
@@ -49,20 +85,8 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame)
|
2023-08-16 22:26:55 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
2024-05-26 03:08:12 +00:00
|
|
|
|
@@ -76,22 +100,21 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame)
|
2023-08-16 22:26:55 +00:00
|
|
|
|
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++)
|
|
|
|
|
+ {
|
2024-05-26 03:08:12 +00:00
|
|
|
|
+ /* If we can't read the instructions, return zero. */
|
|
|
|
|
+ if (!safe_frame_unwind_memory (this_frame,
|
|
|
|
|
+ start_pc + info->offset, buf, sizeof buf))
|
|
|
|
|
+ continue;
|
2023-08-16 22:26:55 +00:00
|
|
|
|
|
|
|
|
|
- /* 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;
|
|
|
|
|
+ /* Check for sigreturn(2). */
|
|
|
|
|
+ if (memcmp (buf, info->sigreturn, sizeof buf))
|
|
|
|
|
+ continue;
|
2024-05-26 03:08:12 +00:00
|
|
|
|
|
|
|
|
|
- return 1;
|
2023-08-16 22:26:55 +00:00
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
|
2024-05-26 03:08:12 +00:00
|
|
|
|
@@ -101,7 +124,10 @@ static CORE_ADDR
|
|
|
|
|
amd64obsd_sigcontext_addr (struct frame_info *this_frame)
|
|
|
|
|
{
|
|
|
|
|
CORE_ADDR pc = get_frame_pc (this_frame);
|
|
|
|
|
+ CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
|
|
|
|
|
ULONGEST offset = (pc & (amd64obsd_page_size - 1));
|
|
|
|
|
+ const amd64obsd_sigreturn_info_t *info;
|
|
|
|
|
+ gdb_byte buf[SIGRETURN_INSN_LEN];
|
|
|
|
|
|
|
|
|
|
/* The %rsp register points at `struct sigcontext' upon entry of a
|
|
|
|
|
signal trampoline. The relevant part of the trampoline is
|
|
|
|
|
@@ -115,10 +141,22 @@ amd64obsd_sigcontext_addr (struct frame_info *this_fra
|
|
|
|
|
(see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq'
|
|
|
|
|
instruction clobbers %rsp, but its value is saved in `%rdi'. */
|
|
|
|
|
|
|
|
|
|
- if (offset > 5)
|
|
|
|
|
- return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
|
|
|
|
|
- else
|
|
|
|
|
- return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
|
|
|
|
+ for (info = amd64obsd_sigreturn_info; info->offset != -1; info++)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* If we can't read the instructions, return %rsp. */
|
|
|
|
|
+ if (!safe_frame_unwind_memory (this_frame,
|
|
|
|
|
+ start_pc + info->offset, buf, sizeof buf))
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ /* Check for sigreturn(2). */
|
|
|
|
|
+ if (memcmp (buf, info->sigreturn, sizeof buf))
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (offset > info->offset - 4 && offset < info->offset + 9)
|
|
|
|
|
+ return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* OpenBSD 3.5 or later. */
|