[PATCH] Moving forward on the road to a truly multi-arched i386

Mark Kettenis kettenis@chello.nl
Fri Jun 14 12:45:00 GMT 2002


Since nobody objected, I checked this in.

It would make sense for people using GDB on the i386 would check if
things still are in working order.

Mark


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* config/i386/i386sol2.mt (TDEPFILES): Add i386-sol2-tdep.o and
	i386bsd-tdep.o.  Remove solib.o, solib-svr4.o and solib-legacy.o.
	Move these to ...
	* config/i386/i386sol2.mh: ... here.
	* config/i386/tm-i386sol2.h (STAB_REG_TO_REGNUM): Remove define.
	(sigtramp_saved_pc, I386V4_SIGTRAMP_SAVED_PC): Don't #undef.
	(SIGCONTEXT_PC_OFFSET): Remove define.
	(IN_SIGTRAMP): Remove define.
	* i386-sol2-tdep.c: New file.

	* config/i386/i386nw.mt (TM_FILE): Change to tm-i386.h.
	* config/i386/tm-i386nw.h: Removed.

	* config/i386/tm-fbsd.h (STAB_REG_TO_REGNUM,
	USE_STRUCT_CONVENTION): Remove defines.
	(JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
	(get_longjmp_target): Remove prototype.
	(IN_SIGTRAMP): Remove define.
	(i386bsd_in_sigtramp): Remove prototype.
	(i386bsd_sigtramp_start, i386bsd_sigtramp_end): Turn into a
	function.  Update comment accordingly
	(SIGTRAMP_START, SIGTRAMP): Adjust definition accordingly.
	(FRAME_SAVED_PC): Remove define.
	(i386bsd_frame_saved_pc): Remove prototype.
	* config/i386/tm-nbsd.h (JB_ELEMENT_SIZE, JB_PC,
	GET_LONGJMP_TARGET): Remove defines.
	(get_longjmp_target): Remove prototype.
	(IN_SIGTRAMP): Remove define.
	(i386bsd_in_sigtramp): Remove prototype.
	(i386bsd_sigtramp_start, i386bsd_sigtramp_end): Turn into a
	function.  Update comment accordingly
	(SIGTRAMP_START, SIGTRAMP): Adjust definition accordingly.
	(FRAME_SAVED_PC): Remove define.
	(i386bsd_frame_saved_pc): Remove prototype.
	* config/i386/tm-nbsdaout.h (i386nbsd_aout_use_struct_convention):
	Remove prototype.
	(USE_STRUCT_CONVENTION): Remove prototype.
	* i386bsd-nat.c (i386bsd_sigcontext_pc_offset): Remove
	declaration.
	(_initialize_i386bsd_nat): Revise logic to determine some
	constants at compile time when compiling a native GDB.  Warn if
	things don't match up with what we expect.
	* i386bsd-tdep.c (i386bsd_sigtramp_start, i386bsd_sigtramp_end):
	Remove variables.
	(i386bsd_in_sigtramp): Rename tp i386bsd_pc_in_sigtramp.  Rewrite
	to use date stored in `struct gdbarch_tdep'.
	(i386bsd_sigcontext_offset): Remove varaible.
	(i386bsd_sigtramp_saved_pc): Make public.  Rewrite to use data
	stored in `struct gdbarch_tdep'.
	(i386bsd_frame_saved_pc): Make static.
	(i386bsd_sigtramp_start, i386bsd_sigtramp_end): New functions.
	(i386bsd_sc_pc_offset, i386nbsd_sc_pc_offset,
	i386fbsd_sigtramp_start, i386fbsd_sigtramp_end,
	i386fbsd4_sc_pc_offset): New variables.
	(i386bsd_init_abi, i386nbsd_init_abi, i386nbsdelf_init_abi,
	i386fbsdaout_init_abi, i386fbsd_init_abi, i386fbsd4_init_abi): New
	functions.
	(i386bsd_aout_osabi_sniffer, _initialize_i386bsd_tdep): New
	functions.
	* i386fbsd-nat.c (_initialize_i386fbsd_nat): Fix type in comment.
	Modify the value of i386fbsd_sigtramp_start and
	i386fbsd_sigtramp_end instead of i386bsd_sigtramp_start and
	i386fbsd_sigtramp_end.
	* i386nbsd-tdep.c: (i386nbsd_aout_use_struct_convention): Remove
	function.

	* config/i386/tm-linux.h (I386_LINUX_ORIG_EAX_REGNUM): Move
	define to i386-linux-tdep.h.
	(NUM_REGS, MAX_NUM_REGS, REGISTER_BYTES, REGISTER_NAME,
	REGISTER_BYTE, REGISTER_RAW_SIZE, STAB_REG_TO_REGNUM): Remove
	defines.
	(i386_linux_register_name, i386_linux_register_byte,
	i386_linux_register_raw_size): Remove prototypes.
	(i386_linux_svr4_fetch_link_map_offsets): Remove prototype.
	(SVR4_FETCH_LINK_MAP_OFFSETS): Remove define.
	(IN_SIGTRAMP, FRAME_CHAIN, FRAME_SAVED_PC, SAVED_PC_AFTER_CALL,
	TARGET_WRITE_PC): Remove defines.
	(i386_linux_in_sigtramp, i386_linux_frame_chain,
	i386_linux_frame_saved_pc, i386_linux_saved_pc_after_call,
	i386_linux_write_pc): Remove prototypes.
	(JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
	(get_longjmp_target): Remove prototype.
	* i386-linux-tdep.h: New file.
	* i386-linux-nat.c: Include "i386-linux-tdep.h".
	* i386-linux-tdep.c: Include "i386-tdep.h" and
	"i386-linux-tdep.h".
	(i386_linux_register_name, i386_linux_register_byte,
	i386_linux_register_raw_size, i386_linux_in_sigtramp,
	i386_linux_write_pc, i386_linux_svr4_fetch_link_map_offsets):
	Make static.
	(i386_linux_init_abi): New function.
	(_initialize_i386_linux_tdep): New function.

	* config/i386/tm-i386.h (SAVED_PC_AFTER_CALL): Remove define.
	(i386_saved_pc_after_call): Remove prototype.
	(MAX_NUM_REGS): Increase to deal with Linux's orig_eax "register".
	(REGISTER_NAME, STAB_REG_TO_REGNUM, SDB_REG_TO_REGNUM,
	DWARF_REG_TO_REGNUM, DWARF2_REG_TO_REGNUM): Remove defines.
	(i386_register_name, i386_stab_reg_to_regnum,
	i386_dwarf_reg_to_regnum): Remove prototypes.
	(SIZEOF_GREGS, SIZEOF_FPU_REGS, SIZEOF_FPU_CTL_REGS,
	SIZEOF_SSE_REGS): Remove defines.
	(REGISTER_BYTES): Remove define.
	(REGISTER_BYTE, REGISTER_RAW_SIZE): Remove defines.
	(i386_register_byte, i386_register_raw_size): Remove prototypes.
	(FRAME_CHAIN, FRAME_SAVED_PC): Remove defines.
	(i386_frame_chain, i386_frame_saved_pc): Remove prototypes.
	* config/i386/tm-i386v4.h (FRAME_CHAIN_VALID): Remove define.
	(JB_ELEMENT_SIZE, JB_PC, JB_EBX, JB_ESI, JB_EDI, JB_EBP, JB_ESP,
	JB_EDX, GET_LONGJMP_TARGET): Remove defines.
	(get_longjmp_target): Remove prototype.
	(I386V4_SIGTRAMP_SAVED_PC, IN_SIGTRAMP): Remove defines.
	(sigtramp_saved_pc): Remove define.
	(i386v4_sigtramp_saved_pc): Remove prototype.
	* config/i386/tm-go32.h (FRAME_CHAIN,
	FRAMELESS_FUNCTION_INVOCATION, FRAME_SAVED_PC): Remove defines.
	(i386go32_frame_saved_pc): Remove prototype.
	(JB_ELEMENT_SIZE, JB_PC, GET_LONGJMP_TARGET): Remove defines.
	(get_longjmp_target): Remove prototype.
	* i386-tdep.h: Include "osabi.h".
	(enum i386_abi): Removed.
	(enum struct_return): New enum.
	(struct gdbarch_tdep): Remove abi member, add osabi, jb_pc_offset,
	struct_return, sigtramp_saved_pc, sigtramp_start, sigtramp_end and
	sc_pc_offset members.
	(i386_gdbarch_register_os_abi): Remove prototype.
	(I386_NUM_GREGS, I386_NUM_FREGS, I386_NUM_XREGS,
	I386_SSE_NUM_REGS): New defines.
	(I386_SIZEOF_GREGS, I386_SIZEOF_FREGS, I386_SIZEOF_XREGS,
	I386_SSE_SIZEOF_REGS): New defines.
	(i386_register_name, i386_register_byte, i386_register_raw_size):
	New prototypes.
	(i386_elf_init_abi, i386_svr4_init_abi): New prototypes.
	(i386bsd_sigtramp_saved_pc): New prototype.
	* i386-tdep.c: Don't include "elf-bfd.h".
	(i386_stab_reg_to_regnum, i386_dwarf_reg_to_regnum,
	i386_frame_chain, i386_saved_pc_after_call): Make static.
	(i386_frame_saved_pc): Rewrite to call architecture dependent
	function to deal with signal handlers.  Make static.
	(i386go32_frame_saved_pc): Removed.
	[GET_LONGJMP_TARGET] (JB_PC, JB_ELEMENT_SIZE, get_longjmp_target):
	Removed.
	(i386_get_longjmp_target): New function.
	(default_struct_convention, pcc_struct_convention,
	reg_struct_convention, valid_conventions, struct_convention): New
	variables.
	(i386_use_struct_convention): New function.
	(i386v4_sigtramp_saved_pc): Renamed to
	i386_svr4_sigtramp_saved_pc.  Made static.  Moved.
	(i386_pc_in_sigtramp): New function.
	(i386_abi_names): Removed.
	(ABI_TAG_OS_GNU_LINUX, ABI_TAG_OS_GNU_HURD,
	ABI_TAG_OS_GNU_SOLARIS, ABI_TAG_OS_FREEBSD, ABI_TAG_OS_NETBSD):
	Removed.
	(process_note_sections, i386_elf_abi_from_note, i386_elf_abi,
	i386_gdbarch_register_os_abi): Removed.
	(struct i386_abi_handler): Removed.
	(i386_abi_handler_list): Removed.
	(i386_svr4_pc_in_sigtramp, i386_go32_pc_in_sigtramp): New
	functions.
	(i386_elf_init_abi, i386_svr4_init_abi, i386_go32_init_abi,
	i386_nw_init_abi): New functions.
	(i386_gdbarch_init): Rewritten to use generic OS ABI framework.
	Use set_gdbarch_xxx() calls instead of relying on macros for a
	number of calls.
	(i386_coff_osabi_sniffer, i386_nlm_osabi_sniffer): New functions.
	(_initialize_i386_tdep): Add new 'struct-convcention' command.
	Register the various architecture variants defined in this file.

Index: i386-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-linux-tdep.c,v
retrieving revision 1.12
diff -u -p -r1.12 i386-linux-tdep.c
--- i386-linux-tdep.c 24 Apr 2002 16:28:15 -0000 1.12
+++ i386-linux-tdep.c 14 Jun 2002 19:41:05 -0000
@@ -33,9 +33,12 @@
 
 #include "solib-svr4.h"		/* For struct link_map_offsets.  */
 
+#include "i386-tdep.h"
+#include "i386-linux-tdep.h"
+
 /* Return the name of register REG.  */
 
-char *
+static char *
 i386_linux_register_name (int reg)
 {
   /* Deal with the extra "orig_eax" pseudo register.  */
@@ -45,7 +48,7 @@ i386_linux_register_name (int reg)
   return i386_register_name (reg);
 }
 
-int
+static int
 i386_linux_register_byte (int reg)
 {
   /* Deal with the extra "orig_eax" pseudo register.  */
@@ -56,7 +59,7 @@ i386_linux_register_byte (int reg)
   return i386_register_byte (reg);
 }
 
-int
+static int
 i386_linux_register_raw_size (int reg)
 {
   /* Deal with the extra "orig_eax" pseudo register.  */
@@ -224,8 +227,8 @@ i386_linux_rt_sigtramp_start (CORE_ADDR 
 
 /* Return whether PC is in a GNU/Linux sigtramp routine.  */
 
-int
-i386_linux_in_sigtramp (CORE_ADDR pc, char *name)
+static int
+i386_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
   if (name)
     return STREQ ("__restore", name) || STREQ ("__restore_rt", name);
@@ -379,7 +382,7 @@ i386_linux_saved_pc_after_call (struct f
 
 /* Set the program counter for process PTID to PC.  */
 
-void
+static void
 i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
 {
   write_register_pid (PC_REGNUM, pc, ptid);
@@ -496,7 +499,7 @@ i386_linux_skip_solib_resolver (CORE_ADD
    from a GDB that was not built on an GNU/Linux x86 host (for cross
    debugging).  */
 
-struct link_map_offsets *
+static struct link_map_offsets *
 i386_linux_svr4_fetch_link_map_offsets (void)
 {
   static struct link_map_offsets lmo;
@@ -527,4 +530,54 @@ i386_linux_svr4_fetch_link_map_offsets (
     }
 
   return lmp;
+}
+
+
+static void
+i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* GNU/Linux uses ELF.  */
+  i386_elf_init_abi (info, gdbarch);
+
+  /* We support the SSE registers on GNU/Linux.  */
+  tdep->num_xmm_regs = I386_NUM_XREGS - 1;
+  /* set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS); */
+
+  /* Since we have the extra "orig_eax" register on GNU/Linux, we have
+     to adjust a few things.  */
+
+  set_gdbarch_write_pc (gdbarch, i386_linux_write_pc);
+  set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS + 1);
+  set_gdbarch_register_name (gdbarch, i386_linux_register_name);
+  set_gdbarch_register_bytes (gdbarch, I386_SSE_SIZEOF_REGS + 4);
+  set_gdbarch_register_byte (gdbarch, i386_linux_register_byte);
+  set_gdbarch_register_raw_size (gdbarch, i386_linux_register_raw_size);
+
+  tdep->jb_pc_offset = 20;	/* From <bits/setjmp.h>.  */
+
+  /* When the i386 Linux kernel calls a signal handler, the return
+     address points to a bit of code on the stack.  These definitions
+     are used to identify this bit of code as a signal trampoline in
+     order to support backtracing through calls to signal handlers.  */
+
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_linux_pc_in_sigtramp);
+  set_gdbarch_frame_chain (gdbarch, i386_linux_frame_chain);
+  set_gdbarch_frame_saved_pc (gdbarch, i386_linux_frame_saved_pc);
+  set_gdbarch_saved_pc_after_call (gdbarch, i386_linux_saved_pc_after_call);
+  tdep->sigtramp_saved_pc = i386_linux_sigtramp_saved_pc;
+
+  set_solib_svr4_fetch_link_map_offsets (gdbarch,
+				       i386_linux_svr4_fetch_link_map_offsets);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern void _initialize_i386_linux_tdep (void);
+
+void
+_initialize_i386_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_LINUX,
+			  i386_linux_init_abi);
 }
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.55
diff -u -p -r1.55 i386-tdep.c
--- i386-tdep.c 27 May 2002 09:17:24 -0000 1.55
+++ i386-tdep.c 14 Jun 2002 19:41:05 -0000
@@ -36,8 +36,6 @@
 #include "value.h"
 #include "gdb_assert.h"
 
-#include "elf-bfd.h"
-
 #include "i386-tdep.h"
 
 /* Names of the registers.  The first 10 registers match the register
@@ -119,7 +117,7 @@ i386_register_virtual_size (int reg)
 /* Convert stabs register number REG to the appropriate register
    number used by GDB.  */
 
-int
+static int
 i386_stab_reg_to_regnum (int reg)
 {
   /* This implements what GCC calls the "default" register map.  */
@@ -150,10 +148,10 @@ i386_stab_reg_to_regnum (int reg)
   return NUM_REGS + NUM_PSEUDO_REGS;
 }
 
-/* Convert Dwarf register number REG to the appropriate register
+/* Convert DWARF register number REG to the appropriate register
    number used by GDB.  */
 
-int
+static int
 i386_dwarf_reg_to_regnum (int reg)
 {
   /* The DWARF register numbering includes %eip and %eflags, and
@@ -466,7 +464,7 @@ i386_get_frame_setup (CORE_ADDR pc)
    frame's nominal address is the address of a 4-byte word containing
    the calling frame's address.  */
 
-CORE_ADDR
+static CORE_ADDR
 i386_frame_chain (struct frame_info *frame)
 {
   if (frame->signal_handler_caller)
@@ -493,30 +491,24 @@ i386_frameless_function_invocation (stru
 
 /* Return the saved program counter for FRAME.  */
 
-CORE_ADDR
+static CORE_ADDR
 i386_frame_saved_pc (struct frame_info *frame)
 {
-  /* FIXME: kettenis/2001-05-09: Conditionalizing the next bit of code
-     on SIGCONTEXT_PC_OFFSET and I386V4_SIGTRAMP_SAVED_PC should be
-     considered a temporary hack.  I plan to come up with something
-     better when we go multi-arch.  */
-#if defined (SIGCONTEXT_PC_OFFSET) || defined (I386V4_SIGTRAMP_SAVED_PC)
   if (frame->signal_handler_caller)
-    return sigtramp_saved_pc (frame);
-#endif
+    {
+      CORE_ADDR (*sigtramp_saved_pc) (struct frame_info *);
+      sigtramp_saved_pc = gdbarch_tdep (current_gdbarch)->sigtramp_saved_pc;
 
-  return read_memory_unsigned_integer (frame->frame + 4, 4);
-}
+      gdb_assert (sigtramp_saved_pc != NULL);
+      return sigtramp_saved_pc (frame);
+    }
 
-CORE_ADDR
-i386go32_frame_saved_pc (struct frame_info *frame)
-{
-  return read_memory_integer (frame->frame + 4, 4);
+  return read_memory_unsigned_integer (frame->frame + 4, 4);
 }
 
 /* Immediately after a function call, return the saved pc.  */
 
-CORE_ADDR
+static CORE_ADDR
 i386_saved_pc_after_call (struct frame_info *frame)
 {
   return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
@@ -834,49 +826,35 @@ i386_pop_frame (void)
 }
 
 
-#ifdef GET_LONGJMP_TARGET
-
-/* FIXME: Multi-arching does not set JB_PC and JB_ELEMENT_SIZE yet.  
-   Fill in with dummy value to enable compilation.  */
-#ifndef JB_PC
-#define JB_PC 0
-#endif /* JB_PC */
-
-#ifndef JB_ELEMENT_SIZE
-#define JB_ELEMENT_SIZE 4
-#endif /* JB_ELEMENT_SIZE */
-
 /* Figure out where the longjmp will land.  Slurp the args out of the
    stack.  We expect the first arg to be a pointer to the jmp_buf
-   structure from which we extract the pc (JB_PC) that we will land
-   at.  The pc is copied into PC.  This routine returns true on
+   structure from which we extract the address that we will land at.
+   This address is copied into PC.  This routine returns true on
    success.  */
 
-int
-get_longjmp_target (CORE_ADDR *pc)
+static int
+i386_get_longjmp_target (CORE_ADDR *pc)
 {
-  char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+  char buf[4];
   CORE_ADDR sp, jb_addr;
+  int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset;
 
-  sp = read_register (SP_REGNUM);
-
-  if (target_read_memory (sp + SP_ARG0,	/* Offset of first arg on stack.  */
-			  buf,
-			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
+  /* If JB_PC_OFFSET is -1, we have no way to find out where the
+     longjmp will land.  */
+  if (jb_pc_offset == -1)
     return 0;
 
-  jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
-
-  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
-			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
+  sp = read_register (SP_REGNUM);
+  if (target_read_memory (sp + 4, buf, 4))
     return 0;
 
-  *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+  jb_addr = extract_address (buf, 4);
+  if (target_read_memory (jb_addr + jb_pc_offset, buf, 4))
+    return 0;
 
+  *pc = extract_address (buf, 4);
   return 1;
 }
-
-#endif /* GET_LONGJMP_TARGET */
 
 
 CORE_ADDR
@@ -1044,6 +1022,37 @@ i386_extract_struct_value_address (char 
 }
 
 
+/* This is the variable that is set with "set struct-convention", and
+   its legitimate values.  */
+static const char default_struct_convention[] = "default";
+static const char pcc_struct_convention[] = "pcc";
+static const char reg_struct_convention[] = "reg";
+static const char *valid_conventions[] =
+{
+  default_struct_convention,
+  pcc_struct_convention,
+  reg_struct_convention,
+  NULL
+};
+static const char *struct_convention = default_struct_convention;
+
+static int
+i386_use_struct_convention (int gcc_p, struct type *type)
+{
+  enum struct_return struct_return;
+
+  if (struct_convention == default_struct_convention)
+    struct_return = gdbarch_tdep (current_gdbarch)->struct_return;
+  else if (struct_convention == pcc_struct_convention)
+    struct_return = pcc_struct_return;
+  else
+    struct_return = reg_struct_return;
+
+  return generic_use_struct_convention (struct_return == reg_struct_return,
+					type);
+}
+
+
 /* Return the GDB type object for the "standard" data type of data in
    register REGNUM.  Perhaps %esi and %edi should go here, but
    potentially they could be used for things other than address.  */
@@ -1122,34 +1131,6 @@ i386_register_convert_to_raw (struct typ
 }
      
 
-#ifdef I386V4_SIGTRAMP_SAVED_PC
-/* Get saved user PC for sigtramp from the pushed ucontext on the
-   stack for all three variants of SVR4 sigtramps.  */
-
-CORE_ADDR
-i386v4_sigtramp_saved_pc (struct frame_info *frame)
-{
-  CORE_ADDR saved_pc_offset = 4;
-  char *name = NULL;
-
-  find_pc_partial_function (frame->pc, &name, NULL, NULL);
-  if (name)
-    {
-      if (STREQ (name, "_sigreturn"))
-	saved_pc_offset = 132 + 14 * 4;
-      else if (STREQ (name, "_sigacthandler"))
-	saved_pc_offset = 80 + 14 * 4;
-      else if (STREQ (name, "sigvechandler"))
-	saved_pc_offset = 120 + 14 * 4;
-    }
-
-  if (frame->next)
-    return read_memory_integer (frame->next->frame + saved_pc_offset, 4);
-  return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4);
-}
-#endif /* I386V4_SIGTRAMP_SAVED_PC */
-
-
 #ifdef STATIC_TRANSFORM_NAME
 /* SunPRO encodes the static variables.  This is not related to C++
    mangling, it is done for C too.  */
@@ -1199,6 +1180,16 @@ skip_trampoline_code (CORE_ADDR pc, char
 }
 
 
+/* Return non-zero if PC and NAME show that we are in a signal
+   trampoline.  */
+
+static int
+i386_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+  return (name && strcmp ("_sigtramp", name) == 0);
+}
+
+
 /* We have two flavours of disassembly.  The machinery on this page
    deals with switching between those.  */
 
@@ -1213,229 +1204,132 @@ gdb_print_insn_i386 (bfd_vma memaddr, di
      or intel_flavor.  */
   internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
-
 
-/* This table matches the indices assigned to enum i386_abi.  Keep
-   them in sync.  */
-static const char * const i386_abi_names[] =
-{
-  "<unknown>",
-  "SVR4",
-  "NetBSD",
-  "GNU/Linux",
-  "GNU/Hurd",
-  "Solaris",
-  "FreeBSD",
-  NULL
-};
 
+/* There are a few i386 architecture variants that differ only
+   slightly from the generic i386 target.  For now, we don't give them
+   their own source file, but include them here.  As a consequence,
+   they'll always be included.  */
 
-#define ABI_TAG_OS_GNU_LINUX	I386_ABI_LINUX
-#define ABI_TAG_OS_GNU_HURD	I386_ABI_HURD
-#define ABI_TAG_OS_GNU_SOLARIS	I386_ABI_INVALID
-#define ABI_TAG_OS_FREEBSD	I386_ABI_FREEBSD
-#define ABI_TAG_OS_NETBSD	I386_ABI_NETBSD
+/* System V Release 4 (SVR4).  */
 
-static void
-process_note_sections (bfd *abfd, asection *sect, void *obj)
+static int
+i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
-  int *abi = obj;
-  const char *name;
-  unsigned int sectsize;
-
-  name = bfd_get_section_name (abfd, sect);
-  sectsize = bfd_section_size (abfd, sect);
-
-  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, data_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we
-	 are looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
+  return (name && (strcmp ("_sigreturn", name) == 0
+		   || strcmp ("_sigacthandler", name) == 0
+		   || strcmp ("sigvechandler", name) == 0));
+}
 
-      name_length = bfd_h_get_32 (abfd, note);
-      data_length = bfd_h_get_32 (abfd, note + 4);
-      note_type = bfd_h_get_32 (abfd, note + 8);
+/* Get saved user PC for sigtramp from the pushed ucontext on the
+   stack for all three variants of SVR4 sigtramps.  */
 
-      if (name_length == 4 && data_length == 16
-	  && note_type == NT_GNU_ABI_TAG
-	  && strcmp (note + 12, "GNU") == 0)
-	{
-	  int abi_tag_os = bfd_h_get_32 (abfd, note + 16);
+CORE_ADDR
+i386_svr4_sigtramp_saved_pc (struct frame_info *frame)
+{
+  CORE_ADDR saved_pc_offset = 4;
+  char *name = NULL;
 
-	  /* The case numbers are from abi-tags in glibc.  */
-	  switch (abi_tag_os)
-	    {
-	    case GNU_ABI_TAG_LINUX:
-	      *abi = ABI_TAG_OS_GNU_LINUX;
-	      break;
-
-	    case GNU_ABI_TAG_HURD:
-	      *abi = ABI_TAG_OS_GNU_HURD;
-	      break;
-
-	    case GNU_ABI_TAG_SOLARIS:
-	      *abi = ABI_TAG_OS_GNU_SOLARIS;
-	      break;
-
-	    default:
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: unknown ABI OS tag %d",
-		 abi_tag_os);
-	      break;
-	    }
-	}
-      else if (name_length == 8 && data_length == 4
-	       && note_type == NT_FREEBSD_ABI_TAG
-	       && strcmp (note + 12, "FreeBSD") == 0)
-	*abi = ABI_TAG_OS_FREEBSD;
-    }
-  /* NetBSD uses a similar trick.  */
-  else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, desc_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-         looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-
-      name_length = bfd_h_get_32 (abfd, note);
-      desc_length = bfd_h_get_32 (abfd, note + 4);
-      note_type = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 7 && desc_length == 4
-	  && note_type == NT_NETBSD_IDENT
-	  && strcmp (note + 12, "NetBSD") == 0)
-	*abi = ABI_TAG_OS_NETBSD;
+  find_pc_partial_function (frame->pc, &name, NULL, NULL);
+  if (name)
+    {
+      if (strcmp (name, "_sigreturn") == 0)
+	saved_pc_offset = 132 + 14 * 4;
+      else if (strcmp (name, "_sigacthandler") == 0)
+	saved_pc_offset = 80 + 14 * 4;
+      else if (strcmp (name, "sigvechandler") == 0)
+	saved_pc_offset = 120 + 14 * 4;
     }
+
+  if (frame->next)
+    return read_memory_integer (frame->next->frame + saved_pc_offset, 4);
+  return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4);
 }
+
+
+/* DJGPP.  */
 
 static int
-i386_elf_abi_from_note (bfd *abfd)
+i386_go32_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
-  enum i386_abi abi = I386_ABI_UNKNOWN;
-  
-  bfd_map_over_sections (abfd, process_note_sections, &abi);
-
-  return abi;
+  /* DJGPP doesn't have any special frames for signal handlers.  */
+  return 0;
 }
+
+
+/* Generic ELF.  */
 
-static enum i386_abi
-i386_elf_abi (bfd *abfd)
+void
+i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  int elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+  /* We typically use stabs-in-ELF with the DWARF register numbering.  */
+  set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+}
 
