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 addr = sp + 8; /* It's an interrupt frame. */ 366 else 367 addr = sp; 368 369 for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++) 370 if (i386obsd_tf_reg_offset[i] != -1) 371 trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]); 372 373 /* Read %cs from trap frame. */ 374 addr += i386obsd_tf_reg_offset[I386_CS_REGNUM]; 375 cs = read_memory_unsigned_integer (addr, 4); 376 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 377 { 378 /* Trap from user space; terminate backtrace. */ 379 trad_frame_set_id (cache, null_frame_id); 380 } 381 else 382 { 383 /* Construct the frame ID using the function start. */ 384 trad_frame_set_id (cache, frame_id_build (sp + 8, func)); 385 } 386 387 return cache; 388 } 389 390 static void 391 i386obsd_trapframe_this_id (struct frame_info *next_frame, 392 void **this_cache, struct frame_id *this_id) 393 { 394 struct trad_frame_cache *cache = 395 i386obsd_trapframe_cache (next_frame, this_cache); 396 397 trad_frame_get_id (cache, this_id); 398 } 399 400 static void 401 i386obsd_trapframe_prev_register (struct frame_info *next_frame, 402 void **this_cache, int regnum, 403 int *optimizedp, enum lval_type *lvalp, 404 CORE_ADDR *addrp, int *realnump, 405 void *valuep) 406 { 407 struct trad_frame_cache *cache = 408 i386obsd_trapframe_cache (next_frame, this_cache); 409 410 trad_frame_get_register (cache, next_frame, regnum, 411 optimizedp, lvalp, addrp, realnump, valuep); 412 } 413 414 static int 415 i386obsd_trapframe_sniffer (const struct frame_unwind *self, 416 struct frame_info *next_frame, 417 void **this_prologue_cache) 418 { 419 ULONGEST cs; 420 char *name; 421 422 /* Check Current Privilege Level and bail out if we're not executing 423 in kernel space. */ 424 cs = frame_unwind_register_unsigned (next_frame, I386_CS_REGNUM); 425 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 426 return 0; 427 428 find_pc_partial_function (frame_pc_unwind (next_frame), &name, NULL, NULL); 429 return (name && (strcmp (name, "calltrap") == 0 430 || strcmp (name, "syscall1") == 0 431 || strncmp (name, "Xintr", 5) == 0 432 || strncmp (name, "Xsoft", 5) == 0)); 433 } 434 435 static const struct frame_unwind i386obsd_trapframe_unwind = { 436 /* FIXME: kettenis/20051219: This really is more like an interrupt 437 frame, but SIGTRAMP_FRAME would print <signal handler called>, 438 which really is not what we want here. */ 439 NORMAL_FRAME, 440 i386obsd_trapframe_this_id, 441 i386obsd_trapframe_prev_register, 442 NULL, 443 i386obsd_trapframe_sniffer 444 }; 445 446 447 static void 448 i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 449 { 450 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 451 452 /* Obviously OpenBSD is BSD-based. */ 453 i386bsd_init_abi (info, gdbarch); 454 455 /* OpenBSD has a different `struct reg'. */ 456 tdep->gregset_reg_offset = i386obsd_r_reg_offset; 457 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset); 458 tdep->sizeof_gregset = 16 * 4; 459 460 /* OpenBSD uses -freg-struct-return by default. */ 461 tdep->struct_return = reg_struct_return; 462 463 /* OpenBSD uses a different memory layout. */ 464 tdep->sigtramp_start = i386obsd_sigtramp_start_addr; 465 tdep->sigtramp_end = i386obsd_sigtramp_end_addr; 466 tdep->sigtramp_p = i386obsd_sigtramp_p; 467 468 /* OpenBSD has a `struct sigcontext' that's different from the 469 original 4.3 BSD. */ 470 tdep->sc_reg_offset = i386obsd_sc_reg_offset; 471 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset); 472 473 /* OpenBSD provides a user-level threads implementation. */ 474 bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread); 475 bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread); 476 477 /* Unwind kernel trap frames correctly. */ 478 frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); 479 } 480 481 /* OpenBSD a.out. */ 482 483 static void 484 i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 485 { 486 i386obsd_init_abi (info, gdbarch); 487 488 /* OpenBSD a.out has a single register set. */ 489 set_gdbarch_regset_from_core_section 490 (gdbarch, i386obsd_aout_regset_from_core_section); 491 } 492 493 /* OpenBSD ELF. */ 494 495 static void 496 i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 497 { 498 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 499 500 /* It's still OpenBSD. */ 501 i386obsd_init_abi (info, gdbarch); 502 503 /* But ELF-based. */ 504 i386_elf_init_abi (info, gdbarch); 505 506 /* OpenBSD ELF uses SVR4-style shared libraries. */ 507 set_gdbarch_in_solib_call_trampoline 508 (gdbarch, generic_in_solib_call_trampoline); 509 set_solib_svr4_fetch_link_map_offsets 510 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 511 } 512 513 514 /* Provide a prototype to silence -Wmissing-prototypes. */ 515 void _initialize_i386obsd_tdep (void); 516 517 void 518 _initialize_i386obsd_tdep (void) 519 { 520 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are 521 indistingushable from NetBSD/i386 a.out binaries, building a GDB 522 that should support both these targets will probably not work as 523 expected. */ 524 #define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT 525 526 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT, 527 i386obsd_aout_init_abi); 528 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF, 529 i386obsd_elf_init_abi); 530 } 531