gdb/mn10300-linux-tdep.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.

  2.    Copyright (C) 2003-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "gdbcore.h"
  16. #include "regcache.h"
  17. #include "mn10300-tdep.h"
  18. #include "bfd.h"
  19. #include "elf-bfd.h"
  20. #include "osabi.h"
  21. #include "regset.h"
  22. #include "solib-svr4.h"
  23. #include "frame.h"
  24. #include "trad-frame.h"
  25. #include "tramp-frame.h"
  26. #include "linux-tdep.h"

  27. /* Transliterated from <asm-mn10300/elf.h>...  */
  28. #define MN10300_ELF_NGREG 28
  29. #define MN10300_ELF_NFPREG 32

  30. typedef gdb_byte   mn10300_elf_greg_t[4];
  31. typedef mn10300_elf_greg_t mn10300_elf_gregset_t[MN10300_ELF_NGREG];

  32. typedef gdb_byte   mn10300_elf_fpreg_t[4];
  33. typedef struct
  34. {
  35.   mn10300_elf_fpreg_t fpregs[MN10300_ELF_NFPREG];
  36.   gdb_byte    fpcr[4];
  37. } mn10300_elf_fpregset_t;

  38. /* elf_gregset_t register indices stolen from include/asm-mn10300/ptrace.h.  */
  39. #define MN10300_ELF_GREGSET_T_REG_INDEX_A3        0
  40. #define MN10300_ELF_GREGSET_T_REG_INDEX_A2        1
  41. #define MN10300_ELF_GREGSET_T_REG_INDEX_D3        2
  42. #define        MN10300_ELF_GREGSET_T_REG_INDEX_D2        3
  43. #define MN10300_ELF_GREGSET_T_REG_INDEX_MCVF        4
  44. #define        MN10300_ELF_GREGSET_T_REG_INDEX_MCRL        5
  45. #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRH        6
  46. #define        MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ        7
  47. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E1        8
  48. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E0        9
  49. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E7        10
  50. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E6        11
  51. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E5        12
  52. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E4        13
  53. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E3        14
  54. #define        MN10300_ELF_GREGSET_T_REG_INDEX_E2        15
  55. #define        MN10300_ELF_GREGSET_T_REG_INDEX_SP        16
  56. #define        MN10300_ELF_GREGSET_T_REG_INDEX_LAR        17
  57. #define        MN10300_ELF_GREGSET_T_REG_INDEX_LIR        18
  58. #define        MN10300_ELF_GREGSET_T_REG_INDEX_MDR        19
  59. #define        MN10300_ELF_GREGSET_T_REG_INDEX_A1        20
  60. #define        MN10300_ELF_GREGSET_T_REG_INDEX_A0        21
  61. #define        MN10300_ELF_GREGSET_T_REG_INDEX_D1        22
  62. #define        MN10300_ELF_GREGSET_T_REG_INDEX_D0        23
  63. #define MN10300_ELF_GREGSET_T_REG_INDEX_ORIG_D0        24
  64. #define        MN10300_ELF_GREGSET_T_REG_INDEX_EPSW        25
  65. #define        MN10300_ELF_GREGSET_T_REG_INDEX_PC        26

  66. /* New gdbarch API for corefile registers.
  67.    Given a section name and size, create a struct reg object
  68.    with a supply_register and a collect_register method.  */

  69. /* Copy register value of REGNUM from regset to regcache.
  70.    If REGNUM is -1, do this for all gp registers in regset.  */

  71. static void
  72. am33_supply_gregset_method (const struct regset *regset,
  73.                             struct regcache *regcache,
  74.                             int regnum, const void *gregs, size_t len)
  75. {
  76.   char zerobuf[MAX_REGISTER_SIZE];
  77.   const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs;
  78.   int i;

  79.   gdb_assert (len == sizeof (mn10300_elf_gregset_t));

  80.   switch (regnum) {
  81.   case E_D0_REGNUM:
  82.     regcache_raw_supply (regcache, E_D0_REGNUM,
  83.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
  84.     break;
  85.   case E_D1_REGNUM:
  86.     regcache_raw_supply (regcache, E_D1_REGNUM,
  87.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
  88.     break;
  89.   case E_D2_REGNUM:
  90.     regcache_raw_supply (regcache, E_D2_REGNUM,
  91.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
  92.     break;
  93.   case E_D3_REGNUM:
  94.     regcache_raw_supply (regcache, E_D3_REGNUM,
  95.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
  96.     break;
  97.   case E_A0_REGNUM:
  98.     regcache_raw_supply (regcache, E_A0_REGNUM,
  99.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
  100.     break;
  101.   case E_A1_REGNUM:
  102.     regcache_raw_supply (regcache, E_A1_REGNUM,
  103.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
  104.     break;
  105.   case E_A2_REGNUM:
  106.     regcache_raw_supply (regcache, E_A2_REGNUM,
  107.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
  108.     break;
  109.   case E_A3_REGNUM:
  110.     regcache_raw_supply (regcache, E_A3_REGNUM,
  111.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
  112.     break;
  113.   case E_SP_REGNUM:
  114.     regcache_raw_supply (regcache, E_SP_REGNUM,
  115.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
  116.     break;
  117.   case E_PC_REGNUM:
  118.     regcache_raw_supply (regcache, E_PC_REGNUM,
  119.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
  120.     break;
  121.   case E_MDR_REGNUM:
  122.     regcache_raw_supply (regcache, E_MDR_REGNUM,
  123.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
  124.     break;
  125.   case E_PSW_REGNUM:
  126.     regcache_raw_supply (regcache, E_PSW_REGNUM,
  127.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
  128.     break;
  129.   case E_LIR_REGNUM:
  130.     regcache_raw_supply (regcache, E_LIR_REGNUM,
  131.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
  132.     break;
  133.   case E_LAR_REGNUM:
  134.     regcache_raw_supply (regcache, E_LAR_REGNUM,
  135.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
  136.     break;
  137.   case E_MDRQ_REGNUM:
  138.     regcache_raw_supply (regcache, E_MDRQ_REGNUM,
  139.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
  140.     break;
  141.   case E_E0_REGNUM:
  142.     regcache_raw_supply (regcache, E_E0_REGNUM,
  143.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
  144.     break;
  145.   case E_E1_REGNUM:
  146.     regcache_raw_supply (regcache, E_E1_REGNUM,
  147.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
  148.     break;
  149.   case E_E2_REGNUM:
  150.     regcache_raw_supply (regcache, E_E2_REGNUM,
  151.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
  152.     break;
  153.   case E_E3_REGNUM:
  154.     regcache_raw_supply (regcache, E_E3_REGNUM,
  155.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
  156.     break;
  157.   case E_E4_REGNUM:
  158.     regcache_raw_supply (regcache, E_E4_REGNUM,
  159.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
  160.     break;
  161.   case E_E5_REGNUM:
  162.     regcache_raw_supply (regcache, E_E5_REGNUM,
  163.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
  164.     break;
  165.   case E_E6_REGNUM:
  166.     regcache_raw_supply (regcache, E_E6_REGNUM,
  167.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
  168.     break;
  169.   case E_E7_REGNUM:
  170.     regcache_raw_supply (regcache, E_E7_REGNUM,
  171.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
  172.     break;

  173.     /* ssp, msp, and usp are inaccessible.  */
  174.   case E_E8_REGNUM:
  175.     memset (zerobuf, 0, MAX_REGISTER_SIZE);
  176.     regcache_raw_supply (regcache, E_E8_REGNUM, zerobuf);
  177.     break;
  178.   case E_E9_REGNUM:
  179.     memset (zerobuf, 0, MAX_REGISTER_SIZE);
  180.     regcache_raw_supply (regcache, E_E9_REGNUM, zerobuf);
  181.     break;
  182.   case E_E10_REGNUM:
  183.     memset (zerobuf, 0, MAX_REGISTER_SIZE);
  184.     regcache_raw_supply (regcache, E_E10_REGNUM, zerobuf);

  185.     break;
  186.   case E_MCRH_REGNUM:
  187.     regcache_raw_supply (regcache, E_MCRH_REGNUM,
  188.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
  189.     break;
  190.   case E_MCRL_REGNUM:
  191.     regcache_raw_supply (regcache, E_MCRL_REGNUM,
  192.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
  193.     break;
  194.   case E_MCVF_REGNUM:
  195.     regcache_raw_supply (regcache, E_MCVF_REGNUM,
  196.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
  197.     break;
  198.   case E_FPCR_REGNUM:
  199.     /* FPCR is numbered among the GP regs, but handled as an FP reg.
  200.        Do nothing.  */
  201.     break;
  202.   case E_FPCR_REGNUM + 1:
  203.     /* The two unused registers beyond fpcr are inaccessible.  */
  204.     memset (zerobuf, 0, MAX_REGISTER_SIZE);
  205.     regcache_raw_supply (regcache, E_FPCR_REGNUM + 1, zerobuf);
  206.     break;
  207.   case E_FPCR_REGNUM + 2:
  208.     memset (zerobuf, 0, MAX_REGISTER_SIZE);
  209.     regcache_raw_supply (regcache, E_FPCR_REGNUM + 2, zerobuf);
  210.     break;
  211.   default:        /* An error, obviously, but should we error out?  */
  212.     break;
  213.   case -1:
  214.     for (i = 0; i < MN10300_ELF_NGREG; i++)
  215.       am33_supply_gregset_method (regset, regcache, i, gregs, len);
  216.     break;
  217.   }
  218.   return;
  219. }

  220. /* Copy fp register value of REGNUM from regset to regcache.
  221.    If REGNUM is -1, do this for all fp registers in regset.  */

  222. static void
  223. am33_supply_fpregset_method (const struct regset *regset,
  224.                              struct regcache *regcache,
  225.                              int regnum, const void *fpregs, size_t len)
  226. {
  227.   const mn10300_elf_fpregset_t *fpregset = fpregs;

  228.   gdb_assert (len == sizeof (mn10300_elf_fpregset_t));

  229.   if (regnum == -1)
  230.     {
  231.       int i;

  232.       for (i = 0; i < MN10300_ELF_NFPREG; i++)
  233.         am33_supply_fpregset_method (regset, regcache,
  234.                                      E_FS0_REGNUM + i, fpregs, len);
  235.       am33_supply_fpregset_method (regset, regcache,
  236.                                    E_FPCR_REGNUM, fpregs, len);
  237.     }
  238.   else if (regnum == E_FPCR_REGNUM)
  239.     regcache_raw_supply (regcache, E_FPCR_REGNUM,
  240.                          &fpregset->fpcr);
  241.   else if (E_FS0_REGNUM <= regnum
  242.            && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
  243.     regcache_raw_supply (regcache, regnum,
  244.                          &fpregset->fpregs[regnum - E_FS0_REGNUM]);

  245.   return;
  246. }

  247. /* Copy register values from regcache to regset.  */

  248. static void
  249. am33_collect_gregset_method (const struct regset *regset,
  250.                              const struct regcache *regcache,
  251.                              int regnum, void *gregs, size_t len)
  252. {
  253.   mn10300_elf_gregset_t *regp = gregs;
  254.   int i;

  255.   gdb_assert (len == sizeof (mn10300_elf_gregset_t));

  256.   switch (regnum) {
  257.   case E_D0_REGNUM:
  258.     regcache_raw_collect (regcache, E_D0_REGNUM,
  259.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0));
  260.     break;
  261.   case E_D1_REGNUM:
  262.     regcache_raw_collect (regcache, E_D1_REGNUM,
  263.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1));
  264.     break;
  265.   case E_D2_REGNUM:
  266.     regcache_raw_collect (regcache, E_D2_REGNUM,
  267.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2));
  268.     break;
  269.   case E_D3_REGNUM:
  270.     regcache_raw_collect (regcache, E_D3_REGNUM,
  271.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3));
  272.     break;
  273.   case E_A0_REGNUM:
  274.     regcache_raw_collect (regcache, E_A0_REGNUM,
  275.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0));
  276.     break;
  277.   case E_A1_REGNUM:
  278.     regcache_raw_collect (regcache, E_A1_REGNUM,
  279.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1));
  280.     break;
  281.   case E_A2_REGNUM:
  282.     regcache_raw_collect (regcache, E_A2_REGNUM,
  283.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2));
  284.     break;
  285.   case E_A3_REGNUM:
  286.     regcache_raw_collect (regcache, E_A3_REGNUM,
  287.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3));
  288.     break;
  289.   case E_SP_REGNUM:
  290.     regcache_raw_collect (regcache, E_SP_REGNUM,
  291.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP));
  292.     break;
  293.   case E_PC_REGNUM:
  294.     regcache_raw_collect (regcache, E_PC_REGNUM,
  295.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC));
  296.     break;
  297.   case E_MDR_REGNUM:
  298.     regcache_raw_collect (regcache, E_MDR_REGNUM,
  299.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR));
  300.     break;
  301.   case E_PSW_REGNUM:
  302.     regcache_raw_collect (regcache, E_PSW_REGNUM,
  303.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW));
  304.     break;
  305.   case E_LIR_REGNUM:
  306.     regcache_raw_collect (regcache, E_LIR_REGNUM,
  307.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR));
  308.     break;
  309.   case E_LAR_REGNUM:
  310.     regcache_raw_collect (regcache, E_LAR_REGNUM,
  311.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR));
  312.     break;
  313.   case E_MDRQ_REGNUM:
  314.     regcache_raw_collect (regcache, E_MDRQ_REGNUM,
  315.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ));
  316.     break;
  317.   case E_E0_REGNUM:
  318.     regcache_raw_collect (regcache, E_E0_REGNUM,
  319.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0));
  320.     break;
  321.   case E_E1_REGNUM:
  322.     regcache_raw_collect (regcache, E_E1_REGNUM,
  323.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1));
  324.     break;
  325.   case E_E2_REGNUM:
  326.     regcache_raw_collect (regcache, E_E2_REGNUM,
  327.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2));
  328.     break;
  329.   case E_E3_REGNUM:
  330.     regcache_raw_collect (regcache, E_E3_REGNUM,
  331.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3));
  332.     break;
  333.   case E_E4_REGNUM:
  334.     regcache_raw_collect (regcache, E_E4_REGNUM,
  335.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4));
  336.     break;
  337.   case E_E5_REGNUM:
  338.     regcache_raw_collect (regcache, E_E5_REGNUM,
  339.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5));
  340.     break;
  341.   case E_E6_REGNUM:
  342.     regcache_raw_collect (regcache, E_E6_REGNUM,
  343.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6));
  344.     break;
  345.   case E_E7_REGNUM:
  346.     regcache_raw_collect (regcache, E_E7_REGNUM,
  347.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7));
  348.     break;

  349.     /* ssp, msp, and usp are inaccessible.  */
  350.   case E_E8_REGNUM:
  351.     /* The gregset struct has noplace to put this: do nothing.  */
  352.     break;
  353.   case E_E9_REGNUM:
  354.     /* The gregset struct has noplace to put this: do nothing.  */
  355.     break;
  356.   case E_E10_REGNUM:
  357.     /* The gregset struct has noplace to put this: do nothing.  */
  358.     break;
  359.   case E_MCRH_REGNUM:
  360.     regcache_raw_collect (regcache, E_MCRH_REGNUM,
  361.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH));
  362.     break;
  363.   case E_MCRL_REGNUM:
  364.     regcache_raw_collect (regcache, E_MCRL_REGNUM,
  365.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL));
  366.     break;
  367.   case E_MCVF_REGNUM:
  368.     regcache_raw_collect (regcache, E_MCVF_REGNUM,
  369.                          (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF));
  370.     break;
  371.   case E_FPCR_REGNUM:
  372.     /* FPCR is numbered among the GP regs, but handled as an FP reg.
  373.        Do nothing.  */
  374.     break;
  375.   case E_FPCR_REGNUM + 1:
  376.     /* The gregset struct has noplace to put this: do nothing.  */
  377.     break;
  378.   case E_FPCR_REGNUM + 2:
  379.     /* The gregset struct has noplace to put this: do nothing.  */
  380.     break;
  381.   default:        /* An error, obviously, but should we error out?  */
  382.     break;
  383.   case -1:
  384.     for (i = 0; i < MN10300_ELF_NGREG; i++)
  385.       am33_collect_gregset_method (regset, regcache, i, gregs, len);
  386.     break;
  387.   }
  388.   return;
  389. }

  390. /* Copy fp register values from regcache to regset.  */

  391. static void
  392. am33_collect_fpregset_method (const struct regset *regset,
  393.                               const struct regcache *regcache,
  394.                               int regnum, void *fpregs, size_t len)
  395. {
  396.   mn10300_elf_fpregset_t *fpregset = fpregs;

  397.   gdb_assert (len == sizeof (mn10300_elf_fpregset_t));

  398.   if (regnum == -1)
  399.     {
  400.       int i;
  401.       for (i = 0; i < MN10300_ELF_NFPREG; i++)
  402.         am33_collect_fpregset_method (regset, regcache, E_FS0_REGNUM + i,
  403.                                       fpregs, len);
  404.       am33_collect_fpregset_method (regset, regcache,
  405.                                     E_FPCR_REGNUM, fpregs, len);
  406.     }
  407.   else if (regnum == E_FPCR_REGNUM)
  408.     regcache_raw_collect (regcache, E_FPCR_REGNUM,
  409.                           &fpregset->fpcr);
  410.   else if (E_FS0_REGNUM <= regnum
  411.            && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG)
  412.     regcache_raw_collect (regcache, regnum,
  413.                           &fpregset->fpregs[regnum - E_FS0_REGNUM]);

  414.   return;
  415. }

  416. static const struct regset am33_gregset =
  417.   {
  418.     NULL, am33_supply_gregset_method, am33_collect_gregset_method
  419.   };

  420. static const struct regset am33_fpregset =
  421.   {
  422.     NULL, am33_supply_fpregset_method, am33_collect_fpregset_method
  423.   };

  424. /* Iterate over core file register note sections.  */

  425. static void
  426. am33_iterate_over_regset_sections (struct gdbarch *gdbarch,
  427.                                    iterate_over_regset_sections_cb *cb,
  428.                                    void *cb_data,
  429.                                    const struct regcache *regcache)
  430. {
  431.   cb (".reg", sizeof (mn10300_elf_gregset_t), &am33_gregset,
  432.       NULL, cb_data);
  433.   cb (".reg2", sizeof(mn10300_elf_fpregset_t), &am33_fpregset,
  434.       NULL, cb_data);
  435. }

  436. static void
  437. am33_linux_sigframe_cache_init (const struct tramp_frame *self,
  438.                                 struct frame_info *this_frame,
  439.                                 struct trad_frame_cache *this_cache,
  440.                                 CORE_ADDR func);

  441. static const struct tramp_frame am33_linux_sigframe = {
  442.   SIGTRAMP_FRAME,
  443.   1,
  444.   {
  445.     /* mov     119,d0 */
  446.     { 0x2c, -1 },
  447.     { 0x77, -1 },
  448.     { 0x00, -1 },
  449.     /* syscall 0 */
  450.     { 0xf0, -1 },
  451.     { 0xe0, -1 },
  452.     { TRAMP_SENTINEL_INSN, -1 }
  453.   },
  454.   am33_linux_sigframe_cache_init
  455. };

  456. static const struct tramp_frame am33_linux_rt_sigframe = {
  457.   SIGTRAMP_FRAME,
  458.   1,
  459.   {
  460.     /* mov     173,d0 */
  461.     { 0x2c, -1 },
  462.     { 0xad, -1 },
  463.     { 0x00, -1 },
  464.     /* syscall 0 */
  465.     { 0xf0, -1 },
  466.     { 0xe0, -1 },
  467.     { TRAMP_SENTINEL_INSN, -1 }
  468.   },
  469.   am33_linux_sigframe_cache_init
  470. };

  471. /* Relevant struct definitions for signal handling...

  472. From arch/mn10300/kernel/sigframe.h:

  473. struct sigframe
  474. {
  475.         void (*pretcode)(void);
  476.         int sig;
  477.         struct sigcontext *psc;
  478.         struct sigcontext sc;
  479.         struct fpucontext fpuctx;
  480.         unsigned long extramask[_NSIG_WORDS-1];
  481.         char retcode[8];
  482. };

  483. struct rt_sigframe
  484. {
  485.         void (*pretcode)(void);
  486.         int sig;
  487.         struct siginfo *pinfo;
  488.         void *puc;
  489.         struct siginfo info;
  490.         struct ucontext uc;
  491.         struct fpucontext fpuctx;
  492.         char retcode[8];
  493. };

  494. From include/asm-mn10300/ucontext.h:

  495. struct ucontext {
  496.         unsigned long          uc_flags;
  497.         struct ucontext  *uc_link;
  498.         stack_t                  uc_stack;
  499.         struct sigcontext uc_mcontext;
  500.         sigset_t          uc_sigmask;
  501. };

  502. From include/asm-mn10300/sigcontext.h:

  503. struct fpucontext {
  504.         unsigned long        fs[32];
  505.         unsigned long        fpcr;
  506. };

  507. struct sigcontext {
  508.         unsigned long        d0;
  509.         unsigned long        d1;
  510.         unsigned long        d2;
  511.         unsigned long        d3;
  512.         unsigned long        a0;
  513.         unsigned long        a1;
  514.         unsigned long        a2;
  515.         unsigned long        a3;
  516.         unsigned long        e0;
  517.         unsigned long        e1;
  518.         unsigned long        e2;
  519.         unsigned long        e3;
  520.         unsigned long        e4;
  521.         unsigned long        e5;
  522.         unsigned long        e6;
  523.         unsigned long        e7;
  524.         unsigned long        lar;
  525.         unsigned long        lir;
  526.         unsigned long        mdr;
  527.         unsigned long        mcvf;
  528.         unsigned long        mcrl;
  529.         unsigned long        mcrh;
  530.         unsigned long        mdrq;
  531.         unsigned long        sp;
  532.         unsigned long        epsw;
  533.         unsigned long        pc;
  534.         struct fpucontext *fpucontext;
  535.         unsigned long        oldmask;
  536. }; */


  537. #define AM33_SIGCONTEXT_D0 0
  538. #define AM33_SIGCONTEXT_D1 4
  539. #define AM33_SIGCONTEXT_D2 8
  540. #define AM33_SIGCONTEXT_D3 12
  541. #define AM33_SIGCONTEXT_A0 16
  542. #define AM33_SIGCONTEXT_A1 20
  543. #define AM33_SIGCONTEXT_A2 24
  544. #define AM33_SIGCONTEXT_A3 28
  545. #define AM33_SIGCONTEXT_E0 32
  546. #define AM33_SIGCONTEXT_E1 36
  547. #define AM33_SIGCONTEXT_E2 40
  548. #define AM33_SIGCONTEXT_E3 44
  549. #define AM33_SIGCONTEXT_E4 48
  550. #define AM33_SIGCONTEXT_E5 52
  551. #define AM33_SIGCONTEXT_E6 56
  552. #define AM33_SIGCONTEXT_E7 60
  553. #define AM33_SIGCONTEXT_LAR 64
  554. #define AM33_SIGCONTEXT_LIR 68
  555. #define AM33_SIGCONTEXT_MDR 72
  556. #define AM33_SIGCONTEXT_MCVF 76
  557. #define AM33_SIGCONTEXT_MCRL 80
  558. #define AM33_SIGCONTEXT_MCRH 84
  559. #define AM33_SIGCONTEXT_MDRQ 88
  560. #define AM33_SIGCONTEXT_SP 92
  561. #define AM33_SIGCONTEXT_EPSW 96
  562. #define AM33_SIGCONTEXT_PC 100
  563. #define AM33_SIGCONTEXT_FPUCONTEXT 104


  564. static void
  565. am33_linux_sigframe_cache_init (const struct tramp_frame *self,
  566.                                 struct frame_info *this_frame,
  567.                                 struct trad_frame_cache *this_cache,
  568.                                 CORE_ADDR func)
  569. {
  570.   CORE_ADDR sc_base, fpubase;
  571.   int i;

  572.   sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
  573.   if (self == &am33_linux_sigframe)
  574.     {
  575.       sc_base += 8;
  576.       sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
  577.     }
  578.   else
  579.     {
  580.       sc_base += 12;
  581.       sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
  582.       sc_base += 20;
  583.     }

  584.   trad_frame_set_reg_addr (this_cache, E_D0_REGNUM,
  585.                            sc_base + AM33_SIGCONTEXT_D0);
  586.   trad_frame_set_reg_addr (this_cache, E_D1_REGNUM,
  587.                            sc_base + AM33_SIGCONTEXT_D1);
  588.   trad_frame_set_reg_addr (this_cache, E_D2_REGNUM,
  589.                            sc_base + AM33_SIGCONTEXT_D2);
  590.   trad_frame_set_reg_addr (this_cache, E_D3_REGNUM,
  591.                            sc_base + AM33_SIGCONTEXT_D3);

  592.   trad_frame_set_reg_addr (this_cache, E_A0_REGNUM,
  593.                            sc_base + AM33_SIGCONTEXT_A0);
  594.   trad_frame_set_reg_addr (this_cache, E_A1_REGNUM,
  595.                            sc_base + AM33_SIGCONTEXT_A1);
  596.   trad_frame_set_reg_addr (this_cache, E_A2_REGNUM,
  597.                            sc_base + AM33_SIGCONTEXT_A2);
  598.   trad_frame_set_reg_addr (this_cache, E_A3_REGNUM,
  599.                            sc_base + AM33_SIGCONTEXT_A3);

  600.   trad_frame_set_reg_addr (this_cache, E_E0_REGNUM,
  601.                            sc_base + AM33_SIGCONTEXT_E0);
  602.   trad_frame_set_reg_addr (this_cache, E_E1_REGNUM,
  603.                            sc_base + AM33_SIGCONTEXT_E1);
  604.   trad_frame_set_reg_addr (this_cache, E_E2_REGNUM,
  605.                            sc_base + AM33_SIGCONTEXT_E2);
  606.   trad_frame_set_reg_addr (this_cache, E_E3_REGNUM,
  607.                            sc_base + AM33_SIGCONTEXT_E3);
  608.   trad_frame_set_reg_addr (this_cache, E_E4_REGNUM,
  609.                            sc_base + AM33_SIGCONTEXT_E4);
  610.   trad_frame_set_reg_addr (this_cache, E_E5_REGNUM,
  611.                            sc_base + AM33_SIGCONTEXT_E5);
  612.   trad_frame_set_reg_addr (this_cache, E_E6_REGNUM,
  613.                            sc_base + AM33_SIGCONTEXT_E6);
  614.   trad_frame_set_reg_addr (this_cache, E_E7_REGNUM,
  615.                            sc_base + AM33_SIGCONTEXT_E7);

  616.   trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM,
  617.                            sc_base + AM33_SIGCONTEXT_LAR);
  618.   trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM,
  619.                            sc_base + AM33_SIGCONTEXT_LIR);
  620.   trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM,
  621.                            sc_base + AM33_SIGCONTEXT_MDR);
  622.   trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM,
  623.                            sc_base + AM33_SIGCONTEXT_MCVF);
  624.   trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM,
  625.                            sc_base + AM33_SIGCONTEXT_MCRL);
  626.   trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM,
  627.                            sc_base + AM33_SIGCONTEXT_MDRQ);

  628.   trad_frame_set_reg_addr (this_cache, E_SP_REGNUM,
  629.                            sc_base + AM33_SIGCONTEXT_SP);
  630.   trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM,
  631.                            sc_base + AM33_SIGCONTEXT_EPSW);
  632.   trad_frame_set_reg_addr (this_cache, E_PC_REGNUM,
  633.                            sc_base + AM33_SIGCONTEXT_PC);

  634.   fpubase = get_frame_memory_unsigned (this_frame,
  635.                                        sc_base + AM33_SIGCONTEXT_FPUCONTEXT,
  636.                                        4);
  637.   if (fpubase)
  638.     {
  639.       for (i = 0; i < 32; i++)
  640.         {
  641.           trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i,
  642.                                    fpubase + 4 * i);
  643.         }
  644.       trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32);
  645.     }

  646.   trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
  647. }

  648. /* AM33 GNU/Linux osabi has been recognized.
  649.    Now's our chance to register our corefile handling.  */

  650. static void
  651. am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
  652. {
  653.   linux_init_abi (info, gdbarch);

  654.   set_gdbarch_iterate_over_regset_sections
  655.     (gdbarch, am33_iterate_over_regset_sections);
  656.   set_solib_svr4_fetch_link_map_offsets
  657.     (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  658.   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
  659.   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
  660. }

  661. /* Provide a prototype to silence -Wmissing-prototypes.  */
  662. extern initialize_file_ftype _initialize_mn10300_linux_tdep;

  663. void
  664. _initialize_mn10300_linux_tdep (void)
  665. {
  666.   gdbarch_register_osabi (bfd_arch_mn10300, 0,
  667.                           GDB_OSABI_LINUX, am33_linux_init_osabi);
  668. }