1/* Generic GNU/Linux target using traditional ptrace register access. 2 3 Copyright (C) 1988-2020 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 "linux-nat-trad.h" 22 23#include "nat/gdb_ptrace.h" 24#include "inf-ptrace.h" 25#include "gdbarch.h" 26 27/* Fetch register REGNUM from the inferior. */ 28 29void 30linux_nat_trad_target::fetch_register (struct regcache *regcache, int regnum) 31{ 32 struct gdbarch *gdbarch = regcache->arch (); 33 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 34 CORE_ADDR addr; 35 gdb_byte *buf; 36 size_t size; 37 pid_t pid; 38 int i; 39 40 /* This isn't really an address, but ptrace thinks of it as one. */ 41 addr = register_u_offset (gdbarch, regnum, 0); 42 if (addr == (CORE_ADDR)-1 43 || gdbarch_cannot_fetch_register (gdbarch, regnum)) 44 { 45 regcache->raw_supply (regnum, NULL); 46 return; 47 } 48 49 pid = get_ptrace_pid (regcache->ptid ()); 50 51 size = register_size (gdbarch, regnum); 52 buf = (gdb_byte *) alloca (size); 53 54 /* Read the register contents from the inferior a chunk at a time. */ 55 for (i = 0; i < size; i += sizeof (PTRACE_TYPE_RET)) 56 { 57 size_t chunk = std::min (sizeof (PTRACE_TYPE_RET), size - i); 58 PTRACE_TYPE_RET val; 59 60 errno = 0; 61 val = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3) (uintptr_t) addr, 0); 62 if (errno != 0) 63 error (_("Couldn't read register %s (#%d): %s."), 64 gdbarch_register_name (gdbarch, regnum), 65 regnum, safe_strerror (errno)); 66 store_unsigned_integer (buf + i, chunk, byte_order, val); 67 68 addr += sizeof (PTRACE_TYPE_RET); 69 } 70 regcache->raw_supply (regnum, buf); 71} 72 73/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 74 for all registers. */ 75 76void 77linux_nat_trad_target::fetch_registers (struct regcache *regcache, int regnum) 78{ 79 if (regnum == -1) 80 for (regnum = 0; 81 regnum < gdbarch_num_regs (regcache->arch ()); 82 regnum++) 83 fetch_register (regcache, regnum); 84 else 85 fetch_register (regcache, regnum); 86} 87 88/* Store register REGNUM into the inferior. */ 89 90void 91linux_nat_trad_target::store_register (const struct regcache *regcache, 92 int regnum) 93{ 94 struct gdbarch *gdbarch = regcache->arch (); 95 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 96 CORE_ADDR addr; 97 size_t size; 98 gdb_byte *buf; 99 pid_t pid; 100 int i; 101 102 /* This isn't really an address, but ptrace thinks of it as one. */ 103 addr = register_u_offset (gdbarch, regnum, 1); 104 if (addr == (CORE_ADDR)-1 105 || gdbarch_cannot_store_register (gdbarch, regnum)) 106 return; 107 108 pid = get_ptrace_pid (regcache->ptid ()); 109 110 size = register_size (gdbarch, regnum); 111 buf = (gdb_byte *) alloca (size); 112 113 /* Write the register contents into the inferior a chunk at a time. */ 114 regcache->raw_collect (regnum, buf); 115 for (i = 0; i < size; i += sizeof (PTRACE_TYPE_RET)) 116 { 117 size_t chunk = std::min (sizeof (PTRACE_TYPE_RET), size - i); 118 PTRACE_TYPE_RET val; 119 120 val = extract_unsigned_integer (buf + i, chunk, byte_order); 121 errno = 0; 122 ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3) (uintptr_t) addr, val); 123 if (errno != 0) 124 error (_("Couldn't write register %s (#%d): %s."), 125 gdbarch_register_name (gdbarch, regnum), 126 regnum, safe_strerror (errno)); 127 128 addr += sizeof (PTRACE_TYPE_RET); 129 } 130} 131 132/* Store register REGNUM back into the inferior. If REGNUM is -1, do 133 this for all registers. */ 134 135void 136linux_nat_trad_target::store_registers (struct regcache *regcache, int regnum) 137{ 138 if (regnum == -1) 139 for (regnum = 0; 140 regnum < gdbarch_num_regs (regcache->arch ()); 141 regnum++) 142 store_register (regcache, regnum); 143 else 144 store_register (regcache, regnum); 145} 146