Add support for "orig_eax" pseudo register on Linux/x86.
[deliverable/binutils-gdb.git] / gdb / config / i386 / tm-linux.h
index e4f70a2078dc6a6f03f44a24600af45614fe49d1..25d978235a40e94cdacc5e9a3e40c04d4f1df74f 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions to target GDB to GNU/Linux on 386.
-   Copyright 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #define TM_LINUX_H
 
 #define I386_GNULINUX_TARGET
+#define HAVE_I387_REGS
+#ifdef HAVE_PTRACE_GETFPXREGS
+#define HAVE_SSE_REGS
+#endif
 
 #include "i386/tm-i386.h"
+#include "tm-linux.h"
 
-/* Size of sigcontext, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_SIZE (88)
-
-/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_PC_OFFSET (56)
-
-/* Offset to saved SP in sigcontext, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_SP_OFFSET (28)
-
-/* We need this file for the SOLIB_TRAMPOLINE stuff. */
+/* 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 41
 
-#include "tm-sysv4.h"
+/* Adjust a few macros to deal with this extra register.  */
 
-/* copy of tm-cygwin32.h */
-#undef REGISTER_RAW_SIZE
-#undef REGISTER_VIRTUAL_SIZE
-#undef REGISTER_VIRTUAL_TYPE
-#undef REGISTER_NAMES
-#undef REGISTER_BYTES
-#undef REGISTER_BYTE
-#undef MAX_REGISTER_VIRTUAL_SIZE
 #undef NUM_REGS
-#undef NUM_FREGS
-
-/* Number of machine registers */
-
-#define NUM_REGS 31
-#define NUM_FREGS 15 
-
-/* Initializer for an array of names of registers.
-   There should be NUM_REGS strings in this initializer.  */
-
-/* the order of the first 8 registers must match the compiler's 
- * numbering scheme (which is the same as the 386 scheme)
- * also, this table must match regmap in i386-pinsn.c.
- */
-
-#define REGISTER_NAMES { "eax",  "ecx",  "edx",  "ebx",  \
-                        "esp",  "ebp",  "esi",  "edi",  \
-                        "eip",  "eflags","cs",  "ss",   \
-                        "ds",   "es",   "fs",   "gs",   \
-                        "cwd",  "swd",  "twd",  "fip",  \
-                        "fcs",  "fopo", "fos",          \
-                        "st",   "st1",  "st2",  "st3",  \
-                         "st4",  "st5",  "st6",  "st7",}
-
-#define LOW_RETURN_REGNUM 0    /* holds low four bytes of result */
-#define HIGH_RETURN_REGNUM 2   /* holds high four bytes of result */
-
-#define FPSTART_REGNUM   16    /* start of FPU registers */
-#define FPCONTROL_REGNUM  16   /* FPU control register */
-#define FPSTATUS_REGNUM   17   /* FPU status register */
-#define FPTAG_REGNUM     18    /* FPU tag register */
-#define FPDATA_REGNUM     23   /* actual floating-point values */
-#define FPEND_REGNUM     (FPSTART_REGNUM + 14) /* last FPU register */
-
-#define FPENV_BYTES (7 * 4)
+#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SSE_REGS + 1)
 
-#define FPREG_RAW_SIZE (10)
+#undef MAX_NUM_REGS
+#define MAX_NUM_REGS (16 + 16 + 9 + 1)
 
