X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmn10300-linux-tdep.c;h=70f377f80ae128ec22528706def1b5deab30660c;hb=228c8f4be0c428369ec6b68e25696863d1e62ed7;hp=a659d855307fba37e155e8561345d7166c53e187;hpb=197e01b6dcd118b70ed3621b62b2ff3fa929d50f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c index a659d85530..70f377f80a 100644 --- a/gdb/mn10300-linux-tdep.c +++ b/gdb/mn10300-linux-tdep.c @@ -1,12 +1,12 @@ /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger. - Copyright (C) 2003, 2004, 2005 - Free Software Foundation, Inc. + + Copyright (C) 2003-2019 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,23 +15,22 @@ 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "gdbcore.h" -#include "gdb_string.h" #include "regcache.h" #include "mn10300-tdep.h" -#include "gdb_assert.h" #include "bfd.h" #include "elf-bfd.h" #include "osabi.h" #include "regset.h" #include "solib-svr4.h" - -#include +#include "frame.h" +#include "trad-frame.h" +#include "tramp-frame.h" +#include "linux-tdep.h" +#include "gdbarch.h" /* Transliterated from ... */ #define MN10300_ELF_NGREG 28 @@ -80,7 +79,7 @@ typedef struct Given a section name and size, create a struct reg object with a supply_register and a collect_register method. */ -/* Copy register value of REGNUM from regset to regcache. +/* Copy register value of REGNUM from regset to regcache. If REGNUM is -1, do this for all gp registers in regset. */ static void @@ -88,131 +87,126 @@ am33_supply_gregset_method (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len) { - char zerobuf[MAX_REGISTER_SIZE]; const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs; int i; - gdb_assert (len == sizeof (mn10300_elf_gregset_t)); + gdb_assert (len >= sizeof (mn10300_elf_gregset_t)); switch (regnum) { case E_D0_REGNUM: - regcache_raw_supply (regcache, E_D0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); + regcache->raw_supply (E_D0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); break; case E_D1_REGNUM: - regcache_raw_supply (regcache, E_D1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); + regcache->raw_supply (E_D1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); break; case E_D2_REGNUM: - regcache_raw_supply (regcache, E_D2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); + regcache->raw_supply (E_D2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); break; case E_D3_REGNUM: - regcache_raw_supply (regcache, E_D3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); + regcache->raw_supply (E_D3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); break; case E_A0_REGNUM: - regcache_raw_supply (regcache, E_A0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); + regcache->raw_supply (E_A0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); break; case E_A1_REGNUM: - regcache_raw_supply (regcache, E_A1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); + regcache->raw_supply (E_A1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); break; case E_A2_REGNUM: - regcache_raw_supply (regcache, E_A2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); + regcache->raw_supply (E_A2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); break; case E_A3_REGNUM: - regcache_raw_supply (regcache, E_A3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); + regcache->raw_supply (E_A3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); break; case E_SP_REGNUM: - regcache_raw_supply (regcache, E_SP_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); + regcache->raw_supply (E_SP_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); break; case E_PC_REGNUM: - regcache_raw_supply (regcache, E_PC_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); + regcache->raw_supply (E_PC_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); break; case E_MDR_REGNUM: - regcache_raw_supply (regcache, E_MDR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); + regcache->raw_supply (E_MDR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); break; case E_PSW_REGNUM: - regcache_raw_supply (regcache, E_PSW_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); + regcache->raw_supply (E_PSW_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); break; case E_LIR_REGNUM: - regcache_raw_supply (regcache, E_LIR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); + regcache->raw_supply (E_LIR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); break; case E_LAR_REGNUM: - regcache_raw_supply (regcache, E_LAR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); + regcache->raw_supply (E_LAR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); break; case E_MDRQ_REGNUM: - regcache_raw_supply (regcache, E_MDRQ_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); + regcache->raw_supply (E_MDRQ_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); break; case E_E0_REGNUM: - regcache_raw_supply (regcache, E_E0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); + regcache->raw_supply (E_E0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); break; case E_E1_REGNUM: - regcache_raw_supply (regcache, E_E1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); + regcache->raw_supply (E_E1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); break; case E_E2_REGNUM: - regcache_raw_supply (regcache, E_E2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); + regcache->raw_supply (E_E2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); break; case E_E3_REGNUM: - regcache_raw_supply (regcache, E_E3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); + regcache->raw_supply (E_E3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); break; case E_E4_REGNUM: - regcache_raw_supply (regcache, E_E4_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); + regcache->raw_supply (E_E4_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); break; case E_E5_REGNUM: - regcache_raw_supply (regcache, E_E5_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); + regcache->raw_supply (E_E5_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); break; case E_E6_REGNUM: - regcache_raw_supply (regcache, E_E6_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); + regcache->raw_supply (E_E6_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); break; case E_E7_REGNUM: - regcache_raw_supply (regcache, E_E7_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); + regcache->raw_supply (E_E7_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); break; /* ssp, msp, and usp are inaccessible. */ case E_E8_REGNUM: - memset (zerobuf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf); + regcache->raw_supply_zeroed (E_E8_REGNUM); break; case E_E9_REGNUM: - memset (zerobuf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf); + regcache->raw_supply_zeroed (E_E9_REGNUM); break; case E_E10_REGNUM: - memset (zerobuf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf); - + regcache->raw_supply_zeroed (E_E10_REGNUM); break; case E_MCRH_REGNUM: - regcache_raw_supply (regcache, E_MCRH_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); + regcache->raw_supply (E_MCRH_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); break; case E_MCRL_REGNUM: - regcache_raw_supply (regcache, E_MCRL_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); + regcache->raw_supply (E_MCRL_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); break; case E_MCVF_REGNUM: - regcache_raw_supply (regcache, E_MCVF_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); + regcache->raw_supply (E_MCVF_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); break; case E_FPCR_REGNUM: /* FPCR is numbered among the GP regs, but handled as an FP reg. @@ -220,12 +214,10 @@ am33_supply_gregset_method (const struct regset *regset, break; case E_FPCR_REGNUM + 1: /* The two unused registers beyond fpcr are inaccessible. */ - memset (zerobuf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf); + regcache->raw_supply_zeroed (E_FPCR_REGNUM + 1); break; case E_FPCR_REGNUM + 2: - memset (zerobuf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf); + regcache->raw_supply_zeroed (E_FPCR_REGNUM + 2); break; default: /* An error, obviously, but should we error out? */ break; @@ -237,17 +229,18 @@ am33_supply_gregset_method (const struct regset *regset, return; } -/* Copy fp register value of REGNUM from regset to regcache. - If REGNUM is -1, do this for all fp registers in regset. */ +/* Copy fp register value of REGNUM from regset to regcache. + If REGNUM is -1, do this for all fp registers in regset. */ static void am33_supply_fpregset_method (const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len) { - const mn10300_elf_fpregset_t *fpregset = fpregs; + const mn10300_elf_fpregset_t *fpregset + = (const mn10300_elf_fpregset_t *) fpregs; - gdb_assert (len == sizeof (mn10300_elf_fpregset_t)); + gdb_assert (len >= sizeof (mn10300_elf_fpregset_t)); if (regnum == -1) { @@ -260,11 +253,10 @@ am33_supply_fpregset_method (const struct regset *regset, E_FPCR_REGNUM, fpregs, len); } else if (regnum == E_FPCR_REGNUM) - regcache_raw_supply (current_regcache, E_FPCR_REGNUM, - &fpregset->fpcr); - else if (E_FS0_REGNUM <= regnum && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG) - regcache_raw_supply (current_regcache, regnum, - &fpregset->fpregs[regnum - E_FS0_REGNUM]); + regcache->raw_supply (E_FPCR_REGNUM, &fpregset->fpcr); + else if (E_FS0_REGNUM <= regnum + && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG) + regcache->raw_supply (regnum, &fpregset->fpregs[regnum - E_FS0_REGNUM]); return; } @@ -276,103 +268,103 @@ am33_collect_gregset_method (const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len) { - mn10300_elf_gregset_t *regp = gregs; + mn10300_elf_gregset_t *regp = (gdb_byte (*)[28][4]) gregs; int i; - gdb_assert (len == sizeof (mn10300_elf_gregset_t)); + gdb_assert (len >= sizeof (mn10300_elf_gregset_t)); switch (regnum) { case E_D0_REGNUM: - regcache_raw_collect (regcache, E_D0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); + regcache->raw_collect (E_D0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); break; case E_D1_REGNUM: - regcache_raw_collect (regcache, E_D1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); + regcache->raw_collect (E_D1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); break; case E_D2_REGNUM: - regcache_raw_collect (regcache, E_D2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); + regcache->raw_collect (E_D2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); break; case E_D3_REGNUM: - regcache_raw_collect (regcache, E_D3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); + regcache->raw_collect (E_D3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); break; case E_A0_REGNUM: - regcache_raw_collect (regcache, E_A0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); + regcache->raw_collect (E_A0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); break; case E_A1_REGNUM: - regcache_raw_collect (regcache, E_A1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); + regcache->raw_collect (E_A1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); break; case E_A2_REGNUM: - regcache_raw_collect (regcache, E_A2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); + regcache->raw_collect (E_A2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); break; case E_A3_REGNUM: - regcache_raw_collect (regcache, E_A3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); + regcache->raw_collect (E_A3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); break; case E_SP_REGNUM: - regcache_raw_collect (regcache, E_SP_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); + regcache->raw_collect (E_SP_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); break; case E_PC_REGNUM: - regcache_raw_collect (regcache, E_PC_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); + regcache->raw_collect (E_PC_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); break; case E_MDR_REGNUM: - regcache_raw_collect (regcache, E_MDR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); + regcache->raw_collect (E_MDR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); break; case E_PSW_REGNUM: - regcache_raw_collect (regcache, E_PSW_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); + regcache->raw_collect (E_PSW_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); break; case E_LIR_REGNUM: - regcache_raw_collect (regcache, E_LIR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); + regcache->raw_collect (E_LIR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); break; case E_LAR_REGNUM: - regcache_raw_collect (regcache, E_LAR_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); + regcache->raw_collect (E_LAR_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); break; case E_MDRQ_REGNUM: - regcache_raw_collect (regcache, E_MDRQ_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); + regcache->raw_collect (E_MDRQ_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); break; case E_E0_REGNUM: - regcache_raw_collect (regcache, E_E0_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); + regcache->raw_collect (E_E0_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); break; case E_E1_REGNUM: - regcache_raw_collect (regcache, E_E1_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); + regcache->raw_collect (E_E1_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); break; case E_E2_REGNUM: - regcache_raw_collect (regcache, E_E2_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); + regcache->raw_collect (E_E2_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); break; case E_E3_REGNUM: - regcache_raw_collect (regcache, E_E3_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); + regcache->raw_collect (E_E3_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); break; case E_E4_REGNUM: - regcache_raw_collect (regcache, E_E4_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); + regcache->raw_collect (E_E4_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); break; case E_E5_REGNUM: - regcache_raw_collect (regcache, E_E5_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); + regcache->raw_collect (E_E5_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); break; case E_E6_REGNUM: - regcache_raw_collect (regcache, E_E6_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); + regcache->raw_collect (E_E6_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); break; case E_E7_REGNUM: - regcache_raw_collect (regcache, E_E7_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); + regcache->raw_collect (E_E7_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); break; /* ssp, msp, and usp are inaccessible. */ @@ -386,16 +378,16 @@ am33_collect_gregset_method (const struct regset *regset, /* The gregset struct has noplace to put this: do nothing. */ break; case E_MCRH_REGNUM: - regcache_raw_collect (regcache, E_MCRH_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); + regcache->raw_collect (E_MCRH_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); break; case E_MCRL_REGNUM: - regcache_raw_collect (regcache, E_MCRL_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); + regcache->raw_collect (E_MCRL_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); break; case E_MCVF_REGNUM: - regcache_raw_collect (regcache, E_MCVF_REGNUM, - (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); + regcache->raw_collect (E_MCVF_REGNUM, + (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); break; case E_FPCR_REGNUM: /* FPCR is numbered among the GP regs, but handled as an FP reg. @@ -424,9 +416,9 @@ am33_collect_fpregset_method (const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len) { - mn10300_elf_fpregset_t *fpregset = fpregs; + mn10300_elf_fpregset_t *fpregset = (mn10300_elf_fpregset_t *) fpregs; - gdb_assert (len == sizeof (mn10300_elf_fpregset_t)); + gdb_assert (len >= sizeof (mn10300_elf_fpregset_t)); if (regnum == -1) { @@ -438,46 +430,289 @@ am33_collect_fpregset_method (const struct regset *regset, E_FPCR_REGNUM, fpregs, len); } else if (regnum == E_FPCR_REGNUM) - regcache_raw_collect (current_regcache, E_FPCR_REGNUM, - &fpregset->fpcr); + regcache->raw_collect (E_FPCR_REGNUM, &fpregset->fpcr); else if (E_FS0_REGNUM <= regnum && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG) - regcache_raw_collect (current_regcache, regnum, - &fpregset->fpregs[regnum - E_FS0_REGNUM]); + regcache->raw_collect (regnum, &fpregset->fpregs[regnum - E_FS0_REGNUM]); return; } -/* Create a struct regset from a corefile register section. */ +static const struct regset am33_gregset = + { + NULL, am33_supply_gregset_method, am33_collect_gregset_method + }; -static const struct regset * -am33_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, - size_t sect_size) +static const struct regset am33_fpregset = + { + NULL, am33_supply_fpregset_method, am33_collect_fpregset_method + }; + +/* Iterate over core file register note sections. */ + +static void +am33_iterate_over_regset_sections (struct gdbarch *gdbarch, + iterate_over_regset_sections_cb *cb, + void *cb_data, + const struct regcache *regcache) { - /* We will call regset_alloc, and pass the names of the supply and - collect methods. */ + cb (".reg", sizeof (mn10300_elf_gregset_t), sizeof (mn10300_elf_gregset_t), + &am33_gregset, NULL, cb_data); + cb (".reg2", sizeof (mn10300_elf_fpregset_t), sizeof (mn10300_elf_fpregset_t), + &am33_fpregset, NULL, cb_data); +} + +static void +am33_linux_sigframe_cache_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func); + +static const struct tramp_frame am33_linux_sigframe = { + SIGTRAMP_FRAME, + 1, + { + /* mov 119,d0 */ + { 0x2c, ULONGEST_MAX }, + { 0x77, ULONGEST_MAX }, + { 0x00, ULONGEST_MAX }, + /* syscall 0 */ + { 0xf0, ULONGEST_MAX }, + { 0xe0, ULONGEST_MAX }, + { TRAMP_SENTINEL_INSN, ULONGEST_MAX } + }, + am33_linux_sigframe_cache_init +}; + +static const struct tramp_frame am33_linux_rt_sigframe = { + SIGTRAMP_FRAME, + 1, + { + /* mov 173,d0 */ + { 0x2c, ULONGEST_MAX }, + { 0xad, ULONGEST_MAX }, + { 0x00, ULONGEST_MAX }, + /* syscall 0 */ + { 0xf0, ULONGEST_MAX }, + { 0xe0, ULONGEST_MAX }, + { TRAMP_SENTINEL_INSN, ULONGEST_MAX } + }, + am33_linux_sigframe_cache_init +}; + +/* Relevant struct definitions for signal handling... + +From arch/mn10300/kernel/sigframe.h: + +struct sigframe +{ + void (*pretcode)(void); + int sig; + struct sigcontext *psc; + struct sigcontext sc; + struct fpucontext fpuctx; + unsigned long extramask[_NSIG_WORDS-1]; + char retcode[8]; +}; + +struct rt_sigframe +{ + void (*pretcode)(void); + int sig; + struct siginfo *pinfo; + void *puc; + struct siginfo info; + struct ucontext uc; + struct fpucontext fpuctx; + char retcode[8]; +}; + +From include/asm-mn10300/ucontext.h: + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; +}; + +From include/asm-mn10300/sigcontext.h: + +struct fpucontext { + unsigned long fs[32]; + unsigned long fpcr; +}; + +struct sigcontext { + unsigned long d0; + unsigned long d1; + unsigned long d2; + unsigned long d3; + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + unsigned long e0; + unsigned long e1; + unsigned long e2; + unsigned long e3; + unsigned long e4; + unsigned long e5; + unsigned long e6; + unsigned long e7; + unsigned long lar; + unsigned long lir; + unsigned long mdr; + unsigned long mcvf; + unsigned long mcrl; + unsigned long mcrh; + unsigned long mdrq; + unsigned long sp; + unsigned long epsw; + unsigned long pc; + struct fpucontext *fpucontext; + unsigned long oldmask; +}; */ + + +#define AM33_SIGCONTEXT_D0 0 +#define AM33_SIGCONTEXT_D1 4 +#define AM33_SIGCONTEXT_D2 8 +#define AM33_SIGCONTEXT_D3 12 +#define AM33_SIGCONTEXT_A0 16 +#define AM33_SIGCONTEXT_A1 20 +#define AM33_SIGCONTEXT_A2 24 +#define AM33_SIGCONTEXT_A3 28 +#define AM33_SIGCONTEXT_E0 32 +#define AM33_SIGCONTEXT_E1 36 +#define AM33_SIGCONTEXT_E2 40 +#define AM33_SIGCONTEXT_E3 44 +#define AM33_SIGCONTEXT_E4 48 +#define AM33_SIGCONTEXT_E5 52 +#define AM33_SIGCONTEXT_E6 56 +#define AM33_SIGCONTEXT_E7 60 +#define AM33_SIGCONTEXT_LAR 64 +#define AM33_SIGCONTEXT_LIR 68 +#define AM33_SIGCONTEXT_MDR 72 +#define AM33_SIGCONTEXT_MCVF 76 +#define AM33_SIGCONTEXT_MCRL 80 +#define AM33_SIGCONTEXT_MCRH 84 +#define AM33_SIGCONTEXT_MDRQ 88 +#define AM33_SIGCONTEXT_SP 92 +#define AM33_SIGCONTEXT_EPSW 96 +#define AM33_SIGCONTEXT_PC 100 +#define AM33_SIGCONTEXT_FPUCONTEXT 104 - if (sect_size == sizeof (mn10300_elf_fpregset_t)) - return regset_alloc (gdbarch, - am33_supply_fpregset_method, - am33_collect_fpregset_method); + +static void +am33_linux_sigframe_cache_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) +{ + CORE_ADDR sc_base, fpubase; + int i; + + sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM); + if (self == &am33_linux_sigframe) + { + sc_base += 8; + sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4); + } else - return regset_alloc (gdbarch, - am33_supply_gregset_method, - am33_collect_gregset_method); -} + { + sc_base += 12; + sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4); + sc_base += 20; + } -/* AM33 Linux osabi has been recognized. + trad_frame_set_reg_addr (this_cache, E_D0_REGNUM, + sc_base + AM33_SIGCONTEXT_D0); + trad_frame_set_reg_addr (this_cache, E_D1_REGNUM, + sc_base + AM33_SIGCONTEXT_D1); + trad_frame_set_reg_addr (this_cache, E_D2_REGNUM, + sc_base + AM33_SIGCONTEXT_D2); + trad_frame_set_reg_addr (this_cache, E_D3_REGNUM, + sc_base + AM33_SIGCONTEXT_D3); + + trad_frame_set_reg_addr (this_cache, E_A0_REGNUM, + sc_base + AM33_SIGCONTEXT_A0); + trad_frame_set_reg_addr (this_cache, E_A1_REGNUM, + sc_base + AM33_SIGCONTEXT_A1); + trad_frame_set_reg_addr (this_cache, E_A2_REGNUM, + sc_base + AM33_SIGCONTEXT_A2); + trad_frame_set_reg_addr (this_cache, E_A3_REGNUM, + sc_base + AM33_SIGCONTEXT_A3); + + trad_frame_set_reg_addr (this_cache, E_E0_REGNUM, + sc_base + AM33_SIGCONTEXT_E0); + trad_frame_set_reg_addr (this_cache, E_E1_REGNUM, + sc_base + AM33_SIGCONTEXT_E1); + trad_frame_set_reg_addr (this_cache, E_E2_REGNUM, + sc_base + AM33_SIGCONTEXT_E2); + trad_frame_set_reg_addr (this_cache, E_E3_REGNUM, + sc_base + AM33_SIGCONTEXT_E3); + trad_frame_set_reg_addr (this_cache, E_E4_REGNUM, + sc_base + AM33_SIGCONTEXT_E4); + trad_frame_set_reg_addr (this_cache, E_E5_REGNUM, + sc_base + AM33_SIGCONTEXT_E5); + trad_frame_set_reg_addr (this_cache, E_E6_REGNUM, + sc_base + AM33_SIGCONTEXT_E6); + trad_frame_set_reg_addr (this_cache, E_E7_REGNUM, + sc_base + AM33_SIGCONTEXT_E7); + + trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM, + sc_base + AM33_SIGCONTEXT_LAR); + trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM, + sc_base + AM33_SIGCONTEXT_LIR); + trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM, + sc_base + AM33_SIGCONTEXT_MDR); + trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM, + sc_base + AM33_SIGCONTEXT_MCVF); + trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM, + sc_base + AM33_SIGCONTEXT_MCRL); + trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM, + sc_base + AM33_SIGCONTEXT_MDRQ); + + trad_frame_set_reg_addr (this_cache, E_SP_REGNUM, + sc_base + AM33_SIGCONTEXT_SP); + trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM, + sc_base + AM33_SIGCONTEXT_EPSW); + trad_frame_set_reg_addr (this_cache, E_PC_REGNUM, + sc_base + AM33_SIGCONTEXT_PC); + + fpubase = get_frame_memory_unsigned (this_frame, + sc_base + AM33_SIGCONTEXT_FPUCONTEXT, + 4); + if (fpubase) + { + for (i = 0; i < 32; i++) + { + trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i, + fpubase + 4 * i); + } + trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32); + } + + trad_frame_set_id (this_cache, frame_id_build (sc_base, func)); +} + +/* AM33 GNU/Linux osabi has been recognized. Now's our chance to register our corefile handling. */ static void -am33_linux_init_osabi (struct gdbarch_info gdbinfo, struct gdbarch *gdbarch) +am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) { - set_gdbarch_regset_from_core_section (gdbarch, - am33_regset_from_core_section); + linux_init_abi (info, gdbarch); + + set_gdbarch_iterate_over_regset_sections + (gdbarch, am33_iterate_over_regset_sections); set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe); + tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe); } void