-  /* The fact that the EI_OSABI byte is set to ELFOSABI_NONE doesn't
-     necessarily mean that this is a System V ELF binary.  To further
-     distinguish between binaries for differens operating systems,
-     check for vendor-specific note elements.  */
-  if (elfosabi == ELFOSABI_NONE)
-    {
-      enum i386_abi abi = i386_elf_abi_from_note (abfd);
+/* System V Release 4 (SVR4).  */
 
-      if (abi != I386_ABI_UNKNOWN)
-	return abi;
+void
+i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-      /* FreeBSD folks are naughty; they stored the string "FreeBSD"
-	 in the padding of the e_ident field of the ELF header.  */
-      if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0)
-	return I386_ABI_FREEBSD;
-    }
+  /* System V Release 4 uses ELF.  */
+  i386_elf_init_abi (info, gdbarch);
 
-  switch (elfosabi)
-    {
-    case ELFOSABI_NONE:
-      return I386_ABI_SVR4;
-    case ELFOSABI_FREEBSD:
-      return I386_ABI_FREEBSD;
-    }
+  /* FIXME: kettenis/20020511: Why do we override this function here?  */
+  set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
 
-  return I386_ABI_UNKNOWN;
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp);
+  tdep->sigtramp_saved_pc = i386_svr4_sigtramp_saved_pc;
+
+  tdep->jb_pc_offset = 20;
 }
 
