Home | History | Annotate | Line # | Download | only in gdb
      1 /* Motorola m68k native support for GNU/Linux.
      2 
      3    Copyright (C) 1996-2024 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "frame.h"
     21 #include "inferior.h"
     22 #include "language.h"
     23 #include "gdbcore.h"
     24 #include "regcache.h"
     25 #include "target.h"
     26 #include "linux-nat.h"
     27 #include "gdbarch.h"
     28 
     29 #include "m68k-tdep.h"
     30 
     31 #include <sys/dir.h>
     32 #include <signal.h>
     33 #include "nat/gdb_ptrace.h"
     34 #include <sys/user.h>
     35 #include <sys/ioctl.h>
     36 #include <fcntl.h>
     37 #include <sys/procfs.h>
     38 
     39 #ifdef HAVE_SYS_REG_H
     40 #include <sys/reg.h>
     41 #endif
     42 
     43 #include <sys/file.h>
     44 #include <sys/stat.h>
     45 
     46 #include "floatformat.h"
     47 
     48 /* Prototypes for supply_gregset etc.  */
     49 #include "gregset.h"
     50 
     51 /* Defines ps_err_e, struct ps_prochandle.  */
     52 #include "gdb_proc_service.h"
     53 
     54 #include "inf-ptrace.h"
     55 
     56 #ifndef PTRACE_GET_THREAD_AREA
     57 #define PTRACE_GET_THREAD_AREA 25
     58 #endif
     59 
     60 
     62 class m68k_linux_nat_target final : public linux_nat_target
     63 {
     64 public:
     65   /* Add our register access methods.  */
     66   void fetch_registers (struct regcache *, int) override;
     67   void store_registers (struct regcache *, int) override;
     68 };
     69 
     70 static m68k_linux_nat_target the_m68k_linux_nat_target;
     71 
     72 /* This table must line up with gdbarch_register_name in "m68k-tdep.c".  */
     73 static const int regmap[] =
     74 {
     75   PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
     76   PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
     77   PT_SR, PT_PC,
     78   /* PT_FP0, ..., PT_FP7 */
     79   21, 24, 27, 30, 33, 36, 39, 42,
     80   /* PT_FPCR, PT_FPSR, PT_FPIAR */
     81   45, 46, 47
     82 };
     83 
     84 /* Which ptrace request retrieves which registers?
     85    These apply to the corresponding SET requests as well.  */
     86 #define NUM_GREGS (18)
     87 #define MAX_NUM_REGS (NUM_GREGS + 11)
     88 
     89 static int
     90 getregs_supplies (int regno)
     91 {
     92   return 0 <= regno && regno < NUM_GREGS;
     93 }
     94 
     95 static int
     96 getfpregs_supplies (int regno)
     97 {
     98   return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
     99 }
    100 
    101 /* Does the current host support the GETREGS request?  */
    102 static int have_ptrace_getregs =
    103 #ifdef HAVE_PTRACE_GETREGS
    104   1
    105 #else
    106   0
    107 #endif
    108 ;
    109 
    110 
    111 
    113 /* Fetching registers directly from the U area, one at a time.  */
    114 
    115 /* Fetch one register.  */
    116 
    117 static void
    118 fetch_register (struct regcache *regcache, int regno)
    119 {
    120   struct gdbarch *gdbarch = regcache->arch ();
    121   long regaddr, val;
    122   int i;
    123   gdb_byte buf[M68K_MAX_REGISTER_SIZE];
    124   pid_t tid = get_ptrace_pid (regcache->ptid ());
    125 
    126   regaddr = 4 * regmap[regno];
    127   for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
    128     {
    129       errno = 0;
    130       val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
    131       memcpy (&buf[i], &val, sizeof (long));
    132       regaddr += sizeof (long);
    133       if (errno != 0)
    134 	error (_("Couldn't read register %s (#%d): %s."),
    135 	       gdbarch_register_name (gdbarch, regno),
    136 	       regno, safe_strerror (errno));
    137     }
    138   regcache->raw_supply (regno, buf);
    139 }
    140 
    141 /* Fetch register values from the inferior.
    142    If REGNO is negative, do this for all registers.
    143    Otherwise, REGNO specifies which register (so we can save time).  */
    144 
    145 static void
    146 old_fetch_inferior_registers (struct regcache *regcache, int regno)
    147 {
    148   if (regno >= 0)
    149     {
    150       fetch_register (regcache, regno);
    151     }
    152   else
    153     {
    154       for (regno = 0;
    155 	   regno < gdbarch_num_regs (regcache->arch ());
    156 	   regno++)
    157 	{
    158 	  fetch_register (regcache, regno);
    159 	}
    160     }
    161 }
    162 
    163 /* Store one register.  */
    164 
    165 static void
    166 store_register (const struct regcache *regcache, int regno)
    167 {
    168   struct gdbarch *gdbarch = regcache->arch ();
    169   long regaddr, val;
    170   int i;
    171   gdb_byte buf[M68K_MAX_REGISTER_SIZE];
    172   pid_t tid = get_ptrace_pid (regcache->ptid ());
    173 
    174   regaddr = 4 * regmap[regno];
    175 
    176   /* Put the contents of regno into a local buffer.  */
    177   regcache->raw_collect (regno, buf);
    178 
    179   /* Store the local buffer into the inferior a chunk at the time.  */
    180   for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
    181     {
    182       errno = 0;
    183       memcpy (&val, &buf[i], sizeof (long));
    184       ptrace (PTRACE_POKEUSER, tid, regaddr, val);
    185       regaddr += sizeof (long);
    186       if (errno != 0)
    187 	error (_("Couldn't write register %s (#%d): %s."),
    188 	       gdbarch_register_name (gdbarch, regno),
    189 	       regno, safe_strerror (errno));
    190     }
    191 }
    192 
    193 /* Store our register values back into the inferior.
    194    If REGNO is negative, do this for all registers.
    195    Otherwise, REGNO specifies which register (so we can save time).  */
    196 
    197 static void
    198 old_store_inferior_registers (const struct regcache *regcache, int regno)
    199 {
    200   if (regno >= 0)
    201     {
    202       store_register (regcache, regno);
    203     }
    204   else
    205     {
    206       for (regno = 0;
    207 	   regno < gdbarch_num_regs (regcache->arch ());
    208 	   regno++)
    209 	{
    210 	  store_register (regcache, regno);
    211 	}
    212     }
    213 }
    214 
    215 /*  Given a pointer to a general register set in /proc format
    217    (elf_gregset_t *), unpack the register contents and supply
    218    them as gdb's idea of the current register values.  */
    219 
    220 void
    221 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
    222 {
    223   struct gdbarch *gdbarch = regcache->arch ();
    224   const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
    225   int regi;
    226 
    227   for (regi = M68K_D0_REGNUM;
    228        regi <= gdbarch_sp_regnum (gdbarch);
    229        regi++)
    230     regcache->raw_supply (regi, &regp[regmap[regi]]);
    231   regcache->raw_supply (gdbarch_ps_regnum (gdbarch), &regp[PT_SR]);
    232   regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
    233 }
    234 
    235 /* Fill register REGNO (if it is a general-purpose register) in
    236    *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
    237    do this for all registers.  */
    238 void
    239 fill_gregset (const struct regcache *regcache,
    240 	      elf_gregset_t *gregsetp, int regno)
    241 {
    242   elf_greg_t *regp = (elf_greg_t *) gregsetp;
    243   int i;
    244 
    245   for (i = 0; i < NUM_GREGS; i++)
    246     if (regno == -1 || regno == i)
    247       regcache->raw_collect (i, regp + regmap[i]);
    248 }
    249 
    250 #ifdef HAVE_PTRACE_GETREGS
    251 
    252 /* Fetch all general-purpose registers from process/thread TID and
    253    store their values in GDB's register array.  */
    254 
    255 static void
    256 fetch_regs (struct regcache *regcache, int tid)
    257 {
    258   elf_gregset_t regs;
    259 
    260   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
    261     {
    262       if (errno == EIO)
    263 	{
    264 	  /* The kernel we're running on doesn't support the GETREGS
    265 	     request.  Reset `have_ptrace_getregs'.  */
    266 	  have_ptrace_getregs = 0;
    267 	  return;
    268 	}
    269 
    270       perror_with_name (_("Couldn't get registers"));
    271     }
    272 
    273   supply_gregset (regcache, (const elf_gregset_t *) &regs);
    274 }
    275 
    276 /* Store all valid general-purpose registers in GDB's register array
    277    into the process/thread specified by TID.  */
    278 
    279 static void
    280 store_regs (const struct regcache *regcache, int tid, int regno)
    281 {
    282   elf_gregset_t regs;
    283 
    284   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
    285     perror_with_name (_("Couldn't get registers"));
    286 
    287   fill_gregset (regcache, &regs, regno);
    288 
    289   if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
    290     perror_with_name (_("Couldn't write registers"));
    291 }
    292 
    293 #else
    294 
    295 static void fetch_regs (struct regcache *regcache, int tid)
    296 {
    297 }
    298 
    299 static void store_regs (const struct regcache *regcache, int tid, int regno)
    300 {
    301 }
    302 
    303 #endif
    304 
    305 
    306 /* Transferring floating-point registers between GDB, inferiors and cores.  */
    308 
    309 /* What is the address of fpN within the floating-point register set F?  */
    310 #define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
    311 
    312 /* Fill GDB's register array with the floating-point register values in
    313    *FPREGSETP.  */
    314 
    315 void
    316 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
    317 {
    318   struct gdbarch *gdbarch = regcache->arch ();
    319   int regi;
    320 
    321   for (regi = gdbarch_fp0_regnum (gdbarch);
    322        regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
    323     regcache->raw_supply
    324       (regi, FPREG_ADDR (fpregsetp, regi - gdbarch_fp0_regnum (gdbarch)));
    325   regcache->raw_supply (M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
    326   regcache->raw_supply (M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
    327   regcache->raw_supply (M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
    328 }
    329 
    330 /* Fill register REGNO (if it is a floating-point register) in
    331    *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
    332    do this for all registers.  */
    333 
    334 void
    335 fill_fpregset (const struct regcache *regcache,
    336 	       elf_fpregset_t *fpregsetp, int regno)
    337 {
    338   struct gdbarch *gdbarch = regcache->arch ();
    339   int i;
    340 
    341   /* Fill in the floating-point registers.  */
    342   for (i = gdbarch_fp0_regnum (gdbarch);
    343        i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
    344     if (regno == -1 || regno == i)
    345       regcache->raw_collect
    346 	(i, FPREG_ADDR (fpregsetp, i - gdbarch_fp0_regnum (gdbarch)));
    347 
    348   /* Fill in the floating-point control registers.  */
    349   for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
    350     if (regno == -1 || regno == i)
    351       regcache->raw_collect (i, &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
    352 }
    353 
    354 #ifdef HAVE_PTRACE_GETREGS
    355 
    356 /* Fetch all floating-point registers from process/thread TID and store
    357    their values in GDB's register array.  */
    358 
    359 static void
    360 fetch_fpregs (struct regcache *regcache, int tid)
    361 {
    362   elf_fpregset_t fpregs;
    363 
    364   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
    365     perror_with_name (_("Couldn't get floating point status"));
    366 
    367   supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
    368 }
    369 
    370 /* Store all valid floating-point registers in GDB's register array
    371    into the process/thread specified by TID.  */
    372 
    373 static void
    374 store_fpregs (const struct regcache *regcache, int tid, int regno)
    375 {
    376   elf_fpregset_t fpregs;
    377 
    378   if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
    379     perror_with_name (_("Couldn't get floating point status"));
    380 
    381   fill_fpregset (regcache, &fpregs, regno);
    382 
    383   if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
    384     perror_with_name (_("Couldn't write floating point status"));
    385 }
    386 
    387 #else
    388 
    389 static void fetch_fpregs (struct regcache *regcache, int tid)
    390 {
    391 }
    392 
    393 static void store_fpregs (const struct regcache *regcache, int tid, int regno)
    394 {
    395 }
    396 
    397 #endif
    398 
    399 /* Transferring arbitrary registers between GDB and inferior.  */
    401 
    402 /* Fetch register REGNO from the child process.  If REGNO is -1, do
    403    this for all registers (including the floating point and SSE
    404    registers).  */
    405 
    406 void
    407 m68k_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
    408 {
    409   pid_t tid;
    410 
    411   /* Use the old method of peeking around in `struct user' if the
    412      GETREGS request isn't available.  */
    413   if (! have_ptrace_getregs)
    414     {
    415       old_fetch_inferior_registers (regcache, regno);
    416       return;
    417     }
    418 
    419   tid = get_ptrace_pid (regcache->ptid ());
    420 
    421   /* Use the PTRACE_GETFPXREGS request whenever possible, since it
    422      transfers more registers in one system call, and we'll cache the
    423      results.  But remember that fetch_fpxregs can fail, and return
    424      zero.  */
    425   if (regno == -1)
    426     {
    427       fetch_regs (regcache, tid);
    428 
    429       /* The call above might reset `have_ptrace_getregs'.  */
    430       if (! have_ptrace_getregs)
    431 	{
    432 	  old_fetch_inferior_registers (regcache, -1);
    433 	  return;
    434 	}
    435 
    436       fetch_fpregs (regcache, tid);
    437       return;
    438     }
    439 
    440   if (getregs_supplies (regno))
    441     {
    442       fetch_regs (regcache, tid);
    443       return;
    444     }
    445 
    446   if (getfpregs_supplies (regno))
    447     {
    448       fetch_fpregs (regcache, tid);
    449       return;
    450     }
    451 
    452   internal_error (_("Got request for bad register number %d."), regno);
    453 }
    454 
    455 /* Store register REGNO back into the child process.  If REGNO is -1,
    456    do this for all registers (including the floating point and SSE
    457    registers).  */
    458 void
    459 m68k_linux_nat_target::store_registers (struct regcache *regcache, int regno)
    460 {
    461   pid_t tid;
    462 
    463   /* Use the old method of poking around in `struct user' if the
    464      SETREGS request isn't available.  */
    465   if (! have_ptrace_getregs)
    466     {
    467       old_store_inferior_registers (regcache, regno);
    468       return;
    469     }
    470 
    471   tid = get_ptrace_pid (regcache->ptid ());
    472 
    473   /* Use the PTRACE_SETFPREGS requests whenever possible, since it
    474      transfers more registers in one system call.  But remember that
    475      store_fpregs can fail, and return zero.  */
    476   if (regno == -1)
    477     {
    478       store_regs (regcache, tid, regno);
    479       store_fpregs (regcache, tid, regno);
    480       return;
    481     }
    482 
    483   if (getregs_supplies (regno))
    484     {
    485       store_regs (regcache, tid, regno);
    486       return;
    487     }
    488 
    489   if (getfpregs_supplies (regno))
    490     {
    491       store_fpregs (regcache, tid, regno);
    492       return;
    493     }
    494 
    495   internal_error (_("Got request to store bad register number %d."), regno);
    496 }
    497 
    498 
    500 /* Fetch the thread-local storage pointer for libthread_db.  */
    501 
    502 ps_err_e
    503 ps_get_thread_area (struct ps_prochandle *ph,
    504 		    lwpid_t lwpid, int idx, void **base)
    505 {
    506   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
    507     return PS_ERR;
    508 
    509   /* IDX is the bias from the thread pointer to the beginning of the
    510      thread descriptor.  It has to be subtracted due to implementation
    511      quirks in libthread_db.  */
    512   *base = (char *) *base - idx;
    513 
    514   return PS_OK;
    515 }
    516 
    517 void _initialize_m68k_linux_nat ();
    518 void
    519 _initialize_m68k_linux_nat ()
    520 {
    521   /* Register the target.  */
    522   linux_target = &the_m68k_linux_nat_target;
    523   add_inf_child_target (&the_m68k_linux_nat_target);
    524 }
    525