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

Mark Kettenis
2002-06-14T19:45:41Z

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;
+}
+\f
+
+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)
}
\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
}
\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 typ
}
\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
}
\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, di
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;
-
- 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);
}
+\f
+
+/* 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;
}
+\f
+
+/* 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;
}
+\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 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;
+}
+\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);
}
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));
}
\f
-/* 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;
+}
+\f
+
+/* 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;
+}
+
+\f
+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;
+}
+
+\f
+/* 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)
-\f
-
-/* 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);
-\f
-
-/* 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);
-\f
+ 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. */
\f

-/* 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
-\f
-
-/* 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)
-
-\f
-/* 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;
+}
+\f
+
+/* 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);
+}