]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/gdb/gdb/ia64-fbsd-tdep.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / gdb / gdb / ia64-fbsd-tdep.c
1 /*
2  * Copyright (c) 2004 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "defs.h"
28 #include "gdb_string.h"
29 #include "regcache.h"
30 #include "regset.h"
31 #include "solib-svr4.h"
32 #include "value.h"
33
34 #include "ia64-tdep.h"
35
36 #define FPREG_SUPPLIES(r) ((r) >= IA64_FR0_REGNUM && (r) <= IA64_FR127_REGNUM)
37 #define GREG_SUPPLIES(r)  (!FPREG_SUPPLIES(r))
38
39 static int reg_offset[462] = {
40     -1,   96,  248,  256,  152,  160,  168,  176,       /* Regs 0-7. */
41    264,  272,  280,  288,    0,   64,  296,  304,       /* Regs 8-15. */
42    312,  320,  328,  336,  344,  352,  360,  368,       /* Regs 16-23. */
43    376,  384,  392,  400,  408,  416,  424,  432,       /* Regs 24-31. */
44     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 32-39. */
45     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 40-47. */
46     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 48-55. */
47     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 56-63. */
48     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 64-71. */
49     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 72-79. */
50     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 80-87. */
51     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 88-95. */
52     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 96-103. */
53     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 104-111. */
54     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 112-119. */
55     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 120-127. */
56     -1,   -1,    0,   16,   32,   48,  320,  336,       /* Regs 128-135. */
57    352,  368,  384,  400,  416,  432,  448,  464,       /* Regs 136-143. */
58     64,   80,   96,  112,  128,  144,  160,  176,       /* Regs 144-151. */
59    192,  208,  224,  240,  256,  272,  288,  304,       /* Regs 152-159. */
60    480,  496,  512,  528,  544,  560,  576,  592,       /* Regs 160-167. */
61    608,  624,  640,  656,  672,  688,  704,  720,       /* Regs 168-175. */
62    736,  752,  768,  784,  800,  816,  832,  848,       /* Regs 176-183. */
63    864,  880,  896,  912,  928,  944,  960,  976,       /* Regs 184-191. */
64    992, 1008, 1024, 1040, 1056, 1072, 1088, 1104,       /* Regs 192-199. */
65   1120, 1136, 1152, 1168, 1184, 1200, 1216, 1232,       /* Regs 200-207. */
66   1248, 1264, 1280, 1296, 1312, 1328, 1344, 1360,       /* Regs 208-215. */
67   1376, 1392, 1408, 1424, 1440, 1456, 1472, 1488,       /* Regs 216-223. */
68   1504, 1520, 1536, 1552, 1568, 1584, 1600, 1616,       /* Regs 224-231. */
69   1632, 1648, 1664, 1680, 1696, 1712, 1728, 1744,       /* Regs 232-239. */
70   1760, 1776, 1792, 1808, 1824, 1840, 1856, 1872,       /* Regs 240-247. */
71   1888, 1904, 1920, 1936, 1952, 1968, 1984, 2000,       /* Regs 248-255. */
72     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 256-263. */
73     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 264-271. */
74     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 272-279. */
75     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 280-287. */
76     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 288-295. */
77     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 296-303. */
78     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 304-311. */
79     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 312-319. */
80     16,  184,  192,  200,  208,  216,  440,  448,       /* Regs 320-327. */
81     -1,   -1,   24,  120,   88,  112,   -1,   -1,       /* Regs 328-335. */
82     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 336-343. */
83     -1,   -1,   -1,   -1,   -1,   -1,   72,  104,       /* Regs 344-351. */
84     40,   48,   -1,   -1,   -1,   -1,   -1,  464,       /* Regs 352-359. */
85    472,   -1,   -1,   -1,   -1,   -1,  456,   -1,       /* Regs 360-367. */
86     -1,   -1,    8,   -1,   -1,   -1,   80,   -1,       /* Regs 368-375. */
87     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 376-383. */
88     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 384-391. */
89     -1,   -1,   -1,   -1,   -1,   -1,   32,  224,       /* Regs 392-399. */
90     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 400-407. */
91     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 408-415. */
92     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 416-423. */
93     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 424-431. */
94     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 432-439. */
95     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 440-447. */
96     -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,       /* Regs 448-455. */
97     -1,   -1,   -1,   -1,   -1,   -1
98 };
99
100 static void
101 ia64_fbsd_regcache_collect (struct regcache *regcache, int regno,
102                             void *regs)
103 {
104   int ofs;
105
106   if (regno < 0 || regno >= NUM_REGS)
107     return;
108
109   ofs = reg_offset[regno];
110   if (regno == IA64_BSP_REGNUM)
111     {
112       uint64_t bsp, bspstore;
113       regcache_raw_collect (regcache, regno, &bsp);
114       regcache_raw_collect (regcache, IA64_BSPSTORE_REGNUM, &bspstore);
115       *(uint64_t *)((char *)regs + ofs) = bsp - bspstore;
116     }
117   else
118     {
119       if (ofs >= 0)
120         regcache_raw_collect (regcache, regno, (char*)regs + ofs);
121     }
122 }
123
124 static void
125 ia64_fbsd_regcache_supply (struct regcache *regcache, int regno,
126                            const void *regs)
127 {
128   int ofs;
129
130   if (regno < 0 || regno >= NUM_REGS)
131     return;
132
133   ofs = reg_offset[regno];
134   if (regno == IA64_BSP_REGNUM)
135     {
136       /* BSP is synthesized. It's not actually present in struct reg,
137          but can be derived from bspstore and ndirty. The offset of
138          IA64_BSP_REGNUM in the reg_offset array above is that of the
139          ndirty field in struct reg. */
140       uint64_t bsp;
141       bsp = *((uint64_t*)((char *)regs + ofs));         /* ndirty */
142       bsp += *((uint64_t*)((char *)regs + reg_offset[IA64_BSPSTORE_REGNUM]));
143       regcache_raw_supply (regcache, regno, &bsp);
144     }
145   else
146     {
147       if (ofs < 0)
148         regcache_raw_supply (regcache, regno, NULL);
149       else
150         regcache_raw_supply (regcache, regno, (char *)regs + ofs);
151     }
152 }
153
154 void
155 fill_fpregset (void *fpregs, int regno)
156 {
157   if (regno == -1)
158     {
159       for (regno = 0; regno < NUM_REGS; regno++)
160         {
161           if (FPREG_SUPPLIES(regno))
162             ia64_fbsd_regcache_collect (current_regcache, regno, fpregs);
163         }
164     }
165   else
166     {
167       if (FPREG_SUPPLIES(regno))
168         ia64_fbsd_regcache_collect (current_regcache, regno, fpregs);
169     }
170 }
171
172 void
173 fill_gregset (void *gregs, int regno)
174 {
175   if (regno == -1)
176     {
177       for (regno = 0; regno < NUM_REGS; regno++)
178         {
179           if (GREG_SUPPLIES(regno))
180             ia64_fbsd_regcache_collect (current_regcache, regno, gregs);
181         }
182     }
183   else
184     {
185       if (GREG_SUPPLIES(regno))
186         ia64_fbsd_regcache_collect (current_regcache, regno, gregs);
187     }
188 }
189
190 void
191 supply_fpregset (const void *fpregs)
192 {
193   int regno;
194
195   for (regno = 0; regno < NUM_REGS; regno++)
196     {
197       if (FPREG_SUPPLIES(regno))
198         ia64_fbsd_regcache_supply (current_regcache, regno, fpregs);
199     }
200 }
201
202 void
203 supply_gregset (const void *gregs)
204 {
205   int regno;
206
207   for (regno = 0; regno < NUM_REGS; regno++)
208     {
209       if (GREG_SUPPLIES(regno))
210         ia64_fbsd_regcache_supply (current_regcache, regno, gregs);
211     }
212 }
213
214 static void
215 ia64_fbsd_supply_gregset (const struct regset *regset,
216                           struct regcache *regcache, int regno,
217                           const void *gregs, size_t len)
218 {
219   if (regno == -1)
220     {
221       for (regno = 0; regno < NUM_REGS; regno++)
222         {
223           if (GREG_SUPPLIES(regno))
224             ia64_fbsd_regcache_supply (regcache, regno, gregs);
225         }
226     }
227   else
228     if (GREG_SUPPLIES(regno))
229       ia64_fbsd_regcache_supply (regcache, regno, gregs);
230 }
231
232 static void
233 ia64_fbsd_supply_fpregset (const struct regset *regset,
234                            struct regcache *regcache, int regno,
235                            const void *fpregs, size_t len)
236 {
237   if (regno == -1)
238     {
239       for (regno = 0; regno < NUM_REGS; regno++)
240         {
241           if (FPREG_SUPPLIES(regno))
242             ia64_fbsd_regcache_supply (regcache, regno, fpregs);
243         }
244     }
245   else
246     if (FPREG_SUPPLIES(regno))
247       ia64_fbsd_regcache_supply (regcache, regno, fpregs);
248 }
249
250 static struct regset gregset = { NULL, ia64_fbsd_supply_gregset };
251 static struct regset fpregset = { NULL, ia64_fbsd_supply_fpregset };
252
253 static const struct regset *
254 ia64_fbsd_regset_from_core_section (struct gdbarch *gdbarch,
255                                     const char *sect_name, size_t sect_size)
256 {
257   if (strcmp (sect_name, ".reg") == 0)
258     return (&gregset);
259   if (strcmp (sect_name, ".reg2") == 0)
260     return (&fpregset);
261   return (NULL);
262 }
263
264 static int
265 ia64_fbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
266 {
267   uint64_t gwpage = 5ULL << 61;
268   return (pc >= gwpage && pc < (gwpage + 8192)) ? 1 : 0;
269 }
270
271 static void
272 ia64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
273 {
274   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
275
276   set_gdbarch_pc_in_sigtramp (gdbarch, ia64_fbsd_pc_in_sigtramp);
277   set_gdbarch_regset_from_core_section (gdbarch,
278                                         ia64_fbsd_regset_from_core_section);
279   set_solib_svr4_fetch_link_map_offsets (gdbarch,
280                                          svr4_lp64_fetch_link_map_offsets);
281   tdep->find_global_pointer = ia64_generic_find_global_pointer;
282 }
283
284 void
285 _initialize_ia64_fbsd_tdep (void)
286 {
287   gdbarch_register_osabi (bfd_arch_ia64, 0ul, GDB_OSABI_FREEBSD_ELF,
288                           ia64_fbsd_init_abi);
289 }