-struct i386_abi_handler
+/* DJGPP.  */
+
+void
+i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  struct i386_abi_handler *next;
-  enum i386_abi abi;
-  void (*init_abi)(struct gdbarch_info, struct gdbarch *);
-};
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_go32_pc_in_sigtramp);
 
-struct i386_abi_handler *i386_abi_handler_list = NULL;
+  tdep->jb_pc_offset = 36;
+}
+
+/* NetWare.  */
 
 void
-i386_gdbarch_register_os_abi (enum i386_abi abi,
-			      void (*init_abi)(struct gdbarch_info,
-					       struct gdbarch *))
+i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  struct i386_abi_handler **handler_p;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  for (handler_p = &i386_abi_handler_list; *handler_p != NULL;
-       handler_p = &(*handler_p)->next)
-    {
-      if ((*handler_p)->abi == abi)
-	{
-	  internal_error
-	    (__FILE__, __LINE__,
-	     "i386_gdbarch_register_abi: A handler for this ABI variant "
-	     "(%d) has already been registered", (int) abi);
-	  /* If user wants to continue, override previous definition.  */
-	  (*handler_p)->init_abi = init_abi;
-	  return;
-	}
-    }
-  (*handler_p)
-    = (struct i386_abi_handler *) xmalloc (sizeof (struct i386_abi_handler));
-  (*handler_p)->next = NULL;
-  (*handler_p)->abi = abi;
-  (*handler_p)->init_abi = init_abi;
+  /* FIXME: kettenis/20020511: Why do we override this function here?  */
+  set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
+
+  tdep->jb_pc_offset = 24;
 }
