* Makefile.in (ppc_tdep_h): Define.
authorJason Thorpe <thorpej@netbsd.org>
Thu, 30 May 2002 01:21:53 +0000 (01:21 +0000)
committerJason Thorpe <thorpej@netbsd.org>
Thu, 30 May 2002 01:21:53 +0000 (01:21 +0000)
(ppc-linux-nat.o)
(ppc-linux-tdep.o)
(rs6000-tdep.o): Use $(ppc_tdep_h).
(ppc-sysv-tdep.o)
(ppcnbsd-nat.o)
(ppcnbsd-tdep.o): New dependency lists.
* ppc-tdep.h: Use generic OS ABI framework.
* ppc-linux-tdep.c (_initialize_ppc_linux_tdep,
ppc_linux_init_abi): New functions.
(ppc_sysv_abi_broken_use_struct_convention)
(ppc_sysv_abi_use_struct_convention)
(ppc_sysv_abi_push_arguments): Move to...
* ppc-sysv-tdep.c: ...here.
* ppcnbsd-nat.c: Don't include gdbcore.h and regcache.h.
* rs6000-tdep.c (process_note_abi_tag_sections)
(get_elfosabi): Remove.
(rs6000_gdbarch_init): Use generic OS ABI framework.
(rs6000_dump_tdep): New function.
(_initialize_rs6000_tdep): Use gdbarch_register.
* config/powerpc/linux.mt (TDEPFILES): Add ppc-sysv-tdep.o.
* config/powerpc/nbsd.mh (NATDEPFILES): Remove solib-legacy.o.
* config/powerpc/aix.mt (TDEPFILES): Use ppc-sysv-tdep.o instead
of ppc-linux-tdep.o.
* config/powerpc/nbsd.mt (TDEPFILES): Likewise.
* config/powerpc/ppc-eabi.mt (TDEPFILES): Likewise.
* config/powerpc/ppc-sim.mt (TDEPFILES): Likewise.
* config/powerpc/ppcle-eabi.mt (TDEPFILES): Likewise.
* config/powerpc/ppcle-sim.mt (TDEPFILES): Likewise.
* config/powerpc/vxworks.mt (TDEPFILES): Likewise.

16 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/config/powerpc/aix.mt
gdb/config/powerpc/linux.mt
gdb/config/powerpc/nbsd.mh
gdb/config/powerpc/nbsd.mt
gdb/config/powerpc/ppc-eabi.mt
gdb/config/powerpc/ppc-sim.mt
gdb/config/powerpc/ppcle-eabi.mt
gdb/config/powerpc/ppcle-sim.mt
gdb/config/powerpc/vxworks.mt
gdb/ppc-linux-tdep.c
gdb/ppc-sysv-tdep.c [new file with mode: 0644]
gdb/ppc-tdep.h
gdb/ppcnbsd-nat.c
gdb/rs6000-tdep.c

