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 int ctx_offset) 227 { 228 CORE_ADDR sp_addr = addr + ctx_offset; 229 CORE_ADDR sp = 0; 230 char buf[4]; 231 int i; 232 233 gdb_assert (regnum >= -1); 234 235 /* if ctx_offset is 0 use old fixed offset */ 236 if (ctx_offset == 0) 237 sp_addr += I386OBSD_UTHREAD_ESP_OFFSET; 238 239 if (regnum == -1 || regnum == I386_ESP_REGNUM) 240 { 241 int offset; 242 243 /* Fetch stack pointer from thread structure. */ 244 sp = read_memory_unsigned_integer (sp_addr, 4); 245 246 /* Adjust the stack pointer such that it looks as if we just 247 returned from _thread_machdep_switch. */ 248 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 249 store_unsigned_integer (buf, 4, sp + offset); 250 regcache_raw_supply (regcache, I386_ESP_REGNUM, buf); 251 } 252 253 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 254 { 255 if (i386obsd_uthread_reg_offset[i] != -1 256 && (regnum == -1 || regnum == i)) 257 { 258 /* Fetch stack pointer from thread structure (if we didn't 259 do so already). */ 260 if (sp == 0) 261 sp = read_memory_unsigned_integer (sp_addr, 4); 262 263 /* Read the saved register from the stack frame. */ 264 read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 265 regcache_raw_supply (regcache, i, buf); 266 } 267 } 268 } 269 270 static void 271 i386obsd_collect_uthread (const struct regcache *regcache, 272 int regnum, CORE_ADDR addr, 273 int ctx_offset) 274 { 275 CORE_ADDR sp_addr = addr + ctx_offset; 276 CORE_ADDR sp = 0; 277 char buf[4]; 278 int i; 279 280 gdb_assert (regnum >= -1); 281 282 /* if ctx_offset is 0 use old fixed offset */ 283 if (ctx_offset == 0) 284 sp_addr += I386OBSD_UTHREAD_ESP_OFFSET; 285 286 if (regnum == -1 || regnum == I386_ESP_REGNUM) 287 { 288 int offset; 289 290 /* Calculate the stack pointer (frame pointer) that will be 291 stored into the thread structure. */ 292 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 293 regcache_raw_collect (regcache, I386_ESP_REGNUM, buf); 294 sp = extract_unsigned_integer (buf, 4) - offset; 295 296 /* Store the stack pointer. */ 297 write_memory_unsigned_integer (sp_addr, 4, sp); 298 299 /* The stack pointer was (potentially) modified. Make sure we 300 build a proper stack frame. */ 301 regnum = -1; 302 } 303 304 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 305 { 306 if (i386obsd_uthread_reg_offset[i] != -1 307 && (regnum == -1 || regnum == i)) 308 { 309 /* Fetch stack pointer from thread structure (if we didn't 310 calculate it already). */ 311 if (sp == 0) 312 sp = read_memory_unsigned_integer (sp_addr, 4); 313 314 /* Write the register into the stack frame. */ 315 regcache_raw_collect (regcache, i, buf); 316 write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 317 } 318 } 319 } 320 321 /* Kernel debugging support. */ 322 323 /* From <machine/frame.h>. Note that %esp and %ess are only saved in 324 a trap frame when entering the kernel from user space. */ 325 static int i386obsd_tf_reg_offset[] = 326 { 327 10 * 4, /* %eax */ 328 9 * 4, /* %ecx */ 329 8 * 4, /* %edx */ 330 7 * 4, /* %ebx */ 331 -1, /* %esp */ 332 6 * 4, /* %ebp */ 333 5 * 4, /* %esi */ 334 4 * 4, /* %edi */ 335 13 * 4, /* %eip */ 336 15 * 4, /* %eflags */ 337 14 * 4, /* %cs */ 338 -1, /* %ss */ 339 3 * 4, /* %ds */ 340 2 * 4, /* %es */ 341 0 * 4, /* %fs */ 342 1 * 4 /* %gs */ 343 }; 344 345 static struct trad_frame_cache * 346 i386obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache) 347 { 348 struct trad_frame_cache *cache; 349 CORE_ADDR func, sp, addr; 350 ULONGEST cs; 351 char *name; 352 int i; 353 354 if (*this_cache) 355 return *this_cache; 356 357 cache = trad_frame_cache_zalloc (next_frame); 358 *this_cache = cache; 359 360 func = frame_func_unwind (next_frame); 361 sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM); 362 363 find_pc_partial_function (func, &name, NULL, NULL); 364 if (name && (strncmp (name, "Xintr", 5) == 0 365 || strncmp (name, "Xresume", 7) == 0 366 || strncmp (name, "Xstray", 6) == 0 367 || strncmp (name, "Xhold", 5) == 0 368 || strncmp (name, "Xrecurse", 8) == 0 369 || strcmp (name, "Xdoreti") == 0 370 || strncmp (name, "Xsoft", 5) == 0)) 371 addr = sp + 8; /* It's an interrupt frame. */ 372 else if (name && strcmp (name, "alltraps") == 0) 373 addr = sp + 4; /* It's a trap frame. */ 374 else if (name && strcmp (name, "calltrap") == 0) 375 addr = sp + 4; /* It's a trap frame with debug symbols. */ 376 else 377 addr = sp; 378 379 for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++) 380 if (i386obsd_tf_reg_offset[i] != -1) 381 trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]); 382 383 /* Read %cs from trap frame. */ 384 addr += i386obsd_tf_reg_offset[I386_CS_REGNUM]; 385 cs = read_memory_unsigned_integer (addr, 4); 386 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 387 { 388 /* Trap from user space; terminate backtrace. */ 389 trad_frame_set_id (cache, null_frame_id); 390 } 391 else 392 { 393 /* Construct the frame ID using the function start. */ 394 trad_frame_set_id (cache, frame_id_build (sp + 8, func)); 395 } 396 397 return cache; 398 } 399 400 static void 401 i386obsd_trapframe_this_id (struct frame_info *next_frame, 402 void **this_cache, struct frame_id *this_id) 403 { 404 struct trad_frame_cache *cache = 405 i386obsd_trapframe_cache (next_frame, this_cache); 406 407 trad_frame_get_id (cache, this_id); 408 } 409 410 static void 411 i386obsd_trapframe_prev_register (struct frame_info *next_frame, 412 void **this_cache, int regnum, 413 int *optimizedp, enum lval_type *lvalp, 414 CORE_ADDR *addrp, int *realnump, 415 void *valuep) 416 { 417 struct trad_frame_cache *cache = 418 i386obsd_trapframe_cache (next_frame, this_cache); 419 420 trad_frame_get_register (cache, next_frame, regnum, 421 optimizedp, lvalp, addrp, realnump, valuep); 422 } 423 424 static int 425 i386obsd_trapframe_sniffer (const struct frame_unwind *self, 426 struct frame_info *next_frame, 427 void **this_prologue_cache) 428 { 429 ULONGEST cs; 430 char *name; 431 432 /* Check Current Privilege Level and bail out if we're not executing 433 in kernel space. */ 434 cs = frame_unwind_register_unsigned (next_frame, I386_CS_REGNUM); 435 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 436 return 0; 437 438 find_pc_partial_function (frame_pc_unwind (next_frame), &name, NULL, NULL); 439 return (name && (strcmp (name, "calltrap") == 0 440 || strcmp (name, "alltraps") == 0 441 || strncmp (name, "Xintr", 5) == 0 442 || strncmp (name, "Xresume", 7) == 0 443 || strncmp (name, "Xstray", 6) == 0 444 || strncmp (name, "Xhold", 5) == 0 445 || strncmp (name, "Xrecurse", 8) == 0 446 || strcmp (name, "Xdoreti") == 0 447 || strncmp (name, "Xsoft", 5) == 0)); 448 } 449 450 static const struct frame_unwind i386obsd_trapframe_unwind = { 451 /* FIXME: kettenis/20051219: This really is more like an interrupt 452 frame, but SIGTRAMP_FRAME would print <signal handler called>, 453 which really is not what we want here. */ 454 NORMAL_FRAME, 455 i386obsd_trapframe_this_id, 456 i386obsd_trapframe_prev_register, 457 NULL, 458 i386obsd_trapframe_sniffer 459 }; 460 461 462 static void 463 i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 464 { 465 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 466 467 /* Obviously OpenBSD is BSD-based. */ 468 i386bsd_init_abi (info, gdbarch); 469 470 /* OpenBSD has a different `struct reg'. */ 471 tdep->gregset_reg_offset = i386obsd_r_reg_offset; 472 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset); 473 tdep->sizeof_gregset = 16 * 4; 474 475 /* OpenBSD uses -freg-struct-return by default. */ 476 tdep->struct_return = reg_struct_return; 477 478 /* OpenBSD uses a different memory layout. */ 479 tdep->sigtramp_start = i386obsd_sigtramp_start_addr; 480 tdep->sigtramp_end = i386obsd_sigtramp_end_addr; 481 tdep->sigtramp_p = i386obsd_sigtramp_p; 482 483 /* OpenBSD has a `struct sigcontext' that's different from the 484 original 4.3 BSD. */ 485 tdep->sc_reg_offset = i386obsd_sc_reg_offset; 486 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset); 487 488 /* OpenBSD provides a user-level threads implementation. */ 489 bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread); 490 bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread); 491 492 /* Unwind kernel trap frames correctly. */ 493 frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); 494 } 495 496 /* OpenBSD a.out. */ 497 498 static void 499 i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 500 { 501 i386obsd_init_abi (info, gdbarch); 502 503 /* OpenBSD a.out has a single register set. */ 504 set_gdbarch_regset_from_core_section 505 (gdbarch, i386obsd_aout_regset_from_core_section); 506 } 507 508 /* OpenBSD ELF. */ 509 510 static void 511 i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 512 { 513 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 514 515 /* It's still OpenBSD. */ 516 i386obsd_init_abi (info, gdbarch); 517 518 /* But ELF-based. */ 519 i386_elf_init_abi (info, gdbarch); 520 521 /* OpenBSD ELF uses SVR4-style shared libraries. */ 522 set_gdbarch_in_solib_call_trampoline 523 (gdbarch, generic_in_solib_call_trampoline); 524 set_solib_svr4_fetch_link_map_offsets 525 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 526 } 527 528 529 /* Provide a prototype to silence -Wmissing-prototypes. */ 530 void _initialize_i386obsd_tdep (void); 531 532 void 533 _initialize_i386obsd_tdep (void) 534 { 535 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are 536 indistingushable from NetBSD/i386 a.out binaries, building a GDB 537 that should support both these targets will probably not work as 538 expected. */ 539 #define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT 540 541 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT, 542 i386obsd_aout_init_abi); 543 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF, 544 i386obsd_elf_init_abi); 545 } 546