+
 
 struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
-  enum i386_abi abi = I386_ABI_UNKNOWN;
-  struct i386_abi_handler *abi_handler;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
+  /* Try to determine the OS ABI of the object we're loading.  */
   if (info.abfd != NULL)
-    {
-      switch (bfd_get_flavour (info.abfd))
-	{
-	case bfd_target_elf_flavour:
-	  abi= i386_elf_abi (info.abfd);
-	  break;
-
-	default:
-	  /* Not sure what to do here, leave the ABI as unknown.  */
-	  break;
-	}
-    }
+    osabi = gdbarch_lookup_osabi (info.abfd);
 
   /* Find a candidate among extant architectures.  */
   for (arches = gdbarch_list_lookup_by_info (arches, &info);
        arches != NULL;
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
-      /* Make sure the ABI selection matches.  */
+      /* Make sure the OS ABI selection matches.  */
       tdep = gdbarch_tdep (arches->gdbarch);
-      if (tdep && tdep->abi == abi)
+      if (tdep && tdep->osabi == osabi)
         return arches->gdbarch;
     }
 
@@ -1443,11 +1337,21 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep = XMALLOC (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
-  tdep->abi = abi;
+  tdep->osabi = osabi;
+
+  /* The i386 default settings don't include the SSE registers.
+     FIXME: kettenis/20020509: They do include the FPU registers for
+     now, which is not quite right.  */
+  tdep->num_xmm_regs = 0;
+
+  tdep->jb_pc_offset = -1;
+  tdep->struct_return = pcc_struct_return;
+  tdep->sigtramp_saved_pc = NULL;
+  tdep->sigtramp_start = 0;
+  tdep->sigtramp_end = 0;
+  tdep->sc_pc_offset = -1;
 
-  /* FIXME: kettenis/2001-11-24: Although not all IA-32 processors
-     have the SSE registers, it's easier to set the default to 8.  */
-  tdep->num_xmm_regs = 8;
+  set_gdbarch_get_longjmp_target (gdbarch, i386_get_longjmp_target);
 
   set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
 
@@ -1463,50 +1367,61 @@ i386_gdbarch_init (struct gdbarch_info i
 
   set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
 
-  /* NOTE: tm-i386nw.h and tm-i386v4.h override this.  */
-  set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+  set_gdbarch_use_struct_convention (gdbarch, i386_use_struct_convention);
 
-  /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-linux.h,
-     tm-ptx.h, tm-symmetry.h currently override this.  Sigh.  */
-  set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SSE_REGS);
+  /* The following redefines make backtracing through sigtramp work.
+     They manufacture a fake sigtramp frame and obtain the saved pc in
+     sigtramp from the sigcontext structure which is pushed by the
+     kernel on the user stack, along with a pointer to it.  */
+
+  set_gdbarch_frame_chain (gdbarch, i386_frame_chain);
+  set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+  set_gdbarch_frame_saved_pc (gdbarch, i386_frame_saved_pc);
+  set_gdbarch_saved_pc_after_call (gdbarch, i386_saved_pc_after_call);
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
+
+  /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-ptx.h,
+     tm-symmetry.h currently override this.  Sigh.  */
+  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS);
+
+  /* Use the "default" register numbering scheme for stabs and COFF.  */
+  set_gdbarch_stab_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
+  set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
+
+  /* Use the DWARF register numbering scheme for DWARF and DWARF 2.  */
+  set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+
+  /* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to
+     be in use on any of the supported i386 targets.  */
+
+  set_gdbarch_register_bytes (gdbarch, I386_SIZEOF_GREGS + I386_SIZEOF_FREGS);
+  set_gdbarch_register_name (gdbarch, i386_register_name);
+  set_gdbarch_register_byte (gdbarch, i386_register_byte);
+  set_gdbarch_register_raw_size (gdbarch, i386_register_raw_size);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
-  if (abi == I386_ABI_UNKNOWN)
-    {
-      /* Don't complain about not knowing the ABI variant if we don't
-	 have an inferior.  */
-      if (info.abfd)
-	fprintf_filtered
-	  (gdb_stderr, "GDB doesn't recognize the ABI of the inferior.  "
-	   "Attempting to continue with the default i386 settings");
-    }
-  else
-    {
-      for (abi_handler = i386_abi_handler_list; abi_handler != NULL;
-	   abi_handler = abi_handler->next)
-	if (abi_handler->abi == abi)
-	  break;
+  gdbarch_init_osabi (info, gdbarch, osabi);
 
-      if (abi_handler)
-	abi_handler->init_abi (info, gdbarch);
-      else
-	{
-	  /* We assume that if GDB_MULTI_ARCH is less than
-	     GDB_MULTI_ARCH_TM that an ABI variant can be supported by
-	     overriding definitions in this file.  */
-	  if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-	    fprintf_filtered
-	      (gdb_stderr,
-	       "A handler for the ABI variant \"%s\" is not built into this "
-	       "configuration of GDB.  "
-	       "Attempting to continue with the default i386 settings",
-	       i386_abi_names[abi]);
-	}
-    }
-  
   return gdbarch;
 }
 
+static enum gdb_osabi
+i386_coff_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "coff-go32-exe") == 0)
+    return GDB_OSABI_GO32;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+i386_nlm_osabi_sniffer (bfd *abfd)
+{
+  return GDB_OSABI_NETWARE;
+}
+
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_i386_tdep (void);
 
@@ -1544,4 +1459,30 @@ and the default value is \"att\".",
 				&setlist);
     add_show_from_set (new_cmd, &showlist);
   }
+
+  /* Add the variable that controls the convention for returning
+     structs.  */
+  {
+    struct cmd_list_element *new_cmd;
+
+    new_cmd = add_set_enum_cmd ("struct-convention", no_class,
+				 valid_conventions,
+				&struct_convention, "\
+Set the convention for returning small structs, valid values \
+are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".",
+                                &setlist);
+    add_show_from_set (new_cmd, &showlist);
+  }
+
+  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
+				  i386_coff_osabi_sniffer);
+  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_nlm_flavour,
+				  i386_nlm_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_SVR4,
+			  i386_svr4_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_GO32,
+			  i386_go32_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETWARE,
+			  i386_nw_init_abi);
 }
Index: i386-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.h,v
retrieving revision 1.6
diff -u -p -r1.6 i386-tdep.h
--- i386-tdep.h 9 May 2002 13:53:36 -0000 1.6
+++ i386-tdep.h 14 Jun 2002 19:41:05 -0000
@@ -1,5 +1,5 @@
 /* Target-dependent code for GDB, the GNU debugger.
-   Copyright 2001
+   Copyright 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -22,6 +22,8 @@
 #ifndef I386_TDEP_H
 #define I386_TDEP_H
 
+#include "osabi.h"
+
 /* GDB's i386 target supports both the 32-bit Intel Architecture
    (IA-32) and the 64-bit AMD x86-64 architecture.  Internally it uses
    a similar register layout for both.
@@ -40,30 +42,38 @@
    differs and is determined by the num_xmm_regs member of `struct
    gdbarch_tdep'.  */
 
