1 /* Target-dependent code for OpenBSD/i386. 2 3 Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002, 4 2003, 2004, 2005 5 Free Software Foundation, Inc. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, 22 Boston, MA 02111-1307, USA. */ 23 24 #include "defs.h" 25 #include "arch-utils.h" 26 #include "frame.h" 27 #include "frame-unwind.h" 28 #include "gdbcore.h" 29 #include "regcache.h" 30 #include "regset.h" 31 #include "symtab.h" 32 #include "objfiles.h" 33 #include "osabi.h" 34 #include "target.h" 35 #include "trad-frame.h" 36 37 #include "gdb_assert.h" 38 #include "gdb_string.h" 39 40 #include "i386-tdep.h" 41 #include "i387-tdep.h" 42 #include "solib-svr4.h" 43 #include "bsd-uthread.h" 44 45 /* Support for signal handlers. */ 46 47 /* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page 48 in virtual memory. The randomness makes it somewhat tricky to 49 detect it, but fortunately we can rely on the fact that the start 50 of the sigtramp routine is page-aligned. By the way, the mapping 51 is read-only, so you cannot place a breakpoint in the signal 52 trampoline. */ 53 54 /* Default page size. */ 55 static const int i386obsd_page_size = 4096; 56 57 /* Offset for sigreturn(2). */ 58 static const int i386obsd_sigreturn_offset[] = { 59 0x0a, /* OpenBSD 3.2 */ 60 0x14, /* OpenBSD 3.6 */ 61 0x3a, /* OpenBSD 3.8 */ 62 -1 63 }; 64 65 /* Return whether the frame preceding NEXT_FRAME corresponds to an 66 OpenBSD sigtramp routine. */ 67 68 static int 69 i386obsd_sigtramp_p (struct frame_info *next_frame) 70 { 71 CORE_ADDR pc = frame_pc_unwind (next_frame); 72 CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1)); 73 const char sigreturn[] = 74 { 75 0xb8, 76 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */ 77 0xcd, 0x80 /* int $0x80 */ 78 }; 79 size_t buflen = sizeof sigreturn; 80 const int *offset; 81 char *name, *buf; 82 83 /* If the function has a valid symbol name, it isn't a 84 trampoline. */ 85 find_pc_partial_function (pc, &name, NULL, NULL); 86 if (name != NULL) 87 return 0; 88 89 /* If the function lives in a valid section (even without a starting 90 point) it isn't a trampoline. */ 91 if (find_pc_section (pc) != NULL) 92 return 0; 93 94 /* Allocate buffer. */ 95 buf = alloca (buflen); 96 97 /* Loop over all offsets. */ 98 for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++) 99 { 100 /* If we can't read the instructions, return zero. */ 101 if (!safe_frame_unwind_memory (next_frame, start_pc + *offset, 102 buf, buflen)) 103 return 0; 104 105 /* Check for sigreturn(2). */ 106 if (memcmp (buf, sigreturn, buflen) == 0) 107 return 1; 108 } 109 110 return 0; 111 } 112 113 /* Mapping between the general-purpose registers in `struct reg' 114 format and GDB's register cache layout. */ 115 116 /* From <machine/reg.h>. */ 117 static int i386obsd_r_reg_offset[] = 118 { 119 0 * 4, /* %eax */ 120 1 * 4, /* %ecx */ 121 2 * 4, /* %edx */ 122 3 * 4, /* %ebx */ 123 4 * 4, /* %esp */ 124 5 * 4, /* %ebp */ 125 6 * 4, /* %esi */ 126 7 * 4, /* %edi */ 127 8 * 4, /* %eip */ 128 9 * 4, /* %eflags */ 129 10 * 4, /* %cs */ 130 11 * 4, /* %ss */ 131 12 * 4, /* %ds */ 132 13 * 4, /* %es */ 133 14 * 4, /* %fs */ 134 15 * 4 /* %gs */ 135 }; 136 137 static void 138 i386obsd_aout_supply_regset (const struct regset *regset, 139 struct regcache *regcache, int regnum, 140 const void *regs, size_t len) 141 { 142 const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); 143 144 gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE); 145 146 i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset); 147 i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset); 148 } 149 150 static const struct regset * 151 i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch, 152 const char *sect_name, 153 size_t sect_size) 154 { 155 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 156 157 /* OpenBSD a.out core dumps don't use seperate register sets for the 158 general-purpose and floating-point registers. */ 159 160 if (strcmp (sect_name, ".reg") == 0 161 && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE) 162 { 163 if (tdep->gregset == NULL) 164 tdep->gregset = 165 regset_alloc (gdbarch, i386obsd_aout_supply_regset, NULL); 166 return tdep->gregset; 167 } 168 169 return NULL; 170 } 171 172 173 /* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */ 174 CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20; 175 CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0; 176 177 /* From <machine/signal.h>. */ 178 int i386obsd_sc_reg_offset[I386_NUM_GREGS] = 179 { 180 10 * 4, /* %eax */ 181 9 * 4, /* %ecx */ 182 8 * 4, /* %edx */ 183 7 * 4, /* %ebx */ 184 14 * 4, /* %esp */ 185 6 * 4, /* %ebp */ 186 5 * 4, /* %esi */ 187 4 * 4, /* %edi */ 188 11 * 4, /* %eip */ 189 13 * 4, /* %eflags */ 190 12 * 4, /* %cs */ 191 15 * 4, /* %ss */ 192 3 * 4, /* %ds */ 193 2 * 4, /* %es */ 194 1 * 4, /* %fs */ 195 0 * 4 /* %gs */ 196 }; 197 198 /* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */ 199 static int i386obsd_uthread_reg_offset[] = 200 { 201 11 * 4, /* %eax */ 202 10 * 4, /* %ecx */ 203 9 * 4, /* %edx */ 204 8 * 4, /* %ebx */ 205 -1, /* %esp */ 206 6 * 4, /* %ebp */ 207 5 * 4, /* %esi */ 208 4 * 4, /* %edi */ 209 12 * 4, /* %eip */ 210 -1, /* %eflags */ 211 13 * 4, /* %cs */ 212 -1, /* %ss */ 213 3 * 4, /* %ds */ 214 2 * 4, /* %es */ 215 1 * 4, /* %fs */ 216 0 * 4 /* %gs */ 217 }; 218 219 /* Offset within the thread structure where we can find the saved 220 stack pointer (%esp). */ 221 #define I386OBSD_UTHREAD_ESP_OFFSET 176 222 223 static void 224 i386obsd_supply_uthread (struct regcache *regcache, 225 int regnum, CORE_ADDR addr) 226 { 227 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET; 228 CORE_ADDR sp = 0; 229 char buf[4]; 230 int i; 231 232 gdb_assert (regnum >= -1); 233 234 if (regnum == -1 || regnum == I386_ESP_REGNUM) 235 { 236 int offset; 237 238 /* Fetch stack pointer from thread structure. */ 239 sp = read_memory_unsigned_integer (sp_addr, 4); 240 241 /* Adjust the stack pointer such that it looks as if we just 242 returned from _thread_machdep_switch. */ 243 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 244 store_unsigned_integer (buf, 4, sp + offset); 245 regcache_raw_supply (regcache, I386_ESP_REGNUM, buf); 246 } 247 248 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 249 { 250 if (i386obsd_uthread_reg_offset[i] != -1 251 && (regnum == -1 || regnum == i)) 252 { 253 /* Fetch stack pointer from thread structure (if we didn't 254 do so already). */ 255 if (sp == 0) 256 sp = read_memory_unsigned_integer (sp_addr, 4); 257 258 /* Read the saved register from the stack frame. */ 259 read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 260 regcache_raw_supply (regcache, i, buf); 261 } 262 } 263 } 264 265 static void 266 i386obsd_collect_uthread (const struct regcache *regcache, 267 int regnum, CORE_ADDR addr) 268 { 269 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET; 270 CORE_ADDR sp = 0; 271 char buf[4]; 272 int i; 273 274 gdb_assert (regnum >= -1); 275 276 if (regnum == -1 || regnum == I386_ESP_REGNUM) 277 { 278 int offset; 279 280 /* Calculate the stack pointer (frame pointer) that will be 281 stored into the thread structure. */ 282 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 283 regcache_raw_collect (regcache, I386_ESP_REGNUM, buf); 284 sp = extract_unsigned_integer (buf, 4) - offset; 285 286 /* Store the stack pointer. */ 287 write_memory_unsigned_integer (sp_addr, 4, sp); 288 289 /* The stack pointer was (potentially) modified. Make sure we 290 build a proper stack frame. */ 291 regnum = -1; 292 } 293 294 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 295 { 296 if (i386obsd_uthread_reg_offset[i] != -1 297 && (regnum == -1 || regnum == i)) 298 { 299 /* Fetch stack pointer from thread structure (if we didn't 300 calculate it already). */ 301 if (sp == 0) 302 sp = read_memory_unsigned_integer (sp_addr, 4); 303 304 /* Write the register into the stack frame. */ 305 regcache_raw_collect (regcache, i, buf); 306 write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 307 } 308 } 309 } 310 311 /* Kernel debugging support. */ 312 313 /* From <machine/frame.h>. Note that %esp and %ess are only saved in 314 a trap frame when entering the kernel from user space. */ 315 static int i386obsd_tf_reg_offset[] = 316 { 317 10 * 4, /* %eax */ 318 9 * 4, /* %ecx */ 319 8 * 4, /* %edx */ 320 7 * 4, /* %ebx */ 321 -1, /* %esp */ 322 6 * 4, /* %ebp */ 323 5 * 4, /* %esi */ 324 4 * 4, /* %edi */ 325 13 * 4, /* %eip */ 326 15 * 4, /* %eflags */ 327 14 * 4, /* %cs */ 328 -1, /* %ss */ 329 3 * 4, /* %ds */ 330 2 * 4, /* %es */ 331 0 * 4, /* %fs */ 332 1 * 4 /* %gs */ 333 }; 334 335 static struct trad_frame_cache * 336 i386obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache) 337 { 338 struct trad_frame_cache *cache; 339 CORE_ADDR func, sp, addr; 340 ULONGEST cs; 341 char *name; 342 int i; 343 344 if (*this_cache) 345 return *this_cache; 346 347 cache = trad_frame_cache_zalloc (next_frame); 348 *this_cache = cache; 349 350 func = frame_func_unwind (next_frame); 351 sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM); 352 353 find_pc_partial_function (func, &name, NULL, NULL); 354 if (name && strncmp (name, "Xintr", 5) == 0) 355 addr = sp + 8; /* It's an interrupt frame. */ 356 else 357 addr = sp; 358 359 for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++) 360 if (i386obsd_tf_reg_offset[i] != -1) 361 trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]); 362 363 /* Read %cs from trap frame. */ 364 addr += i386obsd_tf_reg_offset[I386_CS_REGNUM]; 365 cs = read_memory_unsigned_integer (addr, 4); 366 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 367 { 368 /* Trap from user space; terminate backtrace. */ 369 trad_frame_set_id (cache, null_frame_id); 370 } 371 else 372 { 373 /* Construct the frame ID using the function start. */ 374 trad_frame_set_id (cache, frame_id_build (sp + 8, func)); 375 } 376 377 return cache; 378 } 379 380 static void 381 i386obsd_trapframe_this_id (struct frame_info *next_frame, 382 void **this_cache, struct frame_id *this_id) 383 { 384 struct trad_frame_cache *cache = 385 i386obsd_trapframe_cache (next_frame, this_cache); 386 387 trad_frame_get_id (cache, this_id); 388 } 389 390 static void 391 i386obsd_trapframe_prev_register (struct frame_info *next_frame, 392 void **this_cache, int regnum, 393 int *optimizedp, enum lval_type *lvalp, 394 CORE_ADDR *addrp, int *realnump, 395 void *valuep) 396 { 397 struct trad_frame_cache *cache = 398 i386obsd_trapframe_cache (next_frame, this_cache); 399 400 trad_frame_get_register (cache, next_frame, regnum, 401 optimizedp, lvalp, addrp, realnump, valuep); 402 } 403 404 static int 405 i386obsd_trapframe_sniffer (const struct frame_unwind *self, 406 struct frame_info *next_frame, 407 void **this_prologue_cache) 408 { 409 ULONGEST cs; 410 char *name; 411 412 /* Check Current Privilege Level and bail out if we're not executing 413 in kernel space. */ 414 cs = frame_unwind_register_unsigned (next_frame, I386_CS_REGNUM); 415 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 416 return 0; 417 418 find_pc_partial_function (frame_pc_unwind (next_frame), &name, NULL, NULL); 419 return (name && (strcmp (name, "calltrap") == 0 420 || strcmp (name, "syscall1") == 0 421 || strncmp (name, "Xintr", 5) == 0 422 || strncmp (name, "Xsoft", 5) == 0)); 423 } 424 425 static const struct frame_unwind i386obsd_trapframe_unwind = { 426 /* FIXME: kettenis/20051219: This really is more like an interrupt 427 frame, but SIGTRAMP_FRAME would print <signal handler called>, 428 which really is not what we want here. */ 429 NORMAL_FRAME, 430 i386obsd_trapframe_this_id, 431 i386obsd_trapframe_prev_register, 432 NULL, 433 i386obsd_trapframe_sniffer 434 }; 435 436 437 static void 438 i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 439 { 440 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 441 442 /* Obviously OpenBSD is BSD-based. */ 443 i386bsd_init_abi (info, gdbarch); 444 445 /* OpenBSD has a different `struct reg'. */ 446 tdep->gregset_reg_offset = i386obsd_r_reg_offset; 447 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset); 448 tdep->sizeof_gregset = 16 * 4; 449 450 /* OpenBSD uses -freg-struct-return by default. */ 451 tdep->struct_return = reg_struct_return; 452 453 /* OpenBSD uses a different memory layout. */ 454 tdep->sigtramp_start = i386obsd_sigtramp_start_addr; 455 tdep->sigtramp_end = i386obsd_sigtramp_end_addr; 456 tdep->sigtramp_p = i386obsd_sigtramp_p; 457 458 /* OpenBSD has a `struct sigcontext' that's different from the 459 original 4.3 BSD. */ 460 tdep->sc_reg_offset = i386obsd_sc_reg_offset; 461 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset); 462 463 /* OpenBSD provides a user-level threads implementation. */ 464 bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread); 465 bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread); 466 467 /* Unwind kernel trap frames correctly. */ 468 frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); 469 } 470 471 /* OpenBSD a.out. */ 472 473 static void 474 i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 475 { 476 i386obsd_init_abi (info, gdbarch); 477 478 /* OpenBSD a.out has a single register set. */ 479 set_gdbarch_regset_from_core_section 480 (gdbarch, i386obsd_aout_regset_from_core_section); 481 } 482 483 /* OpenBSD ELF. */ 484 485 static void 486 i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 487 { 488 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 489 490 /* It's still OpenBSD. */ 491 i386obsd_init_abi (info, gdbarch); 492 493 /* But ELF-based. */ 494 i386_elf_init_abi (info, gdbarch); 495 496 /* OpenBSD ELF uses SVR4-style shared libraries. */ 497 set_gdbarch_in_solib_call_trampoline 498 (gdbarch, generic_in_solib_call_trampoline); 499 set_solib_svr4_fetch_link_map_offsets 500 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 501 } 502 503 504 /* Provide a prototype to silence -Wmissing-prototypes. */ 505 void _initialize_i386obsd_tdep (void); 506 507 void 508 _initialize_i386obsd_tdep (void) 509 { 510 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are 511 indistingushable from NetBSD/i386 a.out binaries, building a GDB 512 that should support both these targets will probably not work as 513 expected. */ 514 #define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT 515 516 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT, 517 i386obsd_aout_init_abi); 518 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF, 519 i386obsd_elf_init_abi); 520 } 521