amd64-linux-nat.c revision 1.8
1/* Native-dependent code for GNU/Linux x86-64. 2 3 Copyright (C) 2001-2019 Free Software Foundation, Inc. 4 Contributed by Jiri Smid, SuSE Labs. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include "defs.h" 22#include "inferior.h" 23#include "regcache.h" 24#include "elf/common.h" 25#include <sys/uio.h> 26#include "nat/gdb_ptrace.h" 27#include <asm/prctl.h> 28#include <sys/reg.h> 29#include "gregset.h" 30#include "gdb_proc_service.h" 31 32#include "amd64-nat.h" 33#include "amd64-tdep.h" 34#include "amd64-linux-tdep.h" 35#include "i386-linux-tdep.h" 36#include "common/x86-xstate.h" 37 38#include "x86-linux-nat.h" 39#include "nat/linux-ptrace.h" 40#include "nat/amd64-linux-siginfo.h" 41 42/* This definition comes from prctl.h. Kernels older than 2.5.64 43 do not have it. */ 44#ifndef PTRACE_ARCH_PRCTL 45#define PTRACE_ARCH_PRCTL 30 46#endif 47 48struct amd64_linux_nat_target final : public x86_linux_nat_target 49{ 50 /* Add our register access methods. */ 51 void fetch_registers (struct regcache *, int) override; 52 void store_registers (struct regcache *, int) override; 53 54 bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction) 55 override; 56}; 57 58static amd64_linux_nat_target the_amd64_linux_nat_target; 59 60/* Mapping between the general-purpose registers in GNU/Linux x86-64 61 `struct user' format and GDB's register cache layout for GNU/Linux 62 i386. 63 64 Note that most GNU/Linux x86-64 registers are 64-bit, while the 65 GNU/Linux i386 registers are all 32-bit, but since we're 66 little-endian we get away with that. */ 67 68/* From <sys/reg.h> on GNU/Linux i386. */ 69static int amd64_linux_gregset32_reg_offset[] = 70{ 71 RAX * 8, RCX * 8, /* %eax, %ecx */ 72 RDX * 8, RBX * 8, /* %edx, %ebx */ 73 RSP * 8, RBP * 8, /* %esp, %ebp */ 74 RSI * 8, RDI * 8, /* %esi, %edi */ 75 RIP * 8, EFLAGS * 8, /* %eip, %eflags */ 76 CS * 8, SS * 8, /* %cs, %ss */ 77 DS * 8, ES * 8, /* %ds, %es */ 78 FS * 8, GS * 8, /* %fs, %gs */ 79 -1, -1, -1, -1, -1, -1, -1, -1, 80 -1, -1, -1, -1, -1, -1, -1, -1, 81 -1, -1, -1, -1, -1, -1, -1, -1, -1, 82 -1, -1, -1, -1, -1, -1, -1, -1, 83 -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */ 84 -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */ 85 -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */ 86 -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */ 87 -1, /* PKEYS register PKRU */ 88 ORIG_RAX * 8 /* "orig_eax" */ 89}; 90 91 92/* Transfering the general-purpose registers between GDB, inferiors 93 and core files. */ 94 95/* Fill GDB's register cache with the general-purpose register values 96 in *GREGSETP. */ 97 98void 99supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) 100{ 101 amd64_supply_native_gregset (regcache, gregsetp, -1); 102} 103 104/* Fill register REGNUM (if it is a general-purpose register) in 105 *GREGSETP with the value in GDB's register cache. If REGNUM is -1, 106 do this for all registers. */ 107 108void 109fill_gregset (const struct regcache *regcache, 110 elf_gregset_t *gregsetp, int regnum) 111{ 112 amd64_collect_native_gregset (regcache, gregsetp, regnum); 113} 114 115/* Transfering floating-point registers between GDB, inferiors and cores. */ 116 117/* Fill GDB's register cache with the floating-point and SSE register 118 values in *FPREGSETP. */ 119 120void 121supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp) 122{ 123 amd64_supply_fxsave (regcache, -1, fpregsetp); 124} 125 126/* Fill register REGNUM (if it is a floating-point or SSE register) in 127 *FPREGSETP with the value in GDB's register cache. If REGNUM is 128 -1, do this for all registers. */ 129 130void 131fill_fpregset (const struct regcache *regcache, 132 elf_fpregset_t *fpregsetp, int regnum) 133{ 134 amd64_collect_fxsave (regcache, regnum, fpregsetp); 135} 136 137 138/* Transferring arbitrary registers between GDB and inferior. */ 139 140/* Fetch register REGNUM from the child process. If REGNUM is -1, do 141 this for all registers (including the floating point and SSE 142 registers). */ 143 144void 145amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum) 146{ 147 struct gdbarch *gdbarch = regcache->arch (); 148 int tid; 149 150 /* GNU/Linux LWP ID's are process ID's. */ 151 tid = regcache->ptid ().lwp (); 152 if (tid == 0) 153 tid = regcache->ptid ().pid (); /* Not a threaded program. */ 154 155 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) 156 { 157 elf_gregset_t regs; 158 159 if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0) 160 perror_with_name (_("Couldn't get registers")); 161 162 amd64_supply_native_gregset (regcache, ®s, -1); 163 if (regnum != -1) 164 return; 165 } 166 167 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) 168 { 169 elf_fpregset_t fpregs; 170 171 if (have_ptrace_getregset == TRIBOOL_TRUE) 172 { 173 char xstateregs[X86_XSTATE_MAX_SIZE]; 174 struct iovec iov; 175 176 iov.iov_base = xstateregs; 177 iov.iov_len = sizeof (xstateregs); 178 if (ptrace (PTRACE_GETREGSET, tid, 179 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 180 perror_with_name (_("Couldn't get extended state status")); 181 182 amd64_supply_xsave (regcache, -1, xstateregs); 183 } 184 else 185 { 186 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) 187 perror_with_name (_("Couldn't get floating point status")); 188 189 amd64_supply_fxsave (regcache, -1, &fpregs); 190 } 191#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 192 { 193 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the 194 fs_base and gs_base fields of user_regs_struct can be 195 used directly. */ 196 unsigned long base; 197 198 if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) 199 { 200 if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_FS) < 0) 201 perror_with_name (_("Couldn't get segment register fs_base")); 202 203 regcache->raw_supply (AMD64_FSBASE_REGNUM, &base); 204 } 205 206 if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) 207 { 208 if (ptrace (PTRACE_ARCH_PRCTL, tid, &base, ARCH_GET_GS) < 0) 209 perror_with_name (_("Couldn't get segment register gs_base")); 210 211 regcache->raw_supply (AMD64_GSBASE_REGNUM, &base); 212 } 213 } 214#endif 215 } 216} 217 218/* Store register REGNUM back into the child process. If REGNUM is 219 -1, do this for all registers (including the floating-point and SSE 220 registers). */ 221 222void 223amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum) 224{ 225 struct gdbarch *gdbarch = regcache->arch (); 226 int tid; 227 228 /* GNU/Linux LWP ID's are process ID's. */ 229 tid = regcache->ptid ().lwp (); 230 if (tid == 0) 231 tid = regcache->ptid ().pid (); /* Not a threaded program. */ 232 233 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) 234 { 235 elf_gregset_t regs; 236 237 if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0) 238 perror_with_name (_("Couldn't get registers")); 239 240 amd64_collect_native_gregset (regcache, ®s, regnum); 241 242 if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0) 243 perror_with_name (_("Couldn't write registers")); 244 245 if (regnum != -1) 246 return; 247 } 248 249 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) 250 { 251 elf_fpregset_t fpregs; 252 253 if (have_ptrace_getregset == TRIBOOL_TRUE) 254 { 255 char xstateregs[X86_XSTATE_MAX_SIZE]; 256 struct iovec iov; 257 258 iov.iov_base = xstateregs; 259 iov.iov_len = sizeof (xstateregs); 260 if (ptrace (PTRACE_GETREGSET, tid, 261 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 262 perror_with_name (_("Couldn't get extended state status")); 263 264 amd64_collect_xsave (regcache, regnum, xstateregs, 0); 265 266 if (ptrace (PTRACE_SETREGSET, tid, 267 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 268 perror_with_name (_("Couldn't write extended state status")); 269 } 270 else 271 { 272 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) 273 perror_with_name (_("Couldn't get floating point status")); 274 275 amd64_collect_fxsave (regcache, regnum, &fpregs); 276 277 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0) 278 perror_with_name (_("Couldn't write floating point status")); 279 } 280 281#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 282 { 283 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the 284 fs_base and gs_base fields of user_regs_struct can be 285 used directly. */ 286 void *base; 287 288 if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) 289 { 290 regcache->raw_collect (AMD64_FSBASE_REGNUM, &base); 291 292 if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_FS) < 0) 293 perror_with_name (_("Couldn't write segment register fs_base")); 294 } 295 if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) 296 { 297 298 regcache->raw_collect (AMD64_GSBASE_REGNUM, &base); 299 if (ptrace (PTRACE_ARCH_PRCTL, tid, base, ARCH_SET_GS) < 0) 300 perror_with_name (_("Couldn't write segment register gs_base")); 301 } 302 } 303#endif 304 } 305} 306 307 308/* This function is called by libthread_db as part of its handling of 309 a request for a thread's local storage address. */ 310 311ps_err_e 312ps_get_thread_area (struct ps_prochandle *ph, 313 lwpid_t lwpid, int idx, void **base) 314{ 315 if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32) 316 { 317 unsigned int base_addr; 318 ps_err_e result; 319 320 result = x86_linux_get_thread_area (lwpid, (void *) (long) idx, 321 &base_addr); 322 if (result == PS_OK) 323 { 324 /* Extend the value to 64 bits. Here it's assumed that 325 a "long" and a "void *" are the same. */ 326 (*base) = (void *) (long) base_addr; 327 } 328 return result; 329 } 330 else 331 { 332 333 /* FIXME: ezannoni-2003-07-09 see comment above about include 334 file order. We could be getting bogus values for these two. */ 335 gdb_assert (FS < ELF_NGREG); 336 gdb_assert (GS < ELF_NGREG); 337 switch (idx) 338 { 339 case FS: 340#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 341 { 342 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the 343 fs_base and gs_base fields of user_regs_struct can be 344 used directly. */ 345 unsigned long fs; 346 errno = 0; 347 fs = ptrace (PTRACE_PEEKUSER, lwpid, 348 offsetof (struct user_regs_struct, fs_base), 0); 349 if (errno == 0) 350 { 351 *base = (void *) fs; 352 return PS_OK; 353 } 354 } 355#endif 356 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) 357 return PS_OK; 358 break; 359 case GS: 360#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE 361 { 362 unsigned long gs; 363 errno = 0; 364 gs = ptrace (PTRACE_PEEKUSER, lwpid, 365 offsetof (struct user_regs_struct, gs_base), 0); 366 if (errno == 0) 367 { 368 *base = (void *) gs; 369 return PS_OK; 370 } 371 } 372#endif 373 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) 374 return PS_OK; 375 break; 376 default: /* Should not happen. */ 377 return PS_BADADDR; 378 } 379 } 380 return PS_ERR; /* ptrace failed. */ 381} 382 383 384/* Convert a ptrace/host siginfo object, into/from the siginfo in the 385 layout of the inferiors' architecture. Returns true if any 386 conversion was done; false otherwise. If DIRECTION is 1, then copy 387 from INF to PTRACE. If DIRECTION is 0, copy from PTRACE to 388 INF. */ 389 390bool 391amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace, 392 gdb_byte *inf, 393 int direction) 394{ 395 struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); 396 397 /* Is the inferior 32-bit? If so, then do fixup the siginfo 398 object. */ 399 if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) 400 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction, 401 FIXUP_32); 402 /* No fixup for native x32 GDB. */ 403 else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8) 404 return amd64_linux_siginfo_fixup_common (ptrace, inf, direction, 405 FIXUP_X32); 406 else 407 return false; 408} 409 410void 411_initialize_amd64_linux_nat (void) 412{ 413 amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset; 414 amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS; 415 amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset; 416 amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS; 417 418 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset) 419 == amd64_native_gregset32_num_regs); 420 421 linux_target = &the_amd64_linux_nat_target; 422 423 /* Add the target. */ 424 add_inf_child_target (linux_target); 425} 426