-/* ABI variants that we know about.  */
-enum i386_abi
-{
-  I386_ABI_UNKNOWN = 0,
-
-  /* ELF */
-  I386_ABI_SVR4,		/* This is the default.  */
-  I386_ABI_NETBSD,
-  I386_ABI_LINUX,
-  I386_ABI_HURD,
-  I386_ABI_SOLARIS,
-  I386_ABI_FREEBSD,
+/* Convention for returning structures.  */
 
-  I386_ABI_INVALID = -1
+enum struct_return
+{
+  pcc_struct_return,		/* Return "short" structures in memory.  */
+  reg_struct_return		/* Return "short" structures in registers.  */
 };
 
 /* i386 architecture specific information.  */
 struct gdbarch_tdep
 {
   /* ABI.  */
-  enum i386_abi abi;
+  enum gdb_osabi osabi;
 
   /* Number of SSE registers.  */
   int num_xmm_regs;
+
+  /* Offset of saved PC in jmp_buf.  */
+  int jb_pc_offset;
+
+  /* Convention for returning structures.  */
+  enum struct_return struct_return;
+
+  /* Get saved PC for sigtramp.  */
+  CORE_ADDR (*sigtramp_saved_pc) (struct frame_info *);
+
+  /* Address range where sigtramp lives.  */
+  CORE_ADDR sigtramp_start;
+  CORE_ADDR sigtramp_end;
+
+  /* Offset of saved PC in `struct sigcontext'.  */
+  int sc_pc_offset;
 };
 
 /* Floating-point registers.  */
@@ -129,8 +139,42 @@ struct gdbarch_tdep
 #define IS_FPU_CTRL_REGNUM(n) FPC_REGNUM_P (n)
 #define IS_SSE_REGNUM(n) SSE_REGNUM_P (n)
 
-void i386_gdbarch_register_os_abi (enum i386_abi,
-				   void (*init_abi)(struct gdbarch_info,
-						    struct gdbarch *));
+#define I386_NUM_GREGS	16
+#define I386_NUM_FREGS	16
+#define I386_NUM_XREGS  9
+
+#define I386_SSE_NUM_REGS	(I386_NUM_GREGS + I386_NUM_FREGS \
+				 + I386_NUM_XREGS)
+
+/* Sizes of individual register sets.  These cover the entire register
+   file, so summing up the sizes of those portions actually present
+   yields REGISTER_BYTES.  */
+#define I386_SIZEOF_GREGS	(I386_NUM_GREGS * 4)
+#define I386_SIZEOF_FREGS	(8 * 10 + 8 * 4)
+#define I386_SIZEOF_XREGS	(8 * 16 + 4)
+
+#define I386_SSE_SIZEOF_REGS	(I386_SIZEOF_GREGS + I386_SIZEOF_FREGS \
+				 + I386_SIZEOF_XREGS)
+
+/* Return the name of register REG.  */
+extern char *i386_register_name (int reg);
+
+/* Return the offset into the register array of the start of register
+   number REG.  */
+extern int i386_register_byte (int reg);
+
+/* Return the number of bytes of storage in GDB's register array
+   occupied by register REG.  */
+extern int i386_register_raw_size (int reg);
+
+/* Initialize a basic ELF architecture variant.  */
+extern void i386_elf_init_abi (struct gdbarch_info, struct gdbarch *);
+
+/* Initialize a SVR4 architecture variant.  */
+extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *);
+
+/* Functions exported from i386bsd-tdep.c.  */
+
+extern CORE_ADDR i386bsd_sigtramp_saved_pc (struct frame_info *frame);
 
 #endif /* i386-tdep.h */
Index: i386bsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386bsd-nat.c,v
retrieving revision 1.12
diff -u -p -r1.12 i386bsd-nat.c
--- i386bsd-nat.c 11 May 2002 17:22:26 -0000 1.12
+++ i386bsd-nat.c 14 Jun 2002 19:41:06 -0000
@@ -382,19 +382,39 @@ kernel_u_size (void)
   return (sizeof (struct user));
 }
 
-/* See i386bsd-tdep.c.  */
-extern int i386bsd_sigcontext_pc_offset;
-
 void
 _initialize_i386bsd_nat (void)
 {
+  int sc_pc_offset;
+
   /* To support the recognition of signal handlers, i386bsd-tdep.c
      hardcodes some constants.  Inclusion of this file means that we
      are compiling a native debugger, which means that we can use the
      system header files and sysctl(3) to get at the relevant
      information.  */
 
+#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
+  extern int i386fbsd4_sc_pc_offset;
+#define SC_PC_OFFSET i386fbsd4_sc_pc_offset
+#elif defined (NetBSD) || defined (__NetBSD_Version__)
+  extern int i386nbsd_sc_pc_offset;
+#define SC_PC_OFFSET i386nbsd_sc_pc_offset
+#else
+  extern int i386bsd_sc_pc_offset;
+#define SC_PC_OFFSET i386bsd_sc_pc_offset
+#endif
+
   /* Override the default value for the offset of the program counter
      in the sigcontext structure.  */
-  i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc);
+  sc_pc_offset = offsetof (struct sigcontext, sc_pc);
+
+  if (SC_PC_OFFSET != sc_pc_offset)
+    {
+      warning ("\
+offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>.",
+	       sc_pc_offset, SC_PC_OFFSET);
+    }
+
+  SC_PC_OFFSET = sc_pc_offset;
 }
Index: i386bsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386bsd-tdep.c,v
retrieving revision 1.1
diff -u -p -r1.1 i386bsd-tdep.c
--- i386bsd-tdep.c 13 Jul 2001 18:27:21 -0000 1.1
+++ i386bsd-tdep.c 14 Jun 2002 19:41:06 -0000
@@ -1,5 +1,5 @@
 /* Target-dependent code for i386 BSD's.
-   Copyright 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,26 +23,19 @@
 #include "gdbcore.h"
 #include "regcache.h"
 
-/* Support for signal handlers.  */
-
-/* Range in which to find the signaltramp routine, traditionally found
-   on the use stack, just below the user area.  Initialized to values
-   that work for NetBSD and FreeBSD.  */
+#include "i386-tdep.h"
 
-CORE_ADDR i386bsd_sigtramp_start = 0xbfbfdf20;
-CORE_ADDR i386bsd_sigtramp_end = 0xbfbfdff0;
+/* Support for signal handlers.  */
 
 /* Return whether PC is in a BSD sigtramp routine.  */
 
-int
-i386bsd_in_sigtramp (CORE_ADDR pc, char *name)
+static int
+i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
-  return (pc >= i386bsd_sigtramp_start && pc < i386bsd_sigtramp_end);
-}
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
-/* Offset in the sigcontext structure of the program counter.
-   Initialized to the value from 4.4 BSD Lite.  */
-int i386bsd_sigcontext_pc_offset = 20;
+  return (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end);
+}
 
 /* Assuming FRAME is for a BSD sigtramp routine, return the address of
    the associated sigcontext structure.  */
@@ -62,23 +55,193 @@ i386bsd_sigcontext_addr (struct frame_in
 }
 
 /* Assuming FRAME is for a BSD sigtramp routine, return the saved
-   program counter.  */
+   program counter.
 
-static CORE_ADDR
+   Note: This function is used for Solaris 2 too, so don't make it
+   static.  */
+
+CORE_ADDR
 i386bsd_sigtramp_saved_pc (struct frame_info *frame)
 {
+  int sc_pc_offset = gdbarch_tdep (current_gdbarch)->sc_pc_offset;
   CORE_ADDR addr;
+
   addr = i386bsd_sigcontext_addr (frame);
-  return read_memory_unsigned_integer (addr + i386bsd_sigcontext_pc_offset, 4);
+  return read_memory_unsigned_integer (addr + sc_pc_offset, 4);
 }
 
 /* Return the saved program counter for FRAME.  */
 
-CORE_ADDR
+static CORE_ADDR
 i386bsd_frame_saved_pc (struct frame_info *frame)
 {
   if (frame->signal_handler_caller)
     return i386bsd_sigtramp_saved_pc (frame);
 
   return read_memory_unsigned_integer (frame->frame + 4, 4);
+}
+
+/* Return the start address of the sigtramp routine.  */
+
+CORE_ADDR
+i386bsd_sigtramp_start (CORE_ADDR pc)
+{
+  return gdbarch_tdep (current_gdbarch)->sigtramp_start;
+}
+
+/* Return the end address of the sigtramp routine.  */
+
+CORE_ADDR
+i386bsd_sigtramp_end (CORE_ADDR pc)
+{
+  return gdbarch_tdep (current_gdbarch)->sigtramp_end;
+}
+
+
+/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD).  */
+
+/* From <machine/signal.h>.  */
+int i386bsd_sc_pc_offset = 20;
+
+static void
+i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386bsd_pc_in_sigtramp);
+
+  tdep->jb_pc_offset = 0;
+
+  tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc;
+  tdep->sigtramp_start = 0xfdbfdfc0;
+  tdep->sigtramp_end = 0xfdbfe000;
+  tdep->sc_pc_offset = i386bsd_sc_pc_offset;
+}
+
+/* NetBSD 1.0 or later.  */
+
+/* From <machine/signal.h>.  */
+int i386nbsd_sc_pc_offset = 44;
+
+static void
+i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Obviously NetBSD is BSD-based.  */
+  i386bsd_init_abi (info, gdbarch);
+
+  /* NetBSD uses -freg-struct-return by default.  */
+  tdep->struct_return = reg_struct_return;
+
+  /* NetBSD uses a different memory layout.  */
+  tdep->sigtramp_start = 0xbfbfdf20;
+  tdep->sigtramp_end = 0xbfbfdff0;
+
+  /* NetBSD has a `struct sigcontext' that's different from the
+     origional 4.3 BSD.  */
+  tdep->sc_pc_offset = i386nbsd_sc_pc_offset;
+}
+
+/* NetBSD ELF.  */
+static void
+i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* It's still NetBSD.  */
+  i386nbsd_init_abi (info, gdbarch);
+
+  /* But ELF-based.  */
+  i386_elf_init_abi (info, gdbarch);
+
+  /* NetBSD ELF uses -fpcc-struct-return by default.  */
+  tdep->struct_return = pcc_struct_return;
+
+  /* We support the SSE registers on NetBSD ELF.  */
+  tdep->num_xmm_regs = I386_NUM_XREGS - 1;
+  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS
+			+ I386_NUM_XREGS);
+}
+
+/* FreeBSD 3.0-RELEASE or later.  */
+
+CORE_ADDR i386fbsd_sigtramp_start = 0xbfbfdf20;
+CORE_ADDR i386fbsd_sigtramp_end = 0xbfbfdff0;
+
+static void
+i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Obviously FreeBSD is BSD-based.  */
+  i386bsd_init_abi (info, gdbarch);
+
+  /* FreeBSD uses -freg-struct-return by default.  */
+  tdep->struct_return = reg_struct_return;
+
+  /* FreeBSD uses a different memory layout.  */
+  tdep->sigtramp_start = i386fbsd_sigtramp_start;
+  tdep->sigtramp_end = i386fbsd_sigtramp_end;
+}
+
+static void
+i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  /* It's almost identical to FreeBSD a.out.  */
+  i386fbsdaout_init_abi (info, gdbarch);
+
+  /* Except that it uses ELF.  */
+  i386_elf_init_abi (info, gdbarch);
+}
+
+/* FreeBSD 4.0-RELEASE or later.  */
+
+/* From <machine/signal.h>.  */
+int i386fbsd4_sc_pc_offset = 76;
+
+static void
+i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Inherit stuff from older releases.  We assume that FreeBSD
+     4.0-RELEASE always uses ELF.  */
+  i386fbsd_init_abi (info, gdbarch);
+
+  /* FreeBSD 4.0 introduced a new `struct sigcontext'.  */
+  tdep->sc_pc_offset = i386fbsd4_sc_pc_offset;
+}
+
+
+static enum gdb_osabi
+i386bsd_aout_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0)
+    return GDB_OSABI_NETBSD_AOUT;
+
+  if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0)
+    return GDB_OSABI_FREEBSD_AOUT;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_i386bsd_tdep (void);
+
+void
+_initialize_i386bsd_tdep (void)
+{
+  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour,
+				  i386bsd_aout_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_AOUT,
+			  i386nbsd_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_ELF,
+ 			  i386nbsdelf_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_FREEBSD_AOUT,
+			  i386fbsdaout_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_FREEBSD_ELF,
+			  i386fbsd4_init_abi);
 }
