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