gdb/testsuite/
[deliverable/binutils-gdb.git] / gdb / mips64obsd-tdep.c
CommitLineData
abc08782
MK
1/* Target-dependent code for OpenBSD/mips64.
2
28e7fd62 3 Copyright (C) 2004-2013 Free Software Foundation, Inc.
abc08782
MK
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
abc08782
MK
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
abc08782
MK
19
20#include "defs.h"
89fa5cc8 21#include "gdbtypes.h"
abc08782
MK
22#include "osabi.h"
23#include "regcache.h"
24#include "regset.h"
8e763687
MK
25#include "trad-frame.h"
26#include "tramp-frame.h"
abc08782 27
8e763687 28#include "gdb_assert.h"
abc08782
MK
29#include "gdb_string.h"
30
31#include "mips-tdep.h"
32#include "solib-svr4.h"
33
89fa5cc8
MK
34/* The MIPS64 Floating-Point Quad-Precision format is similar to
35 big-endian IA-64 Quad-Precision format. */
36#define floatformats_mips64_quad floatformats_ia64_quad
37
abc08782
MK
38#define MIPS64OBSD_NUM_REGS 73
39
40/* Core file support. */
41
42/* Supply register REGNUM from the buffer specified by GREGS and LEN
43 in the general-purpose register set REGSET to register cache
44 REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
45
46static void
47mips64obsd_supply_gregset (const struct regset *regset,
48 struct regcache *regcache, int regnum,
49 const void *gregs, size_t len)
50{
51 const char *regs = gregs;
52 int i;
53
54 for (i = 0; i < MIPS64OBSD_NUM_REGS; i++)
55 {
56 if (regnum == i || regnum == -1)
57 regcache_raw_supply (regcache, i, regs + i * 8);
58 }
59}
60
61/* OpenBSD/mips64 register set. */
62
63static struct regset mips64obsd_gregset =
64{
65 NULL,
66 mips64obsd_supply_gregset
67};
68
69/* Return the appropriate register set for the core section identified
70 by SECT_NAME and SECT_SIZE. */
71
72static const struct regset *
73mips64obsd_regset_from_core_section (struct gdbarch *gdbarch,
74 const char *sect_name, size_t sect_size)
75{
76 if (strcmp (sect_name, ".reg") == 0 && sect_size >= MIPS64OBSD_NUM_REGS * 8)
77 return &mips64obsd_gregset;
78
79 return NULL;
80}
81\f
82
8e763687
MK
83/* Signal trampolines. */
84
85static void
86mips64obsd_sigframe_init (const struct tramp_frame *self,
b8a22b94 87 struct frame_info *this_frame,
8e763687
MK
88 struct trad_frame_cache *cache,
89 CORE_ADDR func)
90{
b8a22b94 91 struct gdbarch *gdbarch = get_frame_arch (this_frame);
8e763687
MK
92 CORE_ADDR sp, sigcontext_addr, addr;
93 int regnum;
94
95 /* We find the appropriate instance of `struct sigcontext' at a
96 fixed offset in the signal frame. */
b8a22b94
DJ
97 sp = get_frame_register_signed (this_frame,
98 MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
8e763687
MK
99 sigcontext_addr = sp + 32;
100
101 /* PC. */
102 regnum = mips_regnum (gdbarch)->pc;
f57d151a 103 trad_frame_set_reg_addr (cache,
2eb4d78b 104 regnum + gdbarch_num_regs (gdbarch),
f57d151a 105 sigcontext_addr + 16);
8e763687
MK
106
107 /* GPRs. */
108 for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32;
109 regnum <= MIPS_RA_REGNUM; regnum++, addr += 8)
f57d151a 110 trad_frame_set_reg_addr (cache,
2eb4d78b 111 regnum + gdbarch_num_regs (gdbarch),
f57d151a 112 addr);
8e763687
MK
113
114 /* HI and LO. */
115 regnum = mips_regnum (gdbarch)->lo;
f57d151a 116 trad_frame_set_reg_addr (cache,
2eb4d78b 117 regnum + gdbarch_num_regs (gdbarch),
f57d151a 118 sigcontext_addr + 280);
8e763687 119 regnum = mips_regnum (gdbarch)->hi;
f57d151a 120 trad_frame_set_reg_addr (cache,
2eb4d78b 121 regnum + gdbarch_num_regs (gdbarch),
f57d151a 122 sigcontext_addr + 288);
8e763687
MK
123
124 /* TODO: Handle the floating-point registers. */
125
126 trad_frame_set_id (cache, frame_id_build (sp, func));
127}
128
129static const struct tramp_frame mips64obsd_sigframe =
130{
131 SIGTRAMP_FRAME,
132 MIPS_INSN32_SIZE,
133 {
134 { 0x67a40020, -1 }, /* daddiu a0,sp,32 */
135 { 0x24020067, -1 }, /* li v0,103 */
136 { 0x0000000c, -1 }, /* syscall */
137 { 0x0000000d, -1 }, /* break */
138 { TRAMP_SENTINEL_INSN, -1 }
139 },
140 mips64obsd_sigframe_init
141};
142
143\f
abc08782
MK
144static void
145mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
146{
8e763687
MK
147 /* OpenBSD/mips64 only supports the n64 ABI, but the braindamaged
148 way GDB works, forces us to pretend we can handle them all. */
149
abc08782
MK
150 set_gdbarch_regset_from_core_section
151 (gdbarch, mips64obsd_regset_from_core_section);
152
8e763687
MK
153 tramp_frame_prepend_unwinder (gdbarch, &mips64obsd_sigframe);
154
89fa5cc8
MK
155 set_gdbarch_long_double_bit (gdbarch, 128);
156 set_gdbarch_long_double_format (gdbarch, floatformats_mips64_quad);
157
8e763687 158 /* OpenBSD/mips64 has SVR4-style shared libraries. */
abc08782
MK
159 set_solib_svr4_fetch_link_map_offsets
160 (gdbarch, svr4_lp64_fetch_link_map_offsets);
161}
162
163\f
164/* Provide a prototype to silence -Wmissing-prototypes. */
165void _initialize_mips64obsd_tdep (void);
166
167void
168_initialize_mips64obsd_tdep (void)
169{
170 gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD_ELF,
171 mips64obsd_init_abi);
172}
This page took 0.694841 seconds and 4 git commands to generate.