Index: i386fbsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386fbsd-nat.c,v
retrieving revision 1.1
diff -u -p -r1.1 i386fbsd-nat.c
--- i386fbsd-nat.c 21 Jul 2001 20:16:44 -0000 1.1
+++ i386fbsd-nat.c 14 Jun 2002 19:41:06 -0000
@@ -1,5 +1,5 @@
 /* Native-dependent code for FreeBSD/i386.
-   Copyright 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -79,7 +79,7 @@ _initialize_i386fbsd_nat (void)
 {
   /* FreeBSD provides a kern.ps_strings sysctl that we can use to
      locate the sigtramp.  That way we can still recognize a sigtramp
-     if it's location is changed in a new kernel.  Of course this is
+     if its location is changed in a new kernel.  Of course this is
      still based on the assumption that the sigtramp is placed
      directly under the location where the program arguments and
      environment can be found.  */
@@ -89,13 +89,16 @@ _initialize_i386fbsd_nat (void)
     int ps_strings;
     size_t len;
 
+    extern CORE_ADDR i386fbsd_sigtramp_start;
+    extern CORE_ADDR i386fbsd_sigtramp_end;
+
     mib[0] = CTL_KERN;
     mib[1] = KERN_PS_STRINGS;
     len = sizeof (ps_strings);
     if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
       {
-	i386bsd_sigtramp_start = ps_strings - 128;
-	i386bsd_sigtramp_end = ps_strings;
+	i386fbsd_sigtramp_start = ps_strings - 128;
+	i386fbsd_sigtramp_end = ps_strings;
       }
   }
 #endif
Index: i386nbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386nbsd-tdep.c,v
retrieving revision 1.4
diff -u -p -r1.4 i386nbsd-tdep.c
--- i386nbsd-tdep.c 11 May 2002 21:22:51 -0000 1.4
+++ i386nbsd-tdep.c 14 Jun 2002 19:41:06 -0000
@@ -137,16 +137,6 @@ static struct core_fns i386nbsd_elfcore_
   NULL					/* next */
 };
 
