GDB (API)
|
00001 /* Target-dependent mdebug code for the ALPHA architecture. 00002 Copyright (C) 1993-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 #include "defs.h" 00020 #include "frame.h" 00021 #include "frame-unwind.h" 00022 #include "frame-base.h" 00023 #include "symtab.h" 00024 #include "gdbcore.h" 00025 #include "block.h" 00026 #include "gdb_assert.h" 00027 #include "gdb_string.h" 00028 #include "trad-frame.h" 00029 00030 #include "alpha-tdep.h" 00031 #include "mdebugread.h" 00032 00033 /* FIXME: Some of this code should perhaps be merged with mips. */ 00034 00035 /* *INDENT-OFF* */ 00036 /* Layout of a stack frame on the alpha: 00037 00038 | | 00039 pdr members: | 7th ... nth arg, | 00040 | `pushed' by caller. | 00041 | | 00042 ----------------|-------------------------------|<-- old_sp == vfp 00043 ^ ^ ^ ^ | | 00044 | | | | | | 00045 | |localoff | Copies of 1st .. 6th | 00046 | | | | | argument if necessary. | 00047 | | | v | | 00048 | | | --- |-------------------------------|<-- LOCALS_ADDRESS 00049 | | | | | 00050 | | | | Locals and temporaries. | 00051 | | | | | 00052 | | | |-------------------------------| 00053 | | | | | 00054 |-fregoffset | Saved float registers. | 00055 | | | | F9 | 00056 | | | | . | 00057 | | | | . | 00058 | | | | F2 | 00059 | | v | | 00060 | | -------|-------------------------------| 00061 | | | | 00062 | | | Saved registers. | 00063 | | | S6 | 00064 |-regoffset | . | 00065 | | | . | 00066 | | | S0 | 00067 | | | pdr.pcreg | 00068 | v | | 00069 | ----------|-------------------------------| 00070 | | | 00071 frameoffset | Argument build area, gets | 00072 | | 7th ... nth arg for any | 00073 | | called procedure. | 00074 v | | 00075 -------------|-------------------------------|<-- sp 00076 | | 00077 */ 00078 /* *INDENT-ON* */ 00079 00080 #define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) 00081 #define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) 00082 #define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) 00083 #define PROC_REG_MASK(proc) ((proc)->pdr.regmask) 00084 #define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask) 00085 #define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset) 00086 #define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset) 00087 #define PROC_PC_REG(proc) ((proc)->pdr.pcreg) 00088 #define PROC_LOCALOFF(proc) ((proc)->pdr.localoff) 00089 00090 /* Locate the mdebug PDR for the given PC. Return null if one can't 00091 be found; you'll have to fall back to other methods in that case. */ 00092 00093 static struct mdebug_extra_func_info * 00094 find_proc_desc (CORE_ADDR pc) 00095 { 00096 struct block *b = block_for_pc (pc); 00097 struct mdebug_extra_func_info *proc_desc = NULL; 00098 struct symbol *sym = NULL; 00099 const char *sh_name = NULL; 00100 00101 if (b) 00102 { 00103 CORE_ADDR startaddr; 00104 find_pc_partial_function (pc, &sh_name, &startaddr, NULL); 00105 00106 if (startaddr > BLOCK_START (b)) 00107 /* This is the "pathological" case referred to in a comment in 00108 print_frame_info. It might be better to move this check into 00109 symbol reading. */ 00110 sym = NULL; 00111 else 00112 sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0); 00113 } 00114 00115 if (sym) 00116 { 00117 proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym); 00118 00119 /* Correct incorrect setjmp procedure descriptor from the library 00120 to make backtrace through setjmp work. */ 00121 if (proc_desc->pdr.pcreg == 0 00122 && strcmp (sh_name, "setjmp") == 0) 00123 { 00124 proc_desc->pdr.pcreg = ALPHA_RA_REGNUM; 00125 proc_desc->pdr.regmask = 0x80000000; 00126 proc_desc->pdr.regoffset = -4; 00127 } 00128 00129 /* If we never found a PDR for this function in symbol reading, 00130 then examine prologues to find the information. */ 00131 if (proc_desc->pdr.framereg == -1) 00132 proc_desc = NULL; 00133 } 00134 00135 return proc_desc; 00136 } 00137 00138 /* Return a non-zero result if the function is frameless; zero otherwise. */ 00139 00140 static int 00141 alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc) 00142 { 00143 return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM 00144 && PROC_FRAME_OFFSET (proc_desc) == 0); 00145 } 00146 00147 /* This returns the PC of the first inst after the prologue. If we can't 00148 find the prologue, then return 0. */ 00149 00150 static CORE_ADDR 00151 alpha_mdebug_after_prologue (CORE_ADDR pc, 00152 struct mdebug_extra_func_info *proc_desc) 00153 { 00154 if (proc_desc) 00155 { 00156 /* If function is frameless, then we need to do it the hard way. I 00157 strongly suspect that frameless always means prologueless... */ 00158 if (alpha_mdebug_frameless (proc_desc)) 00159 return 0; 00160 } 00161 00162 return alpha_after_prologue (pc); 00163 } 00164 00165 /* Return non-zero if we *might* be in a function prologue. Return zero 00166 if we are definitively *not* in a function prologue. */ 00167 00168 static int 00169 alpha_mdebug_in_prologue (CORE_ADDR pc, 00170 struct mdebug_extra_func_info *proc_desc) 00171 { 00172 CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc); 00173 return (after_prologue_pc == 0 || pc < after_prologue_pc); 00174 } 00175 00176 00177 /* Frame unwinder that reads mdebug PDRs. */ 00178 00179 struct alpha_mdebug_unwind_cache 00180 { 00181 struct mdebug_extra_func_info *proc_desc; 00182 CORE_ADDR vfp; 00183 struct trad_frame_saved_reg *saved_regs; 00184 }; 00185 00186 /* Extract all of the information about the frame from PROC_DESC 00187 and store the resulting register save locations in the structure. */ 00188 00189 static struct alpha_mdebug_unwind_cache * 00190 alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame, 00191 void **this_prologue_cache) 00192 { 00193 struct alpha_mdebug_unwind_cache *info; 00194 struct mdebug_extra_func_info *proc_desc; 00195 ULONGEST vfp; 00196 CORE_ADDR pc, reg_position; 00197 unsigned long mask; 00198 int ireg, returnreg; 00199 00200 if (*this_prologue_cache) 00201 return *this_prologue_cache; 00202 00203 info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache); 00204 *this_prologue_cache = info; 00205 pc = get_frame_address_in_block (this_frame); 00206 00207 /* ??? We don't seem to be able to cache the lookup of the PDR 00208 from alpha_mdebug_frame_p. It'd be nice if we could change 00209 the arguments to that function. Oh well. */ 00210 proc_desc = find_proc_desc (pc); 00211 info->proc_desc = proc_desc; 00212 gdb_assert (proc_desc != NULL); 00213 00214 info->saved_regs = trad_frame_alloc_saved_regs (this_frame); 00215 00216 /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */ 00217 vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc)); 00218 vfp += PROC_FRAME_OFFSET (info->proc_desc); 00219 info->vfp = vfp; 00220 00221 /* Fill in the offsets for the registers which gen_mask says were saved. */ 00222 00223 reg_position = vfp + PROC_REG_OFFSET (proc_desc); 00224 mask = PROC_REG_MASK (proc_desc); 00225 returnreg = PROC_PC_REG (proc_desc); 00226 00227 /* Note that RA is always saved first, regardless of its actual 00228 register number. */ 00229 if (mask & (1 << returnreg)) 00230 { 00231 /* Clear bit for RA so we don't save it again later. */ 00232 mask &= ~(1 << returnreg); 00233 00234 info->saved_regs[returnreg].addr = reg_position; 00235 reg_position += 8; 00236 } 00237 00238 for (ireg = 0; ireg <= 31; ++ireg) 00239 if (mask & (1 << ireg)) 00240 { 00241 info->saved_regs[ireg].addr = reg_position; 00242 reg_position += 8; 00243 } 00244 00245 reg_position = vfp + PROC_FREG_OFFSET (proc_desc); 00246 mask = PROC_FREG_MASK (proc_desc); 00247 00248 for (ireg = 0; ireg <= 31; ++ireg) 00249 if (mask & (1 << ireg)) 00250 { 00251 info->saved_regs[ALPHA_FP0_REGNUM + ireg].addr = reg_position; 00252 reg_position += 8; 00253 } 00254 00255 /* The stack pointer of the previous frame is computed by popping 00256 the current stack frame. */ 00257 if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM)) 00258 trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, vfp); 00259 00260 return info; 00261 } 00262 00263 /* Given a GDB frame, determine the address of the calling function's 00264 frame. This will be used to create a new GDB frame struct. */ 00265 00266 static void 00267 alpha_mdebug_frame_this_id (struct frame_info *this_frame, 00268 void **this_prologue_cache, 00269 struct frame_id *this_id) 00270 { 00271 struct alpha_mdebug_unwind_cache *info 00272 = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); 00273 00274 *this_id = frame_id_build (info->vfp, get_frame_func (this_frame)); 00275 } 00276 00277 /* Retrieve the value of REGNUM in FRAME. Don't give up! */ 00278 00279 static struct value * 00280 alpha_mdebug_frame_prev_register (struct frame_info *this_frame, 00281 void **this_prologue_cache, int regnum) 00282 { 00283 struct alpha_mdebug_unwind_cache *info 00284 = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); 00285 00286 /* The PC of the previous frame is stored in the link register of 00287 the current frame. Frob regnum so that we pull the value from 00288 the correct place. */ 00289 if (regnum == ALPHA_PC_REGNUM) 00290 regnum = PROC_PC_REG (info->proc_desc); 00291 00292 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); 00293 } 00294 00295 /* Return a non-zero result if the size of the stack frame exceeds the 00296 maximum debuggable frame size (512 Kbytes); zero otherwise. */ 00297 00298 static int 00299 alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc) 00300 { 00301 /* If frame offset is null, we can be in two cases: either the 00302 function is frameless (the stack frame is null) or its 00303 frame exceeds the maximum debuggable frame size (512 Kbytes). */ 00304 00305 return (PROC_FRAME_OFFSET (proc_desc) == 0 00306 && !alpha_mdebug_frameless (proc_desc)); 00307 } 00308 00309 static int 00310 alpha_mdebug_frame_sniffer (const struct frame_unwind *self, 00311 struct frame_info *this_frame, 00312 void **this_cache) 00313 { 00314 CORE_ADDR pc = get_frame_address_in_block (this_frame); 00315 struct mdebug_extra_func_info *proc_desc; 00316 00317 /* If this PC does not map to a PDR, then clearly this isn't an 00318 mdebug frame. */ 00319 proc_desc = find_proc_desc (pc); 00320 if (proc_desc == NULL) 00321 return 0; 00322 00323 /* If we're in the prologue, the PDR for this frame is not yet valid. 00324 Say no here and we'll fall back on the heuristic unwinder. */ 00325 if (alpha_mdebug_in_prologue (pc, proc_desc)) 00326 return 0; 00327 00328 /* If the maximum debuggable frame size has been exceeded, the 00329 proc desc is bogus. Fall back on the heuristic unwinder. */ 00330 if (alpha_mdebug_max_frame_size_exceeded (proc_desc)) 00331 return 0; 00332 00333 return 1; 00334 } 00335 00336 static const struct frame_unwind alpha_mdebug_frame_unwind = { 00337 NORMAL_FRAME, 00338 default_frame_unwind_stop_reason, 00339 alpha_mdebug_frame_this_id, 00340 alpha_mdebug_frame_prev_register, 00341 NULL, 00342 alpha_mdebug_frame_sniffer 00343 }; 00344 00345 static CORE_ADDR 00346 alpha_mdebug_frame_base_address (struct frame_info *this_frame, 00347 void **this_prologue_cache) 00348 { 00349 struct alpha_mdebug_unwind_cache *info 00350 = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); 00351 00352 return info->vfp; 00353 } 00354 00355 static CORE_ADDR 00356 alpha_mdebug_frame_locals_address (struct frame_info *this_frame, 00357 void **this_prologue_cache) 00358 { 00359 struct alpha_mdebug_unwind_cache *info 00360 = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); 00361 00362 return info->vfp - PROC_LOCALOFF (info->proc_desc); 00363 } 00364 00365 static CORE_ADDR 00366 alpha_mdebug_frame_args_address (struct frame_info *this_frame, 00367 void **this_prologue_cache) 00368 { 00369 struct alpha_mdebug_unwind_cache *info 00370 = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache); 00371 00372 return info->vfp - ALPHA_NUM_ARG_REGS * 8; 00373 } 00374 00375 static const struct frame_base alpha_mdebug_frame_base = { 00376 &alpha_mdebug_frame_unwind, 00377 alpha_mdebug_frame_base_address, 00378 alpha_mdebug_frame_locals_address, 00379 alpha_mdebug_frame_args_address 00380 }; 00381 00382 static const struct frame_base * 00383 alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame) 00384 { 00385 CORE_ADDR pc = get_frame_address_in_block (this_frame); 00386 struct mdebug_extra_func_info *proc_desc; 00387 00388 /* If this PC does not map to a PDR, then clearly this isn't an 00389 mdebug frame. */ 00390 proc_desc = find_proc_desc (pc); 00391 if (proc_desc == NULL) 00392 return NULL; 00393 00394 /* If the maximum debuggable frame size has been exceeded, the 00395 proc desc is bogus. Fall back on the heuristic unwinder. */ 00396 if (alpha_mdebug_max_frame_size_exceeded (proc_desc)) 00397 return 0; 00398 00399 return &alpha_mdebug_frame_base; 00400 } 00401 00402 00403 void 00404 alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00405 { 00406 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00407 00408 frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind); 00409 frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer); 00410 }