1131082Smarcel/* 2131082Smarcel * Copyright (c) 2004 Marcel Moolenaar 3131082Smarcel * All rights reserved. 4131082Smarcel * 5131082Smarcel * Redistribution and use in source and binary forms, with or without 6131082Smarcel * modification, are permitted provided that the following conditions 7131082Smarcel * are met: 8131082Smarcel * 9131082Smarcel * 1. Redistributions of source code must retain the above copyright 10131082Smarcel * notice, this list of conditions and the following disclaimer. 11131082Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12131082Smarcel * notice, this list of conditions and the following disclaimer in the 13131082Smarcel * documentation and/or other materials provided with the distribution. 14131082Smarcel * 15131082Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16131082Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17131082Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18131082Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19131082Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20131082Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21131082Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22131082Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23131082Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24131082Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25131082Smarcel */ 26131082Smarcel 27131082Smarcel#include "defs.h" 28131082Smarcel#include "gdb_string.h" 29131082Smarcel#include "regcache.h" 30131082Smarcel#include "regset.h" 31131082Smarcel#include "solib-svr4.h" 32131082Smarcel#include "value.h" 33131082Smarcel 34131082Smarcel#include "ia64-tdep.h" 35131082Smarcel 36131082Smarcel#define FPREG_SUPPLIES(r) ((r) >= IA64_FR0_REGNUM && (r) <= IA64_FR127_REGNUM) 37131082Smarcel#define GREG_SUPPLIES(r) (!FPREG_SUPPLIES(r)) 38131082Smarcel 39131082Smarcelstatic int reg_offset[462] = { 40131082Smarcel -1, 96, 248, 256, 152, 160, 168, 176, /* Regs 0-7. */ 41131082Smarcel 264, 272, 280, 288, 0, 64, 296, 304, /* Regs 8-15. */ 42131082Smarcel 312, 320, 328, 336, 344, 352, 360, 368, /* Regs 16-23. */ 43131082Smarcel 376, 384, 392, 400, 408, 416, 424, 432, /* Regs 24-31. */ 44131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 32-39. */ 45131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 40-47. */ 46131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 48-55. */ 47131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 56-63. */ 48131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 64-71. */ 49131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 72-79. */ 50131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 80-87. */ 51131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 88-95. */ 52131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 96-103. */ 53131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 104-111. */ 54131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 112-119. */ 55131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 120-127. */ 56131082Smarcel -1, -1, 0, 16, 32, 48, 320, 336, /* Regs 128-135. */ 57131082Smarcel 352, 368, 384, 400, 416, 432, 448, 464, /* Regs 136-143. */ 58131082Smarcel 64, 80, 96, 112, 128, 144, 160, 176, /* Regs 144-151. */ 59131082Smarcel 192, 208, 224, 240, 256, 272, 288, 304, /* Regs 152-159. */ 60131082Smarcel 480, 496, 512, 528, 544, 560, 576, 592, /* Regs 160-167. */ 61131082Smarcel 608, 624, 640, 656, 672, 688, 704, 720, /* Regs 168-175. */ 62131082Smarcel 736, 752, 768, 784, 800, 816, 832, 848, /* Regs 176-183. */ 63131082Smarcel 864, 880, 896, 912, 928, 944, 960, 976, /* Regs 184-191. */ 64131082Smarcel 992, 1008, 1024, 1040, 1056, 1072, 1088, 1104, /* Regs 192-199. */ 65131082Smarcel 1120, 1136, 1152, 1168, 1184, 1200, 1216, 1232, /* Regs 200-207. */ 66131082Smarcel 1248, 1264, 1280, 1296, 1312, 1328, 1344, 1360, /* Regs 208-215. */ 67131082Smarcel 1376, 1392, 1408, 1424, 1440, 1456, 1472, 1488, /* Regs 216-223. */ 68131082Smarcel 1504, 1520, 1536, 1552, 1568, 1584, 1600, 1616, /* Regs 224-231. */ 69131082Smarcel 1632, 1648, 1664, 1680, 1696, 1712, 1728, 1744, /* Regs 232-239. */ 70131082Smarcel 1760, 1776, 1792, 1808, 1824, 1840, 1856, 1872, /* Regs 240-247. */ 71131082Smarcel 1888, 1904, 1920, 1936, 1952, 1968, 1984, 2000, /* Regs 248-255. */ 72131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 256-263. */ 73131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 264-271. */ 74131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 272-279. */ 75131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 280-287. */ 76131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 288-295. */ 77131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 296-303. */ 78131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 304-311. */ 79131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 312-319. */ 80131082Smarcel 16, 184, 192, 200, 208, 216, 440, 448, /* Regs 320-327. */ 81131082Smarcel -1, -1, 24, 120, 88, 112, -1, -1, /* Regs 328-335. */ 82131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 336-343. */ 83131082Smarcel -1, -1, -1, -1, -1, -1, 72, 104, /* Regs 344-351. */ 84131082Smarcel 40, 48, -1, -1, -1, -1, -1, 464, /* Regs 352-359. */ 85131082Smarcel 472, -1, -1, -1, -1, -1, 456, -1, /* Regs 360-367. */ 86131082Smarcel -1, -1, 8, -1, -1, -1, 80, -1, /* Regs 368-375. */ 87131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 376-383. */ 88131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 384-391. */ 89131082Smarcel -1, -1, -1, -1, -1, -1, 32, 224, /* Regs 392-399. */ 90131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 400-407. */ 91131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 408-415. */ 92131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 416-423. */ 93131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 424-431. */ 94131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 432-439. */ 95131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 440-447. */ 96131082Smarcel -1, -1, -1, -1, -1, -1, -1, -1, /* Regs 448-455. */ 97131082Smarcel -1, -1, -1, -1, -1, -1 98131082Smarcel}; 99131082Smarcel 100131082Smarcelstatic void 101131082Smarcelia64_fbsd_regcache_collect (struct regcache *regcache, int regno, 102131082Smarcel void *regs) 103131082Smarcel{ 104131082Smarcel int ofs; 105131082Smarcel 106131082Smarcel if (regno < 0 || regno >= NUM_REGS) 107131082Smarcel return; 108131082Smarcel 109131082Smarcel ofs = reg_offset[regno]; 110132685Smarcel if (regno == IA64_BSP_REGNUM) 111132685Smarcel { 112132685Smarcel uint64_t bsp, bspstore; 113132685Smarcel regcache_raw_collect (regcache, regno, &bsp); 114132685Smarcel regcache_raw_collect (regcache, IA64_BSPSTORE_REGNUM, &bspstore); 115132685Smarcel *(uint64_t *)((char *)regs + ofs) = bsp - bspstore; 116132685Smarcel } 117132685Smarcel else 118132685Smarcel { 119132685Smarcel if (ofs >= 0) 120132685Smarcel regcache_raw_collect (regcache, regno, (char*)regs + ofs); 121132685Smarcel } 122131082Smarcel} 123131082Smarcel 124131082Smarcelstatic void 125131082Smarcelia64_fbsd_regcache_supply (struct regcache *regcache, int regno, 126131082Smarcel const void *regs) 127131082Smarcel{ 128131082Smarcel int ofs; 129131082Smarcel 130131082Smarcel if (regno < 0 || regno >= NUM_REGS) 131131082Smarcel return; 132131082Smarcel 133131082Smarcel ofs = reg_offset[regno]; 134131082Smarcel if (regno == IA64_BSP_REGNUM) 135131082Smarcel { 136131082Smarcel /* BSP is synthesized. It's not actually present in struct reg, 137131082Smarcel but can be derived from bspstore and ndirty. The offset of 138131082Smarcel IA64_BSP_REGNUM in the reg_offset array above is that of the 139131082Smarcel ndirty field in struct reg. */ 140131082Smarcel uint64_t bsp; 141131082Smarcel bsp = *((uint64_t*)((char *)regs + ofs)); /* ndirty */ 142131082Smarcel bsp += *((uint64_t*)((char *)regs + reg_offset[IA64_BSPSTORE_REGNUM])); 143131082Smarcel regcache_raw_supply (regcache, regno, &bsp); 144131082Smarcel } 145131082Smarcel else 146131082Smarcel { 147131082Smarcel if (ofs < 0) 148131082Smarcel regcache_raw_supply (regcache, regno, NULL); 149131082Smarcel else 150131082Smarcel regcache_raw_supply (regcache, regno, (char *)regs + ofs); 151131082Smarcel } 152131082Smarcel} 153131082Smarcel 154131082Smarcelvoid 155131082Smarcelfill_fpregset (void *fpregs, int regno) 156131082Smarcel{ 157131082Smarcel if (regno == -1) 158131082Smarcel { 159131082Smarcel for (regno = 0; regno < NUM_REGS; regno++) 160131082Smarcel { 161131082Smarcel if (FPREG_SUPPLIES(regno)) 162131082Smarcel ia64_fbsd_regcache_collect (current_regcache, regno, fpregs); 163131082Smarcel } 164131082Smarcel } 165131082Smarcel else 166131082Smarcel { 167131082Smarcel if (FPREG_SUPPLIES(regno)) 168131082Smarcel ia64_fbsd_regcache_collect (current_regcache, regno, fpregs); 169131082Smarcel } 170131082Smarcel} 171131082Smarcel 172131082Smarcelvoid 173131082Smarcelfill_gregset (void *gregs, int regno) 174131082Smarcel{ 175131082Smarcel if (regno == -1) 176131082Smarcel { 177131082Smarcel for (regno = 0; regno < NUM_REGS; regno++) 178131082Smarcel { 179131082Smarcel if (GREG_SUPPLIES(regno)) 180131082Smarcel ia64_fbsd_regcache_collect (current_regcache, regno, gregs); 181131082Smarcel } 182131082Smarcel } 183131082Smarcel else 184131082Smarcel { 185131082Smarcel if (GREG_SUPPLIES(regno)) 186131082Smarcel ia64_fbsd_regcache_collect (current_regcache, regno, gregs); 187131082Smarcel } 188131082Smarcel} 189131082Smarcel 190131082Smarcelvoid 191132685Smarcelsupply_fpregset (const void *fpregs) 192131082Smarcel{ 193132685Smarcel int regno; 194132685Smarcel 195132685Smarcel for (regno = 0; regno < NUM_REGS; regno++) 196131082Smarcel { 197131082Smarcel if (FPREG_SUPPLIES(regno)) 198131082Smarcel ia64_fbsd_regcache_supply (current_regcache, regno, fpregs); 199131082Smarcel } 200131082Smarcel} 201131082Smarcel 202131082Smarcelvoid 203132685Smarcelsupply_gregset (const void *gregs) 204131082Smarcel{ 205132685Smarcel int regno; 206132685Smarcel 207132685Smarcel for (regno = 0; regno < NUM_REGS; regno++) 208131082Smarcel { 209131082Smarcel if (GREG_SUPPLIES(regno)) 210131082Smarcel ia64_fbsd_regcache_supply (current_regcache, regno, gregs); 211131082Smarcel } 212131082Smarcel} 213131082Smarcel 214131082Smarcelstatic void 215131082Smarcelia64_fbsd_supply_gregset (const struct regset *regset, 216131082Smarcel struct regcache *regcache, int regno, 217131082Smarcel const void *gregs, size_t len) 218131082Smarcel{ 219131082Smarcel if (regno == -1) 220131082Smarcel { 221131082Smarcel for (regno = 0; regno < NUM_REGS; regno++) 222131082Smarcel { 223131082Smarcel if (GREG_SUPPLIES(regno)) 224131082Smarcel ia64_fbsd_regcache_supply (regcache, regno, gregs); 225131082Smarcel } 226131082Smarcel } 227131082Smarcel else 228131082Smarcel if (GREG_SUPPLIES(regno)) 229131082Smarcel ia64_fbsd_regcache_supply (regcache, regno, gregs); 230131082Smarcel} 231131082Smarcel 232131082Smarcelstatic void 233131082Smarcelia64_fbsd_supply_fpregset (const struct regset *regset, 234131082Smarcel struct regcache *regcache, int regno, 235131082Smarcel const void *fpregs, size_t len) 236131082Smarcel{ 237131082Smarcel if (regno == -1) 238131082Smarcel { 239131082Smarcel for (regno = 0; regno < NUM_REGS; regno++) 240131082Smarcel { 241131082Smarcel if (FPREG_SUPPLIES(regno)) 242131082Smarcel ia64_fbsd_regcache_supply (regcache, regno, fpregs); 243131082Smarcel } 244131082Smarcel } 245131082Smarcel else 246131082Smarcel if (FPREG_SUPPLIES(regno)) 247131082Smarcel ia64_fbsd_regcache_supply (regcache, regno, fpregs); 248131082Smarcel} 249131082Smarcel 250131082Smarcelstatic struct regset gregset = { NULL, ia64_fbsd_supply_gregset }; 251131082Smarcelstatic struct regset fpregset = { NULL, ia64_fbsd_supply_fpregset }; 252131082Smarcel 253131082Smarcelstatic const struct regset * 254131082Smarcelia64_fbsd_regset_from_core_section (struct gdbarch *gdbarch, 255131082Smarcel const char *sect_name, size_t sect_size) 256131082Smarcel{ 257131082Smarcel if (strcmp (sect_name, ".reg") == 0) 258131082Smarcel return (&gregset); 259131082Smarcel if (strcmp (sect_name, ".reg2") == 0) 260131082Smarcel return (&fpregset); 261131082Smarcel return (NULL); 262131082Smarcel} 263131082Smarcel 264131082Smarcelstatic int 265131082Smarcelia64_fbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) 266131082Smarcel{ 267131082Smarcel uint64_t gwpage = 5ULL << 61; 268131082Smarcel return (pc >= gwpage && pc < (gwpage + 8192)) ? 1 : 0; 269131082Smarcel} 270131082Smarcel 271131082Smarcelstatic void 272131082Smarcelia64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 273131082Smarcel{ 274131082Smarcel struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 275131082Smarcel 276131082Smarcel set_gdbarch_pc_in_sigtramp (gdbarch, ia64_fbsd_pc_in_sigtramp); 277131082Smarcel set_gdbarch_regset_from_core_section (gdbarch, 278131082Smarcel ia64_fbsd_regset_from_core_section); 279131082Smarcel set_solib_svr4_fetch_link_map_offsets (gdbarch, 280131082Smarcel svr4_lp64_fetch_link_map_offsets); 281131082Smarcel tdep->find_global_pointer = ia64_generic_find_global_pointer; 282131082Smarcel} 283131082Smarcel 284131082Smarcelvoid 285131082Smarcel_initialize_ia64_fbsd_tdep (void) 286131082Smarcel{ 287131082Smarcel gdbarch_register_osabi (bfd_arch_ia64, 0ul, GDB_OSABI_FREEBSD_ELF, 288131082Smarcel ia64_fbsd_init_abi); 289131082Smarcel} 290