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 39static 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 100static void 101ia64_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 124static void 125ia64_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 154void 155fill_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 172void 173fill_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 190void 191supply_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 202void 203supply_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 214static void 215ia64_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 232static void 233ia64_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 250static struct regset gregset = { NULL, ia64_fbsd_supply_gregset }; 251static struct regset fpregset = { NULL, ia64_fbsd_supply_fpregset }; 252 253static const struct regset * 254ia64_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 264static int 265ia64_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 271static void 272ia64_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 284void 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} 290