Home | History | Annotate | Line # | Download | only in gdb
      1      1.1  christos /* Target-dependent code for NetBSD/powerpc.
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2002-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    Contributed by Wasabi Systems, Inc.
      6      1.1  christos 
      7      1.1  christos    This file is part of GDB.
      8      1.1  christos 
      9      1.1  christos    This program is free software; you can redistribute it and/or modify
     10      1.1  christos    it under the terms of the GNU General Public License as published by
     11      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12      1.1  christos    (at your option) any later version.
     13      1.1  christos 
     14      1.1  christos    This program is distributed in the hope that it will be useful,
     15      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17      1.1  christos    GNU General Public License for more details.
     18      1.1  christos 
     19      1.1  christos    You should have received a copy of the GNU General Public License
     20      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21      1.1  christos 
     22      1.1  christos #include "gdbtypes.h"
     23      1.1  christos #include "osabi.h"
     24      1.1  christos #include "regcache.h"
     25      1.1  christos #include "regset.h"
     26      1.1  christos #include "trad-frame.h"
     27      1.1  christos #include "tramp-frame.h"
     28      1.1  christos 
     29      1.1  christos #include "ppc-tdep.h"
     30      1.1  christos #include "netbsd-tdep.h"
     31      1.1  christos #include "ppc-netbsd-tdep.h"
     32      1.1  christos #include "ppc-tdep.h"
     33      1.1  christos #include "solib-svr4.h"
     34      1.1  christos 
     35      1.1  christos /* Register offsets from <machine/reg.h>.  */
     36      1.1  christos static ppc_reg_offsets ppcnbsd_reg_offsets;
     37      1.1  christos 
     38      1.1  christos 
     40      1.1  christos /* Core file support.  */
     41      1.1  christos 
     42      1.1  christos /* NetBSD/powerpc register sets.  */
     43      1.1  christos 
     44      1.1  christos const struct regset ppcnbsd_gregset =
     45      1.1  christos {
     46      1.1  christos   &ppcnbsd_reg_offsets,
     47      1.1  christos   ppc_supply_gregset
     48      1.1  christos };
     49      1.1  christos 
     50      1.1  christos const struct regset ppcnbsd_fpregset =
     51      1.1  christos {
     52      1.1  christos   &ppcnbsd_reg_offsets,
     53      1.1  christos   ppc_supply_fpregset
     54      1.1  christos };
     55      1.1  christos 
     56      1.1  christos /* Iterate over core file register note sections.  */
     57      1.1  christos 
     58      1.1  christos static void
     59      1.1  christos ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
     60      1.1  christos 				      iterate_over_regset_sections_cb *cb,
     61      1.1  christos 				      void *cb_data,
     62      1.1  christos 				      const struct regcache *regcache)
     63      1.1  christos {
     64      1.1  christos   cb (".reg", 148, 148, &ppcnbsd_gregset, NULL, cb_data);
     65      1.1  christos   cb (".reg2", 264, 264, &ppcnbsd_fpregset, NULL, cb_data);
     66      1.1  christos }
     67      1.1  christos 
     68      1.1  christos 
     70      1.1  christos /* NetBSD is confused.  It appears that 1.5 was using the correct SVR4
     71      1.1  christos    convention but, 1.6 switched to the below broken convention.  For
     72      1.1  christos    the moment use the broken convention.  Ulgh!  */
     73      1.1  christos 
     74      1.1  christos static enum return_value_convention
     75      1.1  christos ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
     76      1.1  christos 		      struct type *valtype, struct regcache *regcache,
     77      1.1  christos 		      gdb_byte *readbuf, const gdb_byte *writebuf)
     78      1.1  christos {
     79      1.1  christos #if 0
     80      1.1  christos   if ((valtype->code () == TYPE_CODE_STRUCT
     81      1.1  christos        || valtype->code () == TYPE_CODE_UNION)
     82      1.1  christos       && !((valtype->length () == 16 || valtype->length () == 8)
     83      1.1  christos 	    && valtype->is_vector ())
     84      1.1  christos       && !(valtype->length () == 1
     85      1.1  christos 	   || valtype->length () == 2
     86      1.1  christos 	   || valtype->length () == 4
     87      1.1  christos 	   || valtype->length () == 8))
     88      1.1  christos     return RETURN_VALUE_STRUCT_CONVENTION;
     89      1.1  christos   else
     90      1.1  christos #endif
     91      1.1  christos     return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
     92      1.1  christos 					     regcache, readbuf, writebuf);
     93      1.1  christos }
     94      1.1  christos 
     95      1.1  christos 
     97      1.1  christos /* Signal trampolines.  */
     98      1.1  christos 
     99      1.1  christos extern const struct tramp_frame ppcnbsd2_sigtramp;
    100  1.1.1.2  christos 
    101      1.1  christos static void
    102      1.1  christos ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
    103      1.1  christos 			     const frame_info_ptr &this_frame,
    104      1.1  christos 			     struct trad_frame_cache *this_cache,
    105      1.1  christos 			     CORE_ADDR func)
    106      1.1  christos {
    107      1.1  christos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
    108      1.1  christos   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
    109      1.1  christos   CORE_ADDR addr, base;
    110      1.1  christos   int i;
    111      1.1  christos 
    112      1.1  christos   base = get_frame_register_unsigned (this_frame,
    113      1.1  christos 				      gdbarch_sp_regnum (gdbarch));
    114      1.1  christos   if (self == &ppcnbsd2_sigtramp)
    115      1.1  christos     addr = base + 0x10 + 2 * tdep->wordsize;
    116      1.1  christos   else
    117      1.1  christos     addr = base + 0x18 + 2 * tdep->wordsize;
    118      1.1  christos   for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    119      1.1  christos     {
    120      1.1  christos       int regnum = i + tdep->ppc_gp0_regnum;
    121      1.1  christos       trad_frame_set_reg_addr (this_cache, regnum, addr);
    122      1.1  christos     }
    123      1.1  christos   trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
    124      1.1  christos   addr += tdep->wordsize;
    125      1.1  christos   trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
    126      1.1  christos   addr += tdep->wordsize;
    127      1.1  christos   trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
    128      1.1  christos   addr += tdep->wordsize;
    129      1.1  christos   trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
    130      1.1  christos   addr += tdep->wordsize;
    131      1.1  christos   trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
    132      1.1  christos 			   addr); /* SRR0?  */
    133      1.1  christos   addr += tdep->wordsize;
    134      1.1  christos 
    135      1.1  christos   /* Construct the frame ID using the function start.  */
    136      1.1  christos   trad_frame_set_id (this_cache, frame_id_build (base, func));
    137      1.1  christos }
    138      1.1  christos 
    139      1.1  christos static const struct tramp_frame ppcnbsd_sigtramp =
    140      1.1  christos {
    141      1.1  christos   SIGTRAMP_FRAME,
    142      1.1  christos   4,
    143      1.1  christos   {
    144      1.1  christos     { 0x3821fff0, ULONGEST_MAX },		/* add r1,r1,-16 */
    145      1.1  christos     { 0x4e800021, ULONGEST_MAX },		/* blrl */
    146      1.1  christos     { 0x38610018, ULONGEST_MAX },		/* addi r3,r1,24 */
    147      1.1  christos     { 0x38000127, ULONGEST_MAX },		/* li r0,295 */
    148      1.1  christos     { 0x44000002, ULONGEST_MAX },		/* sc */
    149      1.1  christos     { 0x38000001, ULONGEST_MAX },		/* li r0,1 */
    150      1.1  christos     { 0x44000002, ULONGEST_MAX },		/* sc */
    151      1.1  christos     { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
    152      1.1  christos   },
    153      1.1  christos   ppcnbsd_sigtramp_cache_init
    154      1.1  christos };
    155      1.1  christos 
    156      1.1  christos /* NetBSD 2.0 introduced a slightly different signal trampoline.  */
    157      1.1  christos 
    158      1.1  christos const struct tramp_frame ppcnbsd2_sigtramp =
    159      1.1  christos {
    160      1.1  christos   SIGTRAMP_FRAME,
    161      1.1  christos   4,
    162      1.1  christos   {
    163      1.1  christos     { 0x3821fff0, ULONGEST_MAX },		/* add r1,r1,-16 */
    164      1.1  christos     { 0x4e800021, ULONGEST_MAX },		/* blrl */
    165      1.1  christos     { 0x38610010, ULONGEST_MAX },		/* addi r3,r1,16 */
    166      1.1  christos     { 0x38000127, ULONGEST_MAX },		/* li r0,295 */
    167      1.1  christos     { 0x44000002, ULONGEST_MAX },		/* sc */
    168      1.1  christos     { 0x38000001, ULONGEST_MAX },		/* li r0,1 */
    169      1.1  christos     { 0x44000002, ULONGEST_MAX },		/* sc */
    170      1.1  christos     { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
    171      1.1  christos   },
    172      1.1  christos   ppcnbsd_sigtramp_cache_init
    173      1.1  christos };
    174      1.1  christos 
    175      1.1  christos 
    177      1.1  christos static void
    178      1.1  christos ppcnbsd_init_abi (struct gdbarch_info info,
    179      1.1  christos 		  struct gdbarch *gdbarch)
    180      1.1  christos {
    181      1.1  christos   nbsd_init_abi (info, gdbarch);
    182      1.1  christos 
    183      1.1  christos   /* NetBSD doesn't support the 128-bit `long double' from the psABI.  */
    184      1.1  christos   set_gdbarch_long_double_bit (gdbarch, 64);
    185      1.1  christos   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
    186      1.1  christos 
    187      1.1  christos   /* For NetBSD, this is an on again, off again thing.  Some systems
    188      1.1  christos      do use the broken struct convention, and some don't.  */
    189      1.1  christos   set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
    190      1.1  christos 
    191      1.1  christos   /* NetBSD uses SVR4-style shared libraries.  */
    192      1.1  christos   set_solib_svr4_fetch_link_map_offsets
    193      1.1  christos     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
    194      1.1  christos 
    195      1.1  christos   set_gdbarch_iterate_over_regset_sections
    196      1.1  christos     (gdbarch, ppcnbsd_iterate_over_regset_sections);
    197      1.1  christos 
    198      1.1  christos   tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
    199      1.1  christos   tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
    200      1.1  christos }
    201      1.1  christos 
    202      1.1  christos void _initialize_ppcnbsd_tdep ();
    203      1.1  christos void
    204      1.1  christos _initialize_ppcnbsd_tdep ()
    205      1.1  christos {
    206      1.1  christos   gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD,
    207      1.1  christos 			  ppcnbsd_init_abi);
    208      1.1  christos 
    209      1.1  christos   /* Register NetBSD OSABI also for rs6000, which is default target
    210      1.1  christos      used before any executable image is loaded.  */
    211      1.1  christos   gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_NETBSD,
    212      1.1  christos 			  ppcnbsd_init_abi);
    213      1.1  christos 
    214      1.1  christos   /* Avoid initializing the register offsets again if they were
    215      1.1  christos      already initialized by ppc-netbsd-nat.c.  */
    216      1.1  christos   if (ppcnbsd_reg_offsets.pc_offset == 0)
    217      1.1  christos     {
    218      1.1  christos       /* General-purpose registers.  */
    219      1.1  christos       ppcnbsd_reg_offsets.r0_offset = 0;
    220      1.1  christos       ppcnbsd_reg_offsets.gpr_size = 4;
    221      1.1  christos       ppcnbsd_reg_offsets.xr_size = 4;
    222      1.1  christos       ppcnbsd_reg_offsets.lr_offset = 128;
    223      1.1  christos       ppcnbsd_reg_offsets.cr_offset = 132;
    224      1.1  christos       ppcnbsd_reg_offsets.xer_offset = 136;
    225      1.1  christos       ppcnbsd_reg_offsets.ctr_offset = 140;
    226      1.1  christos       ppcnbsd_reg_offsets.pc_offset = 144;
    227      1.1  christos       ppcnbsd_reg_offsets.ps_offset = -1;
    228      1.1  christos       ppcnbsd_reg_offsets.mq_offset = -1;
    229      1.1  christos 
    230      1.1  christos       /* Floating-point registers.  */
    231      1.1  christos       ppcnbsd_reg_offsets.f0_offset = 0;
    232      1.1  christos       ppcnbsd_reg_offsets.fpscr_offset = 256;
    233                          ppcnbsd_reg_offsets.fpscr_size = 4;
    234                    
    235                        }
    236                    }
    237