-/* Total amount of space needed to store our copies of the machine's
-   FPU state.  */
-
-#define FPREG_BYTES (FPENV_BYTES + 8 * FPREG_RAW_SIZE)
-
-/* Total amount of space needed to store our copies of the machine's
-   register state, the array `registers'.  */
-
-#define REGISTER_BYTES (FPSTART_REGNUM * 4 + FPREG_BYTES)
-
-/* Index within `registers' of the first byte of the space for
-   register N.  */
-
-#define REGISTER_BYTE(N) (((N) < FPDATA_REGNUM) ? \
-                         (N) * 4 : \
-                         (((N) - FPDATA_REGNUM) * FPREG_RAW_SIZE) \
-                         + (FPDATA_REGNUM * 4))
-
-/* Number of bytes of storage in the actual machine representation
-   for register N.  */
-
-#define REGISTER_RAW_SIZE(N) (((N) < FPDATA_REGNUM) ? 4 : FPREG_RAW_SIZE)
-
-/* Number of bytes of storage in the program's representation
-   for register N. */
-
-#define REGISTER_VIRTUAL_SIZE(N) (((N) < FPDATA_REGNUM) ? 4 : FPREG_RAW_SIZE)
-
-/* Largest value REGISTER_RAW_SIZE can have.  */
-
-#undef MAX_REGISTER_RAW_SIZE
-#define MAX_REGISTER_RAW_SIZE FPREG_RAW_SIZE
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
-
-#define MAX_REGISTER_VIRTUAL_SIZE FPREG_RAW_SIZE
-
-#if defined(HAVE_LONG_DOUBLE) && defined(HOST_I386)
-/* The host and target are i386 machines and the compiler supports
-   long doubles. Long doubles on the host therefore have the same
-   layout as a 387 FPU stack register. */
-#define LD_I387
-#endif
-
-#define TARGET_LONG_DOUBLE_BIT 80
-
-#ifdef LD_I387
-extern int i387_extract_floating (PTR addr, int len, long double *dretptr);
-extern int i387_store_floating   (PTR addr, int len, long double val);
-
-#define TARGET_EXTRACT_FLOATING i387_extract_floating
-#define TARGET_STORE_FLOATING   i387_store_floating
-
-#define TARGET_ANALYZE_FLOATING                                        \
-  do                                                           \
-    {                                                          \
-      unsigned expon;                                          \
-                                                               \
-      low = extract_unsigned_integer (valaddr, 4);             \
-      high = extract_unsigned_integer (valaddr + 4, 4);                \
-      expon = extract_unsigned_integer (valaddr + 8, 2);       \
-                                                               \
-      nonnegative = ((expon & 0x8000) == 0);                   \
-      is_nan = ((expon & 0x7fff) == 0x7fff)                    \
-       && ((high & 0x80000000) == 0x80000000)                  \
-       && (((high & 0x7fffffff) | low) != 0);                  \
-    }                                                          \
-  while (0)
-#endif
-
-#ifndef LD_I387
-/* Nonzero if register N requires conversion
-   from raw format to virtual format.  */
-#define REGISTER_CONVERTIBLE(N) \
-  ((N < FPDATA_REGNUM) ? 0 : 1)
-#endif
+#undef REGISTER_BYTES
+#define REGISTER_BYTES \
+  (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS + 4)
 
-#ifdef LD_I387
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
-{ \
-  long double val = *((long double *)FROM); \
-  store_floating ((TO), TYPE_LENGTH (TYPE), val); \
-}
-#else
-/* Convert data from raw format for register REGNUM in buffer FROM
-   to virtual format with type TYPE in buffer TO.  */
-extern void
-i387_to_double PARAMS ((char *, char *));
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
-{ \
-  double val; \
-  i387_to_double ((FROM), (char *)&val); \
-  store_floating ((TO), TYPE_LENGTH (TYPE), val); \
-}
-#endif
+#undef REGISTER_NAME
+#define REGISTER_NAME(reg) i386_linux_register_name ((reg))
+extern char *i386_linux_register_name (int reg);
 
-#ifdef LD_I387
-#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
-{ \
-  long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
-  *((long double *)TO) = val; \
-}
-#else
-extern void
-double_to_i387 PARAMS ((char *, char *));
-
-#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
-{ \
-  double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
-  double_to_i387((char *)&val, (TO)); \
-}
-#endif
+#undef REGISTER_BYTE
+#define REGISTER_BYTE(reg) i386_linux_register_byte ((reg))
+extern int i386_linux_register_byte (int reg);
 
-/* Return the GDB type object for the "standard" data type
-   of data in register N.  */
-
-#ifdef LD_I387
-#define REGISTER_VIRTUAL_TYPE(N) \
-  ((N < FPDATA_REGNUM) ? builtin_type_int : \
-   builtin_type_long_double)
-#else
-#define REGISTER_VIRTUAL_TYPE(N) \
-  ((N < FPDATA_REGNUM) ? builtin_type_int : \
-   builtin_type_double)
-#endif
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(reg) i386_linux_register_raw_size ((reg))
+extern int i386_linux_register_raw_size (int reg);
 
