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
i386obsd_sigtramp_p(struct frame_info * next_frame)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
i386obsd_aout_supply_regset(const struct regset * regset,struct regcache * regcache,int regnum,const void * regs,size_t len)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 *
i386obsd_aout_regset_from_core_section(struct gdbarch * gdbarch,const char * sect_name,size_t sect_size)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
i386obsd_supply_uthread(struct regcache * regcache,int regnum,CORE_ADDR addr,int ctx_offset)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
i386obsd_collect_uthread(const struct regcache * regcache,int regnum,CORE_ADDR addr,int ctx_offset)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 *
i386obsd_trapframe_cache(struct frame_info * next_frame,void ** this_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
i386obsd_trapframe_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)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
i386obsd_trapframe_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)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
i386obsd_trapframe_sniffer(const struct frame_unwind * self,struct frame_info * next_frame,void ** this_prologue_cache)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
i386obsd_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)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
i386obsd_aout_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)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
i386obsd_elf_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)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
_initialize_i386obsd_tdep(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