-/* FIXME: should be multi-arch'd */
-int
-i386nbsd_aout_use_struct_convention (int gcc_p, struct type *type)
-{
-  return !(TYPE_LENGTH (type) == 1
-	   || TYPE_LENGTH (type) == 2
-	   || TYPE_LENGTH (type) == 4
-	   || TYPE_LENGTH (type) == 8);
-}
-
 void
 _initialize_i386nbsd_tdep (void)
 {
Index: config/i386/i386nw.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/i386nw.mt,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 i386nw.mt
--- config/i386/i386nw.mt 16 Apr 1999 01:34:18 -0000 1.1.1.1
+++ config/i386/i386nw.mt 14 Jun 2002 19:41:06 -0000
@@ -1,3 +1,3 @@
 # Target: Intel 386 running NetWare
 TDEPFILES= i386-tdep.o i387-tdep.o
-TM_FILE= tm-i386nw.h
+TM_FILE= tm-i386.h
Index: config/i386/i386sol2.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/i386sol2.mh,v
retrieving revision 1.5
diff -u -p -r1.5 i386sol2.mh
--- config/i386/i386sol2.mh 11 May 2002 17:22:27 -0000 1.5
+++ config/i386/i386sol2.mh 14 Jun 2002 19:41:06 -0000
@@ -5,4 +5,5 @@ XM_CLIBS= -lsocket -lnsl
 
 NAT_FILE= nm-i386sol2.h
 NATDEPFILES= core-regset.o fork-child.o i386v4-nat.o corelow.o \
-	procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o
+	procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o \
+        solib.o solib-svr4.o solib-legacy.o
Index: config/i386/i386sol2.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/i386sol2.mt,v
retrieving revision 1.3
diff -u -p -r1.3 i386sol2.mt
--- config/i386/i386sol2.mt 10 Mar 2001 06:17:21 -0000 1.3
+++ config/i386/i386sol2.mt 14 Jun 2002 19:41:06 -0000
@@ -1,3 +1,3 @@
-# Target: Intel 386 running SVR4
-TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o
+# Target: Intel 386 running Solaris 2 (SVR4)
+TDEPFILES= i386-tdep.o i387-tdep.o i386-sol2-tdep.o i386bsd-tdep.o
 TM_FILE= tm-i386sol2.h
Index: config/i386/tm-fbsd.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-fbsd.h,v
retrieving revision 1.5
diff -u -p -r1.5 tm-fbsd.h
--- config/i386/tm-fbsd.h 28 Jul 2001 17:03:38 -0000 1.5
+++ config/i386/tm-fbsd.h 14 Jun 2002 19:41:06 -0000
@@ -24,56 +24,17 @@
 #define HAVE_I387_REGS
 #include "i386/tm-i386.h"
 
-/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering
-   scheme by default, so we must redefine STAB_REG_TO_REGNUM.  This
-   messes up the floating-point registers for a.out, but there is not
-   much we can do about that.  */
-
-#undef STAB_REG_TO_REGNUM
-#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-
-/* FreeBSD uses the old gcc convention for struct returns.  */
-
-#define USE_STRUCT_CONVENTION(gcc_p, type) \
-  generic_use_struct_convention (1, type)
-
-
-/* Support for longjmp.  */
-
-/* Details about jmp_buf.  It's supposed to be an array of integers.  */
-
-#define JB_ELEMENT_SIZE 4	/* Size of elements in jmp_buf.  */
-#define JB_PC		0	/* Array index of saved PC.  */
-
-/* Figure out where the longjmp will land.  Store the address that
-   longjmp will jump to in *ADDR, and return non-zero if successful.  */
-
-#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
-extern int get_longjmp_target (CORE_ADDR *addr);
-
-
-/* Support for signal handlers.  */
-
-#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
-extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
-
 /* These defines allow the recognition of sigtramps as a function name
    <sigtramp>.
 
-   FIXME: kettenis/2001-07-13: These should be added to the target
-   vector and turned into functions when we go "multi-arch".  */
-
-#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
-#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
-extern CORE_ADDR i386bsd_sigtramp_start;
-extern CORE_ADDR i386bsd_sigtramp_end;
-
-/* Override FRAME_SAVED_PC to enable the recognition of signal handlers.  */
-
-#undef FRAME_SAVED_PC
-#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
-extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
-
+   FIXME: kettenis/2002-05-12: Of course these defines will have to go
+   if we go truly "multi-arch", but I don't know yet how to get rid of
+   them.  */
+
+#define SIGTRAMP_START(pc) i386bsd_sigtramp_start (pc)
+#define SIGTRAMP_END(pc) i386bsd_sigtramp_end (pc)
+extern CORE_ADDR i386bsd_sigtramp_start (CORE_ADDR pc);
+extern CORE_ADDR i386bsd_sigtramp_end (CORE_ADDR pc);
 
 /* Shared library support.  */
 
Index: config/i386/tm-go32.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-go32.h,v
retrieving revision 1.5
diff -u -p -r1.5 tm-go32.h
--- config/i386/tm-go32.h 2 Dec 2001 18:29:08 -0000 1.5
+++ config/i386/tm-go32.h 14 Jun 2002 19:41:06 -0000
@@ -26,43 +26,4 @@
 
 #include "i386/tm-i386.h"
 
-/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
-   chain-pointer.
-   In the case of the i386, the frame's nominal address
-   is the address of a 4-byte word containing the calling frame's address.
-   DJGPP doesn't have any special frames for signal handlers, they are
-   just normal C functions. */
-#undef  FRAME_CHAIN
-#define FRAME_CHAIN(thisframe) \
-  (!inside_entry_file ((thisframe)->pc) ? \
-   read_memory_integer ((thisframe)->frame, 4) :\
-   0)
-
-/* A macro that tells us whether the function invocation represented
-   by FI does not have a frame on the stack associated with it.  If it
-   does not, FRAMELESS is set to 1, else 0.  */
-#undef  FRAMELESS_FUNCTION_INVOCATION
-#define FRAMELESS_FUNCTION_INVOCATION(FI) \
-     (frameless_look_for_prologue(FI))
-
-extern CORE_ADDR i386go32_frame_saved_pc (struct frame_info *frame);
-#undef  FRAME_SAVED_PC
-#define FRAME_SAVED_PC(FRAME) (i386go32_frame_saved_pc ((FRAME)))
-
-/* Support for longjmp.  */
-
-/* Details about jmp_buf.  It's supposed to be an array of integers.  */
-
-#define JB_ELEMENT_SIZE 4	/* Size of elements in jmp_buf.  */
-#define JB_PC		8	/* Array index of saved PC inside jmp_buf.  */
-
-/* Figure out where the longjmp will land.  Slurp the args out of the
-   stack.  We expect the first arg to be a pointer to the jmp_buf
-   structure from which we extract the pc (JB_PC) that we will land
-   at.  The pc is copied into ADDR.  This routine returns true on
-   success.  */
-
-#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
-extern int get_longjmp_target (CORE_ADDR *addr);
-
 #endif /* TM_GO32_H */
Index: config/i386/tm-i386.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-i386.h,v
retrieving revision 1.29
diff -u -p -r1.29 tm-i386.h
--- config/i386/tm-i386.h 29 Jan 2002 04:42:37 -0000 1.29
+++ config/i386/tm-i386.h 14 Jun 2002 19:41:06 -0000
@@ -63,11 +63,6 @@ struct type;
 
 extern int i386_skip_prologue (int);
 
-/* Immediately after a function call, return the saved pc.  */
-
-#define SAVED_PC_AFTER_CALL(frame) i386_saved_pc_after_call (frame)
-extern CORE_ADDR i386_saved_pc_after_call (struct frame_info *frame);
-
 /* Stack grows downward.  */
 
 #define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
@@ -118,7 +113,7 @@ extern CORE_ADDR i386_saved_pc_after_cal
 #endif
 
 /* Largest number of registers we could have in any configuration.  */
-#define MAX_NUM_REGS (16 + 16 + 9)
+#define MAX_NUM_REGS (16 + 16 + 9 + 1)
 
 /* Register numbers of various important registers.
    Note that some of these values are "real" register numbers,
@@ -139,60 +134,8 @@ extern CORE_ADDR i386_saved_pc_after_cal
 #else
 #define FP0_REGNUM 0
 #endif
-
-/* Return the name of register REG.  */
-
-#define REGISTER_NAME(reg) i386_register_name ((reg))
-extern char *i386_register_name (int reg);
-
-/* Use the "default" register numbering scheme for stabs and COFF.  */
-
-#define STAB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg))
-#define SDB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg))
-extern int i386_stab_reg_to_regnum (int reg);
-
-/* Use the DWARF register numbering scheme for DWARF and DWARF 2.  */
-
-#define DWARF_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-#define DWARF2_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-extern int i386_dwarf_reg_to_regnum (int reg);
-
-/* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to be
-   in use on any of the supported i386 targets.  */
 
 
-/* Sizes of individual register sets.  These cover the entire register
-   file, so summing up the sizes of those portions actually present
-   yields REGISTER_BYTES.  */
-#define SIZEOF_GREGS (NUM_GREGS * 4)
-#define SIZEOF_FPU_REGS (8 * 10)
-#define SIZEOF_FPU_CTRL_REGS (8 * 4)
-#define SIZEOF_SSE_REGS (8 * 16 + 4)
-
-
-/* Total amount of space needed to store our copies of the machine's register
-   state, the array `registers'. */
-#ifdef HAVE_SSE_REGS
-#define REGISTER_BYTES \
-  (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS)
-#else
-#ifdef HAVE_I387_REGS
-#define REGISTER_BYTES (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS)
-#else
-#define REGISTER_BYTES (SIZEOF_GREGS)
-#endif
-#endif
-
-/* Return the offset into the register array of the start of register
-   number REG.  */
-#define REGISTER_BYTE(reg) i386_register_byte ((reg))
-extern int i386_register_byte (int reg);
-
-/* Return the number of bytes of storage in GDB's register array
-   occupied by register REG.  */
-#define REGISTER_RAW_SIZE(reg) i386_register_raw_size ((reg))
-extern int i386_register_raw_size (int reg);
-
 /* Largest value REGISTER_RAW_SIZE can have.  */
 #define MAX_REGISTER_RAW_SIZE 16
 
@@ -275,18 +218,6 @@ extern void i386_store_return_value (str
   i386_extract_struct_value_address ((regbuf))
 extern CORE_ADDR i386_extract_struct_value_address (char *regbuf);
 
-/* The following redefines make backtracing through sigtramp work.
-   They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
-   from the sigcontext structure which is pushed by the kernel on the
-   user stack, along with a pointer to it.  */
-
-/* Return the chain-pointer for FRAME.  In the case of the i386, the
-   frame's nominal address is the address of a 4-byte word containing
-   the calling frame's address.  */
-
-#define FRAME_CHAIN(frame) i386_frame_chain ((frame))
-extern CORE_ADDR i386_frame_chain (struct frame_info *frame);
-
 /* Determine whether the function invocation represented by FRAME does
    not have a from on the stack associated with it.  If it does not,
    return non-zero, otherwise return zero.  */
@@ -294,11 +225,6 @@ extern CORE_ADDR i386_frame_chain (struc
 #define FRAMELESS_FUNCTION_INVOCATION(frame) \
   i386_frameless_function_invocation (frame)
 extern int i386_frameless_function_invocation (struct frame_info *frame);
-
-/* Return the saved program counter for FRAME.  */
-
-#define FRAME_SAVED_PC(frame) i386_frame_saved_pc (frame)
-extern CORE_ADDR i386_frame_saved_pc (struct frame_info *frame);
 
 #define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
 
Index: config/i386/tm-i386sol2.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-i386sol2.h,v
retrieving revision 1.10
diff -u -p -r1.10 tm-i386sol2.h
--- config/i386/tm-i386sol2.h 30 Jul 2001 21:45:26 -0000 1.10
+++ config/i386/tm-i386sol2.h 14 Jun 2002 19:41:06 -0000
@@ -24,11 +24,6 @@
 #define HAVE_I387_REGS
 #include "i386/tm-i386v4.h"
 
-/* We use stabs-in-ELF with the DWARF register numbering scheme.  */
-
-#undef STAB_REG_TO_REGNUM
-#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-
 /* If the current gcc for for this target does not produce correct
    debugging information for float parameters, both prototyped and
    unprototyped, then define this macro.  This forces gdb to always
@@ -36,15 +31,6 @@
    callee. */
 
 #define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1)
-
-/* Signal handler frames under Solaris 2 are recognized by a return address
-   of 0xFFFFFFFF, the third parameter on the signal handler stack is
-   a pointer to an ucontext.  */
-#undef sigtramp_saved_pc
-#undef I386V4_SIGTRAMP_SAVED_PC
-#define SIGCONTEXT_PC_OFFSET (36 + 14 * 4)
-#undef IN_SIGTRAMP
-#define IN_SIGTRAMP(pc, name) (pc == 0xFFFFFFFF)
 
 /* The SunPRO compiler puts out 0 instead of the address in N_SO symbols,
    and for SunPRO 3.0, N_FUN symbols too.  */
Index: config/i386/tm-i386v4.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-i386v4.h,v
retrieving revision 1.5
diff -u -p -r1.5 tm-i386v4.h
--- config/i386/tm-i386v4.h 5 Jun 2002 19:18:19 -0000 1.5
+++ config/i386/tm-i386v4.h 14 Jun 2002 19:41:06 -0000
@@ -31,49 +31,4 @@
 
 #include "config/tm-sysv4.h"
 
-/* Use the alternate method of determining valid frame chains. */
-
-#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
-
-/* Offsets (in target ints) into jmp_buf.  Not defined in any system header
-   file, so we have to step through setjmp/longjmp with a debugger and figure
-   them out.  Note that <setjmp> defines _JBLEN as 10, which is the default
-   if no specific machine is selected, even though we only use 6 slots. */
-
-#define JB_ELEMENT_SIZE sizeof(int)	/* jmp_buf[_JBLEN] is array of ints */
-
-#define JB_EBX	0
-#define JB_ESI	1
-#define JB_EDI	2
-#define JB_EBP	3
-#define JB_ESP	4
-#define JB_EDX	5
-
-#define JB_PC	JB_EDX		/* Setjmp()'s return PC saved in EDX */
-
-/* Figure out where the longjmp will land.  Slurp the args out of the stack.
-   We expect the first arg to be a pointer to the jmp_buf structure from which
-   we extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
-   This routine returns true on success */
-
-extern int get_longjmp_target (CORE_ADDR *);
-
-#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
-
-/* The following redefines make backtracing through sigtramp work.
-   They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
-   from the ucontext structure which is pushed by the kernel on the
-   user stack. Unfortunately there are three variants of sigtramp handlers.  */
-
-#define I386V4_SIGTRAMP_SAVED_PC
-#define IN_SIGTRAMP(pc, name) ((name)					\
-			       && (STREQ ("_sigreturn", name)		\
-				   || STREQ ("_sigacthandler", name)	\
-				   || STREQ ("sigvechandler", name)))
-
-/* Saved Pc.  Get it from ucontext if within sigtramp.  */
-
-#define sigtramp_saved_pc i386v4_sigtramp_saved_pc
-extern CORE_ADDR i386v4_sigtramp_saved_pc (struct frame_info *);
-
 #endif /* ifndef TM_I386V4_H */
Index: config/i386/tm-linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-linux.h,v
retrieving revision 1.19
diff -u -p -r1.19 tm-linux.h
--- config/i386/tm-linux.h 5 Jun 2002 19:18:19 -0000 1.19
+++ config/i386/tm-linux.h 14 Jun 2002 19:41:06 -0000
@@ -33,72 +33,9 @@
 #include "i386/tm-i386.h"
 #include "config/tm-linux.h"
 
-/* Register number for the "orig_eax" pseudo-register.  If this
-   pseudo-register contains a value >= 0 it is interpreted as the
-   system call number that the kernel is supposed to restart.  */
-#define I386_LINUX_ORIG_EAX_REGNUM (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS)
-
-/* Adjust a few macros to deal with this extra register.  */
-
-#undef NUM_REGS
-#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS + 1)
-
-#undef MAX_NUM_REGS
-#define MAX_NUM_REGS (16 + 16 + 9 + 1)
-
-#undef REGISTER_BYTES
-#define REGISTER_BYTES \
-  (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS + 4)
-
-#undef REGISTER_NAME
-#define REGISTER_NAME(reg) i386_linux_register_name ((reg))
-extern char *i386_linux_register_name (int reg);
-
-#undef REGISTER_BYTE
-#define REGISTER_BYTE(reg) i386_linux_register_byte ((reg))
-extern int i386_linux_register_byte (int reg);
-
-#undef REGISTER_RAW_SIZE
-#define REGISTER_RAW_SIZE(reg) i386_linux_register_raw_size ((reg))
-extern int i386_linux_register_raw_size (int reg);
-
-/* GNU/Linux ELF uses stabs-in-ELF with the DWARF register numbering
-   scheme by default, so we must redefine STAB_REG_TO_REGNUM.  This
-   messes up the floating-point registers for a.out, but there is not
-   much we can do about that.  */
-#undef STAB_REG_TO_REGNUM
-#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-
-/* Use target_specific function to define link map offsets.  */
-extern struct link_map_offsets *i386_linux_svr4_fetch_link_map_offsets (void);
-#define SVR4_FETCH_LINK_MAP_OFFSETS() i386_linux_svr4_fetch_link_map_offsets ()
-
 /* The following works around a problem with /usr/include/sys/procfs.h  */
 #define sys_quotactl 1
 
-/* When the i386 Linux kernel calls a signal handler, the return
-   address points to a bit of code on the stack.  These definitions
-   are used to identify this bit of code as a signal trampoline in
-   order to support backtracing through calls to signal handlers.  */
-
-#define IN_SIGTRAMP(pc, name) i386_linux_in_sigtramp (pc, name)
-extern int i386_linux_in_sigtramp (CORE_ADDR, char *);
-
-#undef FRAME_CHAIN
-#define FRAME_CHAIN(frame) i386_linux_frame_chain (frame)
-extern CORE_ADDR i386_linux_frame_chain (struct frame_info *frame);
-
-#undef FRAME_SAVED_PC
-#define FRAME_SAVED_PC(frame) i386_linux_frame_saved_pc (frame)
-extern CORE_ADDR i386_linux_frame_saved_pc (struct frame_info *frame);
-
-#undef SAVED_PC_AFTER_CALL
-#define SAVED_PC_AFTER_CALL(frame) i386_linux_saved_pc_after_call (frame)
-extern CORE_ADDR i386_linux_saved_pc_after_call (struct frame_info *);
-
-#define TARGET_WRITE_PC(pc, ptid) i386_linux_write_pc (pc, ptid)
-extern void i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid);
-
 /* When we call a function in a shared library, and the PLT sends us
    into the dynamic linker to find the function's real address, we
    need to skip over the dynamic linker call.  This function decides
@@ -110,22 +47,5 @@ extern CORE_ADDR i386_linux_skip_solib_r
 /* N_FUN symbols in shared libaries have 0 for their values and need
    to be relocated. */
 #define SOFUN_ADDRESS_MAYBE_MISSING
-
-
-/* Support for longjmp.  */
-
-/* Details about jmp_buf.  It's supposed to be an array of integers.  */
-
-#define JB_ELEMENT_SIZE 4	/* Size of elements in jmp_buf.  */
-#define JB_PC		5	/* Array index of saved PC.  */
-
-/* Figure out where the longjmp will land.  Slurp the args out of the
-   stack.  We expect the first arg to be a pointer to the jmp_buf
-   structure from which we extract the pc (JB_PC) that we will land
-   at.  The pc is copied into ADDR.  This routine returns true on
-   success.  */
-
-#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
-extern int get_longjmp_target (CORE_ADDR *addr);
 
 #endif /* #ifndef TM_LINUX_H */
Index: config/i386/tm-nbsd.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-nbsd.h,v
retrieving revision 1.10
diff -u -p -r1.10 tm-nbsd.h
--- config/i386/tm-nbsd.h 22 May 2002 03:59:54 -0000 1.10
+++ config/i386/tm-nbsd.h 14 Jun 2002 19:41:06 -0000
@@ -26,39 +26,16 @@
 
 #include "i386/tm-i386.h"
 
-#define JB_ELEMENT_SIZE sizeof(int)	/* jmp_buf[_JBLEN] is array of ints */
-#define JB_PC	0		/* Setjmp()'s return PC saved here */
-
-/* Figure out where the longjmp will land.  Slurp the args out of the stack.
-   We expect the first arg to be a pointer to the jmp_buf structure from which
-   we extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
-   This routine returns true on success */
-
-extern int get_longjmp_target (CORE_ADDR *);
-
-#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
-
-
-/* Support for signal handlers.  */
-
-#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
-extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
-
 /* These defines allow the recognition of sigtramps as a function name
    <sigtramp>.
 
-   FIXME: kettenis/2001-07-13: These should be added to the target
-   vector and turned into functions when we go "multi-arch".  */
-
-#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
-#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
-extern CORE_ADDR i386bsd_sigtramp_start;
-extern CORE_ADDR i386bsd_sigtramp_end;
-
-/* Override FRAME_SAVED_PC to enable the recognition of signal handlers.  */
-
-#undef FRAME_SAVED_PC
-#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
-extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
+   FIXME: kettenis/2002-05-12: Of course these defines will have to go
+   if we go truly "multi-arch", but I don't know yet how to get rid of
+   them.  */
+
+#define SIGTRAMP_START(pc) i386bsd_sigtramp_start (pc)
+#define SIGTRAMP_END(pc) i386bsd_sigtramp_end (pc)
+extern CORE_ADDR i386bsd_sigtramp_start (CORE_ADDR pc);
+extern CORE_ADDR i386bsd_sigtramp_end (CORE_ADDR pc);
 
 #endif /* TM_NBSD_H */
Index: config/i386/tm-nbsdaout.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-nbsdaout.h,v
retrieving revision 1.1
diff -u -p -r1.1 tm-nbsdaout.h
--- config/i386/tm-nbsdaout.h 22 May 2002 03:59:54 -0000 1.1
+++ config/i386/tm-nbsdaout.h 14 Jun 2002 19:41:06 -0000
@@ -27,8 +27,4 @@
 #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
   (name && !strcmp(name, "_DYNAMIC"))
 
-extern use_struct_convention_fn i386nbsd_aout_use_struct_convention;
-#define USE_STRUCT_CONVENTION(gcc_p, type) \
-        i386nbsd_aout_use_struct_convention(gcc_p, type)
-
 #endif /* TM_NBSDAOUT_H */
--- /dev/null	Fri Jun 14 21:40:52 2002
+++ i386-linux-tdep.h	Sun Jun  9 16:08:22 2002
@@ -0,0 +1,36 @@
+/* Target-dependent code for Linux/x86.
+   Copyright 2002
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef I386_LINUX_TDEP_H
+#define I386_LINUX_TDEP_H
+
+/* The Linux kernel pretends there is an additional "orig_eax"
+   register.  Since GDB needs access to that register to be able to
+   properly restart system calls when necessary (see
+   i386-linux-tdep.c) we need our own versions of a number of
+   functions that deal with GDB's register cache.  */
+
+/* Register number for the "orig_eax" pseudo-register.  If this
+   pseudo-register contains a value >= 0 it is interpreted as the
+   system call number that the kernel is supposed to restart.  */
+#define I386_LINUX_ORIG_EAX_REGNUM I386_SSE_NUM_REGS
+
+#endif /* i386-linux-tdep.h */
--- /dev/null	Fri Jun 14 21:40:52 2002
+++ i386-sol2-tdep.c	Sun Jun  9 16:56:43 2002
@@ -0,0 +1,59 @@
+/* Target-dependent code for Solaris x86.
+   Copyright 2002 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+
+#include "i386-tdep.h"
+
+static int
+i386_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+  /* Signal handler frames under Solaris 2 are recognized by a return
+     address of 0xffffffff.  */
+  return (pc == 0xffffffff);
+}
+
+/* Solaris 2.  */
+
+static void
+i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Solaris is SVR4-based.  */
+  i386_svr4_init_abi (info, gdbarch);
+
+  /* Signal trampolines are different from SVR4, in fact they're
+     rather similar to BSD.  */
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp);
+  tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc;
+  tdep->sc_pc_offset = 36 + 14 * 4;
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_i386_sol2_tdep (void);
+
+void
+_initialize_i386_sol2_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_SOLARIS,
+			  i386_sol2_init_abi);
+}



More information about the Gdb-patches mailing list