xref: /dflybsd-src/contrib/gdb-7/gdb/amd64dfly-tdep.c (revision e0cb4e00e7683d8be35887ea90c8e33e065e45c0)
169e0f06dSSimon Schubert /* Target-dependent code for DragonFly/amd64.
269e0f06dSSimon Schubert 
38a286ab3SJohn Marino    Copyright (C) 2003-2013 Free Software Foundation, Inc.
469e0f06dSSimon Schubert 
569e0f06dSSimon Schubert    This file is part of GDB.
669e0f06dSSimon Schubert 
769e0f06dSSimon Schubert    This program is free software; you can redistribute it and/or modify
869e0f06dSSimon Schubert    it under the terms of the GNU General Public License as published by
969e0f06dSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
1069e0f06dSSimon Schubert    (at your option) any later version.
1169e0f06dSSimon Schubert 
1269e0f06dSSimon Schubert    This program is distributed in the hope that it will be useful,
1369e0f06dSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
1469e0f06dSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1569e0f06dSSimon Schubert    GNU General Public License for more details.
1669e0f06dSSimon Schubert 
1769e0f06dSSimon Schubert    You should have received a copy of the GNU General Public License
1869e0f06dSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1969e0f06dSSimon Schubert 
2069e0f06dSSimon Schubert #include "defs.h"
2169e0f06dSSimon Schubert #include "arch-utils.h"
2269e0f06dSSimon Schubert #include "frame.h"
2369e0f06dSSimon Schubert #include "gdbcore.h"
2469e0f06dSSimon Schubert #include "regcache.h"
2569e0f06dSSimon Schubert #include "osabi.h"
2669e0f06dSSimon Schubert 
2769e0f06dSSimon Schubert #include "gdb_assert.h"
2869e0f06dSSimon Schubert #include "gdb_string.h"
2969e0f06dSSimon Schubert 
3069e0f06dSSimon Schubert #include "amd64-tdep.h"
3169e0f06dSSimon Schubert #include "solib-svr4.h"
3269e0f06dSSimon Schubert 
3369e0f06dSSimon Schubert /* Support for signal handlers.  */
3469e0f06dSSimon Schubert 
3569e0f06dSSimon Schubert /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
3669e0f06dSSimon Schubert    address of the associated sigcontext structure.  */
3769e0f06dSSimon Schubert 
3869e0f06dSSimon Schubert static CORE_ADDR
amd64dfly_sigcontext_addr(struct frame_info * this_frame)3969e0f06dSSimon Schubert amd64dfly_sigcontext_addr (struct frame_info *this_frame)
4069e0f06dSSimon Schubert {
418a286ab3SJohn Marino   struct gdbarch *gdbarch = get_frame_arch (this_frame);
428a286ab3SJohn Marino   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
4369e0f06dSSimon Schubert   CORE_ADDR sp;
448a286ab3SJohn Marino   gdb_byte buf[8];
4569e0f06dSSimon Schubert 
4669e0f06dSSimon Schubert   /* The `struct sigcontext' (which really is an `ucontext_t' on
47*e0cb4e00SSascha Wildner      DragonFly/amd64) lives at a fixed offset in the signal frame.  See
48*e0cb4e00SSascha Wildner      <machine/sigframe.h>.  */
498a286ab3SJohn Marino   get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
508a286ab3SJohn Marino   sp = extract_unsigned_integer (buf, 8, byte_order);
5169e0f06dSSimon Schubert   return sp + 16;
5269e0f06dSSimon Schubert }
53*e0cb4e00SSascha Wildner 
5469e0f06dSSimon Schubert /* Mapping between the general-purpose registers in `struct reg'
5569e0f06dSSimon Schubert    format and GDB's register cache layout.
5669e0f06dSSimon Schubert 
5769e0f06dSSimon Schubert    Note that some registers are 32-bit, but since we're little-endian
5869e0f06dSSimon Schubert    we get away with that.  */
5969e0f06dSSimon Schubert 
6069e0f06dSSimon Schubert /* From <machine/reg.h>.  */
6169e0f06dSSimon Schubert static int amd64dfly_r_reg_offset[] =
6269e0f06dSSimon Schubert {
6369e0f06dSSimon Schubert   6 * 8,			/* %rax */
6469e0f06dSSimon Schubert   7 * 8,			/* %rbx */
6569e0f06dSSimon Schubert   3 * 8,			/* %rcx */
6669e0f06dSSimon Schubert   2 * 8,			/* %rdx */
6769e0f06dSSimon Schubert   1 * 8,			/* %rsi */
6869e0f06dSSimon Schubert   0 * 8,			/* %rdi */
6969e0f06dSSimon Schubert   8 * 8,			/* %rbp */
7069e0f06dSSimon Schubert   23 * 8,			/* %rsp */
7169e0f06dSSimon Schubert   4 * 8,			/* %r8 ... */
7269e0f06dSSimon Schubert   5 * 8,
7369e0f06dSSimon Schubert   9 * 8,
7469e0f06dSSimon Schubert   10 * 8,
7569e0f06dSSimon Schubert   11 * 8,
7669e0f06dSSimon Schubert   12 * 8,
7769e0f06dSSimon Schubert   13 * 8,
7869e0f06dSSimon Schubert   14 * 8,			/* ... %r15 */
7969e0f06dSSimon Schubert   20 * 8,			/* %rip */
8069e0f06dSSimon Schubert   22 * 8,			/* %eflags */
8169e0f06dSSimon Schubert   21 * 8,			/* %cs */
8269e0f06dSSimon Schubert   24 * 8,			/* %ss */
8369e0f06dSSimon Schubert   -1,				/* %ds */
8469e0f06dSSimon Schubert   -1,				/* %es */
8569e0f06dSSimon Schubert   -1,				/* %fs */
8669e0f06dSSimon Schubert   -1				/* %gs */
8769e0f06dSSimon Schubert };
8869e0f06dSSimon Schubert 
8969e0f06dSSimon Schubert /* Location of the signal trampoline.  */
9069e0f06dSSimon Schubert CORE_ADDR amd64dfly_sigtramp_start_addr = 0x7fffffffffc0ULL;
9169e0f06dSSimon Schubert CORE_ADDR amd64dfly_sigtramp_end_addr = 0x7fffffffffe0ULL;
9269e0f06dSSimon Schubert 
9369e0f06dSSimon Schubert /* From <machine/signal.h>.  */
9469e0f06dSSimon Schubert int amd64dfly_sc_reg_offset[] =
9569e0f06dSSimon Schubert {
9669e0f06dSSimon Schubert   24 + 6 * 8,			/* %rax */
9769e0f06dSSimon Schubert   24 + 7 * 8,			/* %rbx */
9869e0f06dSSimon Schubert   24 + 3 * 8,			/* %rcx */
9969e0f06dSSimon Schubert   24 + 2 * 8,			/* %rdx */
10069e0f06dSSimon Schubert   24 + 1 * 8,			/* %rsi */
10169e0f06dSSimon Schubert   24 + 0 * 8,			/* %rdi */
10269e0f06dSSimon Schubert   24 + 8 * 8,			/* %rbp */
10369e0f06dSSimon Schubert   24 + 23 * 8,			/* %rsp */
10469e0f06dSSimon Schubert   24 + 4 * 8,			/* %r8 ... */
10569e0f06dSSimon Schubert   24 + 5 * 8,
10669e0f06dSSimon Schubert   24 + 9 * 8,
10769e0f06dSSimon Schubert   24 + 10 * 8,
10869e0f06dSSimon Schubert   24 + 11 * 8,
10969e0f06dSSimon Schubert   24 + 12 * 8,
11069e0f06dSSimon Schubert   24 + 13 * 8,
11169e0f06dSSimon Schubert   24 + 14 * 8,			/* ... %r15 */
11269e0f06dSSimon Schubert   24 + 20 * 8,			/* %rip */
11369e0f06dSSimon Schubert   24 + 22 * 8,			/* %eflags */
11469e0f06dSSimon Schubert   24 + 21 * 8,			/* %cs */
11569e0f06dSSimon Schubert   24 + 24 * 8,			/* %ss */
11669e0f06dSSimon Schubert   -1,				/* %ds */
11769e0f06dSSimon Schubert   -1,				/* %es */
11869e0f06dSSimon Schubert   -1,				/* %fs */
11969e0f06dSSimon Schubert   -1				/* %gs */
12069e0f06dSSimon Schubert };
12169e0f06dSSimon Schubert 
12269e0f06dSSimon Schubert /* From /usr/src/lib/libc/amd64/gen/_setjmp.S.  */
12369e0f06dSSimon Schubert static int amd64dfly_jmp_buf_reg_offset[] =
12469e0f06dSSimon Schubert {
12569e0f06dSSimon Schubert   -1,				/* %rax */
12669e0f06dSSimon Schubert   1 * 8,			/* %rbx */
12769e0f06dSSimon Schubert   -1,				/* %rcx */
12869e0f06dSSimon Schubert   -1,				/* %rdx */
12969e0f06dSSimon Schubert   -1,				/* %rsi */
13069e0f06dSSimon Schubert   -1,				/* %rdi */
13169e0f06dSSimon Schubert   3 * 8,			/* %rbp */
13269e0f06dSSimon Schubert   2 * 8,			/* %rsp */
13369e0f06dSSimon Schubert   -1,				/* %r8 ... */
13469e0f06dSSimon Schubert   -1,
13569e0f06dSSimon Schubert   -1,
13669e0f06dSSimon Schubert   -1,				/* ... %r11 */
13769e0f06dSSimon Schubert   4 * 8,			/* %r12 ... */
13869e0f06dSSimon Schubert   5 * 8,
13969e0f06dSSimon Schubert   6 * 8,
14069e0f06dSSimon Schubert   7 * 8,			/* ... %r15 */
14169e0f06dSSimon Schubert   0 * 8				/* %rip */
14269e0f06dSSimon Schubert };
14369e0f06dSSimon Schubert 
14469e0f06dSSimon Schubert static void
amd64dfly_init_abi(struct gdbarch_info info,struct gdbarch * gdbarch)14569e0f06dSSimon Schubert amd64dfly_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
14669e0f06dSSimon Schubert {
14769e0f06dSSimon Schubert   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
14869e0f06dSSimon Schubert 
14969e0f06dSSimon Schubert   i386bsd_init_abi (info, gdbarch);
15069e0f06dSSimon Schubert 
15169e0f06dSSimon Schubert   tdep->gregset_reg_offset = amd64dfly_r_reg_offset;
15269e0f06dSSimon Schubert   tdep->gregset_num_regs = ARRAY_SIZE (amd64dfly_r_reg_offset);
15369e0f06dSSimon Schubert   tdep->sizeof_gregset = 25 * 8;
15469e0f06dSSimon Schubert 
15569e0f06dSSimon Schubert   amd64_init_abi (info, gdbarch);
15669e0f06dSSimon Schubert 
15769e0f06dSSimon Schubert   tdep->sigtramp_start = amd64dfly_sigtramp_start_addr;
15869e0f06dSSimon Schubert   tdep->sigtramp_end = amd64dfly_sigtramp_end_addr;
15969e0f06dSSimon Schubert   tdep->sigcontext_addr = amd64dfly_sigcontext_addr;
16069e0f06dSSimon Schubert   tdep->sc_reg_offset = amd64dfly_sc_reg_offset;
16169e0f06dSSimon Schubert   tdep->sc_num_regs = ARRAY_SIZE (amd64dfly_sc_reg_offset);
16269e0f06dSSimon Schubert 
16369e0f06dSSimon Schubert   set_solib_svr4_fetch_link_map_offsets
16469e0f06dSSimon Schubert     (gdbarch, svr4_lp64_fetch_link_map_offsets);
16569e0f06dSSimon Schubert }
166*e0cb4e00SSascha Wildner 
16769e0f06dSSimon Schubert 
16869e0f06dSSimon Schubert /* Provide a prototype to silence -Wmissing-prototypes.  */
16969e0f06dSSimon Schubert void _initialize_amd64dfly_tdep (void);
17069e0f06dSSimon Schubert 
17169e0f06dSSimon Schubert void
_initialize_amd64dfly_tdep(void)17269e0f06dSSimon Schubert _initialize_amd64dfly_tdep (void)
17369e0f06dSSimon Schubert {
17469e0f06dSSimon Schubert   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
17569e0f06dSSimon Schubert 			  GDB_OSABI_DRAGONFLY, amd64dfly_init_abi);
17669e0f06dSSimon Schubert }
177