index 01b1a5b64471181e4fa6714e152269a0b1715dfa..36d7038212a901fdbe19ed07c21aafd84ae364df 100644 (file)
@@ -1,3 +1,36 @@
+2002-05-20  Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * Makefile.in (ppc_tdep_h): Define.
+       (ppc-linux-nat.o)
+       (ppc-linux-tdep.o)
+       (rs6000-tdep.o): Use $(ppc_tdep_h).
+       (ppc-sysv-tdep.o)
+       (ppcnbsd-nat.o)
+       (ppcnbsd-tdep.o): New dependency lists.
+       * ppc-tdep.h: Use generic OS ABI framework.
+       * ppc-linux-tdep.c (_initialize_ppc_linux_tdep,
+       ppc_linux_init_abi): New functions.
+       (ppc_sysv_abi_broken_use_struct_convention)
+       (ppc_sysv_abi_use_struct_convention)
+       (ppc_sysv_abi_push_arguments): Move to...
+       * ppc-sysv-tdep.c: ...here.
+       * ppcnbsd-nat.c: Don't include gdbcore.h and regcache.h.
+       * rs6000-tdep.c (process_note_abi_tag_sections)
+       (get_elfosabi): Remove.
+       (rs6000_gdbarch_init): Use generic OS ABI framework.
+       (rs6000_dump_tdep): New function.
+       (_initialize_rs6000_tdep): Use gdbarch_register.
+       * config/powerpc/linux.mt (TDEPFILES): Add ppc-sysv-tdep.o.
+       * config/powerpc/nbsd.mh (NATDEPFILES): Remove solib-legacy.o.
+       * config/powerpc/aix.mt (TDEPFILES): Use ppc-sysv-tdep.o instead
+       of ppc-linux-tdep.o.
+       * config/powerpc/nbsd.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppc-eabi.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppc-sim.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppcle-eabi.mt (TDEPFILES): Likewise.
+       * config/powerpc/ppcle-sim.mt (TDEPFILES): Likewise.
+       * config/powerpc/vxworks.mt (TDEPFILES): Likewise.
+
 2002-05-29  Jim Blandy  <jimb@redhat.com>
 
        * macroscope.c (default_macro_scope): Put `void' in empty argument
index c8dba9150d2aef55ce7aee5d0c5b9c84d5bc926d..57421b0ccd15b41518cccd0c5a998469c6d4023c 100644 (file)
@@ -646,6 +646,7 @@ memattr_h =     memattr.h
 monitor_h =    monitor.h
 objfiles_h =   objfiles.h
 parser_defs_h =        parser-defs.h $(doublest_h)
+ppc_tdep_h =   ppc-tdep.h osabi.h
 regcache_h =   regcache.h
 remote_h =     remote.h
 remote_utils_h =  remote-utils.h $(target_h)
@@ -1226,7 +1227,8 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
        nindy-share/ttyflush.c nindy-tdep.c \
        ns32k-tdep.c solib-osf.c \
        somread.c somsolib.c $(HPREAD_SOURCE) \
-       ppc-linux-nat.c ppc-linux-tdep.c \
+       ppc-sysv-tdep.o ppc-linux-nat.c ppc-linux-tdep.c \
+       ppcnbsd-nat.o ppcnbsd-tdep.o \
        procfs.c \
        remote-adapt.c remote-array.c remote-bug.c remote-e7000.c remote-eb.c \
        remote-es.c remote-hms.c remote-mips.c \
@@ -1901,10 +1903,20 @@ ppc-bdm.o: ppc-bdm.c $(defs_h) $(gdbcore_h) $(gdb_string_h) $(frame_h) \
        $(objfiles_h) $(gdb_stabs_h) $(serial_h) ocd.h $(regcache_h)
 
 ppc-linux-nat.o: ppc-linux-nat.c $(defs_h) $(gdbcore_h) $(frame_h) \
-       $(inferior_h) $(target_h) $(regcache_h) ppc-tdep.h
+       $(inferior_h) $(target_h) $(regcache_h) $(ppc_tdep_h)
 
 ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
-       $(target_h) ppc-tdep.h $(regcache_h) $(value_h)
+       $(target_h) $(ppc_tdep_h) $(regcache_h) $(value_h)
+
+ppc-sysv-tdep.o: ppc-sysv-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
+       $(value_h) $(regcache_h) $(ppc_tdep_h)
+
+ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(ppc_tdep_h) \
+       ppcnbsd-tdep.h
+
+ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
+       $(target_h) $(breakpoint_h) $(value_h) $(ppc_tdep_t) ppcnbsd-tdep.h \
+       nbsd-tdep.h
 
 ppcbug-rom.o: ppcbug-rom.c $(monitor_h) $(bfd_h) $(gdb_wait_h) $(defs_h) \
        $(gdbcmd_h) $(inferior_h) $(target_h) $(serial_h) $(terminal_h) \
@@ -2041,7 +2053,7 @@ rs6000-nat.o: rs6000-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(target_h) \
        $(gdb_stabs_h) $(regcache_h) $(arch_utils_h)
 
 rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
-       $(target_h) ppc-tdep.h $(regcache_h) $(value_h) $(parser_defs_h)
+       $(target_h) $(ppc_tdep_h) $(regcache_h) $(value_h) $(parser_defs_h)
 
 s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \
        $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
index 706129ae2c773b9e6f79c27edd9dddf3ef126824..d7ba624da913668d2ccfcbc290b7c9231f2800f9 100644 (file)
@@ -1,3 +1,3 @@
 # Target: PowerPC running AIX
-TDEPFILES= rs6000-tdep.o xcoffread.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o xcoffread.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-ppc-aix.h
index 01160b9870466d4426fb1b8cbe8fb158009ef7bf..a1d08c2d38e36f41593a8fc8fab5a221b772c099 100644 (file)
@@ -1,5 +1,6 @@
 # Target: Motorola PPC on Linux
-TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o solib-legacy.o
+TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o solib.o \
+       solib-svr4.o solib-legacy.o
 TM_FILE= tm-linux.h
 
 SIM_OBS = remote-sim.o
index 9d29986d996c1db90368843e2dc538e395d128ac..26ba24d9860214c97e975dd671fcda92b18392d2 100644 (file)
@@ -1,3 +1,3 @@
 # Host: PowerPC, running NetBSD
-NATDEPFILES= fork-child.o infptrace.o inftarg.o ppcnbsd-nat.o solib-legacy.o
+NATDEPFILES= fork-child.o infptrace.o inftarg.o ppcnbsd-nat.o
 NAT_FILE= nm-nbsd.h
index cbf559b658d548ea4a813b3a498b7eac69fa542d..d492f9d763cb07be644f167a614b44faf27b50fd 100644 (file)
@@ -1,5 +1,5 @@
 # Target: PowerPC, running NetBSD
-TDEPFILES= rs6000-tdep.o ppcnbsd-tdep.o nbsd-tdep.o ppc-linux-tdep.o corelow.o \
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o nbsd-tdep.o corelow.o \
        solib.o solib-svr4.o
 TM_FILE= tm-nbsd.h
 
index 2d4a77fcdefb51716a543c47a8474c5d890a5a77..5ef8cd9befb97a7b838e1b28e3a86373ee9eb5a3 100644 (file)
@@ -1,3 +1,3 @@
 # Target: PowerPC running eabi
-TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-ppc-eabi.h
index f2ad1f0b2c43ecea119893124c0196dbbd6510bc..187bf39e8d5651b5f8cbfd3db799cc7c76f1bca6 100644 (file)
@@ -1,5 +1,5 @@
 # Target: PowerPC running eabi and including the simulator
-TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-ppc-eabi.h
 
 SIM_OBS = remote-sim.o
index e7480975730330d5893ed82c98d6d52ef43ce357..ee05f16379762177026201a37b488e06555d2cac 100644 (file)
@@ -1,3 +1,3 @@
 # Target: PowerPC running eabi in little endian mode
-TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-ppcle-eabi.h
index 558c0dc885e56ebaf74d41b43dd4be8eb90c01b3..31cb9006a302e189649f549f60db4a675379ccd0 100644 (file)
@@ -1,5 +1,5 @@
 # Target: PowerPC running eabi in little endian mode under the simulator
-TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-ppcle-eabi.h
 
 SIM_OBS = remote-sim.o
index ba6e17bcb1c8f09021e0f91149eb8d9245875cc1..eca028f80aaebcd79e59cd3caccce2a9cac4e35d 100644 (file)
@@ -1,3 +1,3 @@
 # Target: Powerpc running VxWorks
-TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o solib.o solib-svr4.o
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o solib.o solib-svr4.o
 TM_FILE= tm-vxworks.h
index f358274140bf7d6afee135fa8b04572484f78e49..1a88d4052d3aef5e181183670b0bb55fea2cac92 100644 (file)
@@ -411,293 +411,6 @@ ppc_linux_frame_chain (struct frame_info *thisframe)
     return rs6000_frame_chain (thisframe);
 }
 
-/* FIXME: Move the following to rs6000-tdep.c (or some other file where
-   it may be used generically by ports which use either the SysV ABI or
-   the EABI */
-
-/* Until November 2001, gcc was not complying to the SYSV ABI for
-   returning structures less than or equal to 8 bytes in size.  It was
-   returning everything in memory.  When this was corrected, it wasn't
-   fixed for native platforms.  */
-int
-ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
-{
-  if (TYPE_LENGTH (value_type) == 16
-      && TYPE_VECTOR (value_type))
-    return 0;
-
-  return generic_use_struct_convention (gcc_p, value_type);
-}
-
-/* Structures 8 bytes or less long are returned in the r3 & r4
-   registers, according to the SYSV ABI. */
-int
-ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
-{
-  if (TYPE_LENGTH (value_type) == 16
-      && TYPE_VECTOR (value_type))
-    return 0;
-
-  return (TYPE_LENGTH (value_type) > 8);
-}
-
-/* round2 rounds x up to the nearest multiple of s assuming that s is a
-   power of 2 */
-
-#undef round2
-#define round2(x,s) ((((long) (x) - 1) & ~(long)((s)-1)) + (s))
-
-/* Pass the arguments in either registers, or in the stack. Using the
-   ppc sysv ABI, the first eight words of the argument list (that might
-   be less than eight parameters if some parameters occupy more than one
-   word) are passed in r3..r10 registers.  float and double parameters are
-   passed in fpr's, in addition to that. Rest of the parameters if any
-   are passed in user stack. 
-
-   If the function is returning a structure, then the return address is passed
-   in r3, then the first 7 words of the parametes can be passed in registers,
-   starting from r4. */
-
-CORE_ADDR
-ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
-                            int struct_return, CORE_ADDR struct_addr)
-{
-  int argno;
-  /* Next available general register for non-float, non-vector arguments. */
-  int greg;
-  /* Next available floating point register for float arguments. */
-  int freg;
-  /* Next available vector register for vector arguments. */
-  int vreg;
-  int argstkspace;
-  int structstkspace;
-  int argoffset;
-  int structoffset;
-  struct value *arg;
-  struct type *type;
-  int len;
-  char old_sp_buf[4];
-  CORE_ADDR saved_sp;
-
-  greg = struct_return ? 4 : 3;
-  freg = 1;
-  vreg = 2;
-  argstkspace = 0;
-  structstkspace = 0;
-
-  /* Figure out how much new stack space is required for arguments
-     which don't fit in registers.  Unlike the PowerOpen ABI, the
-     SysV ABI doesn't reserve any extra space for parameters which
-     are put in registers. */
-  for (argno = 0; argno < nargs; argno++)
-    {
-      arg = args[argno];
-      type = check_typedef (VALUE_TYPE (arg));
-      len = TYPE_LENGTH (type);
-
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
-       {
-         if (freg <= 8)
-           freg++;
-         else
-           {
-             /* SysV ABI converts floats to doubles when placed in
-                memory and requires 8 byte alignment */
-             if (argstkspace & 0x4)
-               argstkspace += 4;
-             argstkspace += 8;
-           }
-       }
-      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)  /* long long */
-       {
-         if (greg > 9)
-           {
-             greg = 11;
-             if (argstkspace & 0x4)
-               argstkspace += 4;
-             argstkspace += 8;
-           }
-         else
-           {
-             if ((greg & 1) == 0)
-               greg++;
-             greg += 2;
-           }
-       }
-      else if (!TYPE_VECTOR (type))
-        {
-         if (len > 4
-             || TYPE_CODE (type) == TYPE_CODE_STRUCT
-             || TYPE_CODE (type) == TYPE_CODE_UNION)
-           {
-             /* Rounding to the nearest multiple of 8 may not be necessary,
-                but it is safe.  Particularly since we don't know the
-                field types of the structure */
-             structstkspace += round2 (len, 8);
-           }
-         if (greg <= 10)
-           greg++;
-         else
-           argstkspace += 4;
-       }
-      else
-        {
-          if (len == 16
-             && TYPE_CODE (type) == TYPE_CODE_ARRAY
-             && TYPE_VECTOR (type))
-           {
-             if (vreg <= 13)
-               vreg++;
-             else
-               {
-                 /* Vector arguments must be aligned to 16 bytes on
-                     the stack. */
-                 argstkspace += round2 (argstkspace, 16);
-                 argstkspace += 16;
-               }
-           }
-       }
-    }
-
-  /* Get current SP location */
-  saved_sp = read_sp ();
-
-  sp -= argstkspace + structstkspace;
-
-  /* Allocate space for backchain and callee's saved lr */
-  sp -= 8;
-
-  /* Make sure that we maintain 16 byte alignment */
-  sp &= ~0x0f;
-
-  /* Update %sp before proceeding any further */
-  write_register (SP_REGNUM, sp);
-
-  /* write the backchain */
-  store_address (old_sp_buf, 4, saved_sp);
-  write_memory (sp, old_sp_buf, 4);
-
-  argoffset = 8;
-  structoffset = argoffset + argstkspace;
-  freg = 1;
-  greg = 3;
-  vreg = 2;
-  /* Fill in r3 with the return structure, if any */
-  if (struct_return)
-    {
-      char val_buf[4];
-      store_address (val_buf, 4, struct_addr);
-      memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
-      greg++;
-    }
-  /* Now fill in the registers and stack... */
-  for (argno = 0; argno < nargs; argno++)
-    {
-      arg = args[argno];
-      type = check_typedef (VALUE_TYPE (arg));
-      len = TYPE_LENGTH (type);
-
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
-       {
-         if (freg <= 8)
-           {
-             if (len > 8)
-               printf_unfiltered (
-                                  "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
-             memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
-                     VALUE_CONTENTS (arg), len);
-             freg++;
-           }
-         else
-           {
-             /* SysV ABI converts floats to doubles when placed in
-                memory and requires 8 byte alignment */
-             /* FIXME: Convert floats to doubles */
-             if (argoffset & 0x4)
-               argoffset += 4;
-             write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
-             argoffset += 8;
-           }
-       }
-      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)  /* long long */
-       {
-         if (greg > 9)
-           {
-             greg = 11;
-             if (argoffset & 0x4)
-               argoffset += 4;
-             write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
-             argoffset += 8;
-           }
-         else
-           {
-             if ((greg & 1) == 0)
-               greg++;
-
-             memcpy (&registers[REGISTER_BYTE (greg)],
-                     VALUE_CONTENTS (arg), 4);
-             memcpy (&registers[REGISTER_BYTE (greg + 1)],
-                     VALUE_CONTENTS (arg) + 4, 4);
-             greg += 2;
-           }
-       }
-      else if (!TYPE_VECTOR (type))
-       {
-         char val_buf[4];
-         if (len > 4
-             || TYPE_CODE (type) == TYPE_CODE_STRUCT
-             || TYPE_CODE (type) == TYPE_CODE_UNION)
-           {
-             write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
-             store_address (val_buf, 4, sp + structoffset);
-             structoffset += round2 (len, 8);
-           }
-         else
-           {
-             memset (val_buf, 0, 4);
-             memcpy (val_buf, VALUE_CONTENTS (arg), len);
-           }
-         if (greg <= 10)
-           {
-             memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
-             greg++;
-           }
-         else
-           {
-             write_memory (sp + argoffset, val_buf, 4);
-             argoffset += 4;
-           }
-       }
-      else
-       {
-         if (len == 16
-             && TYPE_CODE (type) == TYPE_CODE_ARRAY
-             && TYPE_VECTOR (type))
-           {
-             struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-             char *v_val_buf = alloca (16);
-             memset (v_val_buf, 0, 16);
-             memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
-             if (vreg <= 13)
-               {
-                 memcpy (&registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
-                                                   + vreg)],
-                         v_val_buf, 16);
-                 vreg++;
-               }
-             else
-               {
-                 write_memory (sp + argoffset, v_val_buf, 16);
-                 argoffset += 16;
-               }
-           }
-        }
-    }
-
-  target_store_registers (-1);
-  return sp;
-}
-
 /* ppc_linux_memory_remove_breakpoints attempts to remove a breakpoint
    in much the same fashion as memory_remove_breakpoint in mem-break.c,
    but is careful not to write back the previous contents if the code
@@ -886,3 +599,44 @@ ppc_linux_svr4_fetch_link_map_offsets (void)
 
   return lmp;
 }
+
+static void
+ppc_linux_init_abi (struct gdbarch_info info,
+                    struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Until November 2001, gcc was not complying to the SYSV ABI for
+     returning structures less than or equal to 8 bytes in size. It was
+     returning everything in memory. When this was corrected, it wasn't
+     fixed for native platforms.  */
+  set_gdbarch_use_struct_convention (gdbarch,
+                                   ppc_sysv_abi_broken_use_struct_convention);
+
+  if (tdep->wordsize == 4)
+    {
+      /* Note: kevinb/2002-04-12: See note in rs6000_gdbarch_init regarding
+        *_push_arguments().  The same remarks hold for the methods below.  */
+      set_gdbarch_frameless_function_invocation (gdbarch,
+        ppc_linux_frameless_function_invocation);
+      set_gdbarch_frame_chain (gdbarch, ppc_linux_frame_chain);
+      set_gdbarch_frame_saved_pc (gdbarch, ppc_linux_frame_saved_pc);
+
+      set_gdbarch_frame_init_saved_regs (gdbarch,
+                                         ppc_linux_frame_init_saved_regs);
+      set_gdbarch_init_extra_frame_info (gdbarch,
+                                         ppc_linux_init_extra_frame_info);
+
+      set_gdbarch_memory_remove_breakpoint (gdbarch,
+                                            ppc_linux_memory_remove_breakpoint);
+      set_solib_svr4_fetch_link_map_offsets
+        (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
+    }
+}
+
+void
+_initialize_ppc_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_powerpc, GDB_OSABI_LINUX,
+                         ppc_linux_init_abi);
+}
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
new file mode 100644 (file)
index 0000000..0d33683
--- /dev/null
@@ -0,0 +1,312 @@
+/* Target-dependent code for PowerPC systems using the SVR4 ABI
+   for GDB, the GNU debugger.
+
+   Copyright 2000, 2001, 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 "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "value.h"
+
+#include "ppc-tdep.h"
+
+/* round2 rounds x up to the nearest multiple of s assuming that s is a
+   power of 2 */
+
+#undef round2
+#define round2(x,s) ((((long) (x) - 1) & ~(long)((s)-1)) + (s))
+
+/* Pass the arguments in either registers, or in the stack. Using the
+   ppc sysv ABI, the first eight words of the argument list (that might
+   be less than eight parameters if some parameters occupy more than one
+   word) are passed in r3..r10 registers.  float and double parameters are
+   passed in fpr's, in addition to that. Rest of the parameters if any
+   are passed in user stack. 
+
+   If the function is returning a structure, then the return address is passed
+   in r3, then the first 7 words of the parametes can be passed in registers,
+   starting from r4. */
+
+CORE_ADDR
+ppc_sysv_abi_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                            int struct_return, CORE_ADDR struct_addr)
+{
+  int argno;
+  /* Next available general register for non-float, non-vector arguments. */
+  int greg;
+  /* Next available floating point register for float arguments. */
+  int freg;
+  /* Next available vector register for vector arguments. */
+  int vreg;
+  int argstkspace;
+  int structstkspace;
+  int argoffset;
+  int structoffset;
+  struct value *arg;
+  struct type *type;
+  int len;
+  char old_sp_buf[4];
+  CORE_ADDR saved_sp;
+
+  greg = struct_return ? 4 : 3;
+  freg = 1;
+  vreg = 2;
+  argstkspace = 0;
+  structstkspace = 0;
+
+  /* Figure out how much new stack space is required for arguments
+     which don't fit in registers.  Unlike the PowerOpen ABI, the
+     SysV ABI doesn't reserve any extra space for parameters which
+     are put in registers. */
+  for (argno = 0; argno < nargs; argno++)
+    {
+      arg = args[argno];
+      type = check_typedef (VALUE_TYPE (arg));
+      len = TYPE_LENGTH (type);
+
+      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+       {
+         if (freg <= 8)
+           freg++;
+         else
+           {
+             /* SysV ABI converts floats to doubles when placed in
+                memory and requires 8 byte alignment */
+             if (argstkspace & 0x4)
+               argstkspace += 4;
+             argstkspace += 8;
+           }
+       }
+      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)  /* long long */
+       {
+         if (greg > 9)
+           {
+             greg = 11;
+             if (argstkspace & 0x4)
+               argstkspace += 4;
+             argstkspace += 8;
+           }
+         else
+           {
+             if ((greg & 1) == 0)
+               greg++;
+             greg += 2;
+           }
+       }
+      else if (!TYPE_VECTOR (type))
+        {
+         if (len > 4
+             || TYPE_CODE (type) == TYPE_CODE_STRUCT
+             || TYPE_CODE (type) == TYPE_CODE_UNION)
+           {
+             /* Rounding to the nearest multiple of 8 may not be necessary,
+                but it is safe.  Particularly since we don't know the
+                field types of the structure */
+             structstkspace += round2 (len, 8);
+           }
+         if (greg <= 10)
+           greg++;
+         else
+           argstkspace += 4;
+       }
+      else
+        {
+          if (len == 16
+             && TYPE_CODE (type) == TYPE_CODE_ARRAY
+             && TYPE_VECTOR (type))
+           {
+             if (vreg <= 13)
+               vreg++;
+             else
+               {
+                 /* Vector arguments must be aligned to 16 bytes on
+                     the stack. */
+                 argstkspace += round2 (argstkspace, 16);
+                 argstkspace += 16;
+               }
+           }
+       }
+    }
+
+  /* Get current SP location */
+  saved_sp = read_sp ();
+
+  sp -= argstkspace + structstkspace;
+
+  /* Allocate space for backchain and callee's saved lr */
+  sp -= 8;
+
+  /* Make sure that we maintain 16 byte alignment */
+  sp &= ~0x0f;
+
+  /* Update %sp before proceeding any further */
+  write_register (SP_REGNUM, sp);
+
+  /* write the backchain */
+  store_address (old_sp_buf, 4, saved_sp);
+  write_memory (sp, old_sp_buf, 4);
+
+  argoffset = 8;
+  structoffset = argoffset + argstkspace;
+  freg = 1;
+  greg = 3;
+  vreg = 2;
+  /* Fill in r3 with the return structure, if any */
+  if (struct_return)
+    {
+      char val_buf[4];
+      store_address (val_buf, 4, struct_addr);
+      memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+      greg++;
+    }
+  /* Now fill in the registers and stack... */
+  for (argno = 0; argno < nargs; argno++)
+    {
+      arg = args[argno];
+      type = check_typedef (VALUE_TYPE (arg));
+      len = TYPE_LENGTH (type);
+
+      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+       {
+         if (freg <= 8)
+           {
+             if (len > 8)
+               printf_unfiltered (
+                                  "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
+             memcpy (&registers[REGISTER_BYTE (FP0_REGNUM + freg)],
+                     VALUE_CONTENTS (arg), len);
+             freg++;
+           }
+         else
+           {
+             /* SysV ABI converts floats to doubles when placed in
+                memory and requires 8 byte alignment */
+             /* FIXME: Convert floats to doubles */
+             if (argoffset & 0x4)
+               argoffset += 4;
+             write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+             argoffset += 8;
+           }
+       }
+      else if (TYPE_CODE (type) == TYPE_CODE_INT && len == 8)  /* long long */
+       {
+         if (greg > 9)
+           {
+             greg = 11;
+             if (argoffset & 0x4)
+               argoffset += 4;
+             write_memory (sp + argoffset, (char *) VALUE_CONTENTS (arg), len);
+             argoffset += 8;
+           }
+         else
+           {
+             if ((greg & 1) == 0)
+               greg++;
+
+             memcpy (&registers[REGISTER_BYTE (greg)],
+                     VALUE_CONTENTS (arg), 4);
+             memcpy (&registers[REGISTER_BYTE (greg + 1)],
+                     VALUE_CONTENTS (arg) + 4, 4);
+             greg += 2;
+           }
+       }
+      else if (!TYPE_VECTOR (type))
+       {
+         char val_buf[4];
+         if (len > 4
+             || TYPE_CODE (type) == TYPE_CODE_STRUCT
+             || TYPE_CODE (type) == TYPE_CODE_UNION)
+           {
+             write_memory (sp + structoffset, VALUE_CONTENTS (arg), len);
+             store_address (val_buf, 4, sp + structoffset);
+             structoffset += round2 (len, 8);
+           }
+         else
+           {
+             memset (val_buf, 0, 4);
+             memcpy (val_buf, VALUE_CONTENTS (arg), len);
+           }
+         if (greg <= 10)
+           {
+             memcpy (&registers[REGISTER_BYTE (greg)], val_buf, 4);
+             greg++;
+           }
+         else
+           {
+             write_memory (sp + argoffset, val_buf, 4);
+             argoffset += 4;
+           }
+       }
+      else
+       {
+         if (len == 16
+             && TYPE_CODE (type) == TYPE_CODE_ARRAY
+             && TYPE_VECTOR (type))
+           {
+             struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+             char *v_val_buf = alloca (16);
+             memset (v_val_buf, 0, 16);
+             memcpy (v_val_buf, VALUE_CONTENTS (arg), len);
+             if (vreg <= 13)
+               {
+                 memcpy (&registers[REGISTER_BYTE (tdep->ppc_vr0_regnum
+                                                   + vreg)],
+                         v_val_buf, 16);
+                 vreg++;
+               }
+             else
+               {
+                 write_memory (sp + argoffset, v_val_buf, 16);
+                 argoffset += 16;
+               }
+           }
+        }
+    }
+
+  target_store_registers (-1);
+  return sp;
+}
+
+/* Until November 2001, gcc was not complying to the SYSV ABI for 
+   returning structures less than or equal to 8 bytes in size.  It was
+   returning everything in memory.  When this was corrected, it wasn't
+   fixed for native platforms.  */
+int     
+ppc_sysv_abi_broken_use_struct_convention (int gcc_p, struct type *value_type)
+{  
+  if (TYPE_LENGTH (value_type) == 16 
+      && TYPE_VECTOR (value_type))
+    return 0;                            
+
+  return generic_use_struct_convention (gcc_p, value_type);
+}
+
+/* Structures 8 bytes or less long are returned in the r3 & r4
+   registers, according to the SYSV ABI. */
+int
+ppc_sysv_abi_use_struct_convention (int gcc_p, struct type *value_type)
+{
+  if (TYPE_LENGTH (value_type) == 16
+      && TYPE_VECTOR (value_type))
+    return 0;
+
+  return (TYPE_LENGTH (value_type) > 8);
+}   
index 3da66ad1405977ceb743739134929dcdac0c6376..2f40742abcd0df0428d467572eed229dbf68485b 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef PPC_TDEP_H
 #define PPC_TDEP_H
 
+#include "osabi.h"
+
 struct frame_info;
 struct value;
 
@@ -52,7 +54,7 @@ int altivec_register_p (int regno);
 struct gdbarch_tdep
   {
     int wordsize;              /* size in bytes of fixed-point word */
-    int osabi;                 /* OS / ABI from ELF header */
+    enum gdb_osabi osabi;      /* OS / ABI from ELF header */
     int *regoff;               /* byte offsets in register arrays */
     const struct reg *regs;    /* from current variant */
     int ppc_gp0_regnum;                /* GPR register 0 */
index 2e43ce46411a2b9199ac710f118d38a2eb0ae5c5..ce097d7a59da75d16d9a5226d255c48d75f54581 100644 (file)
@@ -25,8 +25,6 @@
 
 #include "defs.h"
 #include "inferior.h"
-#include "gdbcore.h"
-#include "regcache.h"
 
 #include "ppc-tdep.h"
 #include "ppcnbsd-tdep.h"
index 2ba81ea2abade859ffe647e84ce764149bc56c13..f91de78898d356b20e7d458606b3644f4f12f16d 100644 (file)
@@ -2402,88 +2402,7 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 
   return NULL;
 }
-
-
-
-\f
-static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
-{
-  int *os_ident_ptr = 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 = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-                                (file_ptr) 0, (bfd_size_type) sectsize);
-
-      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);
-
-      if (name_length == 4 && data_length == 16 && note_type == 1
-          && strcmp (note + 12, "GNU") == 0)
-       {
-         int os_number = bfd_h_get_32 (abfd, note + 16);
-
-         /* The case numbers are from abi-tags in glibc */
-         switch (os_number)
-           {
-           case 0 :
-             *os_ident_ptr = ELFOSABI_LINUX;
-             break;
-           case 1 :
-             *os_ident_ptr = ELFOSABI_HURD;
-             break;
-           case 2 :
-             *os_ident_ptr = ELFOSABI_SOLARIS;
-             break;
-           default :
-             internal_error (__FILE__, __LINE__,
-                             "process_note_abi_sections: unknown OS number %d",
-                             os_number);
-             break;
-           }
-       }
-    }
-}
-
-/* Return one of the ELFOSABI_ constants for BFDs representing ELF
-   executables.  If it's not an ELF executable or if the OS/ABI couldn't
-   be determined, simply return -1. */
-
-static int
-get_elfosabi (bfd *abfd)
-{
-  int elfosabi = -1;
-
-  if (abfd != NULL && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    {
-      elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
-
-      /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
-         that we're on a SYSV system.  However, GNU/Linux uses a note section
-        to record OS/ABI info, but leaves e_ident[EI_OSABI] zero.  So we
-        have to check the note sections too. */
-      if (elfosabi == 0)
-       {
-         bfd_map_over_sections (abfd,
-                                process_note_abi_tag_sections,
-                                &elfosabi);
-       }
-    }
-
-  return elfosabi;
-}
-
 \f
-
 /* Initialize the current architecture based on INFO.  If possible, re-use an
    architecture from ARCHES, which is a list of architectures already created
    during this debugging session.
@@ -2502,7 +2421,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum bfd_architecture arch;
   unsigned long mach;
   bfd abfd;
-  int osabi, sysv_abi;
+  int sysv_abi;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
   gdbarch_print_insn_ftype *print_insn;
 
   from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
@@ -2513,7 +2433,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
 
-  osabi = get_elfosabi (info.abfd);
+  if (info.abfd)
+    osabi = gdbarch_lookup_osabi (info.abfd);
 
   /* Check word size.  If INFO is from a binary file, infer it from
      that, else choose a likely default. */
@@ -2726,57 +2647,23 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Not sure on this. FIXMEmgo */
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  /* Until November 2001, gcc was not complying to the SYSV ABI for
-     returning structures less than or equal to 8 bytes in size. It was
-     returning everything in memory. When this was corrected, it wasn't
-     fixed for native platforms. */
   if (sysv_abi)
-    {
-      if (osabi == ELFOSABI_LINUX
-          || osabi == ELFOSABI_NETBSD
-          || osabi == ELFOSABI_FREEBSD)
-       set_gdbarch_use_struct_convention (gdbarch,
-                                          ppc_sysv_abi_broken_use_struct_convention);
-      else
-       set_gdbarch_use_struct_convention (gdbarch,
-                                          ppc_sysv_abi_use_struct_convention);
-    }
+    set_gdbarch_use_struct_convention (gdbarch,
+                                      ppc_sysv_abi_use_struct_convention);
   else
-    {
-      set_gdbarch_use_struct_convention (gdbarch,
-                                        generic_use_struct_convention);
-    }
+    set_gdbarch_use_struct_convention (gdbarch,
+                                      generic_use_struct_convention);
 
   set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
-  /* Note: kevinb/2002-04-12: See note above regarding *_push_arguments().
-     The same remarks hold for the methods below.  */
-  if (osabi == ELFOSABI_LINUX && wordsize == 4)
-    {
-      set_gdbarch_frameless_function_invocation (gdbarch,
-       ppc_linux_frameless_function_invocation);
-      set_gdbarch_frame_chain (gdbarch, ppc_linux_frame_chain);
-      set_gdbarch_frame_saved_pc (gdbarch, ppc_linux_frame_saved_pc);
-
-      set_gdbarch_frame_init_saved_regs (gdbarch,
-                                        ppc_linux_frame_init_saved_regs);
-      set_gdbarch_init_extra_frame_info (gdbarch,
-                                        ppc_linux_init_extra_frame_info);
-
-      set_gdbarch_memory_remove_breakpoint (gdbarch,
-                                           ppc_linux_memory_remove_breakpoint);
-      set_solib_svr4_fetch_link_map_offsets 
-       (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
-    }
-  else
-    {
-      set_gdbarch_frameless_function_invocation (gdbarch,
-       rs6000_frameless_function_invocation);
-      set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain);
-      set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
 
-      set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
-      set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
-    }
+  set_gdbarch_frameless_function_invocation (gdbarch,
+                                         rs6000_frameless_function_invocation);
+  set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain);
+  set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
+
+  set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
+  set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
+
   if (!sysv_abi)
     {
       /* Handle RS/6000 function pointers (which are really function
@@ -2792,9 +2679,24 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      now that the C compiler delays popping them.  */
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
 
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch, osabi);
+
   return gdbarch;
 }
 
+static void
+rs6000_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (tdep == NULL)
+    return;
+
+  fprintf_unfiltered (file, "rs6000_dump_tdep: OS ABI = %s\n",
+                     gdbarch_osabi_name (tdep->osabi));
+}
+
 static struct cmd_list_element *info_powerpc_cmdlist = NULL;
 
 static void
@@ -2808,8 +2710,8 @@ rs6000_info_powerpc_command (char *args, int from_tty)
 void
 _initialize_rs6000_tdep (void)
 {
-  register_gdbarch_init (bfd_arch_rs6000, rs6000_gdbarch_init);
-  register_gdbarch_init (bfd_arch_powerpc, rs6000_gdbarch_init);
+  gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
+  gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
 
   /* Add root prefix command for "info powerpc" commands */
   add_prefix_cmd ("powerpc", class_info, rs6000_info_powerpc_command,
@@ -2819,5 +2721,4 @@ _initialize_rs6000_tdep (void)
   add_cmd ("altivec", class_info, rs6000_altivec_registers_info,
           "Display the contents of the AltiVec registers.",
           &info_powerpc_cmdlist);
-
 }