1699b0f92Schristos /* Target-dependent code for OpenBSD/amd64. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2003-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "frame.h" 22699b0f92Schristos #include "frame-unwind.h" 23699b0f92Schristos #include "gdbcore.h" 24699b0f92Schristos #include "symtab.h" 25699b0f92Schristos #include "objfiles.h" 26699b0f92Schristos #include "osabi.h" 27699b0f92Schristos #include "regcache.h" 28699b0f92Schristos #include "regset.h" 29699b0f92Schristos #include "target.h" 30699b0f92Schristos #include "trad-frame.h" 31699b0f92Schristos 32699b0f92Schristos #include "obsd-tdep.h" 33699b0f92Schristos #include "amd64-tdep.h" 34699b0f92Schristos #include "i387-tdep.h" 357d62b00eSchristos #include "gdbsupport/x86-xstate.h" 36699b0f92Schristos #include "solib-svr4.h" 37699b0f92Schristos #include "bsd-uthread.h" 38699b0f92Schristos 39699b0f92Schristos /* Support for signal handlers. */ 40699b0f92Schristos 41699b0f92Schristos /* Default page size. */ 42699b0f92Schristos static const int amd64obsd_page_size = 4096; 43699b0f92Schristos 44699b0f92Schristos /* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp 45699b0f92Schristos routine. */ 46699b0f92Schristos 47699b0f92Schristos static int 48*6881a400Schristos amd64obsd_sigtramp_p (frame_info_ptr this_frame) 49699b0f92Schristos { 50699b0f92Schristos CORE_ADDR pc = get_frame_pc (this_frame); 51699b0f92Schristos CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1)); 52699b0f92Schristos const gdb_byte osigreturn[] = 53699b0f92Schristos { 54699b0f92Schristos 0x48, 0xc7, 0xc0, 55699b0f92Schristos 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ 56699b0f92Schristos 0xcd, 0x80 /* int $0x80 */ 57699b0f92Schristos }; 58699b0f92Schristos const gdb_byte sigreturn[] = 59699b0f92Schristos { 60699b0f92Schristos 0x48, 0xc7, 0xc0, 61699b0f92Schristos 0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */ 62699b0f92Schristos 0x0f, 0x05 /* syscall */ 63699b0f92Schristos }; 64699b0f92Schristos size_t buflen = (sizeof sigreturn) + 1; 65699b0f92Schristos gdb_byte *buf; 66699b0f92Schristos const char *name; 67699b0f92Schristos 68699b0f92Schristos /* If the function has a valid symbol name, it isn't a 69699b0f92Schristos trampoline. */ 70699b0f92Schristos find_pc_partial_function (pc, &name, NULL, NULL); 71699b0f92Schristos if (name != NULL) 72699b0f92Schristos return 0; 73699b0f92Schristos 74699b0f92Schristos /* If the function lives in a valid section (even without a starting 75699b0f92Schristos point) it isn't a trampoline. */ 76699b0f92Schristos if (find_pc_section (pc) != NULL) 77699b0f92Schristos return 0; 78699b0f92Schristos 79699b0f92Schristos /* If we can't read the instructions at START_PC, return zero. */ 80699b0f92Schristos buf = (gdb_byte *) alloca ((sizeof sigreturn) + 1); 81*6881a400Schristos if (!safe_frame_unwind_memory (this_frame, start_pc + 6, {buf, buflen})) 82699b0f92Schristos return 0; 83699b0f92Schristos 84699b0f92Schristos /* Check for sigreturn(2). Depending on how the assembler encoded 85699b0f92Schristos the `movq %rsp, %rdi' instruction, the code starts at offset 6 or 86699b0f92Schristos 7. OpenBSD 5.0 and later use the `syscall' instruction. Older 87699b0f92Schristos versions use `int $0x80'. Check for both. */ 88699b0f92Schristos if (memcmp (buf, sigreturn, sizeof sigreturn) 89699b0f92Schristos && memcmp (buf + 1, sigreturn, sizeof sigreturn) 90699b0f92Schristos && memcmp (buf, osigreturn, sizeof osigreturn) 91699b0f92Schristos && memcmp (buf + 1, osigreturn, sizeof osigreturn)) 92699b0f92Schristos return 0; 93699b0f92Schristos 94699b0f92Schristos return 1; 95699b0f92Schristos } 96699b0f92Schristos 97699b0f92Schristos /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the 98699b0f92Schristos address of the associated sigcontext structure. */ 99699b0f92Schristos 100699b0f92Schristos static CORE_ADDR 101*6881a400Schristos amd64obsd_sigcontext_addr (frame_info_ptr this_frame) 102699b0f92Schristos { 103699b0f92Schristos CORE_ADDR pc = get_frame_pc (this_frame); 104699b0f92Schristos ULONGEST offset = (pc & (amd64obsd_page_size - 1)); 105699b0f92Schristos 106699b0f92Schristos /* The %rsp register points at `struct sigcontext' upon entry of a 107699b0f92Schristos signal trampoline. The relevant part of the trampoline is 108699b0f92Schristos 109699b0f92Schristos call *%rax 110699b0f92Schristos movq %rsp, %rdi 111699b0f92Schristos pushq %rdi 112699b0f92Schristos movq $SYS_sigreturn,%rax 113699b0f92Schristos int $0x80 114699b0f92Schristos 115699b0f92Schristos (see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq' 116699b0f92Schristos instruction clobbers %rsp, but its value is saved in `%rdi'. */ 117699b0f92Schristos 118699b0f92Schristos if (offset > 5) 119699b0f92Schristos return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM); 120699b0f92Schristos else 121699b0f92Schristos return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); 122699b0f92Schristos } 123699b0f92Schristos 124699b0f92Schristos /* OpenBSD 3.5 or later. */ 125699b0f92Schristos 126699b0f92Schristos /* Mapping between the general-purpose registers in `struct reg' 127699b0f92Schristos format and GDB's register cache layout. */ 128699b0f92Schristos 129699b0f92Schristos /* From <machine/reg.h>. */ 130699b0f92Schristos int amd64obsd_r_reg_offset[] = 131699b0f92Schristos { 132699b0f92Schristos 14 * 8, /* %rax */ 133699b0f92Schristos 13 * 8, /* %rbx */ 134699b0f92Schristos 3 * 8, /* %rcx */ 135699b0f92Schristos 2 * 8, /* %rdx */ 136699b0f92Schristos 1 * 8, /* %rsi */ 137699b0f92Schristos 0 * 8, /* %rdi */ 138699b0f92Schristos 12 * 8, /* %rbp */ 139699b0f92Schristos 15 * 8, /* %rsp */ 140699b0f92Schristos 4 * 8, /* %r8 .. */ 141699b0f92Schristos 5 * 8, 142699b0f92Schristos 6 * 8, 143699b0f92Schristos 7 * 8, 144699b0f92Schristos 8 * 8, 145699b0f92Schristos 9 * 8, 146699b0f92Schristos 10 * 8, 147699b0f92Schristos 11 * 8, /* ... %r15 */ 148699b0f92Schristos 16 * 8, /* %rip */ 149699b0f92Schristos 17 * 8, /* %eflags */ 150699b0f92Schristos 18 * 8, /* %cs */ 151699b0f92Schristos 19 * 8, /* %ss */ 152699b0f92Schristos 20 * 8, /* %ds */ 153699b0f92Schristos 21 * 8, /* %es */ 154699b0f92Schristos 22 * 8, /* %fs */ 155699b0f92Schristos 23 * 8 /* %gs */ 156699b0f92Schristos }; 157699b0f92Schristos 158699b0f92Schristos /* From <machine/signal.h>. */ 159699b0f92Schristos static int amd64obsd_sc_reg_offset[] = 160699b0f92Schristos { 161699b0f92Schristos 14 * 8, /* %rax */ 162699b0f92Schristos 13 * 8, /* %rbx */ 163699b0f92Schristos 3 * 8, /* %rcx */ 164699b0f92Schristos 2 * 8, /* %rdx */ 165699b0f92Schristos 1 * 8, /* %rsi */ 166699b0f92Schristos 0 * 8, /* %rdi */ 167699b0f92Schristos 12 * 8, /* %rbp */ 168699b0f92Schristos 24 * 8, /* %rsp */ 169699b0f92Schristos 4 * 8, /* %r8 ... */ 170699b0f92Schristos 5 * 8, 171699b0f92Schristos 6 * 8, 172699b0f92Schristos 7 * 8, 173699b0f92Schristos 8 * 8, 174699b0f92Schristos 9 * 8, 175699b0f92Schristos 10 * 8, 176699b0f92Schristos 11 * 8, /* ... %r15 */ 177699b0f92Schristos 21 * 8, /* %rip */ 178699b0f92Schristos 23 * 8, /* %eflags */ 179699b0f92Schristos 22 * 8, /* %cs */ 180699b0f92Schristos 25 * 8, /* %ss */ 181699b0f92Schristos 18 * 8, /* %ds */ 182699b0f92Schristos 17 * 8, /* %es */ 183699b0f92Schristos 16 * 8, /* %fs */ 184699b0f92Schristos 15 * 8 /* %gs */ 185699b0f92Schristos }; 186699b0f92Schristos 187699b0f92Schristos /* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c. */ 188699b0f92Schristos static int amd64obsd_uthread_reg_offset[] = 189699b0f92Schristos { 190699b0f92Schristos 19 * 8, /* %rax */ 191699b0f92Schristos 16 * 8, /* %rbx */ 192699b0f92Schristos 18 * 8, /* %rcx */ 193699b0f92Schristos 17 * 8, /* %rdx */ 194699b0f92Schristos 14 * 8, /* %rsi */ 195699b0f92Schristos 13 * 8, /* %rdi */ 196699b0f92Schristos 15 * 8, /* %rbp */ 197699b0f92Schristos -1, /* %rsp */ 198699b0f92Schristos 12 * 8, /* %r8 ... */ 199699b0f92Schristos 11 * 8, 200699b0f92Schristos 10 * 8, 201699b0f92Schristos 9 * 8, 202699b0f92Schristos 8 * 8, 203699b0f92Schristos 7 * 8, 204699b0f92Schristos 6 * 8, 205699b0f92Schristos 5 * 8, /* ... %r15 */ 206699b0f92Schristos 20 * 8, /* %rip */ 207699b0f92Schristos 4 * 8, /* %eflags */ 208699b0f92Schristos 21 * 8, /* %cs */ 209699b0f92Schristos -1, /* %ss */ 210699b0f92Schristos 3 * 8, /* %ds */ 211699b0f92Schristos 2 * 8, /* %es */ 212699b0f92Schristos 1 * 8, /* %fs */ 213699b0f92Schristos 0 * 8 /* %gs */ 214699b0f92Schristos }; 215699b0f92Schristos 216699b0f92Schristos /* Offset within the thread structure where we can find the saved 217699b0f92Schristos stack pointer (%esp). */ 218699b0f92Schristos #define AMD64OBSD_UTHREAD_RSP_OFFSET 400 219699b0f92Schristos 220699b0f92Schristos static void 221699b0f92Schristos amd64obsd_supply_uthread (struct regcache *regcache, 222699b0f92Schristos int regnum, CORE_ADDR addr) 223699b0f92Schristos { 2247f2ac410Schristos struct gdbarch *gdbarch = regcache->arch (); 225699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 226699b0f92Schristos CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET; 227699b0f92Schristos CORE_ADDR sp = 0; 228699b0f92Schristos gdb_byte buf[8]; 229699b0f92Schristos int i; 230699b0f92Schristos 231699b0f92Schristos gdb_assert (regnum >= -1); 232699b0f92Schristos 233699b0f92Schristos if (regnum == -1 || regnum == AMD64_RSP_REGNUM) 234699b0f92Schristos { 235699b0f92Schristos int offset; 236699b0f92Schristos 237699b0f92Schristos /* Fetch stack pointer from thread structure. */ 238699b0f92Schristos sp = read_memory_unsigned_integer (sp_addr, 8, byte_order); 239699b0f92Schristos 240699b0f92Schristos /* Adjust the stack pointer such that it looks as if we just 241699b0f92Schristos returned from _thread_machdep_switch. */ 242699b0f92Schristos offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8; 243699b0f92Schristos store_unsigned_integer (buf, 8, byte_order, sp + offset); 2447f2ac410Schristos regcache->raw_supply (AMD64_RSP_REGNUM, buf); 245699b0f92Schristos } 246699b0f92Schristos 247699b0f92Schristos for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++) 248699b0f92Schristos { 249699b0f92Schristos if (amd64obsd_uthread_reg_offset[i] != -1 250699b0f92Schristos && (regnum == -1 || regnum == i)) 251699b0f92Schristos { 252699b0f92Schristos /* Fetch stack pointer from thread structure (if we didn't 253699b0f92Schristos do so already). */ 254699b0f92Schristos if (sp == 0) 255699b0f92Schristos sp = read_memory_unsigned_integer (sp_addr, 8, byte_order); 256699b0f92Schristos 257699b0f92Schristos /* Read the saved register from the stack frame. */ 258699b0f92Schristos read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8); 2597f2ac410Schristos regcache->raw_supply (i, buf); 260699b0f92Schristos } 261699b0f92Schristos } 262699b0f92Schristos } 263699b0f92Schristos 264699b0f92Schristos static void 265699b0f92Schristos amd64obsd_collect_uthread (const struct regcache *regcache, 266699b0f92Schristos int regnum, CORE_ADDR addr) 267699b0f92Schristos { 2687f2ac410Schristos struct gdbarch *gdbarch = regcache->arch (); 269699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 270699b0f92Schristos CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET; 271699b0f92Schristos CORE_ADDR sp = 0; 272699b0f92Schristos gdb_byte buf[8]; 273699b0f92Schristos int i; 274699b0f92Schristos 275699b0f92Schristos gdb_assert (regnum >= -1); 276699b0f92Schristos 277699b0f92Schristos if (regnum == -1 || regnum == AMD64_RSP_REGNUM) 278699b0f92Schristos { 279699b0f92Schristos int offset; 280699b0f92Schristos 281699b0f92Schristos /* Calculate the stack pointer (frame pointer) that will be 282699b0f92Schristos stored into the thread structure. */ 283699b0f92Schristos offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8; 2847f2ac410Schristos regcache->raw_collect (AMD64_RSP_REGNUM, buf); 285699b0f92Schristos sp = extract_unsigned_integer (buf, 8, byte_order) - offset; 286699b0f92Schristos 287699b0f92Schristos /* Store the stack pointer. */ 288699b0f92Schristos write_memory_unsigned_integer (sp_addr, 8, byte_order, sp); 289699b0f92Schristos 290699b0f92Schristos /* The stack pointer was (potentially) modified. Make sure we 291699b0f92Schristos build a proper stack frame. */ 292699b0f92Schristos regnum = -1; 293699b0f92Schristos } 294699b0f92Schristos 295699b0f92Schristos for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++) 296699b0f92Schristos { 297699b0f92Schristos if (amd64obsd_uthread_reg_offset[i] != -1 298699b0f92Schristos && (regnum == -1 || regnum == i)) 299699b0f92Schristos { 300699b0f92Schristos /* Fetch stack pointer from thread structure (if we didn't 301699b0f92Schristos calculate it already). */ 302699b0f92Schristos if (sp == 0) 303699b0f92Schristos sp = read_memory_unsigned_integer (sp_addr, 8, byte_order); 304699b0f92Schristos 305699b0f92Schristos /* Write the register into the stack frame. */ 3067f2ac410Schristos regcache->raw_collect (i, buf); 307699b0f92Schristos write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8); 308699b0f92Schristos } 309699b0f92Schristos } 310699b0f92Schristos } 311699b0f92Schristos /* Kernel debugging support. */ 312699b0f92Schristos 313699b0f92Schristos /* From <machine/frame.h>. Easy since `struct trapframe' matches 314699b0f92Schristos `struct sigcontext'. */ 315699b0f92Schristos #define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset 316699b0f92Schristos 317699b0f92Schristos static struct trad_frame_cache * 318*6881a400Schristos amd64obsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) 319699b0f92Schristos { 320699b0f92Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 321699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 322699b0f92Schristos struct trad_frame_cache *cache; 323699b0f92Schristos CORE_ADDR func, sp, addr; 324699b0f92Schristos ULONGEST cs; 325699b0f92Schristos const char *name; 326699b0f92Schristos int i; 327699b0f92Schristos 328699b0f92Schristos if (*this_cache) 329699b0f92Schristos return (struct trad_frame_cache *) *this_cache; 330699b0f92Schristos 331699b0f92Schristos cache = trad_frame_cache_zalloc (this_frame); 332699b0f92Schristos *this_cache = cache; 333699b0f92Schristos 334699b0f92Schristos func = get_frame_func (this_frame); 335699b0f92Schristos sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); 336699b0f92Schristos 337699b0f92Schristos find_pc_partial_function (func, &name, NULL, NULL); 338699b0f92Schristos if (name && startswith (name, "Xintr")) 339699b0f92Schristos addr = sp + 8; /* It's an interrupt frame. */ 340699b0f92Schristos else 341699b0f92Schristos addr = sp; 342699b0f92Schristos 343699b0f92Schristos for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++) 344699b0f92Schristos if (amd64obsd_tf_reg_offset[i] != -1) 345699b0f92Schristos trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]); 346699b0f92Schristos 347699b0f92Schristos /* Read %cs from trap frame. */ 348699b0f92Schristos addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; 349699b0f92Schristos cs = read_memory_unsigned_integer (addr, 8, byte_order); 350699b0f92Schristos if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 351699b0f92Schristos { 352699b0f92Schristos /* Trap from user space; terminate backtrace. */ 353699b0f92Schristos trad_frame_set_id (cache, outer_frame_id); 354699b0f92Schristos } 355699b0f92Schristos else 356699b0f92Schristos { 357699b0f92Schristos /* Construct the frame ID using the function start. */ 358699b0f92Schristos trad_frame_set_id (cache, frame_id_build (sp + 16, func)); 359699b0f92Schristos } 360699b0f92Schristos 361699b0f92Schristos return cache; 362699b0f92Schristos } 363699b0f92Schristos 364699b0f92Schristos static void 365*6881a400Schristos amd64obsd_trapframe_this_id (frame_info_ptr this_frame, 366699b0f92Schristos void **this_cache, struct frame_id *this_id) 367699b0f92Schristos { 368699b0f92Schristos struct trad_frame_cache *cache = 369699b0f92Schristos amd64obsd_trapframe_cache (this_frame, this_cache); 370699b0f92Schristos 371699b0f92Schristos trad_frame_get_id (cache, this_id); 372699b0f92Schristos } 373699b0f92Schristos 374699b0f92Schristos static struct value * 375*6881a400Schristos amd64obsd_trapframe_prev_register (frame_info_ptr this_frame, 376699b0f92Schristos void **this_cache, int regnum) 377699b0f92Schristos { 378699b0f92Schristos struct trad_frame_cache *cache = 379699b0f92Schristos amd64obsd_trapframe_cache (this_frame, this_cache); 380699b0f92Schristos 381699b0f92Schristos return trad_frame_get_register (cache, this_frame, regnum); 382699b0f92Schristos } 383699b0f92Schristos 384699b0f92Schristos static int 385699b0f92Schristos amd64obsd_trapframe_sniffer (const struct frame_unwind *self, 386*6881a400Schristos frame_info_ptr this_frame, 387699b0f92Schristos void **this_prologue_cache) 388699b0f92Schristos { 389699b0f92Schristos ULONGEST cs; 390699b0f92Schristos const char *name; 391699b0f92Schristos 392699b0f92Schristos /* Check Current Privilege Level and bail out if we're not executing 393699b0f92Schristos in kernel space. */ 394699b0f92Schristos cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM); 395699b0f92Schristos if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 396699b0f92Schristos return 0; 397699b0f92Schristos 398699b0f92Schristos find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL); 399699b0f92Schristos return (name && ((strcmp (name, "calltrap") == 0) 400699b0f92Schristos || (strcmp (name, "osyscall1") == 0) 401699b0f92Schristos || (strcmp (name, "Xsyscall") == 0) 402699b0f92Schristos || (startswith (name, "Xintr")))); 403699b0f92Schristos } 404699b0f92Schristos 405*6881a400Schristos static const struct frame_unwind amd64obsd_trapframe_unwind = 406*6881a400Schristos { 407699b0f92Schristos /* FIXME: kettenis/20051219: This really is more like an interrupt 408699b0f92Schristos frame, but SIGTRAMP_FRAME would print <signal handler called>, 409699b0f92Schristos which really is not what we want here. */ 410*6881a400Schristos "amd64 openbsd trap", 411699b0f92Schristos NORMAL_FRAME, 412699b0f92Schristos default_frame_unwind_stop_reason, 413699b0f92Schristos amd64obsd_trapframe_this_id, 414699b0f92Schristos amd64obsd_trapframe_prev_register, 415699b0f92Schristos NULL, 416699b0f92Schristos amd64obsd_trapframe_sniffer 417699b0f92Schristos }; 418699b0f92Schristos 419699b0f92Schristos 420699b0f92Schristos static void 421699b0f92Schristos amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 422699b0f92Schristos { 423*6881a400Schristos i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); 424699b0f92Schristos 4257f2ac410Schristos amd64_init_abi (info, gdbarch, 4267f2ac410Schristos amd64_target_description (X86_XSTATE_SSE_MASK, true)); 427699b0f92Schristos obsd_init_abi (info, gdbarch); 428699b0f92Schristos 429699b0f92Schristos /* Initialize general-purpose register set details. */ 430699b0f92Schristos tdep->gregset_reg_offset = amd64obsd_r_reg_offset; 431699b0f92Schristos tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset); 432699b0f92Schristos tdep->sizeof_gregset = 24 * 8; 433699b0f92Schristos 434699b0f92Schristos tdep->jb_pc_offset = 7 * 8; 435699b0f92Schristos 436699b0f92Schristos tdep->sigtramp_p = amd64obsd_sigtramp_p; 437699b0f92Schristos tdep->sigcontext_addr = amd64obsd_sigcontext_addr; 438699b0f92Schristos tdep->sc_reg_offset = amd64obsd_sc_reg_offset; 439699b0f92Schristos tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset); 440699b0f92Schristos 441699b0f92Schristos /* OpenBSD provides a user-level threads implementation. */ 442699b0f92Schristos bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread); 443699b0f92Schristos bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread); 444699b0f92Schristos 445699b0f92Schristos /* OpenBSD uses SVR4-style shared libraries. */ 446699b0f92Schristos set_solib_svr4_fetch_link_map_offsets 447699b0f92Schristos (gdbarch, svr4_lp64_fetch_link_map_offsets); 448699b0f92Schristos 449699b0f92Schristos /* Unwind kernel trap frames correctly. */ 450699b0f92Schristos frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind); 451699b0f92Schristos } 452699b0f92Schristos 4537d62b00eSchristos void _initialize_amd64obsd_tdep (); 454699b0f92Schristos void 4557d62b00eSchristos _initialize_amd64obsd_tdep () 456699b0f92Schristos { 457699b0f92Schristos /* The OpenBSD/amd64 native dependent code makes this assumption. */ 458699b0f92Schristos gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS); 459699b0f92Schristos 460699b0f92Schristos gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, 461699b0f92Schristos GDB_OSABI_OPENBSD, amd64obsd_init_abi); 462699b0f92Schristos } 463