GDB (API)
|
00001 /* Target-dependent code for OpenBSD/i386. 00002 00003 Copyright (C) 1988-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "arch-utils.h" 00022 #include "frame.h" 00023 #include "frame-unwind.h" 00024 #include "gdbcore.h" 00025 #include "regcache.h" 00026 #include "regset.h" 00027 #include "symtab.h" 00028 #include "objfiles.h" 00029 #include "osabi.h" 00030 #include "target.h" 00031 #include "trad-frame.h" 00032 00033 #include "gdb_assert.h" 00034 #include "gdb_string.h" 00035 00036 #include "i386-tdep.h" 00037 #include "i387-tdep.h" 00038 #include "solib-svr4.h" 00039 #include "bsd-uthread.h" 00040 00041 /* Support for signal handlers. */ 00042 00043 /* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page 00044 in virtual memory. The randomness makes it somewhat tricky to 00045 detect it, but fortunately we can rely on the fact that the start 00046 of the sigtramp routine is page-aligned. We recognize the 00047 trampoline by looking for the code that invokes the sigreturn 00048 system call. The offset where we can find that code varies from 00049 release to release. 00050 00051 By the way, the mapping mentioned above is read-only, so you cannot 00052 place a breakpoint in the signal trampoline. */ 00053 00054 /* Default page size. */ 00055 static const int i386obsd_page_size = 4096; 00056 00057 /* Offset for sigreturn(2). */ 00058 static const int i386obsd_sigreturn_offset[] = { 00059 0x0a, /* OpenBSD 3.2 */ 00060 0x14, /* OpenBSD 3.6 */ 00061 0x3a, /* OpenBSD 3.8 */ 00062 -1 00063 }; 00064 00065 /* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp 00066 routine. */ 00067 00068 static int 00069 i386obsd_sigtramp_p (struct frame_info *this_frame) 00070 { 00071 CORE_ADDR pc = get_frame_pc (this_frame); 00072 CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1)); 00073 /* The call sequence invoking sigreturn(2). */ 00074 const gdb_byte sigreturn[] = 00075 { 00076 0xb8, 00077 0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */ 00078 0xcd, 0x80 /* int $0x80 */ 00079 }; 00080 size_t buflen = sizeof sigreturn; 00081 const int *offset; 00082 gdb_byte *buf; 00083 const char *name; 00084 00085 /* If the function has a valid symbol name, it isn't a 00086 trampoline. */ 00087 find_pc_partial_function (pc, &name, NULL, NULL); 00088 if (name != NULL) 00089 return 0; 00090 00091 /* If the function lives in a valid section (even without a starting 00092 point) it isn't a trampoline. */ 00093 if (find_pc_section (pc) != NULL) 00094 return 0; 00095 00096 /* Allocate buffer. */ 00097 buf = alloca (buflen); 00098 00099 /* Loop over all offsets. */ 00100 for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++) 00101 { 00102 /* If we can't read the instructions, return zero. */ 00103 if (!safe_frame_unwind_memory (this_frame, start_pc + *offset, 00104 buf, buflen)) 00105 return 0; 00106 00107 /* Check for sigreturn(2). */ 00108 if (memcmp (buf, sigreturn, buflen) == 0) 00109 return 1; 00110 } 00111 00112 return 0; 00113 } 00114 00115 /* Mapping between the general-purpose registers in `struct reg' 00116 format and GDB's register cache layout. */ 00117 00118 /* From <machine/reg.h>. */ 00119 static int i386obsd_r_reg_offset[] = 00120 { 00121 0 * 4, /* %eax */ 00122 1 * 4, /* %ecx */ 00123 2 * 4, /* %edx */ 00124 3 * 4, /* %ebx */ 00125 4 * 4, /* %esp */ 00126 5 * 4, /* %ebp */ 00127 6 * 4, /* %esi */ 00128 7 * 4, /* %edi */ 00129 8 * 4, /* %eip */ 00130 9 * 4, /* %eflags */ 00131 10 * 4, /* %cs */ 00132 11 * 4, /* %ss */ 00133 12 * 4, /* %ds */ 00134 13 * 4, /* %es */ 00135 14 * 4, /* %fs */ 00136 15 * 4 /* %gs */ 00137 }; 00138 00139 static void 00140 i386obsd_aout_supply_regset (const struct regset *regset, 00141 struct regcache *regcache, int regnum, 00142 const void *regs, size_t len) 00143 { 00144 const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); 00145 const gdb_byte *gregs = regs; 00146 00147 gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE); 00148 00149 i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset); 00150 i387_supply_fsave (regcache, regnum, gregs + tdep->sizeof_gregset); 00151 } 00152 00153 static const struct regset * 00154 i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch, 00155 const char *sect_name, 00156 size_t sect_size) 00157 { 00158 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00159 00160 /* OpenBSD a.out core dumps don't use seperate register sets for the 00161 general-purpose and floating-point registers. */ 00162 00163 if (strcmp (sect_name, ".reg") == 0 00164 && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE) 00165 { 00166 if (tdep->gregset == NULL) 00167 tdep->gregset = 00168 regset_alloc (gdbarch, i386obsd_aout_supply_regset, NULL); 00169 return tdep->gregset; 00170 } 00171 00172 return NULL; 00173 } 00174 00175 00176 /* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */ 00177 CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20; 00178 CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0; 00179 00180 /* From <machine/signal.h>. */ 00181 int i386obsd_sc_reg_offset[I386_NUM_GREGS] = 00182 { 00183 10 * 4, /* %eax */ 00184 9 * 4, /* %ecx */ 00185 8 * 4, /* %edx */ 00186 7 * 4, /* %ebx */ 00187 14 * 4, /* %esp */ 00188 6 * 4, /* %ebp */ 00189 5 * 4, /* %esi */ 00190 4 * 4, /* %edi */ 00191 11 * 4, /* %eip */ 00192 13 * 4, /* %eflags */ 00193 12 * 4, /* %cs */ 00194 15 * 4, /* %ss */ 00195 3 * 4, /* %ds */ 00196 2 * 4, /* %es */ 00197 1 * 4, /* %fs */ 00198 0 * 4 /* %gs */ 00199 }; 00200 00201 /* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */ 00202 static int i386obsd_uthread_reg_offset[] = 00203 { 00204 11 * 4, /* %eax */ 00205 10 * 4, /* %ecx */ 00206 9 * 4, /* %edx */ 00207 8 * 4, /* %ebx */ 00208 -1, /* %esp */ 00209 6 * 4, /* %ebp */ 00210 5 * 4, /* %esi */ 00211 4 * 4, /* %edi */ 00212 12 * 4, /* %eip */ 00213 -1, /* %eflags */ 00214 13 * 4, /* %cs */ 00215 -1, /* %ss */ 00216 3 * 4, /* %ds */ 00217 2 * 4, /* %es */ 00218 1 * 4, /* %fs */ 00219 0 * 4 /* %gs */ 00220 }; 00221 00222 /* Offset within the thread structure where we can find the saved 00223 stack pointer (%esp). */ 00224 #define I386OBSD_UTHREAD_ESP_OFFSET 176 00225 00226 static void 00227 i386obsd_supply_uthread (struct regcache *regcache, 00228 int regnum, CORE_ADDR addr) 00229 { 00230 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00231 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00232 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET; 00233 CORE_ADDR sp = 0; 00234 gdb_byte buf[4]; 00235 int i; 00236 00237 gdb_assert (regnum >= -1); 00238 00239 if (regnum == -1 || regnum == I386_ESP_REGNUM) 00240 { 00241 int offset; 00242 00243 /* Fetch stack pointer from thread structure. */ 00244 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order); 00245 00246 /* Adjust the stack pointer such that it looks as if we just 00247 returned from _thread_machdep_switch. */ 00248 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 00249 store_unsigned_integer (buf, 4, byte_order, sp + offset); 00250 regcache_raw_supply (regcache, I386_ESP_REGNUM, buf); 00251 } 00252 00253 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 00254 { 00255 if (i386obsd_uthread_reg_offset[i] != -1 00256 && (regnum == -1 || regnum == i)) 00257 { 00258 /* Fetch stack pointer from thread structure (if we didn't 00259 do so already). */ 00260 if (sp == 0) 00261 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order); 00262 00263 /* Read the saved register from the stack frame. */ 00264 read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 00265 regcache_raw_supply (regcache, i, buf); 00266 } 00267 } 00268 } 00269 00270 static void 00271 i386obsd_collect_uthread (const struct regcache *regcache, 00272 int regnum, CORE_ADDR addr) 00273 { 00274 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00275 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00276 CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET; 00277 CORE_ADDR sp = 0; 00278 gdb_byte buf[4]; 00279 int i; 00280 00281 gdb_assert (regnum >= -1); 00282 00283 if (regnum == -1 || regnum == I386_ESP_REGNUM) 00284 { 00285 int offset; 00286 00287 /* Calculate the stack pointer (frame pointer) that will be 00288 stored into the thread structure. */ 00289 offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4; 00290 regcache_raw_collect (regcache, I386_ESP_REGNUM, buf); 00291 sp = extract_unsigned_integer (buf, 4, byte_order) - offset; 00292 00293 /* Store the stack pointer. */ 00294 write_memory_unsigned_integer (sp_addr, 4, byte_order, sp); 00295 00296 /* The stack pointer was (potentially) modified. Make sure we 00297 build a proper stack frame. */ 00298 regnum = -1; 00299 } 00300 00301 for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++) 00302 { 00303 if (i386obsd_uthread_reg_offset[i] != -1 00304 && (regnum == -1 || regnum == i)) 00305 { 00306 /* Fetch stack pointer from thread structure (if we didn't 00307 calculate it already). */ 00308 if (sp == 0) 00309 sp = read_memory_unsigned_integer (sp_addr, 4, byte_order); 00310 00311 /* Write the register into the stack frame. */ 00312 regcache_raw_collect (regcache, i, buf); 00313 write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4); 00314 } 00315 } 00316 } 00317 00318 /* Kernel debugging support. */ 00319 00320 /* From <machine/frame.h>. Note that %esp and %ess are only saved in 00321 a trap frame when entering the kernel from user space. */ 00322 static int i386obsd_tf_reg_offset[] = 00323 { 00324 10 * 4, /* %eax */ 00325 9 * 4, /* %ecx */ 00326 8 * 4, /* %edx */ 00327 7 * 4, /* %ebx */ 00328 -1, /* %esp */ 00329 6 * 4, /* %ebp */ 00330 5 * 4, /* %esi */ 00331 4 * 4, /* %edi */ 00332 13 * 4, /* %eip */ 00333 15 * 4, /* %eflags */ 00334 14 * 4, /* %cs */ 00335 -1, /* %ss */ 00336 3 * 4, /* %ds */ 00337 2 * 4, /* %es */ 00338 0 * 4, /* %fs */ 00339 1 * 4 /* %gs */ 00340 }; 00341 00342 static struct trad_frame_cache * 00343 i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) 00344 { 00345 struct gdbarch *gdbarch = get_frame_arch (this_frame); 00346 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00347 struct trad_frame_cache *cache; 00348 CORE_ADDR func, sp, addr; 00349 ULONGEST cs; 00350 const char *name; 00351 int i; 00352 00353 if (*this_cache) 00354 return *this_cache; 00355 00356 cache = trad_frame_cache_zalloc (this_frame); 00357 *this_cache = cache; 00358 00359 func = get_frame_func (this_frame); 00360 sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); 00361 00362 find_pc_partial_function (func, &name, NULL, NULL); 00363 if (name && strncmp (name, "Xintr", 5) == 0) 00364 addr = sp + 8; /* It's an interrupt frame. */ 00365 else 00366 addr = sp; 00367 00368 for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++) 00369 if (i386obsd_tf_reg_offset[i] != -1) 00370 trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]); 00371 00372 /* Read %cs from trap frame. */ 00373 addr += i386obsd_tf_reg_offset[I386_CS_REGNUM]; 00374 cs = read_memory_unsigned_integer (addr, 4, byte_order); 00375 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 00376 { 00377 /* Trap from user space; terminate backtrace. */ 00378 trad_frame_set_id (cache, outer_frame_id); 00379 } 00380 else 00381 { 00382 /* Construct the frame ID using the function start. */ 00383 trad_frame_set_id (cache, frame_id_build (sp + 8, func)); 00384 } 00385 00386 return cache; 00387 } 00388 00389 static void 00390 i386obsd_trapframe_this_id (struct frame_info *this_frame, 00391 void **this_cache, struct frame_id *this_id) 00392 { 00393 struct trad_frame_cache *cache = 00394 i386obsd_trapframe_cache (this_frame, this_cache); 00395 00396 trad_frame_get_id (cache, this_id); 00397 } 00398 00399 static struct value * 00400 i386obsd_trapframe_prev_register (struct frame_info *this_frame, 00401 void **this_cache, int regnum) 00402 { 00403 struct trad_frame_cache *cache = 00404 i386obsd_trapframe_cache (this_frame, this_cache); 00405 00406 return trad_frame_get_register (cache, this_frame, regnum); 00407 } 00408 00409 static int 00410 i386obsd_trapframe_sniffer (const struct frame_unwind *self, 00411 struct frame_info *this_frame, 00412 void **this_prologue_cache) 00413 { 00414 ULONGEST cs; 00415 const char *name; 00416 00417 /* Check Current Privilege Level and bail out if we're not executing 00418 in kernel space. */ 00419 cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM); 00420 if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 00421 return 0; 00422 00423 find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL); 00424 return (name && (strcmp (name, "calltrap") == 0 00425 || strcmp (name, "syscall1") == 0 00426 || strncmp (name, "Xintr", 5) == 0 00427 || strncmp (name, "Xsoft", 5) == 0)); 00428 } 00429 00430 static const struct frame_unwind i386obsd_trapframe_unwind = { 00431 /* FIXME: kettenis/20051219: This really is more like an interrupt 00432 frame, but SIGTRAMP_FRAME would print <signal handler called>, 00433 which really is not what we want here. */ 00434 NORMAL_FRAME, 00435 default_frame_unwind_stop_reason, 00436 i386obsd_trapframe_this_id, 00437 i386obsd_trapframe_prev_register, 00438 NULL, 00439 i386obsd_trapframe_sniffer 00440 }; 00441 00442 00443 static void 00444 i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00445 { 00446 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00447 00448 /* Obviously OpenBSD is BSD-based. */ 00449 i386bsd_init_abi (info, gdbarch); 00450 00451 /* OpenBSD has a different `struct reg'. */ 00452 tdep->gregset_reg_offset = i386obsd_r_reg_offset; 00453 tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset); 00454 tdep->sizeof_gregset = 16 * 4; 00455 00456 /* OpenBSD uses -freg-struct-return by default. */ 00457 tdep->struct_return = reg_struct_return; 00458 00459 /* OpenBSD uses a different memory layout. */ 00460 tdep->sigtramp_start = i386obsd_sigtramp_start_addr; 00461 tdep->sigtramp_end = i386obsd_sigtramp_end_addr; 00462 tdep->sigtramp_p = i386obsd_sigtramp_p; 00463 00464 /* OpenBSD has a `struct sigcontext' that's different from the 00465 original 4.3 BSD. */ 00466 tdep->sc_reg_offset = i386obsd_sc_reg_offset; 00467 tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset); 00468 00469 /* OpenBSD provides a user-level threads implementation. */ 00470 bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread); 00471 bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread); 00472 00473 /* Unwind kernel trap frames correctly. */ 00474 frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); 00475 } 00476 00477 /* OpenBSD a.out. */ 00478 00479 static void 00480 i386obsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00481 { 00482 i386obsd_init_abi (info, gdbarch); 00483 00484 /* OpenBSD a.out has a single register set. */ 00485 set_gdbarch_regset_from_core_section 00486 (gdbarch, i386obsd_aout_regset_from_core_section); 00487 } 00488 00489 /* OpenBSD ELF. */ 00490 00491 static void 00492 i386obsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00493 { 00494 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00495 00496 /* It's still OpenBSD. */ 00497 i386obsd_init_abi (info, gdbarch); 00498 00499 /* But ELF-based. */ 00500 i386_elf_init_abi (info, gdbarch); 00501 00502 /* OpenBSD ELF uses SVR4-style shared libraries. */ 00503 set_solib_svr4_fetch_link_map_offsets 00504 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 00505 } 00506 00507 00508 /* Provide a prototype to silence -Wmissing-prototypes. */ 00509 void _initialize_i386obsd_tdep (void); 00510 00511 void 00512 _initialize_i386obsd_tdep (void) 00513 { 00514 /* FIXME: kettenis/20021020: Since OpenBSD/i386 binaries are 00515 indistingushable from NetBSD/i386 a.out binaries, building a GDB 00516 that should support both these targets will probably not work as 00517 expected. */ 00518 #define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT 00519 00520 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_AOUT, 00521 i386obsd_aout_init_abi); 00522 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD_ELF, 00523 i386obsd_elf_init_abi); 00524 }