GDB (xrefs)
/tmp/gdb-8.1/gdb/i386-obsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for OpenBSD/i386.
2 
3  Copyright (C) 1988-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "frame.h"
23 #include "frame-unwind.h"
24 #include "gdbcore.h"
25 #include "regcache.h"
26 #include "regset.h"
27 #include "symtab.h"
28 #include "objfiles.h"
29 #include "osabi.h"
30 #include "target.h"
31 #include "trad-frame.h"
32 
33 #include "obsd-tdep.h"
34 #include "i386-tdep.h"
35 #include "i387-tdep.h"
36 #include "solib-svr4.h"
37 #include "bsd-uthread.h"
38 
39 /* Support for signal handlers. */
40 
41 /* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
42  in virtual memory. The randomness makes it somewhat tricky to
43  detect it, but fortunately we can rely on the fact that the start
44  of the sigtramp routine is page-aligned. We recognize the
45  trampoline by looking for the code that invokes the sigreturn
46  system call. The offset where we can find that code varies from
47  release to release.
48 
49  By the way, the mapping mentioned above is read-only, so you cannot
50  place a breakpoint in the signal trampoline. */
51 
52 /* Default page size. */
53 static const int i386obsd_page_size = 4096;
54 
55 /* Offset for sigreturn(2). */
56 static const int i386obsd_sigreturn_offset[] = {
57  0x0a, /* OpenBSD 3.2 */
58  0x14, /* OpenBSD 3.6 */
59  0x3a, /* OpenBSD 3.8 */
60  -1
61 };
62 
63 /* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
64  routine. */
65 
66 static int
67 i386obsd_sigtramp_p (struct frame_info *this_frame)
68 {
69  CORE_ADDR pc = get_frame_pc (this_frame);
70  CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
71  /* The call sequence invoking sigreturn(2). */
72  const gdb_byte sigreturn[] =
73  {
74  0xb8,
75  0x67, 0x00, 0x00, 0x00, /* movl $SYS_sigreturn, %eax */
76  0xcd, 0x80 /* int $0x80 */
77  };
78  size_t buflen = sizeof sigreturn;
79  const int *offset;
80  gdb_byte *buf;
81  const char *name;
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 = (gdb_byte *) alloca (buflen);
96 
97  /* Loop over all offsets. */
99  {
100  /* If we can't read the instructions, return zero. */
101  if (!safe_frame_unwind_memory (this_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 
138 
139 /* Sigtramp routine location for OpenBSD 3.1 and earlier releases. */
142 
143 /* From <machine/signal.h>. */
145 {
146  10 * 4, /* %eax */
147  9 * 4, /* %ecx */
148  8 * 4, /* %edx */
149  7 * 4, /* %ebx */
150  14 * 4, /* %esp */
151  6 * 4, /* %ebp */
152  5 * 4, /* %esi */
153  4 * 4, /* %edi */
154  11 * 4, /* %eip */
155  13 * 4, /* %eflags */
156  12 * 4, /* %cs */
157  15 * 4, /* %ss */
158  3 * 4, /* %ds */
159  2 * 4, /* %es */
160  1 * 4, /* %fs */
161  0 * 4 /* %gs */
162 };
163 
164 /* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c. */
166 {
167  11 * 4, /* %eax */
168  10 * 4, /* %ecx */
169  9 * 4, /* %edx */
170  8 * 4, /* %ebx */
171  -1, /* %esp */
172  6 * 4, /* %ebp */
173  5 * 4, /* %esi */
174  4 * 4, /* %edi */
175  12 * 4, /* %eip */
176  -1, /* %eflags */
177  13 * 4, /* %cs */
178  -1, /* %ss */
179  3 * 4, /* %ds */
180  2 * 4, /* %es */
181  1 * 4, /* %fs */
182  0 * 4 /* %gs */
183 };
184 
185 /* Offset within the thread structure where we can find the saved
186  stack pointer (%esp). */
187 #define I386OBSD_UTHREAD_ESP_OFFSET 176
188 
189 static void
191  int regnum, CORE_ADDR addr)
192 {
193  struct gdbarch *gdbarch = regcache->arch ();
194  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
195  CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
196  CORE_ADDR sp = 0;
197  gdb_byte buf[4];
198  int i;
199 
200  gdb_assert (regnum >= -1);
201 
202  if (regnum == -1 || regnum == I386_ESP_REGNUM)
203  {
204  int offset;
205 
206  /* Fetch stack pointer from thread structure. */
207  sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
208 
209  /* Adjust the stack pointer such that it looks as if we just
210  returned from _thread_machdep_switch. */
212  store_unsigned_integer (buf, 4, byte_order, sp + offset);
214  }
215 
216  for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
217  {
218  if (i386obsd_uthread_reg_offset[i] != -1
219  && (regnum == -1 || regnum == i))
220  {
221  /* Fetch stack pointer from thread structure (if we didn't
222  do so already). */
223  if (sp == 0)
224  sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
225 
226  /* Read the saved register from the stack frame. */
227  read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
228  regcache_raw_supply (regcache, i, buf);
229  }
230  }
231 }
232 
233 static void
235  int regnum, CORE_ADDR addr)
236 {
237  struct gdbarch *gdbarch = regcache->arch ();
238  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
239  CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
240  CORE_ADDR sp = 0;
241  gdb_byte buf[4];
242  int i;
243 
244  gdb_assert (regnum >= -1);
245 
246  if (regnum == -1 || regnum == I386_ESP_REGNUM)
247  {
248  int offset;
249 
250  /* Calculate the stack pointer (frame pointer) that will be
251  stored into the thread structure. */
254  sp = extract_unsigned_integer (buf, 4, byte_order) - offset;
255 
256  /* Store the stack pointer. */
257  write_memory_unsigned_integer (sp_addr, 4, byte_order, sp);
258 
259  /* The stack pointer was (potentially) modified. Make sure we
260  build a proper stack frame. */
261  regnum = -1;
262  }
263 
264  for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
265  {
266  if (i386obsd_uthread_reg_offset[i] != -1
267  && (regnum == -1 || regnum == i))
268  {
269  /* Fetch stack pointer from thread structure (if we didn't
270  calculate it already). */
271  if (sp == 0)
272  sp = read_memory_unsigned_integer (sp_addr, 4, byte_order);
273 
274  /* Write the register into the stack frame. */
275  regcache_raw_collect (regcache, i, buf);
276  write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
277  }
278  }
279 }
280 
281 /* Kernel debugging support. */
282 
283 /* From <machine/frame.h>. Note that %esp and %ess are only saved in
284  a trap frame when entering the kernel from user space. */
286 {
287  10 * 4, /* %eax */
288  9 * 4, /* %ecx */
289  8 * 4, /* %edx */
290  7 * 4, /* %ebx */
291  -1, /* %esp */
292  6 * 4, /* %ebp */
293  5 * 4, /* %esi */
294  4 * 4, /* %edi */
295  13 * 4, /* %eip */
296  15 * 4, /* %eflags */
297  14 * 4, /* %cs */
298  -1, /* %ss */
299  3 * 4, /* %ds */
300  2 * 4, /* %es */
301  0 * 4, /* %fs */
302  1 * 4 /* %gs */
303 };
304 
305 static struct trad_frame_cache *
306 i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
307 {
308  struct gdbarch *gdbarch = get_frame_arch (this_frame);
309  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
310  struct trad_frame_cache *cache;
311  CORE_ADDR func, sp, addr;
312  ULONGEST cs;
313  const char *name;
314  int i;
315 
316  if (*this_cache)
317  return (struct trad_frame_cache *) *this_cache;
318 
320  *this_cache = cache;
321 
324 
325  find_pc_partial_function (func, &name, NULL, NULL);
326  if (name && startswith (name, "Xintr"))
327  addr = sp + 8; /* It's an interrupt frame. */
328  else
329  addr = sp;
330 
331  for (i = 0; i < ARRAY_SIZE (i386obsd_tf_reg_offset); i++)
332  if (i386obsd_tf_reg_offset[i] != -1)
333  trad_frame_set_reg_addr (cache, i, addr + i386obsd_tf_reg_offset[i]);
334 
335  /* Read %cs from trap frame. */
337  cs = read_memory_unsigned_integer (addr, 4, byte_order);
338  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
339  {
340  /* Trap from user space; terminate backtrace. */
342  }
343  else
344  {
345  /* Construct the frame ID using the function start. */
346  trad_frame_set_id (cache, frame_id_build (sp + 8, func));
347  }
348 
349  return cache;
350 }
351 
352 static void
354  void **this_cache, struct frame_id *this_id)
355 {
356  struct trad_frame_cache *cache =
357  i386obsd_trapframe_cache (this_frame, this_cache);
358 
359  trad_frame_get_id (cache, this_id);
360 }
361 
362 static struct value *
364  void **this_cache, int regnum)
365 {
366  struct trad_frame_cache *cache =
367  i386obsd_trapframe_cache (this_frame, this_cache);
368 
369  return trad_frame_get_register (cache, this_frame, regnum);
370 }
371 
372 static int
374  struct frame_info *this_frame,
375  void **this_prologue_cache)
376 {
377  ULONGEST cs;
378  const char *name;
379 
380  /* Check Current Privilege Level and bail out if we're not executing
381  in kernel space. */
383  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
384  return 0;
385 
387  return (name && (strcmp (name, "calltrap") == 0
388  || strcmp (name, "syscall1") == 0
389  || startswith (name, "Xintr")
390  || startswith (name, "Xsoft")));
391 }
392 
394  /* FIXME: kettenis/20051219: This really is more like an interrupt
395  frame, but SIGTRAMP_FRAME would print <signal handler called>,
396  which really is not what we want here. */
397  NORMAL_FRAME,
401  NULL,
403 };
404 
405 
406 static void
408 {
409  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
410 
411  /* Obviously OpenBSD is BSD-based. */
412  i386bsd_init_abi (info, gdbarch);
413  obsd_init_abi (info, gdbarch);
414  i386_elf_init_abi (info, gdbarch);
415 
416  /* OpenBSD has a different `struct reg'. */
418  tdep->gregset_num_regs = ARRAY_SIZE (i386obsd_r_reg_offset);
419  tdep->sizeof_gregset = 16 * 4;
420 
421  /* OpenBSD uses -freg-struct-return by default. */
423 
424  /* OpenBSD uses a different memory layout. */
428 
429  /* OpenBSD has a `struct sigcontext' that's different from the
430  original 4.3 BSD. */
432  tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
433 
434  /* OpenBSD provides a user-level threads implementation. */
437 
438  /* Unwind kernel trap frames correctly. */
440 
441  /* OpenBSD ELF uses SVR4-style shared libraries. */
444 }
445 
446 void
448 {
449  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD,
451 }
static int i386obsd_uthread_reg_offset[]
#define I386_NUM_GREGS
Definition: i386-tdep.h:332
void trad_frame_set_reg_addr(struct trad_frame_cache *this_trad_cache, int regnum, CORE_ADDR addr)
Definition: trad-frame.c:126
#define I386_SEL_UPL
Definition: i386-tdep.h:381
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:624
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2376
bfd_vma CORE_ADDR
Definition: common-types.h:41
int sc_num_regs
Definition: i386-tdep.h:227
void write_memory_unsigned_integer(CORE_ADDR addr, int len, enum bfd_endian byte_order, ULONGEST value)
Definition: corefile.c:417
void(* func)(char *)
CORE_ADDR sigtramp_start
Definition: i386-tdep.h:216
void trad_frame_set_id(struct trad_frame_cache *this_trad_cache, struct frame_id this_id)
Definition: trad-frame.c:171
CORE_ADDR sigtramp_end
Definition: i386-tdep.h:217
struct m32c_reg * pc
Definition: m32c-tdep.c:116
static const int i386obsd_sigreturn_offset[]
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3183
static int i386obsd_trapframe_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache)
void bsd_uthread_set_collect_uthread(struct gdbarch *gdbarch, void(*collect_uthread)(const struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:81
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1491
void obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: obsd-tdep.c:319
void frame_unwind_prepend_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:64
static const struct frame_unwind i386obsd_trapframe_unwind
void _initialize_i386obsd_tdep(void)
static int i386obsd_tf_reg_offset[]
void trad_frame_get_id(struct trad_frame_cache *this_trad_cache, struct frame_id *this_id)
Definition: trad-frame.c:178
static struct trad_frame_cache * i386obsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
const char *const name
Definition: aarch64-tdep.c:76
static struct value * i386obsd_trapframe_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
int i386obsd_sc_reg_offset[I386_NUM_GREGS]
enum struct_return struct_return
Definition: arm-tdep.h:137
static int i386obsd_r_reg_offset[]
static ULONGEST extract_unsigned_integer(const gdb_byte *addr, int len, enum bfd_endian byte_order)
Definition: defs.h:577
int safe_frame_unwind_memory(struct frame_info *this_frame, CORE_ADDR addr, gdb_byte *buf, int len)
Definition: frame.c:2681
static void i386obsd_supply_uthread(struct regcache *regcache, int regnum, CORE_ADDR addr)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1509
void i386bsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: i386-bsd-tdep.c:75
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3137
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:320
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:107
struct trad_frame_cache * trad_frame_cache_zalloc(struct frame_info *this_frame)
Definition: trad-frame.c:36
static int i386obsd_sigtramp_p(struct frame_info *this_frame)
int regnum
Definition: aarch64-tdep.c:77
void read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: corefile.c:258
struct obj_section * find_pc_section(CORE_ADDR pc)
Definition: objfiles.c:1395
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1308
static void i386obsd_trapframe_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition: osabi.c:143
struct frame_info * this_frame
Definition: trad-frame.c:29
#define gdb_assert(expr)
Definition: gdb_assert.h:32
Definition: value.c:169
int * gregset_reg_offset
Definition: i386-tdep.h:61
struct frame_id this_id
Definition: trad-frame.c:32
CORE_ADDR i386obsd_sigtramp_end_addr
bfd_byte gdb_byte
Definition: common-types.h:38
#define I386_SEL_RPL
Definition: i386-tdep.h:380
int(* sigtramp_p)(struct frame_info *)
Definition: i386-tdep.h:220
CORE_ADDR i386obsd_sigtramp_start_addr
void i386_elf_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: i386-tdep.c:4439
int offset
Definition: agent.c:65
gdbarch * arch() const
Definition: regcache.c:221
size_t sizeof_gregset
Definition: i386-tdep.h:63
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1004
int * sc_reg_offset
Definition: i386-tdep.h:226
unsigned long long ULONGEST
Definition: common-types.h:53
enum unwind_stop_reason default_frame_unwind_stop_reason(struct frame_info *this_frame, void **this_cache)
Definition: frame-unwind.c:184
const struct frame_id outer_frame_id
Definition: frame.c:577
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1085
static void i386obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
Definition: corefile.c:326
void write_memory(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
Definition: corefile.c:394
static const int i386obsd_page_size
void bsd_uthread_set_supply_uthread(struct gdbarch *gdbarch, void(*supply_uthread)(struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:67
#define I386OBSD_UTHREAD_ESP_OFFSET
int gregset_num_regs
Definition: i386-tdep.h:62
struct value * trad_frame_get_register(struct trad_frame_cache *this_trad_cache, struct frame_info *this_frame, int regnum)
Definition: trad-frame.c:162
enum bfd_endian byte_order
Definition: gdbarch.c:137
static void i386obsd_collect_uthread(const struct regcache *regcache, int regnum, CORE_ADDR addr)
CORE_ADDR get_frame_func(struct frame_info *this_frame)
Definition: frame.c:1001
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2691
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition: defs.h:604