1 /* Target-dependent mdebug code for the ALPHA architecture. 2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 3 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 2 of the License, or 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 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #include "defs.h" 23 #include "frame.h" 24 #include "frame-unwind.h" 25 #include "frame-base.h" 26 #include "symtab.h" 27 #include "gdbcore.h" 28 #include "block.h" 29 #include "gdb_assert.h" 30 31 #include "alpha-tdep.h" 32 33 /* FIXME: Some of this code should perhaps be merged with mips. */ 34 35 /* *INDENT-OFF* */ 36 /* Layout of a stack frame on the alpha: 37 38 | | 39 pdr members: | 7th ... nth arg, | 40 | `pushed' by caller. | 41 | | 42 ----------------|-------------------------------|<-- old_sp == vfp 43 ^ ^ ^ ^ | | 44 | | | | | | 45 | |localoff | Copies of 1st .. 6th | 46 | | | | | argument if necessary. | 47 | | | v | | 48 | | | --- |-------------------------------|<-- LOCALS_ADDRESS 49 | | | | | 50 | | | | Locals and temporaries. | 51 | | | | | 52 | | | |-------------------------------| 53 | | | | | 54 |-fregoffset | Saved float registers. | 55 | | | | F9 | 56 | | | | . | 57 | | | | . | 58 | | | | F2 | 59 | | v | | 60 | | -------|-------------------------------| 61 | | | | 62 | | | Saved registers. | 63 | | | S6 | 64 |-regoffset | . | 65 | | | . | 66 | | | S0 | 67 | | | pdr.pcreg | 68 | v | | 69 | ----------|-------------------------------| 70 | | | 71 frameoffset | Argument build area, gets | 72 | | 7th ... nth arg for any | 73 | | called procedure. | 74 v | | 75 -------------|-------------------------------|<-- sp 76 | | 77 */ 78 /* *INDENT-ON* */ 79 80 #define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) 81 #define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) 82 #define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) 83 #define PROC_REG_MASK(proc) ((proc)->pdr.regmask) 84 #define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) 85 #define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) 86 #define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) 87 #define PROC_PC_REG(proc) ((proc)->pdr.pcreg) 88 #define PROC_LOCALOFF(proc) ((proc)->pdr.localoff) 89 90 /* Locate the mdebug PDR for the given PC. Return null if one can't 91 be found; you'll have to fall back to other methods in that case. */ 92 93 static alpha_extra_func_info_t 94 find_proc_desc (CORE_ADDR pc) 95 { 96 struct block *b = block_for_pc (pc); 97 alpha_extra_func_info_t proc_desc = NULL; 98 struct symbol *sym = NULL; 99 100 if (b) 101 { 102 CORE_ADDR startaddr; 103 find_pc_partial_function (pc, NULL, &startaddr, NULL); 104 105 if (startaddr > BLOCK_START (b)) 106 /* This is the "pathological" case referred to in a comment in 107 print_frame_info. It might be better to move this check into 108 symbol reading. */ 109 sym = NULL; 110 else 111 sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL); 112 } 113 114 if (sym) 115 { 116 proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym); 117 118 /* If we never found a PDR for this function in symbol reading, 119 then examine prologues to find the information. */ 120 if (proc_desc->pdr.framereg == -1) 121 proc_desc = NULL; 122 } 123 124 return proc_desc; 125 } 126 127 /* This returns the PC of the first inst after the prologue. If we can't 128 find the prologue, then return 0. */ 129 130 static CORE_ADDR 131 alpha_mdebug_after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) 132 { 133 if (proc_desc) 134 { 135 /* If function is frameless, then we need to do it the hard way. I 136 strongly suspect that frameless always means prologueless... */ 137 if (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM 138 && PROC_FRAME_OFFSET (proc_desc) == 0) 139 return 0; 140 } 141 142 return alpha_after_prologue (pc); 143 } 144 145 /* Return non-zero if we *might* be in a function prologue. Return zero 146 if we are definitively *not* in a function prologue. */ 147 148 static int 149 alpha_mdebug_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc) 150 { 151 CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc); 152 return (after_prologue_pc == 0 || pc < after_prologue_pc); 153 } 154 155 156 /* Frame unwinder that reads mdebug PDRs. */ 157 158 struct alpha_mdebug_unwind_cache 159 { 160 alpha_extra_func_info_t proc_desc; 161 CORE_ADDR vfp; 162 CORE_ADDR *saved_regs; 163 }; 164 165 /* Extract all of the information about the frame from PROC_DESC 166 and store the resulting register save locations in the structure. */ 167 168 static struct alpha_mdebug_unwind_cache * 169 alpha_mdebug_frame_unwind_cache (struct frame_info *next_frame, 170 void **this_prologue_cache) 171 { 172 struct alpha_mdebug_unwind_cache *info; 173 alpha_extra_func_info_t proc_desc; 174 ULONGEST vfp; 175 CORE_ADDR pc, reg_position; 176 unsigned long mask; 177 int ireg, returnreg; 178 179 if (*this_prologue_cache) 180 return *this_prologue_cache; 181 182 info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache); 183 *this_prologue_cache = info; 184 pc = frame_pc_unwind (next_frame); 185 186 /* ??? We don't seem to be able to cache the lookup of the PDR 187 from alpha_mdebug_frame_p. It'd be nice if we could change 188 the arguments to that function. Oh well. */ 189 proc_desc = find_proc_desc (pc); 190 info->proc_desc = proc_desc; 191 gdb_assert (proc_desc != NULL); 192 193 info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); 194 195 /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */ 196 frame_unwind_unsigned_register (next_frame, PROC_FRAME_REG (proc_desc), &vfp); 197 vfp += PROC_FRAME_OFFSET (info->proc_desc); 198 info->vfp = vfp; 199 200 /* Fill in the offsets for the registers which gen_mask says were saved. */ 201 202 reg_position = vfp + PROC_REG_OFFSET (proc_desc); 203 mask = PROC_REG_MASK (proc_desc); 204 returnreg = PROC_PC_REG (proc_desc); 205 206 /* Note that RA is always saved first, regardless of its actual 207 register number. */ 208 if (mask & (1 << returnreg)) 209 { 210 /* Clear bit for RA so we don't save it again later. */ 211 mask &= ~(1 << returnreg); 212 213 info->saved_regs[returnreg] = reg_position; 214 reg_position += 8; 215 } 216 217 for (ireg = 0; ireg <= 31; ++ireg) 218 if (mask & (1 << ireg)) 219 { 220 info->saved_regs[ireg] = reg_position; 221 reg_position += 8; 222 } 223 224 reg_position = vfp + PROC_FREG_OFFSET (proc_desc); 225 mask = PROC_FREG_MASK (proc_desc); 226 227 for (ireg = 0; ireg <= 31; ++ireg) 228 if (mask & (1 << ireg)) 229 { 230 info->saved_regs[ALPHA_FP0_REGNUM + ireg] = reg_position; 231 reg_position += 8; 232 } 233 234 return info; 235 } 236 237 /* Given a GDB frame, determine the address of the calling function's 238 frame. This will be used to create a new GDB frame struct. */ 239 240 static void 241 alpha_mdebug_frame_this_id (struct frame_info *next_frame, 242 void **this_prologue_cache, 243 struct frame_id *this_id) 244 { 245 struct alpha_mdebug_unwind_cache *info 246 = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); 247 248 *this_id = frame_id_build (info->vfp, frame_func_unwind (next_frame)); 249 } 250 251 /* Retrieve the value of REGNUM in FRAME. Don't give up! */ 252 253 static void 254 alpha_mdebug_frame_prev_register (struct frame_info *next_frame, 255 void **this_prologue_cache, 256 int regnum, int *optimizedp, 257 enum lval_type *lvalp, CORE_ADDR *addrp, 258 int *realnump, void *bufferp) 259 { 260 struct alpha_mdebug_unwind_cache *info 261 = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); 262 263 /* The PC of the previous frame is stored in the link register of 264 the current frame. Frob regnum so that we pull the value from 265 the correct place. */ 266 if (regnum == ALPHA_PC_REGNUM) 267 regnum = PROC_PC_REG (info->proc_desc); 268 269 /* For all registers known to be saved in the current frame, 270 do the obvious and pull the value out. */ 271 if (info->saved_regs[regnum]) 272 { 273 *optimizedp = 0; 274 *lvalp = lval_memory; 275 *addrp = info->saved_regs[regnum]; 276 *realnump = -1; 277 if (bufferp != NULL) 278 get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE); 279 return; 280 } 281 282 /* The stack pointer of the previous frame is computed by popping 283 the current stack frame. */ 284 if (regnum == ALPHA_SP_REGNUM) 285 { 286 *optimizedp = 0; 287 *lvalp = not_lval; 288 *addrp = 0; 289 *realnump = -1; 290 if (bufferp != NULL) 291 store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp); 292 return; 293 } 294 295 /* Otherwise assume the next frame has the same register value. */ 296 frame_register (next_frame, regnum, optimizedp, lvalp, addrp, 297 realnump, bufferp); 298 } 299 300 static const struct frame_unwind alpha_mdebug_frame_unwind = { 301 NORMAL_FRAME, 302 alpha_mdebug_frame_this_id, 303 alpha_mdebug_frame_prev_register 304 }; 305 306 const struct frame_unwind * 307 alpha_mdebug_frame_sniffer (struct frame_info *next_frame) 308 { 309 CORE_ADDR pc = frame_pc_unwind (next_frame); 310 alpha_extra_func_info_t proc_desc; 311 312 /* If this PC does not map to a PDR, then clearly this isn't an 313 mdebug frame. */ 314 proc_desc = find_proc_desc (pc); 315 if (proc_desc == NULL) 316 return NULL; 317 318 /* If we're in the prologue, the PDR for this frame is not yet valid. 319 Say no here and we'll fall back on the heuristic unwinder. */ 320 if (alpha_mdebug_in_prologue (pc, proc_desc)) 321 return NULL; 322 323 return &alpha_mdebug_frame_unwind; 324 } 325 326 static CORE_ADDR 327 alpha_mdebug_frame_base_address (struct frame_info *next_frame, 328 void **this_prologue_cache) 329 { 330 struct alpha_mdebug_unwind_cache *info 331 = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); 332 333 return info->vfp; 334 } 335 336 static CORE_ADDR 337 alpha_mdebug_frame_locals_address (struct frame_info *next_frame, 338 void **this_prologue_cache) 339 { 340 struct alpha_mdebug_unwind_cache *info 341 = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); 342 343 return info->vfp - PROC_LOCALOFF (info->proc_desc); 344 } 345 346 static CORE_ADDR 347 alpha_mdebug_frame_args_address (struct frame_info *next_frame, 348 void **this_prologue_cache) 349 { 350 struct alpha_mdebug_unwind_cache *info 351 = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache); 352 353 return info->vfp - ALPHA_NUM_ARG_REGS * 8; 354 } 355 356 static const struct frame_base alpha_mdebug_frame_base = { 357 &alpha_mdebug_frame_unwind, 358 alpha_mdebug_frame_base_address, 359 alpha_mdebug_frame_locals_address, 360 alpha_mdebug_frame_args_address 361 }; 362 363 static const struct frame_base * 364 alpha_mdebug_frame_base_sniffer (struct frame_info *next_frame) 365 { 366 CORE_ADDR pc = frame_pc_unwind (next_frame); 367 alpha_extra_func_info_t proc_desc; 368 369 /* If this PC does not map to a PDR, then clearly this isn't an 370 mdebug frame. */ 371 proc_desc = find_proc_desc (pc); 372 if (proc_desc == NULL) 373 return NULL; 374 375 return &alpha_mdebug_frame_base; 376 } 377 378 379 void 380 alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 381 { 382 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 383 384 frame_unwind_append_sniffer (gdbarch, alpha_mdebug_frame_sniffer); 385 frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer); 386 } 387