GDB (API)
/home/stan/gdb/src/gdb/mn10300-linux-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbcore.h"
00022 #include "gdb_string.h"
00023 #include "regcache.h"
00024 #include "mn10300-tdep.h"
00025 #include "gdb_assert.h"
00026 #include "bfd.h"
00027 #include "elf-bfd.h"
00028 #include "osabi.h"
00029 #include "regset.h"
00030 #include "solib-svr4.h"
00031 #include "frame.h"
00032 #include "trad-frame.h"
00033 #include "tramp-frame.h"
00034 #include "linux-tdep.h"
00035 
00036 #include <stdlib.h>
00037 
00038 /* Transliterated from <asm-mn10300/elf.h>...  */
00039 #define MN10300_ELF_NGREG 28
00040 #define MN10300_ELF_NFPREG 32
00041 
00042 typedef gdb_byte   mn10300_elf_greg_t[4];
00043 typedef mn10300_elf_greg_t mn10300_elf_gregset_t[MN10300_ELF_NGREG];
00044 
00045 typedef gdb_byte   mn10300_elf_fpreg_t[4];
00046 typedef struct
00047 {
00048   mn10300_elf_fpreg_t fpregs[MN10300_ELF_NFPREG];
00049   gdb_byte    fpcr[4];
00050 } mn10300_elf_fpregset_t;
00051 
00052 /* elf_gregset_t register indices stolen from include/asm-mn10300/ptrace.h.  */
00053 #define MN10300_ELF_GREGSET_T_REG_INDEX_A3      0
00054 #define MN10300_ELF_GREGSET_T_REG_INDEX_A2      1
00055 #define MN10300_ELF_GREGSET_T_REG_INDEX_D3      2
00056 #define MN10300_ELF_GREGSET_T_REG_INDEX_D2      3
00057 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCVF    4
00058 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRL    5
00059 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRH    6
00060 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ    7
00061 #define MN10300_ELF_GREGSET_T_REG_INDEX_E1      8
00062 #define MN10300_ELF_GREGSET_T_REG_INDEX_E0      9
00063 #define MN10300_ELF_GREGSET_T_REG_INDEX_E7      10
00064 #define MN10300_ELF_GREGSET_T_REG_INDEX_E6      11
00065 #define MN10300_ELF_GREGSET_T_REG_INDEX_E5      12
00066 #define MN10300_ELF_GREGSET_T_REG_INDEX_E4      13
00067 #define MN10300_ELF_GREGSET_T_REG_INDEX_E3      14
00068 #define MN10300_ELF_GREGSET_T_REG_INDEX_E2      15
00069 #define MN10300_ELF_GREGSET_T_REG_INDEX_SP      16
00070 #define MN10300_ELF_GREGSET_T_REG_INDEX_LAR     17
00071 #define MN10300_ELF_GREGSET_T_REG_INDEX_LIR     18
00072 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDR     19
00073 #define MN10300_ELF_GREGSET_T_REG_INDEX_A1      20
00074 #define MN10300_ELF_GREGSET_T_REG_INDEX_A0      21
00075 #define MN10300_ELF_GREGSET_T_REG_INDEX_D1      22
00076 #define MN10300_ELF_GREGSET_T_REG_INDEX_D0      23
00077 #define MN10300_ELF_GREGSET_T_REG_INDEX_ORIG_D0 24
00078 #define MN10300_ELF_GREGSET_T_REG_INDEX_EPSW    25
00079 #define MN10300_ELF_GREGSET_T_REG_INDEX_PC      26
00080 
00081 /* New gdbarch API for corefile registers.
00082    Given a section name and size, create a struct reg object
00083    with a supply_register and a collect_register method.  */
00084 
00085 /* Copy register value of REGNUM from regset to regcache.
00086    If REGNUM is -1, do this for all gp registers in regset.  */
00087 
00088 static void
00089 am33_supply_gregset_method (const struct regset *regset, 
00090                             struct regcache *regcache, 
00091                             int regnum, const void *gregs, size_t len)
00092 {
00093   char zerobuf[MAX_REGISTER_SIZE];
00094   const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
00095   int i;
00096 
00097   gdb_assert (len == sizeof (mn10300_elf_gregset_t));
00098 
00099   switch (regnum) {
00100   case E_D0_REGNUM:
00101     regcache_raw_supply (regcache, E_D0_REGNUM, 
00102                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
00103     break;
00104   case E_D1_REGNUM:
00105     regcache_raw_supply (regcache, E_D1_REGNUM, 
00106                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
00107     break;
00108   case E_D2_REGNUM:
00109     regcache_raw_supply (regcache, E_D2_REGNUM, 
00110                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
00111     break;
00112   case E_D3_REGNUM:
00113     regcache_raw_supply (regcache, E_D3_REGNUM, 
00114                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
00115     break;
00116   case E_A0_REGNUM:
00117     regcache_raw_supply (regcache, E_A0_REGNUM, 
00118                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
00119     break;
00120   case E_A1_REGNUM:
00121     regcache_raw_supply (regcache, E_A1_REGNUM, 
00122                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
00123     break;
00124   case E_A2_REGNUM:
00125     regcache_raw_supply (regcache, E_A2_REGNUM, 
00126                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
00127     break;
00128   case E_A3_REGNUM:
00129     regcache_raw_supply (regcache, E_A3_REGNUM, 
00130                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
00131     break;
00132   case E_SP_REGNUM:
00133     regcache_raw_supply (regcache, E_SP_REGNUM, 
00134                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
00135     break;
00136   case E_PC_REGNUM:
00137     regcache_raw_supply (regcache, E_PC_REGNUM, 
00138                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
00139     break;
00140   case E_MDR_REGNUM:
00141     regcache_raw_supply (regcache, E_MDR_REGNUM, 
00142                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
00143     break;
00144   case E_PSW_REGNUM:
00145     regcache_raw_supply (regcache, E_PSW_REGNUM, 
00146                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
00147     break;
00148   case E_LIR_REGNUM:
00149     regcache_raw_supply (regcache, E_LIR_REGNUM, 
00150                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
00151     break;
00152   case E_LAR_REGNUM:
00153     regcache_raw_supply (regcache, E_LAR_REGNUM, 
00154                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
00155     break;
00156   case E_MDRQ_REGNUM:
00157     regcache_raw_supply (regcache, E_MDRQ_REGNUM, 
00158                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
00159     break;
00160   case E_E0_REGNUM:
00161     regcache_raw_supply (regcache, E_E0_REGNUM,   
00162                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
00163     break;
00164   case E_E1_REGNUM:
00165     regcache_raw_supply (regcache, E_E1_REGNUM,
00166                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
00167     break;
00168   case E_E2_REGNUM:
00169     regcache_raw_supply (regcache, E_E2_REGNUM, 
00170                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
00171     break;
00172   case E_E3_REGNUM:
00173     regcache_raw_supply (regcache, E_E3_REGNUM, 
00174                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
00175     break;
00176   case E_E4_REGNUM:
00177     regcache_raw_supply (regcache, E_E4_REGNUM, 
00178                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
00179     break;
00180   case E_E5_REGNUM:
00181     regcache_raw_supply (regcache, E_E5_REGNUM, 
00182                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
00183     break;
00184   case E_E6_REGNUM:
00185     regcache_raw_supply (regcache, E_E6_REGNUM, 
00186                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
00187     break;
00188   case E_E7_REGNUM:
00189     regcache_raw_supply (regcache, E_E7_REGNUM, 
00190                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
00191     break;
00192 
00193     /* ssp, msp, and usp are inaccessible.  */
00194   case E_E8_REGNUM:
00195     memset (zerobuf, 0, MAX_REGISTER_SIZE);
00196     regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
00197     break;
00198   case E_E9_REGNUM:
00199     memset (zerobuf, 0, MAX_REGISTER_SIZE);
00200     regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
00201     break;
00202   case E_E10_REGNUM:
00203     memset (zerobuf, 0, MAX_REGISTER_SIZE);
00204     regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);
00205 
00206     break;
00207   case E_MCRH_REGNUM:
00208     regcache_raw_supply (regcache, E_MCRH_REGNUM, 
00209                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
00210     break;
00211   case E_MCRL_REGNUM:
00212     regcache_raw_supply (regcache, E_MCRL_REGNUM, 
00213                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
00214     break;
00215   case E_MCVF_REGNUM:
00216     regcache_raw_supply (regcache, E_MCVF_REGNUM, 
00217                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
00218     break;
00219   case E_FPCR_REGNUM:
00220     /* FPCR is numbered among the GP regs, but handled as an FP reg.
00221        Do nothing.  */
00222     break;
00223   case E_FPCR_REGNUM + 1:
00224     /* The two unused registers beyond fpcr are inaccessible.  */
00225     memset (zerobuf, 0, MAX_REGISTER_SIZE);
00226     regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
00227     break;
00228   case E_FPCR_REGNUM + 2:
00229     memset (zerobuf, 0, MAX_REGISTER_SIZE);
00230     regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
00231     break;
00232   default:      /* An error, obviously, but should we error out?  */
00233     break;
00234   case -1:
00235     for (i = 0; i < MN10300_ELF_NGREG; i++)
00236       am33_supply_gregset_method (regset, regcache, i, gregs, len);
00237     break;
00238   }
00239   return;
00240 }
00241 
00242 /* Copy fp register value of REGNUM from regset to regcache.
00243    If REGNUM is -1, do this for all fp registers in regset.  */
00244 
00245 static void
00246 am33_supply_fpregset_method (const struct regset *regset, 
00247                              struct regcache *regcache, 
00248                              int regnum, const void *fpregs, size_t len)
00249 {
00250   const mn10300_elf_fpregset_t *fpregset = fpregs;
00251 
00252   gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
00253 
00254   if (regnum == -1)
00255     {
00256       int i;
00257 
00258       for (i = 0; i < MN10300_ELF_NFPREG; i++)
00259         am33_supply_fpregset_method (regset, regcache,
00260                                      E_FS0_REGNUM + i, fpregs, len);
00261       am33_supply_fpregset_method (regset, regcache, 
00262                                    E_FPCR_REGNUM, fpregs, len);
00263     }
00264   else if (regnum == E_FPCR_REGNUM)
00265     regcache_raw_supply (regcache, E_FPCR_REGNUM, 
00266                          &fpregset->fpcr);
00267   else if (E_FS0_REGNUM <= regnum
00268            && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
00269     regcache_raw_supply (regcache, regnum, 
00270                          &fpregset->fpregs[regnum - E_FS0_REGNUM]);
00271 
00272   return;
00273 }
00274 
00275 /* Copy register values from regcache to regset.  */
00276 
00277 static void
00278 am33_collect_gregset_method (const struct regset *regset, 
00279                              const struct regcache *regcache, 
00280                              int regnum, void *gregs, size_t len)
00281 {
00282   mn10300_elf_gregset_t *regp = gregs;
00283   int i;
00284 
00285   gdb_assert (len == sizeof (mn10300_elf_gregset_t));
00286 
00287   switch (regnum) {
00288   case E_D0_REGNUM:
00289     regcache_raw_collect (regcache, E_D0_REGNUM, 
00290                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
00291     break;
00292   case E_D1_REGNUM:
00293     regcache_raw_collect (regcache, E_D1_REGNUM, 
00294                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
00295     break;
00296   case E_D2_REGNUM:
00297     regcache_raw_collect (regcache, E_D2_REGNUM, 
00298                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
00299     break;
00300   case E_D3_REGNUM:
00301     regcache_raw_collect (regcache, E_D3_REGNUM, 
00302                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
00303     break;
00304   case E_A0_REGNUM:
00305     regcache_raw_collect (regcache, E_A0_REGNUM, 
00306                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
00307     break;
00308   case E_A1_REGNUM:
00309     regcache_raw_collect (regcache, E_A1_REGNUM, 
00310                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
00311     break;
00312   case E_A2_REGNUM:
00313     regcache_raw_collect (regcache, E_A2_REGNUM, 
00314                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
00315     break;
00316   case E_A3_REGNUM:
00317     regcache_raw_collect (regcache, E_A3_REGNUM, 
00318                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
00319     break;
00320   case E_SP_REGNUM:
00321     regcache_raw_collect (regcache, E_SP_REGNUM, 
00322                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
00323     break;
00324   case E_PC_REGNUM:
00325     regcache_raw_collect (regcache, E_PC_REGNUM, 
00326                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
00327     break;
00328   case E_MDR_REGNUM:
00329     regcache_raw_collect (regcache, E_MDR_REGNUM, 
00330                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
00331     break;
00332   case E_PSW_REGNUM:
00333     regcache_raw_collect (regcache, E_PSW_REGNUM, 
00334                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
00335     break;
00336   case E_LIR_REGNUM:
00337     regcache_raw_collect (regcache, E_LIR_REGNUM, 
00338                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
00339     break;
00340   case E_LAR_REGNUM:
00341     regcache_raw_collect (regcache, E_LAR_REGNUM, 
00342                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
00343     break;
00344   case E_MDRQ_REGNUM:
00345     regcache_raw_collect (regcache, E_MDRQ_REGNUM, 
00346                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
00347     break;
00348   case E_E0_REGNUM:
00349     regcache_raw_collect (regcache, E_E0_REGNUM,   
00350                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
00351     break;
00352   case E_E1_REGNUM:
00353     regcache_raw_collect (regcache, E_E1_REGNUM,
00354                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
00355     break;
00356   case E_E2_REGNUM:
00357     regcache_raw_collect (regcache, E_E2_REGNUM, 
00358                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
00359     break;
00360   case E_E3_REGNUM:
00361     regcache_raw_collect (regcache, E_E3_REGNUM, 
00362                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
00363     break;
00364   case E_E4_REGNUM:
00365     regcache_raw_collect (regcache, E_E4_REGNUM, 
00366                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
00367     break;
00368   case E_E5_REGNUM:
00369     regcache_raw_collect (regcache, E_E5_REGNUM, 
00370                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
00371     break;
00372   case E_E6_REGNUM:
00373     regcache_raw_collect (regcache, E_E6_REGNUM, 
00374                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
00375     break;
00376   case E_E7_REGNUM:
00377     regcache_raw_collect (regcache, E_E7_REGNUM, 
00378                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
00379     break;
00380 
00381     /* ssp, msp, and usp are inaccessible.  */
00382   case E_E8_REGNUM:
00383     /* The gregset struct has noplace to put this: do nothing.  */
00384     break;
00385   case E_E9_REGNUM:
00386     /* The gregset struct has noplace to put this: do nothing.  */
00387     break;
00388   case E_E10_REGNUM:
00389     /* The gregset struct has noplace to put this: do nothing.  */
00390     break;
00391   case E_MCRH_REGNUM:
00392     regcache_raw_collect (regcache, E_MCRH_REGNUM, 
00393                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
00394     break;
00395   case E_MCRL_REGNUM:
00396     regcache_raw_collect (regcache, E_MCRL_REGNUM, 
00397                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
00398     break;
00399   case E_MCVF_REGNUM:
00400     regcache_raw_collect (regcache, E_MCVF_REGNUM, 
00401                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
00402     break;
00403   case E_FPCR_REGNUM:
00404     /* FPCR is numbered among the GP regs, but handled as an FP reg.
00405        Do nothing.  */
00406     break;
00407   case E_FPCR_REGNUM + 1:
00408     /* The gregset struct has noplace to put this: do nothing.  */
00409     break;
00410   case E_FPCR_REGNUM + 2:
00411     /* The gregset struct has noplace to put this: do nothing.  */
00412     break;
00413   default:      /* An error, obviously, but should we error out?  */
00414     break;
00415   case -1:
00416     for (i = 0; i < MN10300_ELF_NGREG; i++)
00417       am33_collect_gregset_method (regset, regcache, i, gregs, len);
00418     break;
00419   }
00420   return;
00421 }
00422 
00423 /* Copy fp register values from regcache to regset.  */
00424 
00425 static void
00426 am33_collect_fpregset_method (const struct regset *regset, 
00427                               const struct regcache *regcache, 
00428                               int regnum, void *fpregs, size_t len)
00429 {
00430   mn10300_elf_fpregset_t *fpregset = fpregs;
00431 
00432   gdb_assert (len == sizeof (mn10300_elf_fpregset_t));
00433 
00434   if (regnum == -1)
00435     {
00436       int i;
00437       for (i = 0; i < MN10300_ELF_NFPREG; i++)
00438         am33_collect_fpregset_method (regset, regcache, E_FS0_REGNUM + i,
00439                                       fpregs, len);
00440       am33_collect_fpregset_method (regset, regcache, 
00441                                     E_FPCR_REGNUM, fpregs, len);
00442     }
00443   else if (regnum == E_FPCR_REGNUM)
00444     regcache_raw_collect (regcache, E_FPCR_REGNUM, 
00445                           &fpregset->fpcr);
00446   else if (E_FS0_REGNUM <= regnum
00447            && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
00448     regcache_raw_collect (regcache, regnum, 
00449                           &fpregset->fpregs[regnum - E_FS0_REGNUM]);
00450 
00451   return;
00452 }
00453 
00454 /* Create a struct regset from a corefile register section.  */
00455 
00456 static const struct regset *
00457 am33_regset_from_core_section (struct gdbarch *gdbarch, 
00458                                const char *sect_name, 
00459                                size_t sect_size)
00460 {
00461   /* We will call regset_alloc, and pass the names of the supply and
00462      collect methods.  */
00463 
00464   if (sect_size == sizeof (mn10300_elf_fpregset_t))
00465     return regset_alloc (gdbarch, 
00466                          am33_supply_fpregset_method,
00467                          am33_collect_fpregset_method);
00468   else
00469     return regset_alloc (gdbarch, 
00470                          am33_supply_gregset_method,
00471                          am33_collect_gregset_method);
00472 }
00473 
00474 static void
00475 am33_linux_sigframe_cache_init (const struct tramp_frame *self,
00476                                 struct frame_info *this_frame,
00477                                 struct trad_frame_cache *this_cache,
00478                                 CORE_ADDR func);
00479 
00480 static const struct tramp_frame am33_linux_sigframe = {
00481   SIGTRAMP_FRAME,
00482   1,
00483   {
00484     /* mov     119,d0 */
00485     { 0x2c, -1 },
00486     { 0x77, -1 },
00487     { 0x00, -1 },
00488     /* syscall 0 */
00489     { 0xf0, -1 },
00490     { 0xe0, -1 },
00491     { TRAMP_SENTINEL_INSN, -1 }
00492   },
00493   am33_linux_sigframe_cache_init
00494 };
00495 
00496 static const struct tramp_frame am33_linux_rt_sigframe = {
00497   SIGTRAMP_FRAME,
00498   1,
00499   {
00500     /* mov     173,d0 */
00501     { 0x2c, -1 },
00502     { 0xad, -1 },
00503     { 0x00, -1 },
00504     /* syscall 0 */
00505     { 0xf0, -1 },
00506     { 0xe0, -1 },
00507     { TRAMP_SENTINEL_INSN, -1 }
00508   },
00509   am33_linux_sigframe_cache_init
00510 };
00511 
00512 /* Relevant struct definitions for signal handling...
00513 
00514 From arch/mn10300/kernel/sigframe.h:
00515 
00516 struct sigframe
00517 {
00518         void (*pretcode)(void);
00519         int sig;
00520         struct sigcontext *psc;
00521         struct sigcontext sc;
00522         struct fpucontext fpuctx;
00523         unsigned long extramask[_NSIG_WORDS-1];
00524         char retcode[8];
00525 };
00526 
00527 struct rt_sigframe
00528 {
00529         void (*pretcode)(void);
00530         int sig;
00531         struct siginfo *pinfo;
00532         void *puc;
00533         struct siginfo info;
00534         struct ucontext uc;
00535         struct fpucontext fpuctx;
00536         char retcode[8];
00537 };
00538 
00539 From include/asm-mn10300/ucontext.h:
00540 
00541 struct ucontext {
00542         unsigned long     uc_flags;
00543         struct ucontext  *uc_link;
00544         stack_t           uc_stack;
00545         struct sigcontext uc_mcontext;
00546         sigset_t          uc_sigmask;
00547 };
00548 
00549 From include/asm-mn10300/sigcontext.h:
00550 
00551 struct fpucontext {
00552         unsigned long   fs[32];
00553         unsigned long   fpcr;
00554 };
00555 
00556 struct sigcontext {
00557         unsigned long   d0;
00558         unsigned long   d1;
00559         unsigned long   d2;
00560         unsigned long   d3;
00561         unsigned long   a0;
00562         unsigned long   a1;
00563         unsigned long   a2;
00564         unsigned long   a3;
00565         unsigned long   e0;
00566         unsigned long   e1;
00567         unsigned long   e2;
00568         unsigned long   e3;
00569         unsigned long   e4;
00570         unsigned long   e5;
00571         unsigned long   e6;
00572         unsigned long   e7;
00573         unsigned long   lar;
00574         unsigned long   lir;
00575         unsigned long   mdr;
00576         unsigned long   mcvf;
00577         unsigned long   mcrl;
00578         unsigned long   mcrh;
00579         unsigned long   mdrq;
00580         unsigned long   sp;
00581         unsigned long   epsw;
00582         unsigned long   pc;
00583         struct fpucontext *fpucontext;
00584         unsigned long   oldmask;
00585 }; */
00586 
00587 
00588 #define AM33_SIGCONTEXT_D0 0
00589 #define AM33_SIGCONTEXT_D1 4
00590 #define AM33_SIGCONTEXT_D2 8
00591 #define AM33_SIGCONTEXT_D3 12
00592 #define AM33_SIGCONTEXT_A0 16
00593 #define AM33_SIGCONTEXT_A1 20
00594 #define AM33_SIGCONTEXT_A2 24
00595 #define AM33_SIGCONTEXT_A3 28
00596 #define AM33_SIGCONTEXT_E0 32
00597 #define AM33_SIGCONTEXT_E1 36
00598 #define AM33_SIGCONTEXT_E2 40
00599 #define AM33_SIGCONTEXT_E3 44
00600 #define AM33_SIGCONTEXT_E4 48
00601 #define AM33_SIGCONTEXT_E5 52
00602 #define AM33_SIGCONTEXT_E6 56
00603 #define AM33_SIGCONTEXT_E7 60
00604 #define AM33_SIGCONTEXT_LAR 64
00605 #define AM33_SIGCONTEXT_LIR 68
00606 #define AM33_SIGCONTEXT_MDR 72
00607 #define AM33_SIGCONTEXT_MCVF 76
00608 #define AM33_SIGCONTEXT_MCRL 80
00609 #define AM33_SIGCONTEXT_MCRH 84
00610 #define AM33_SIGCONTEXT_MDRQ 88
00611 #define AM33_SIGCONTEXT_SP 92
00612 #define AM33_SIGCONTEXT_EPSW 96
00613 #define AM33_SIGCONTEXT_PC 100
00614 #define AM33_SIGCONTEXT_FPUCONTEXT 104
00615 
00616 
00617 static void
00618 am33_linux_sigframe_cache_init (const struct tramp_frame *self,
00619                                 struct frame_info *this_frame,
00620                                 struct trad_frame_cache *this_cache,
00621                                 CORE_ADDR func)
00622 {
00623   CORE_ADDR sc_base, fpubase;
00624   int i;
00625 
00626   sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
00627   if (self == &am33_linux_sigframe)
00628     {
00629       sc_base += 8;
00630       sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
00631     }
00632   else
00633     {
00634       sc_base += 12;
00635       sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
00636       sc_base += 20;
00637     }
00638 
00639   trad_frame_set_reg_addr (this_cache, E_D0_REGNUM,
00640                            sc_base + AM33_SIGCONTEXT_D0);
00641   trad_frame_set_reg_addr (this_cache, E_D1_REGNUM,
00642                            sc_base + AM33_SIGCONTEXT_D1);
00643   trad_frame_set_reg_addr (this_cache, E_D2_REGNUM,
00644                            sc_base + AM33_SIGCONTEXT_D2);
00645   trad_frame_set_reg_addr (this_cache, E_D3_REGNUM,
00646                            sc_base + AM33_SIGCONTEXT_D3);
00647 
00648   trad_frame_set_reg_addr (this_cache, E_A0_REGNUM,
00649                            sc_base + AM33_SIGCONTEXT_A0);
00650   trad_frame_set_reg_addr (this_cache, E_A1_REGNUM,
00651                            sc_base + AM33_SIGCONTEXT_A1);
00652   trad_frame_set_reg_addr (this_cache, E_A2_REGNUM,
00653                            sc_base + AM33_SIGCONTEXT_A2);
00654   trad_frame_set_reg_addr (this_cache, E_A3_REGNUM,
00655                            sc_base + AM33_SIGCONTEXT_A3);
00656 
00657   trad_frame_set_reg_addr (this_cache, E_E0_REGNUM,
00658                            sc_base + AM33_SIGCONTEXT_E0);
00659   trad_frame_set_reg_addr (this_cache, E_E1_REGNUM,
00660                            sc_base + AM33_SIGCONTEXT_E1);
00661   trad_frame_set_reg_addr (this_cache, E_E2_REGNUM,
00662                            sc_base + AM33_SIGCONTEXT_E2);
00663   trad_frame_set_reg_addr (this_cache, E_E3_REGNUM,
00664                            sc_base + AM33_SIGCONTEXT_E3);
00665   trad_frame_set_reg_addr (this_cache, E_E4_REGNUM,
00666                            sc_base + AM33_SIGCONTEXT_E4);
00667   trad_frame_set_reg_addr (this_cache, E_E5_REGNUM,
00668                            sc_base + AM33_SIGCONTEXT_E5);
00669   trad_frame_set_reg_addr (this_cache, E_E6_REGNUM,
00670                            sc_base + AM33_SIGCONTEXT_E6);
00671   trad_frame_set_reg_addr (this_cache, E_E7_REGNUM,
00672                            sc_base + AM33_SIGCONTEXT_E7);
00673 
00674   trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM,
00675                            sc_base + AM33_SIGCONTEXT_LAR);
00676   trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM,
00677                            sc_base + AM33_SIGCONTEXT_LIR);
00678   trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM,
00679                            sc_base + AM33_SIGCONTEXT_MDR);
00680   trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM,
00681                            sc_base + AM33_SIGCONTEXT_MCVF);
00682   trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM,
00683                            sc_base + AM33_SIGCONTEXT_MCRL);
00684   trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM,
00685                            sc_base + AM33_SIGCONTEXT_MDRQ);
00686 
00687   trad_frame_set_reg_addr (this_cache, E_SP_REGNUM,
00688                            sc_base + AM33_SIGCONTEXT_SP);
00689   trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM,
00690                            sc_base + AM33_SIGCONTEXT_EPSW);
00691   trad_frame_set_reg_addr (this_cache, E_PC_REGNUM,
00692                            sc_base + AM33_SIGCONTEXT_PC);
00693 
00694   fpubase = get_frame_memory_unsigned (this_frame,
00695                                        sc_base + AM33_SIGCONTEXT_FPUCONTEXT,
00696                                        4);
00697   if (fpubase)
00698     {
00699       for (i = 0; i < 32; i++)
00700         {
00701           trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i,
00702                                    fpubase + 4 * i);
00703         }
00704       trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32);
00705     }
00706 
00707   trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
00708 }
00709 
00710 /* AM33 GNU/Linux osabi has been recognized.
00711    Now's our chance to register our corefile handling.  */
00712 
00713 static void
00714 am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
00715 {
00716   linux_init_abi (info, gdbarch);
00717 
00718   set_gdbarch_regset_from_core_section (gdbarch, 
00719                                         am33_regset_from_core_section);
00720   set_solib_svr4_fetch_link_map_offsets
00721     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
00722 
00723   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
00724   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
00725 }
00726 
00727 /* Provide a prototype to silence -Wmissing-prototypes.  */
00728 extern initialize_file_ftype _initialize_mn10300_linux_tdep;
00729 
00730 void
00731 _initialize_mn10300_linux_tdep (void)
00732 {
00733   gdbarch_register_osabi (bfd_arch_mn10300, 0,
00734                           GDB_OSABI_LINUX, am33_linux_init_osabi);
00735 }
00736 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines