diff options
-rw-r--r-- | gdb/ChangeLog | 171 | ||||
-rw-r--r-- | gdb/config/i386/i386nw.mt | 2 | ||||
-rw-r--r-- | gdb/config/i386/i386sol2.mh | 3 | ||||
-rw-r--r-- | gdb/config/i386/i386sol2.mt | 4 | ||||
-rw-r--r-- | gdb/config/i386/tm-fbsd.h | 53 | ||||
-rw-r--r-- | gdb/config/i386/tm-go32.h | 39 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386.h | 76 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386nw.h | 49 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386sol2.h | 14 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386v4.h | 45 | ||||
-rw-r--r-- | gdb/config/i386/tm-linux.h | 80 | ||||
-rw-r--r-- | gdb/config/i386/tm-nbsd.h | 37 | ||||
-rw-r--r-- | gdb/config/i386/tm-nbsdaout.h | 4 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.c | 67 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.h | 36 | ||||
-rw-r--r-- | gdb/i386-sol2-tdep.c | 59 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 529 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 80 | ||||
-rw-r--r-- | gdb/i386bsd-nat.c | 28 | ||||
-rw-r--r-- | gdb/i386bsd-tdep.c | 201 | ||||
-rw-r--r-- | gdb/i386fbsd-nat.c | 11 | ||||
-rw-r--r-- | gdb/i386nbsd-tdep.c | 10 |
22 files changed, 856 insertions, 742 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8b041c42e94..dfe01b916f5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,174 @@ +2002-06-14 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. + 2002-06-14 Daniel Jacobowitz <drow@mvista.com> * gdbtypes.h (TYPE_FLAG_VARARGS): Update comment. diff --git a/gdb/config/i386/i386nw.mt b/gdb/config/i386/i386nw.mt index 3109c42149e..9eafe7dcfd7 100644 --- a/gdb/config/i386/i386nw.mt +++ b/gdb/config/i386/i386nw.mt @@ -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 diff --git a/gdb/config/i386/i386sol2.mh b/gdb/config/i386/i386sol2.mh index ec93f4a75b9..931cc132bbb 100644 --- a/gdb/config/i386/i386sol2.mh +++ b/gdb/config/i386/i386sol2.mh @@ -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 diff --git a/gdb/config/i386/i386sol2.mt b/gdb/config/i386/i386sol2.mt index 86d93a378b1..f8fabd494b7 100644 --- a/gdb/config/i386/i386sol2.mt +++ b/gdb/config/i386/i386sol2.mt @@ -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 diff --git a/gdb/config/i386/tm-fbsd.h b/gdb/config/i386/tm-fbsd.h index 61f5de57f4a..f51859d0b46 100644 --- a/gdb/config/i386/tm-fbsd.h +++ b/gdb/config/i386/tm-fbsd.h @@ -24,56 +24,17 @@ #define HAVE_I387_REGS #include "i386/tm-i386.h" -/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering - scheme by default, so we must redefine STAB_REG_TO_REGNUM. This - messes up the floating-point registers for a.out, but there is not - much we can do about that. */ - -#undef STAB_REG_TO_REGNUM -#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) - -/* FreeBSD uses the old gcc convention for struct returns. */ - -#define USE_STRUCT_CONVENTION(gcc_p, type) \ - generic_use_struct_convention (1, type) - - -/* Support for longjmp. */ - -/* Details about jmp_buf. It's supposed to be an array of integers. */ - -#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */ -#define JB_PC 0 /* Array index of saved PC. */ - -/* Figure out where the longjmp will land. Store the address that - longjmp will jump to in *ADDR, and return non-zero if successful. */ - -#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr) -extern int get_longjmp_target (CORE_ADDR *addr); - - -/* Support for signal handlers. */ - -#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name) -extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name); - /* These defines allow the recognition of sigtramps as a function name <sigtramp>. - FIXME: kettenis/2001-07-13: These should be added to the target - vector and turned into functions when we go "multi-arch". */ - -#define SIGTRAMP_START(pc) i386bsd_sigtramp_start -#define SIGTRAMP_END(pc) i386bsd_sigtramp_end -extern CORE_ADDR i386bsd_sigtramp_start; -extern CORE_ADDR i386bsd_sigtramp_end; - -/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */ + 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. */ -#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); - +#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. */ diff --git a/gdb/config/i386/tm-go32.h b/gdb/config/i386/tm-go32.h index b660827bd66..79370e778a2 100644 --- a/gdb/config/i386/tm-go32.h +++ b/gdb/config/i386/tm-go32.h @@ -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 */ diff --git a/gdb/config/i386/tm-i386.h b/gdb/config/i386/tm-i386.h index f9326fecb9a..8fae6104c52 100644 --- a/gdb/config/i386/tm-i386.h +++ b/gdb/config/i386/tm-i386.h @@ -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_call (struct frame_info *frame); #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_call (struct frame_info *frame); #else #define FP0_REGNUM 0 #endif - -/* Return the name of register REG. */ - -#define REGISTER_NAME(reg) i386_register_name ((reg)) -extern char *i386_register_name (int reg); - -/* Use the "default" register numbering scheme for stabs and COFF. */ - -#define STAB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg)) -#define SDB_REG_TO_REGNUM(reg) i386_stab_reg_to_regnum ((reg)) -extern int i386_stab_reg_to_regnum (int reg); - -/* Use the DWARF register numbering scheme for DWARF and DWARF 2. */ - -#define DWARF_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) -#define DWARF2_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg)) -extern int i386_dwarf_reg_to_regnum (int reg); - -/* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to be - in use on any of the supported i386 targets. */ -/* Sizes of individual register sets. These cover the entire register - file, so summing up the sizes of those portions actually present - yields REGISTER_BYTES. */ -#define SIZEOF_GREGS (NUM_GREGS * 4) -#define SIZEOF_FPU_REGS (8 * 10) -#define SIZEOF_FPU_CTRL_REGS (8 * 4) -#define SIZEOF_SSE_REGS (8 * 16 + 4) - - -/* Total amount of space needed to store our copies of the machine's register - state, the array `registers'. */ -#ifdef HAVE_SSE_REGS -#define REGISTER_BYTES \ - (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS) -#else -#ifdef HAVE_I387_REGS -#define REGISTER_BYTES (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS) -#else -#define REGISTER_BYTES (SIZEOF_GREGS) -#endif -#endif - -/* Return the offset into the register array of the start of register - number REG. */ -#define REGISTER_BYTE(reg) i386_register_byte ((reg)) -extern int i386_register_byte (int reg); - -/* Return the number of bytes of storage in GDB's register array - occupied by register REG. */ -#define REGISTER_RAW_SIZE(reg) i386_register_raw_size ((reg)) -extern int i386_register_raw_size (int reg); - /* Largest value REGISTER_RAW_SIZE can have. */ #define MAX_REGISTER_RAW_SIZE 16 @@ -275,18 +218,6 @@ extern void i386_store_return_value (struct type *type, char *valbuf); 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. */ @@ -295,11 +226,6 @@ extern CORE_ADDR i386_frame_chain (struct frame_info *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) #define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) diff --git a/gdb/config/i386/tm-i386nw.h b/gdb/config/i386/tm-i386nw.h deleted file mode 100644 index 9ede2c040e0..00000000000 --- a/gdb/config/i386/tm-i386nw.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Macro definitions for i386 running NetWare. - Copyright 1993, 1994, 1995, 1998, 1999, 2000 - 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 TM_I386NW_H -#define TM_I386NW_H 1 - -#include "i386/tm-i386.h" - -/* Stop backtracing when we wander into main. */ - -#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. */ - -#define JB_ELEMENT_SIZE 4 /* jmp_buf[] is array of ints */ - -#define JB_PC 6 /* 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) - -#endif /* ifndef TM_I386NW_H */ diff --git a/gdb/config/i386/tm-i386sol2.h b/gdb/config/i386/tm-i386sol2.h index c90e0d475ae..7473f3bbc91 100644 --- a/gdb/config/i386/tm-i386sol2.h +++ b/gdb/config/i386/tm-i386sol2.h @@ -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 @@ -37,15 +32,6 @@ #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. */ #define SOFUN_ADDRESS_MAYBE_MISSING diff --git a/gdb/config/i386/tm-i386v4.h b/gdb/config/i386/tm-i386v4.h index 010edb4d361..7ebd27d7660 100644 --- a/gdb/config/i386/tm-i386v4.h +++ b/gdb/config/i386/tm-i386v4.h @@ -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 */ diff --git a/gdb/config/i386/tm-linux.h b/gdb/config/i386/tm-linux.h index 9c11c896187..7bfdf03895c 100644 --- a/gdb/config/i386/tm-linux.h +++ b/gdb/config/i386/tm-linux.h @@ -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_resolver (CORE_ADDR pc); /* N_FUN symbols in shared libaries have 0 for their values and need to be relocated. */ #define SOFUN_ADDRESS_MAYBE_MISSING - - -/* Support for longjmp. */ - -/* Details about jmp_buf. It's supposed to be an array of integers. */ - -#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */ -#define JB_PC 5 /* Array index of saved PC. */ - -/* Figure out where the longjmp will land. Slurp the args out of the - stack. We expect the first arg to be a pointer to the jmp_buf - structure from which we extract the pc (JB_PC) that we will land - at. The pc is copied into ADDR. This routine returns true on - success. */ - -#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr) -extern int get_longjmp_target (CORE_ADDR *addr); #endif /* #ifndef TM_LINUX_H */ diff --git a/gdb/config/i386/tm-nbsd.h b/gdb/config/i386/tm-nbsd.h index b4fb7542830..55ef6fa56fc 100644 --- a/gdb/config/i386/tm-nbsd.h +++ b/gdb/config/i386/tm-nbsd.h @@ -26,39 +26,16 @@ #include "i386/tm-i386.h" -#define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */ -#define JB_PC 0 /* Setjmp()'s return PC saved here */ - -/* Figure out where the longjmp will land. Slurp the args out of the stack. - We expect the first arg to be a pointer to the jmp_buf structure from which - we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. - This routine returns true on success */ - -extern int get_longjmp_target (CORE_ADDR *); - -#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) - - -/* Support for signal handlers. */ - -#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name) -extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name); - /* These defines allow the recognition of sigtramps as a function name <sigtramp>. - FIXME: kettenis/2001-07-13: These should be added to the target - vector and turned into functions when we go "multi-arch". */ - -#define SIGTRAMP_START(pc) i386bsd_sigtramp_start -#define SIGTRAMP_END(pc) i386bsd_sigtramp_end -extern CORE_ADDR i386bsd_sigtramp_start; -extern CORE_ADDR i386bsd_sigtramp_end; - -/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */ + 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. */ -#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); +#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 */ diff --git a/gdb/config/i386/tm-nbsdaout.h b/gdb/config/i386/tm-nbsdaout.h index 95fe2e74a5b..8dde114cf82 100644 --- a/gdb/config/i386/tm-nbsdaout.h +++ b/gdb/config/i386/tm-nbsdaout.h @@ -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 */ diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 9592decee19..12a2ab9004d 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -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 pc) /* 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 frame_info *frame) /* 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_ADDR pc) 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; @@ -528,3 +531,53 @@ i386_linux_svr4_fetch_link_map_offsets (void) return lmp; } + + +static void +i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* GNU/Linux uses ELF. */ + i386_elf_init_abi (info, gdbarch); + + /* We support the SSE registers on GNU/Linux. */ + tdep->num_xmm_regs = I386_NUM_XREGS - 1; + /* set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS); */ + + /* Since we have the extra "orig_eax" register on GNU/Linux, we have + to adjust a few things. */ + + set_gdbarch_write_pc (gdbarch, i386_linux_write_pc); + set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS + 1); + set_gdbarch_register_name (gdbarch, i386_linux_register_name); + set_gdbarch_register_bytes (gdbarch, I386_SSE_SIZEOF_REGS + 4); + set_gdbarch_register_byte (gdbarch, i386_linux_register_byte); + set_gdbarch_register_raw_size (gdbarch, i386_linux_register_raw_size); + + tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */ + + /* When the i386 Linux kernel calls a signal handler, the return + address points to a bit of code on the stack. These definitions + are used to identify this bit of code as a signal trampoline in + order to support backtracing through calls to signal handlers. */ + + set_gdbarch_pc_in_sigtramp (gdbarch, i386_linux_pc_in_sigtramp); + set_gdbarch_frame_chain (gdbarch, i386_linux_frame_chain); + set_gdbarch_frame_saved_pc (gdbarch, i386_linux_frame_saved_pc); + set_gdbarch_saved_pc_after_call (gdbarch, i386_linux_saved_pc_after_call); + tdep->sigtramp_saved_pc = i386_linux_sigtramp_saved_pc; + + set_solib_svr4_fetch_link_map_offsets (gdbarch, + i386_linux_svr4_fetch_link_map_offsets); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern void _initialize_i386_linux_tdep (void); + +void +_initialize_i386_linux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_LINUX, + i386_linux_init_abi); +} diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h new file mode 100644 index 00000000000..3c30130ede9 --- /dev/null +++ b/gdb/i386-linux-tdep.h @@ -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 */ diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c new file mode 100644 index 00000000000..714f5db9b36 --- /dev/null +++ b/gdb/i386-sol2-tdep.c @@ -0,0 +1,59 @@ +/* Target-dependent code for Solaris x86. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" + +#include "i386-tdep.h" + +static int +i386_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + /* Signal handler frames under Solaris 2 are recognized by a return + address of 0xffffffff. */ + return (pc == 0xffffffff); +} + +/* Solaris 2. */ + +static void +i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Solaris is SVR4-based. */ + i386_svr4_init_abi (info, gdbarch); + + /* Signal trampolines are different from SVR4, in fact they're + rather similar to BSD. */ + set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp); + tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc; + tdep->sc_pc_offset = 36 + 14 * 4; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386_sol2_tdep (void); + +void +_initialize_i386_sol2_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_SOLARIS, + i386_sol2_init_abi); +} diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 54746eeb865..ab52ba41325 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -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) } -#ifdef GET_LONGJMP_TARGET - -/* FIXME: Multi-arching does not set JB_PC and JB_ELEMENT_SIZE yet. - Fill in with dummy value to enable compilation. */ -#ifndef JB_PC -#define JB_PC 0 -#endif /* JB_PC */ - -#ifndef JB_ELEMENT_SIZE -#define JB_ELEMENT_SIZE 4 -#endif /* JB_ELEMENT_SIZE */ - /* Figure out where the longjmp will land. Slurp the args out of the stack. We expect the first arg to be a pointer to the jmp_buf - structure from which we extract the pc (JB_PC) that we will land - at. The pc is copied into PC. This routine returns true on + structure from which we extract the address that we will land at. + This address is copied into PC. This routine returns true on success. */ -int -get_longjmp_target (CORE_ADDR *pc) +static int +i386_get_longjmp_target (CORE_ADDR *pc) { - char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; + char buf[4]; CORE_ADDR sp, jb_addr; + int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset; - sp = read_register (SP_REGNUM); - - if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack. */ - buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) + /* If JB_PC_OFFSET is -1, we have no way to find out where the + longjmp will land. */ + if (jb_pc_offset == -1) return 0; - jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); - - if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, - TARGET_PTR_BIT / TARGET_CHAR_BIT)) + sp = read_register (SP_REGNUM); + if (target_read_memory (sp + 4, buf, 4)) return 0; - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); + jb_addr = extract_address (buf, 4); + if (target_read_memory (jb_addr + jb_pc_offset, buf, 4)) + return 0; + *pc = extract_address (buf, 4); return 1; } - -#endif /* GET_LONGJMP_TARGET */ CORE_ADDR @@ -1044,6 +1022,37 @@ i386_extract_struct_value_address (char *regbuf) } +/* This is the variable that is set with "set struct-convention", and + its legitimate values. */ +static const char default_struct_convention[] = "default"; +static const char pcc_struct_convention[] = "pcc"; +static const char reg_struct_convention[] = "reg"; +static const char *valid_conventions[] = +{ + default_struct_convention, + pcc_struct_convention, + reg_struct_convention, + NULL +}; +static const char *struct_convention = default_struct_convention; + +static int +i386_use_struct_convention (int gcc_p, struct type *type) +{ + enum struct_return struct_return; + + if (struct_convention == default_struct_convention) + struct_return = gdbarch_tdep (current_gdbarch)->struct_return; + else if (struct_convention == pcc_struct_convention) + struct_return = pcc_struct_return; + else + struct_return = reg_struct_return; + + return generic_use_struct_convention (struct_return == reg_struct_return, + type); +} + + /* Return the GDB type object for the "standard" data type of data in register REGNUM. Perhaps %esi and %edi should go here, but potentially they could be used for things other than address. */ @@ -1122,34 +1131,6 @@ i386_register_convert_to_raw (struct type *type, int regnum, } -#ifdef I386V4_SIGTRAMP_SAVED_PC -/* Get saved user PC for sigtramp from the pushed ucontext on the - stack for all three variants of SVR4 sigtramps. */ - -CORE_ADDR -i386v4_sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR saved_pc_offset = 4; - char *name = NULL; - - find_pc_partial_function (frame->pc, &name, NULL, NULL); - if (name) - { - if (STREQ (name, "_sigreturn")) - saved_pc_offset = 132 + 14 * 4; - else if (STREQ (name, "_sigacthandler")) - saved_pc_offset = 80 + 14 * 4; - else if (STREQ (name, "sigvechandler")) - saved_pc_offset = 120 + 14 * 4; - } - - if (frame->next) - return read_memory_integer (frame->next->frame + saved_pc_offset, 4); - return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4); -} -#endif /* I386V4_SIGTRAMP_SAVED_PC */ - - #ifdef STATIC_TRANSFORM_NAME /* SunPRO encodes the static variables. This is not related to C++ mangling, it is done for C too. */ @@ -1199,6 +1180,16 @@ skip_trampoline_code (CORE_ADDR pc, char *name) } +/* Return non-zero if PC and NAME show that we are in a signal + trampoline. */ + +static int +i386_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + return (name && strcmp ("_sigtramp", name) == 0); +} + + /* We have two flavours of disassembly. The machinery on this page deals with switching between those. */ @@ -1213,229 +1204,132 @@ gdb_print_insn_i386 (bfd_vma memaddr, disassemble_info *info) or intel_flavor. */ internal_error (__FILE__, __LINE__, "failed internal consistency check"); } - -/* This table matches the indices assigned to enum i386_abi. Keep - them in sync. */ -static const char * const i386_abi_names[] = -{ - "<unknown>", - "SVR4", - "NetBSD", - "GNU/Linux", - "GNU/Hurd", - "Solaris", - "FreeBSD", - NULL -}; +/* There are a few i386 architecture variants that differ only + slightly from the generic i386 target. For now, we don't give them + their own source file, but include them here. As a consequence, + they'll always be included. */ -#define ABI_TAG_OS_GNU_LINUX I386_ABI_LINUX -#define ABI_TAG_OS_GNU_HURD I386_ABI_HURD -#define ABI_TAG_OS_GNU_SOLARIS I386_ABI_INVALID -#define ABI_TAG_OS_FREEBSD I386_ABI_FREEBSD -#define ABI_TAG_OS_NETBSD I386_ABI_NETBSD +/* System V Release 4 (SVR4). */ -static void -process_note_sections (bfd *abfd, asection *sect, void *obj) +static int +i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name) { - int *abi = obj; - const char *name; - unsigned int sectsize; + 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); +} + - 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; +} + - 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; } + 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; +} + + /* 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); } diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 0bdbb057e2f..64af99d1e66 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -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 */ diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c index ad5a3013f34..a941d5b468c 100644 --- a/gdb/i386bsd-nat.c +++ b/gdb/i386bsd-nat.c @@ -382,19 +382,39 @@ kernel_u_size (void) return (sizeof (struct user)); } -/* See i386bsd-tdep.c. */ -extern int i386bsd_sigcontext_pc_offset; - void _initialize_i386bsd_nat (void) { + int sc_pc_offset; + /* To support the recognition of signal handlers, i386bsd-tdep.c hardcodes some constants. Inclusion of this file means that we are compiling a native debugger, which means that we can use the system header files and sysctl(3) to get at the relevant information. */ +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011 + extern int i386fbsd4_sc_pc_offset; +#define SC_PC_OFFSET i386fbsd4_sc_pc_offset +#elif defined (NetBSD) || defined (__NetBSD_Version__) + extern int i386nbsd_sc_pc_offset; +#define SC_PC_OFFSET i386nbsd_sc_pc_offset +#else + extern int i386bsd_sc_pc_offset; +#define SC_PC_OFFSET i386bsd_sc_pc_offset +#endif + /* Override the default value for the offset of the program counter in the sigcontext structure. */ - i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc); + sc_pc_offset = offsetof (struct sigcontext, sc_pc); + + if (SC_PC_OFFSET != sc_pc_offset) + { + warning ("\ +offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\ +Please report this to <bug-gdb@gnu.org>.", + sc_pc_offset, SC_PC_OFFSET); + } + + SC_PC_OFFSET = sc_pc_offset; } diff --git a/gdb/i386bsd-tdep.c b/gdb/i386bsd-tdep.c index a01ed6b89e6..e6427b3ac9f 100644 --- a/gdb/i386bsd-tdep.c +++ b/gdb/i386bsd-tdep.c @@ -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,19 +55,24 @@ i386bsd_sigcontext_addr (struct frame_info *frame) } /* 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) @@ -82,3 +80,168 @@ i386bsd_frame_saved_pc (struct frame_info *frame) return read_memory_unsigned_integer (frame->frame + 4, 4); } + +/* Return the start address of the sigtramp routine. */ + +CORE_ADDR +i386bsd_sigtramp_start (CORE_ADDR pc) +{ + return gdbarch_tdep (current_gdbarch)->sigtramp_start; +} + +/* Return the end address of the sigtramp routine. */ + +CORE_ADDR +i386bsd_sigtramp_end (CORE_ADDR pc) +{ + return gdbarch_tdep (current_gdbarch)->sigtramp_end; +} + + +/* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD). */ + +/* From <machine/signal.h>. */ +int i386bsd_sc_pc_offset = 20; + +static void +i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + set_gdbarch_pc_in_sigtramp (gdbarch, i386bsd_pc_in_sigtramp); + + tdep->jb_pc_offset = 0; + + tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc; + tdep->sigtramp_start = 0xfdbfdfc0; + tdep->sigtramp_end = 0xfdbfe000; + tdep->sc_pc_offset = i386bsd_sc_pc_offset; +} + +/* NetBSD 1.0 or later. */ + +/* From <machine/signal.h>. */ +int i386nbsd_sc_pc_offset = 44; + +static void +i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously NetBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* NetBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* NetBSD uses a different memory layout. */ + tdep->sigtramp_start = 0xbfbfdf20; + tdep->sigtramp_end = 0xbfbfdff0; + + /* NetBSD has a `struct sigcontext' that's different from the + origional 4.3 BSD. */ + tdep->sc_pc_offset = i386nbsd_sc_pc_offset; +} + +/* NetBSD ELF. */ +static void +i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* It's still NetBSD. */ + i386nbsd_init_abi (info, gdbarch); + + /* But ELF-based. */ + i386_elf_init_abi (info, gdbarch); + + /* NetBSD ELF uses -fpcc-struct-return by default. */ + tdep->struct_return = pcc_struct_return; + + /* We support the SSE registers on NetBSD ELF. */ + tdep->num_xmm_regs = I386_NUM_XREGS - 1; + set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS + + I386_NUM_XREGS); +} + +/* FreeBSD 3.0-RELEASE or later. */ + +CORE_ADDR i386fbsd_sigtramp_start = 0xbfbfdf20; +CORE_ADDR i386fbsd_sigtramp_end = 0xbfbfdff0; + +static void +i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Obviously FreeBSD is BSD-based. */ + i386bsd_init_abi (info, gdbarch); + + /* FreeBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + + /* FreeBSD uses a different memory layout. */ + tdep->sigtramp_start = i386fbsd_sigtramp_start; + tdep->sigtramp_end = i386fbsd_sigtramp_end; +} + +static void +i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* It's almost identical to FreeBSD a.out. */ + i386fbsdaout_init_abi (info, gdbarch); + + /* Except that it uses ELF. */ + i386_elf_init_abi (info, gdbarch); +} + +/* FreeBSD 4.0-RELEASE or later. */ + +/* From <machine/signal.h>. */ +int i386fbsd4_sc_pc_offset = 76; + +static void +i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Inherit stuff from older releases. We assume that FreeBSD + 4.0-RELEASE always uses ELF. */ + i386fbsd_init_abi (info, gdbarch); + + /* FreeBSD 4.0 introduced a new `struct sigcontext'. */ + tdep->sc_pc_offset = i386fbsd4_sc_pc_offset; +} + + +static enum gdb_osabi +i386bsd_aout_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "a.out-i386-netbsd") == 0) + return GDB_OSABI_NETBSD_AOUT; + + if (strcmp (bfd_get_target (abfd), "a.out-i386-freebsd") == 0) + return GDB_OSABI_FREEBSD_AOUT; + + return GDB_OSABI_UNKNOWN; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386bsd_tdep (void); + +void +_initialize_i386bsd_tdep (void) +{ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_aout_flavour, + i386bsd_aout_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_AOUT, + i386nbsd_init_abi); + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_ELF, + i386nbsdelf_init_abi); + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_FREEBSD_AOUT, + i386fbsdaout_init_abi); + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_FREEBSD_ELF, + i386fbsd4_init_abi); +} diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c index 1c19ac87eb4..a80d0a0af89 100644 --- a/gdb/i386fbsd-nat.c +++ b/gdb/i386fbsd-nat.c @@ -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 diff --git a/gdb/i386nbsd-tdep.c b/gdb/i386nbsd-tdep.c index 02ba77c7be9..c327d426de4 100644 --- a/gdb/i386nbsd-tdep.c +++ b/gdb/i386nbsd-tdep.c @@ -137,16 +137,6 @@ static struct core_fns i386nbsd_elfcore_fns = 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) { |