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