* config/i386/i386sol2.mt (TDEPFILES): Add i386-sol2-tdep.o and
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 54746eeb8654a1473a551a940d98fd44b22d88ac..ab52ba41325afbfdd48a208aae2698c0f4e7e297 100644 (file)
@@ -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 (struct frame_info *frame)
 
 /* 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)
 }
 \f
 
-#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 */
 \f
 
 CORE_ADDR
@@ -1044,6 +1022,37 @@ i386_extract_struct_value_address (char *regbuf)
 }
 \f
 
+/* 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);
+}
+\f
+
 /* 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 type *type, int regnum,
 }
 \f     
 
-#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 */
-\f
-
 #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 *name)
 }
 \f
 
+/* 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);
+}
+\f
+
 /* 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, disassemble_info *info)
      or intel_flavor.  */
   internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
-
 \f
-/* 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;
+  return (name && (strcmp ("_sigreturn", name) == 0
+                  || strcmp ("_sigacthandler", name) == 0
+                  || strcmp ("sigvechandler", name) == 0));
+}
 
-  name = bfd_get_section_name (abfd, sect);
-  sectsize = bfd_section_size (abfd, sect);
+/* Get saved user PC for sigtramp from the pushed ucontext on the
+   stack for all three variants of SVR4 sigtramps.  */
 
-  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+CORE_ADDR
+i386_svr4_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)
     {
-      unsigned int name_length, data_length, note_type;
-      char *note;
+      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 the section is larger than this, it's probably not what we
-        are looking for.  */
-      if (sectsize > 128)
-       sectsize = 128;
+  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);
+}
+\f
 
-      note = alloca (sectsize);
+/* DJGPP.  */
 
-      bfd_get_section_contents (abfd, sect, note,
-                               (file_ptr) 0, (bfd_size_type) sectsize);
+static int
+i386_go32_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+  /* DJGPP doesn't have any special frames for signal handlers.  */
+  return 0;
+}
+\f
 
-      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);
+/* Generic ELF.  */
 
-      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);
+void
+i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  /* We typically use stabs-in-ELF with the DWARF register numbering.  */
+  set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+}
 
-         /* 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;
+/* System V Release 4 (SVR4).  */
 
-      /* If the section is larger than this, it's probably not what we are
-         looking for.  */
-      if (sectsize > 128)
-       sectsize = 128;
+void
+i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-      note = alloca (sectsize);
+  /* System V Release 4 uses ELF.  */
+  i386_elf_init_abi (info, gdbarch);
 
-      bfd_get_section_contents (abfd, sect, note,
-                               (file_ptr) 0, (bfd_size_type) sectsize);
+  /* FIXME: kettenis/20020511: Why do we override this function here?  */
+  set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
 
-      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);
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp);
+  tdep->sigtramp_saved_pc = i386_svr4_sigtramp_saved_pc;
 
-      if (name_length == 7 && desc_length == 4
-         && note_type == NT_NETBSD_IDENT
-         && strcmp (note + 12, "NetBSD") == 0)
-       *abi = ABI_TAG_OS_NETBSD;
-    }
+  tdep->jb_pc_offset = 20;
 }
 
-static int
-i386_elf_abi_from_note (bfd *abfd)
-{
-  enum i386_abi abi = I386_ABI_UNKNOWN;
-  
-  bfd_map_over_sections (abfd, process_note_sections, &abi);
-
-  return abi;
-}
+/* DJGPP.  */
 
-static enum i386_abi
-i386_elf_abi (bfd *abfd)
+void
+i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  int elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
-
-  /* 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);
-
-      if (abi != I386_ABI_UNKNOWN)
-       return abi;
-
-      /* 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;
-    }
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  switch (elfosabi)
-    {
-    case ELFOSABI_NONE:
-      return I386_ABI_SVR4;
-    case ELFOSABI_FREEBSD:
-      return I386_ABI_FREEBSD;
-    }
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386_go32_pc_in_sigtramp);
 
-  return I386_ABI_UNKNOWN;
+  tdep->jb_pc_offset = 36;
 }
 
-struct i386_abi_handler
-{
-  struct i386_abi_handler *next;
-  enum i386_abi abi;
-  void (*init_abi)(struct gdbarch_info, struct gdbarch *);
-};
-
-struct i386_abi_handler *i386_abi_handler_list = NULL;
+/* 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;
 }
+\f
 
 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 info, struct gdbarch_list *arches)
   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;
 
-  /* 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;
+  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;
+
+  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 info, struct gdbarch_list *arches)
 
   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_use_struct_convention (gdbarch, i386_use_struct_convention);
+
+  /* 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);
 
-  /* 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);
+  /* 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;
+}
+\f
+
 /* 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);
 }
This page took 0.031064 seconds and 4 git commands to generate.