amd64-linux-nat.c revision 1.5
1/* Native-dependent code for GNU/Linux x86-64. 2 3 Copyright (C) 2001-2015 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 <sys/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 42/* Mapping between the general-purpose registers in GNU/Linux x86-64 43 `struct user' format and GDB's register cache layout for GNU/Linux 44 i386. 45 46 Note that most GNU/Linux x86-64 registers are 64-bit, while the 47 GNU/Linux i386 registers are all 32-bit, but since we're 48 little-endian we get away with that. */ 49 50/* From <sys/reg.h> on GNU/Linux i386. */ 51static int amd64_linux_gregset32_reg_offset[] = 52{ 53 RAX * 8, RCX * 8, /* %eax, %ecx */ 54 RDX * 8, RBX * 8, /* %edx, %ebx */ 55 RSP * 8, RBP * 8, /* %esp, %ebp */ 56 RSI * 8, RDI * 8, /* %esi, %edi */ 57 RIP * 8, EFLAGS * 8, /* %eip, %eflags */ 58 CS * 8, SS * 8, /* %cs, %ss */ 59 DS * 8, ES * 8, /* %ds, %es */ 60 FS * 8, GS * 8, /* %fs, %gs */ 61 -1, -1, -1, -1, -1, -1, -1, -1, 62 -1, -1, -1, -1, -1, -1, -1, -1, 63 -1, -1, -1, -1, -1, -1, -1, -1, -1, 64 -1, -1, -1, -1, -1, -1, -1, -1, 65 -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */ 66 -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */ 67 -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */ 68 -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */ 69 ORIG_RAX * 8 /* "orig_eax" */ 70}; 71 72 73/* Transfering the general-purpose registers between GDB, inferiors 74 and core files. */ 75 76/* Fill GDB's register cache with the general-purpose register values 77 in *GREGSETP. */ 78 79void 80supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) 81{ 82 amd64_supply_native_gregset (regcache, gregsetp, -1); 83} 84 85/* Fill register REGNUM (if it is a general-purpose register) in 86 *GREGSETP with the value in GDB's register cache. If REGNUM is -1, 87 do this for all registers. */ 88 89void 90fill_gregset (const struct regcache *regcache, 91 elf_gregset_t *gregsetp, int regnum) 92{ 93 amd64_collect_native_gregset (regcache, gregsetp, regnum); 94} 95 96/* Transfering floating-point registers between GDB, inferiors and cores. */ 97 98/* Fill GDB's register cache with the floating-point and SSE register 99 values in *FPREGSETP. */ 100 101void 102supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp) 103{ 104 amd64_supply_fxsave (regcache, -1, fpregsetp); 105} 106 107/* Fill register REGNUM (if it is a floating-point or SSE register) in 108 *FPREGSETP with the value in GDB's register cache. If REGNUM is 109 -1, do this for all registers. */ 110 111void 112fill_fpregset (const struct regcache *regcache, 113 elf_fpregset_t *fpregsetp, int regnum) 114{ 115 amd64_collect_fxsave (regcache, regnum, fpregsetp); 116} 117 118 119/* Transferring arbitrary registers between GDB and inferior. */ 120 121/* Fetch register REGNUM from the child process. If REGNUM is -1, do 122 this for all registers (including the floating point and SSE 123 registers). */ 124 125static void 126amd64_linux_fetch_inferior_registers (struct target_ops *ops, 127 struct regcache *regcache, int regnum) 128{ 129 struct gdbarch *gdbarch = get_regcache_arch (regcache); 130 int tid; 131 132 /* GNU/Linux LWP ID's are process ID's. */ 133 tid = ptid_get_lwp (inferior_ptid); 134 if (tid == 0) 135 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ 136 137 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) 138 { 139 elf_gregset_t regs; 140 141 if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0) 142 perror_with_name (_("Couldn't get registers")); 143 144 amd64_supply_native_gregset (regcache, ®s, -1); 145 if (regnum != -1) 146 return; 147 } 148 149 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) 150 { 151 elf_fpregset_t fpregs; 152 153 if (have_ptrace_getregset == TRIBOOL_TRUE) 154 { 155 char xstateregs[X86_XSTATE_MAX_SIZE]; 156 struct iovec iov; 157 158 iov.iov_base = xstateregs; 159 iov.iov_len = sizeof (xstateregs); 160 if (ptrace (PTRACE_GETREGSET, tid, 161 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 162 perror_with_name (_("Couldn't get extended state status")); 163 164 amd64_supply_xsave (regcache, -1, xstateregs); 165 } 166 else 167 { 168 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) 169 perror_with_name (_("Couldn't get floating point status")); 170 171 amd64_supply_fxsave (regcache, -1, &fpregs); 172 } 173 } 174} 175 176/* Store register REGNUM back into the child process. If REGNUM is 177 -1, do this for all registers (including the floating-point and SSE 178 registers). */ 179 180static void 181amd64_linux_store_inferior_registers (struct target_ops *ops, 182 struct regcache *regcache, int regnum) 183{ 184 struct gdbarch *gdbarch = get_regcache_arch (regcache); 185 int tid; 186 187 /* GNU/Linux LWP ID's are process ID's. */ 188 tid = ptid_get_lwp (inferior_ptid); 189 if (tid == 0) 190 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ 191 192 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) 193 { 194 elf_gregset_t regs; 195 196 if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0) 197 perror_with_name (_("Couldn't get registers")); 198 199 amd64_collect_native_gregset (regcache, ®s, regnum); 200 201 if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0) 202 perror_with_name (_("Couldn't write registers")); 203 204 if (regnum != -1) 205 return; 206 } 207 208 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) 209 { 210 elf_fpregset_t fpregs; 211 212 if (have_ptrace_getregset == TRIBOOL_TRUE) 213 { 214 char xstateregs[X86_XSTATE_MAX_SIZE]; 215 struct iovec iov; 216 217 iov.iov_base = xstateregs; 218 iov.iov_len = sizeof (xstateregs); 219 if (ptrace (PTRACE_GETREGSET, tid, 220 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 221 perror_with_name (_("Couldn't get extended state status")); 222 223 amd64_collect_xsave (regcache, regnum, xstateregs, 0); 224 225 if (ptrace (PTRACE_SETREGSET, tid, 226 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) 227 perror_with_name (_("Couldn't write extended state status")); 228 } 229 else 230 { 231 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) 232 perror_with_name (_("Couldn't get floating point status")); 233 234 amd64_collect_fxsave (regcache, regnum, &fpregs); 235 236 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0) 237 perror_with_name (_("Couldn't write floating point status")); 238 } 239 } 240} 241 242 243/* This function is called by libthread_db as part of its handling of 244 a request for a thread's local storage address. */ 245 246ps_err_e 247ps_get_thread_area (const struct ps_prochandle *ph, 248 lwpid_t lwpid, int idx, void **base) 249{ 250 if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32) 251 { 252 unsigned int base_addr; 253 ps_err_e result; 254 255 result = x86_linux_get_thread_area (lwpid, (void *) (long) idx, 256 &base_addr); 257 if (result == PS_OK) 258 { 259 /* Extend the value to 64 bits. Here it's assumed that 260 a "long" and a "void *" are the same. */ 261 (*base) = (void *) (long) base_addr; 262 } 263 return result; 264 } 265 else 266 { 267 /* This definition comes from prctl.h, but some kernels may not 268 have it. */ 269#ifndef PTRACE_ARCH_PRCTL 270#define PTRACE_ARCH_PRCTL 30 271#endif 272 /* FIXME: ezannoni-2003-07-09 see comment above about include 273 file order. We could be getting bogus values for these two. */ 274 gdb_assert (FS < ELF_NGREG); 275 gdb_assert (GS < ELF_NGREG); 276 switch (idx) 277 { 278 case FS: 279#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE 280 { 281 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the 282 fs_base and gs_base fields of user_regs_struct can be 283 used directly. */ 284 unsigned long fs; 285 errno = 0; 286 fs = ptrace (PTRACE_PEEKUSER, lwpid, 287 offsetof (struct user_regs_struct, fs_base), 0); 288 if (errno == 0) 289 { 290 *base = (void *) fs; 291 return PS_OK; 292 } 293 } 294#endif 295 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) 296 return PS_OK; 297 break; 298 case GS: 299#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE 300 { 301 unsigned long gs; 302 errno = 0; 303 gs = ptrace (PTRACE_PEEKUSER, lwpid, 304 offsetof (struct user_regs_struct, gs_base), 0); 305 if (errno == 0) 306 { 307 *base = (void *) gs; 308 return PS_OK; 309 } 310 } 311#endif 312 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) 313 return PS_OK; 314 break; 315 default: /* Should not happen. */ 316 return PS_BADADDR; 317 } 318 } 319 return PS_ERR; /* ptrace failed. */ 320} 321 322 323/* When GDB is built as a 64-bit application on linux, the 324 PTRACE_GETSIGINFO data is always presented in 64-bit layout. Since 325 debugging a 32-bit inferior with a 64-bit GDB should look the same 326 as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit 327 conversion in-place ourselves. */ 328 329/* These types below (compat_*) define a siginfo type that is layout 330 compatible with the siginfo type exported by the 32-bit userspace 331 support. */ 332 333typedef int compat_int_t; 334typedef unsigned int compat_uptr_t; 335 336typedef int compat_time_t; 337typedef int compat_timer_t; 338typedef int compat_clock_t; 339 340struct compat_timeval 341{ 342 compat_time_t tv_sec; 343 int tv_usec; 344}; 345 346typedef union compat_sigval 347{ 348 compat_int_t sival_int; 349 compat_uptr_t sival_ptr; 350} compat_sigval_t; 351 352typedef struct compat_siginfo 353{ 354 int si_signo; 355 int si_errno; 356 int si_code; 357 358 union 359 { 360 int _pad[((128 / sizeof (int)) - 3)]; 361 362 /* kill() */ 363 struct 364 { 365 unsigned int _pid; 366 unsigned int _uid; 367 } _kill; 368 369 /* POSIX.1b timers */ 370 struct 371 { 372 compat_timer_t _tid; 373 int _overrun; 374 compat_sigval_t _sigval; 375 } _timer; 376 377 /* POSIX.1b signals */ 378 struct 379 { 380 unsigned int _pid; 381 unsigned int _uid; 382 compat_sigval_t _sigval; 383 } _rt; 384 385 /* SIGCHLD */ 386 struct 387 { 388 unsigned int _pid; 389 unsigned int _uid; 390 int _status; 391 compat_clock_t _utime; 392 compat_clock_t _stime; 393 } _sigchld; 394 395 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 396 struct 397 { 398 unsigned int _addr; 399 } _sigfault; 400 401 /* SIGPOLL */ 402 struct 403 { 404 int _band; 405 int _fd; 406 } _sigpoll; 407 } _sifields; 408} compat_siginfo_t; 409 410/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */ 411typedef struct compat_x32_clock 412{ 413 int lower; 414 int upper; 415} compat_x32_clock_t; 416 417typedef struct compat_x32_siginfo 418{ 419 int si_signo; 420 int si_errno; 421 int si_code; 422 423 union 424 { 425 int _pad[((128 / sizeof (int)) - 3)]; 426 427 /* kill() */ 428 struct 429 { 430 unsigned int _pid; 431 unsigned int _uid; 432 } _kill; 433 434 /* POSIX.1b timers */ 435 struct 436 { 437 compat_timer_t _tid; 438 int _overrun; 439 compat_sigval_t _sigval; 440 } _timer; 441 442 /* POSIX.1b signals */ 443 struct 444 { 445 unsigned int _pid; 446 unsigned int _uid; 447 compat_sigval_t _sigval; 448 } _rt; 449 450 /* SIGCHLD */ 451 struct 452 { 453 unsigned int _pid; 454 unsigned int _uid; 455 int _status; 456 compat_x32_clock_t _utime; 457 compat_x32_clock_t _stime; 458 } _sigchld; 459 460 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ 461 struct 462 { 463 unsigned int _addr; 464 } _sigfault; 465 466 /* SIGPOLL */ 467 struct 468 { 469 int _band; 470 int _fd; 471 } _sigpoll; 472 } _sifields; 473} compat_x32_siginfo_t; 474 475#define cpt_si_pid _sifields._kill._pid 476#define cpt_si_uid _sifields._kill._uid 477#define cpt_si_timerid _sifields._timer._tid 478#define cpt_si_overrun _sifields._timer._overrun 479#define cpt_si_status _sifields._sigchld._status 480#define cpt_si_utime _sifields._sigchld._utime 481#define cpt_si_stime _sifields._sigchld._stime 482#define cpt_si_ptr _sifields._rt._sigval.sival_ptr 483#define cpt_si_addr _sifields._sigfault._addr 484#define cpt_si_band _sifields._sigpoll._band 485#define cpt_si_fd _sifields._sigpoll._fd 486 487/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun. 488 In their place is si_timer1,si_timer2. */ 489#ifndef si_timerid 490#define si_timerid si_timer1 491#endif 492#ifndef si_overrun 493#define si_overrun si_timer2 494#endif 495 496static void 497compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from) 498{ 499 memset (to, 0, sizeof (*to)); 500 501 to->si_signo = from->si_signo; 502 to->si_errno = from->si_errno; 503 to->si_code = from->si_code; 504 505 if (to->si_code == SI_TIMER) 506 { 507 to->cpt_si_timerid = from->si_timerid; 508 to->cpt_si_overrun = from->si_overrun; 509 to->cpt_si_ptr = (intptr_t) from->si_ptr; 510 } 511 else if (to->si_code == SI_USER) 512 { 513 to->cpt_si_pid = from->si_pid; 514 to->cpt_si_uid = from->si_uid; 515 } 516 else if (to->si_code < 0) 517 { 518 to->cpt_si_pid = from->si_pid; 519 to->cpt_si_uid = from->si_uid; 520 to->cpt_si_ptr = (intptr_t) from->si_ptr; 521 } 522 else 523 { 524 switch (to->si_signo) 525 { 526 case SIGCHLD: 527 to->cpt_si_pid = from->si_pid; 528 to->cpt_si_uid = from->si_uid; 529 to->cpt_si_status = from->si_status; 530 to->cpt_si_utime = from->si_utime; 531 to->cpt_si_stime = from->si_stime; 532 break; 533 case SIGILL: 534 case SIGFPE: 535 case SIGSEGV: 536 case SIGBUS: 537 to->cpt_si_addr = (intptr_t) from->si_addr; 538 break; 539 case SIGPOLL: 540 to->cpt_si_band = from->si_band; 541 to->cpt_si_fd = from->si_fd; 542 break; 543 default: 544 to->cpt_si_pid = from->si_pid; 545 to->cpt_si_uid = from->si_uid; 546 to->cpt_si_ptr = (intptr_t) from->si_ptr; 547 break; 548 } 549 } 550} 551 552static void 553siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from) 554{ 555 memset (to, 0, sizeof (*to)); 556 557 to->si_signo = from->si_signo; 558 to->si_errno = from->si_errno; 559 to->si_code = from->si_code; 560 561 if (to->si_code == SI_TIMER) 562 { 563 to->si_timerid = from->cpt_si_timerid; 564 to->si_overrun = from->cpt_si_overrun; 565 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr; 566 } 567 else if (to->si_code == SI_USER) 568 { 569 to->si_pid = from->cpt_si_pid; 570 to->si_uid = from->cpt_si_uid; 571 } 572 if (to->si_code < 0) 573 { 574 to->si_pid = from->cpt_si_pid; 575 to->si_uid = from->cpt_si_uid; 576 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr; 577 } 578 else 579 { 580 switch (to->si_signo) 581 { 582 case SIGCHLD: 583 to->si_pid = from->cpt_si_pid; 584 to->si_uid = from->cpt_si_uid; 585 to->si_status = from->cpt_si_status; 586 to->si_utime = from->cpt_si_utime; 587 to->si_stime = from->cpt_si_stime; 588 break; 589 case SIGILL: 590 case SIGFPE: 591 case SIGSEGV: 592 case SIGBUS: 593 to->si_addr = (void *) (intptr_t) from->cpt_si_addr; 594 break; 595 case SIGPOLL: 596 to->si_band = from->cpt_si_band; 597 to->si_fd = from->cpt_si_fd; 598 break; 599 default: 600 to->si_pid = from->cpt_si_pid; 601 to->si_uid = from->cpt_si_uid; 602 to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr; 603 break; 604 } 605 } 606} 607 608static void 609compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to, 610 siginfo_t *from) 611{ 612 memset (to, 0, sizeof (*to)); 613 614 to->si_signo = from->si_signo; 615 to->si_errno = from->si_errno; 616 to->si_code = from->si_code; 617 618 if (to->si_code == SI_TIMER) 619 { 620 to->cpt_si_timerid = from->si_timerid; 621 to->cpt_si_overrun = from->si_overrun; 622 to->cpt_si_ptr = (intptr_t) from->si_ptr; 623 } 624 else if (to->si_code == SI_USER) 625 { 626 to->cpt_si_pid = from->si_pid; 627 to->cpt_si_uid = from->si_uid; 628 } 629 else if (to->si_code < 0) 630 { 631 to->cpt_si_pid = from->si_pid; 632 to->cpt_si_uid = from->si_uid; 633 to->cpt_si_ptr = (intptr_t) from->si_ptr; 634 } 635 else 636 { 637 switch (to->si_signo) 638 { 639 case SIGCHLD: 640 to->cpt_si_pid = from->si_pid; 641 to->cpt_si_uid = from->si_uid; 642 to->cpt_si_status = from->si_status; 643 memcpy (&to->cpt_si_utime, &from->si_utime, 644 sizeof (to->cpt_si_utime)); 645 memcpy (&to->cpt_si_stime, &from->si_stime, 646 sizeof (to->cpt_si_stime)); 647 break; 648 case SIGILL: 649 case SIGFPE: 650 case SIGSEGV: 651 case SIGBUS: 652 to->cpt_si_addr = (intptr_t) from->si_addr; 653 break; 654 case SIGPOLL: 655 to->cpt_si_band = from->si_band; 656 to->cpt_si_fd = from->si_fd; 657 break; 658 default: 659 to->cpt_si_pid = from->si_pid; 660 to->cpt_si_uid = from->si_uid; 661 to->cpt_si_ptr = (intptr_t) from->si_ptr; 662 break; 663 } 664 } 665} 666 667static void 668siginfo_from_compat_x32_siginfo (siginfo_t *to, 669 compat_x32_siginfo_t *from) 670{ 671 memset (to, 0, sizeof (*to)); 672 673 to->si_signo = from->si_signo; 674 to->si_errno = from->si_errno; 675 to->si_code = from->si_code; 676 677 if (to->si_code == SI_TIMER) 678 { 679 to->si_timerid = from->cpt_si_timerid; 680 to->si_overrun = from->cpt_si_overrun; 681 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr; 682 } 683 else if (to->si_code == SI_USER) 684 { 685 to->si_pid = from->cpt_si_pid; 686 to->si_uid = from->cpt_si_uid; 687 } 688 if (to->si_code < 0) 689 { 690 to->si_pid = from->cpt_si_pid; 691 to->si_uid = from->cpt_si_uid; 692 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr; 693 } 694 else 695 { 696 switch (to->si_signo) 697 { 698 case SIGCHLD: 699 to->si_pid = from->cpt_si_pid; 700 to->si_uid = from->cpt_si_uid; 701 to->si_status = from->cpt_si_status; 702 memcpy (&to->si_utime, &from->cpt_si_utime, 703 sizeof (to->si_utime)); 704 memcpy (&to->si_stime, &from->cpt_si_stime, 705 sizeof (to->si_stime)); 706 break; 707 case SIGILL: 708 case SIGFPE: 709 case SIGSEGV: 710 case SIGBUS: 711 to->si_addr = (void *) (intptr_t) from->cpt_si_addr; 712 break; 713 case SIGPOLL: 714 to->si_band = from->cpt_si_band; 715 to->si_fd = from->cpt_si_fd; 716 break; 717 default: 718 to->si_pid = from->cpt_si_pid; 719 to->si_uid = from->cpt_si_uid; 720 to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr; 721 break; 722 } 723 } 724} 725 726/* Convert a native/host siginfo object, into/from the siginfo in the 727 layout of the inferiors' architecture. Returns true if any 728 conversion was done; false otherwise. If DIRECTION is 1, then copy 729 from INF to NATIVE. If DIRECTION is 0, copy from NATIVE to 730 INF. */ 731 732static int 733amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction) 734{ 735 struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); 736 737 /* Is the inferior 32-bit? If so, then do fixup the siginfo 738 object. */ 739 if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) 740 { 741 gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t)); 742 743 if (direction == 0) 744 compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native); 745 else 746 siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf); 747 748 return 1; 749 } 750 /* No fixup for native x32 GDB. */ 751 else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8) 752 { 753 gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t)); 754 755 if (direction == 0) 756 compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf, 757 native); 758 else 759 siginfo_from_compat_x32_siginfo (native, 760 (struct compat_x32_siginfo *) inf); 761 762 return 1; 763 } 764 else 765 return 0; 766} 767 768 769/* Provide a prototype to silence -Wmissing-prototypes. */ 770void _initialize_amd64_linux_nat (void); 771 772void 773_initialize_amd64_linux_nat (void) 774{ 775 struct target_ops *t; 776 777 amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset; 778 amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS; 779 amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset; 780 amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS; 781 782 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset) 783 == amd64_native_gregset32_num_regs); 784 785 /* Create a generic x86 GNU/Linux target. */ 786 t = x86_linux_create_target (); 787 788 /* Add our register access methods. */ 789 t->to_fetch_registers = amd64_linux_fetch_inferior_registers; 790 t->to_store_registers = amd64_linux_store_inferior_registers; 791 792 /* Add the target. */ 793 x86_linux_add_target (t); 794 795 /* Add our siginfo layout converter. */ 796 linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup); 797} 798