198944Sobrien/* Target-dependent code for i386 BSD's.
298944Sobrien
3130803Smarcel   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4130803Smarcel
598944Sobrien   This file is part of GDB.
698944Sobrien
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1198944Sobrien
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1698944Sobrien
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2098944Sobrien   Boston, MA 02111-1307, USA.  */
2198944Sobrien
2298944Sobrien#include "defs.h"
23130803Smarcel#include "arch-utils.h"
2498944Sobrien#include "frame.h"
2598944Sobrien#include "gdbcore.h"
2698944Sobrien#include "regcache.h"
27130803Smarcel#include "osabi.h"
2898944Sobrien
29130803Smarcel#include "gdb_string.h"
3098944Sobrien
31130803Smarcel#include "i386-tdep.h"
3298944Sobrien
33130803Smarcel/* Support for signal handlers.  */
3498944Sobrien
3598944Sobrien/* Return whether PC is in a BSD sigtramp routine.  */
3698944Sobrien
3798944Sobrienint
38130803Smarceli386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
3998944Sobrien{
40130803Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
41130803Smarcel
42130803Smarcel  return (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end);
4398944Sobrien}
4498944Sobrien
45130803Smarcel/* Assuming NEXT_FRAME is for a frame following a BSD sigtramp
46130803Smarcel   routine, return the address of the associated sigcontext structure.  */
4798944Sobrien
4898944Sobrienstatic CORE_ADDR
49130803Smarceli386bsd_sigcontext_addr (struct frame_info *next_frame)
5098944Sobrien{
51130803Smarcel  char buf[4];
52130803Smarcel  CORE_ADDR sp;
5398944Sobrien
54130803Smarcel  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
55130803Smarcel  sp = extract_unsigned_integer (buf, 4);
56130803Smarcel
57130803Smarcel  return read_memory_unsigned_integer (sp + 8, 4);
5898944Sobrien}
5998944Sobrien
60130803Smarcel/* Return the start address of the sigtramp routine.  */
6198944Sobrien
62130803SmarcelCORE_ADDR
63130803Smarceli386bsd_sigtramp_start (CORE_ADDR pc)
6498944Sobrien{
65130803Smarcel  return gdbarch_tdep (current_gdbarch)->sigtramp_start;
6698944Sobrien}
6798944Sobrien
68130803Smarcel/* Return the end address of the sigtramp routine.  */
6998944Sobrien
7098944SobrienCORE_ADDR
71130803Smarceli386bsd_sigtramp_end (CORE_ADDR pc)
7298944Sobrien{
73130803Smarcel  return gdbarch_tdep (current_gdbarch)->sigtramp_end;
74130803Smarcel}
75130803Smarcel
7698944Sobrien
77130803Smarcel/* Support for shared libraries.  */
78130803Smarcel
79130803Smarcel/* Return non-zero if we are in a shared library trampoline code stub.  */
80130803Smarcel
81130803Smarcelint
82130803Smarceli386bsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
83130803Smarcel{
84130803Smarcel  return (name && !strcmp (name, "_DYNAMIC"));
8598944Sobrien}
86130803Smarcel
87130803Smarcel/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD).  */
88130803Smarcel
89130803Smarcel/* From <machine/signal.h>.  */
90130803Smarcelint i386bsd_sc_reg_offset[] =
91130803Smarcel{
92130803Smarcel  -1,				/* %eax */
93130803Smarcel  -1,				/* %ecx */
94130803Smarcel  -1,				/* %edx */
95130803Smarcel  -1,				/* %ebx */
96130803Smarcel  8 + 0 * 4,			/* %esp */
97130803Smarcel  8 + 1 * 4,			/* %ebp */
98130803Smarcel  -1,				/* %esi */
99130803Smarcel  -1,				/* %edi */
100130803Smarcel  8 + 3 * 4,			/* %eip */
101130803Smarcel  8 + 4 * 4,			/* %eflags */
102130803Smarcel  -1,				/* %cs */
103130803Smarcel  -1,				/* %ss */
104130803Smarcel  -1,				/* %ds */
105130803Smarcel  -1,				/* %es */
106130803Smarcel  -1,				/* %fs */
107130803Smarcel  -1				/* %gs */
108130803Smarcel};
109130803Smarcel
110130803Smarcelvoid
111130803Smarceli386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
112130803Smarcel{
113130803Smarcel  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
114130803Smarcel
115130803Smarcel  set_gdbarch_pc_in_sigtramp (gdbarch, i386bsd_pc_in_sigtramp);
116130803Smarcel
117130803Smarcel  /* Allow the recognition of sigtramps as a function named <sigtramp>.  */
118130803Smarcel  set_gdbarch_sigtramp_start (gdbarch, i386bsd_sigtramp_start);
119130803Smarcel  set_gdbarch_sigtramp_end (gdbarch, i386bsd_sigtramp_end);
120130803Smarcel
121130803Smarcel  /* Assume SunOS-style shared libraries.  */
122130803Smarcel  set_gdbarch_in_solib_call_trampoline (gdbarch,
123130803Smarcel					i386bsd_aout_in_solib_call_trampoline);
124130803Smarcel
125130803Smarcel  tdep->jb_pc_offset = 0;
126130803Smarcel
127130803Smarcel  tdep->sigtramp_start = 0xfdbfdfc0;
128130803Smarcel  tdep->sigtramp_end = 0xfdbfe000;
129130803Smarcel  tdep->sigcontext_addr = i386bsd_sigcontext_addr;
130130803Smarcel  tdep->sc_reg_offset = i386bsd_sc_reg_offset;
131130803Smarcel  tdep->sc_num_regs = ARRAY_SIZE (i386bsd_sc_reg_offset);
132130803Smarcel}
133130803Smarcel
134130803Smarcel
135130803Smarcelstatic enum gdb_osabi
136130803Smarceli386bsd_aout_osabi_sniffer (bfd *abfd)
137130803Smarcel{
138130803Smarcel  if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0)
139130803Smarcel    return GDB_OSABI_NETBSD_AOUT;
140130803Smarcel
141130803Smarcel  if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0)
142130803Smarcel    return GDB_OSABI_FREEBSD_AOUT;
143130803Smarcel
144130803Smarcel  return GDB_OSABI_UNKNOWN;
145130803Smarcel}
146130803Smarcel
147130803Smarcelstatic enum gdb_osabi
148130803Smarceli386bsd_core_osabi_sniffer (bfd *abfd)
149130803Smarcel{
150130803Smarcel  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
151130803Smarcel    return GDB_OSABI_NETBSD_AOUT;
152130803Smarcel
153130803Smarcel  return GDB_OSABI_UNKNOWN;
154130803Smarcel}
155130803Smarcel
156130803Smarcel
157130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes.  */
158130803Smarcelvoid _initialize_i386bsd_tdep (void);
159130803Smarcel
160130803Smarcelvoid
161130803Smarcel_initialize_i386bsd_tdep (void)
162130803Smarcel{
163130803Smarcel  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour,
164130803Smarcel				  i386bsd_aout_osabi_sniffer);
165130803Smarcel
166130803Smarcel  /* BFD doesn't set the architecture for NetBSD style a.out core
167130803Smarcel     files.  */
168130803Smarcel  gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_unknown_flavour,
169130803Smarcel				  i386bsd_core_osabi_sniffer);
170130803Smarcel}
171