-/* end of copy */
+/* 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))
 
-extern void i387_float_info(void);
-#define FLOAT_INFO { i387_float_info (); }
+/* 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
 
-/* Define DO_REGISTERS_INFO() to do machine-specific formatting
-   of register dumps. */
-
-#define DO_REGISTERS_INFO(_regnum, fp) i386_do_registers_info(_regnum, fp)
-extern void i386_do_registers_info PARAMS ((int, int));
-
-extern void i387_print_register PARAMS ((char *, int));
-
 /* 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 I386_LINUX_SIGTRAMP
-#define IN_SIGTRAMP(pc, name) ((name) == NULL && i386_linux_sigtramp (pc))
-
-extern int i386_linux_sigtramp PARAMS ((CORE_ADDR));
-
-/* We need our own version of sigtramp_saved_pc to get the saved PC in
-   a sigtramp routine.  */
-
-#define sigtramp_saved_pc i386_linux_sigtramp_saved_pc
-extern CORE_ADDR i386_linux_sigtramp_saved_pc PARAMS ((struct frame_info *));
-
-/* Signal trampolines don't have a meaningful frame.  As in tm-i386.h,
-   the frame pointer value we use is actually the frame pointer of the
-   calling frame--that is, the frame which was in progress when the
-   signal trampoline was entered.  gdb mostly treats this frame
-   pointer value as a magic cookie.  We detect the case of a signal
-   trampoline by looking at the SIGNAL_HANDLER_CALLER field, which is
-   set based on IN_SIGTRAMP.
-
-   When a signal trampoline is invoked from a frameless function, we
-   essentially have two frameless functions in a row.  In this case,
-   we use the same magic cookie for three frames in a row.  We detect
-   this case by seeing whether the next frame has
-   SIGNAL_HANDLER_CALLER set, and, if it does, checking whether the
-   current frame is actually frameless.  In this case, we need to get
-   the PC by looking at the SP register value stored in the signal
-   context.
-
-   This should work in most cases except in horrible situations where
-   a signal occurs just as we enter a function but before the frame
-   has been set up.  */
-
-#define FRAMELESS_SIGNAL(FRAME)                                        \
-  ((FRAME)->next != NULL                                       \
-   && (FRAME)->next->signal_handler_caller                     \
-   && frameless_look_for_prologue (FRAME))
+#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)                                     \
-  ((FRAME)->signal_handler_caller                              \
-   ? (FRAME)->frame                                            \
-    : (FRAMELESS_SIGNAL (FRAME)                                        \
-       ? (FRAME)->frame                                                \
-       : (!inside_entry_file ((FRAME)->pc)                     \
-         ? read_memory_integer ((FRAME)->frame, 4)             \
-         : 0)))
+#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)                                  \
-  ((FRAME)->signal_handler_caller                              \
-   ? sigtramp_saved_pc (FRAME)                                 \
-   : (FRAMELESS_SIGNAL (FRAME)                                 \
-      ? read_memory_integer (i386_linux_sigtramp_saved_sp ((FRAME)->next), 4) \
-      : read_memory_integer ((FRAME)->frame + 4, 4)))
-
-extern CORE_ADDR i386_linux_sigtramp_saved_sp PARAMS ((struct frame_info *));
-
-/* Some versions of Linux have real-time signal support in the C library, and
-   some don't.  We have to include this file to find out.  */
-#include <signal.h>
-
-#ifdef __SIGRTMIN
-#define REALTIME_LO __SIGRTMIN
-#define REALTIME_HI (__SIGRTMAX + 1)
-#else
-#define REALTIME_LO 32
-#define REALTIME_HI 64
-#endif
+#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
@@ -313,6 +108,22 @@ 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
+\f
 
-#endif /* #ifndef TM_LINUX_H */
+/* 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 */
This page took 0.029094 seconds and 4 git commands to generate.