1/* Traditional frame unwind support, for GDB the GNU Debugger. 2 3 Copyright 2003 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 "trad-frame.h" 25#include "regcache.h" 26 27/* A traditional frame is unwound by analysing the function prologue 28 and using the information gathered to track registers. For 29 non-optimized frames, the technique is reliable (just need to check 30 for all potential instruction sequences). */ 31 32struct trad_frame_saved_reg * 33trad_frame_alloc_saved_regs (struct frame_info *next_frame) 34{ 35 int regnum; 36 struct gdbarch *gdbarch = get_frame_arch (next_frame); 37 int numregs = NUM_REGS + NUM_PSEUDO_REGS; 38 struct trad_frame_saved_reg *this_saved_regs 39 = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg); 40 for (regnum = 0; regnum < numregs; regnum++) 41 { 42 this_saved_regs[regnum].realreg = regnum; 43 this_saved_regs[regnum].addr = -1; 44 } 45 return this_saved_regs; 46} 47 48enum { REG_VALUE = -1, REG_UNKNOWN = -2 }; 49 50int 51trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) 52{ 53 return (this_saved_regs[regnum].realreg == REG_VALUE); 54} 55 56int 57trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) 58{ 59 return (this_saved_regs[regnum].realreg >= 0 60 && this_saved_regs[regnum].addr != -1); 61} 62 63int 64trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], 65 int regnum) 66{ 67 return (this_saved_regs[regnum].realreg >= 0 68 && this_saved_regs[regnum].addr == -1); 69} 70 71void 72trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], 73 int regnum, LONGEST val) 74{ 75 /* Make the REALREG invalid, indicating that the ADDR contains the 76 register's value. */ 77 this_saved_regs[regnum].realreg = REG_VALUE; 78 this_saved_regs[regnum].addr = val; 79} 80 81void 82trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], 83 int regnum) 84{ 85 /* Make the REALREG invalid, indicating that the value is not known. */ 86 this_saved_regs[regnum].realreg = REG_UNKNOWN; 87 this_saved_regs[regnum].addr = -1; 88} 89 90void 91trad_frame_prev_register (struct frame_info *next_frame, 92 struct trad_frame_saved_reg this_saved_regs[], 93 int regnum, int *optimizedp, 94 enum lval_type *lvalp, CORE_ADDR *addrp, 95 int *realregp, void *bufferp) 96{ 97 struct gdbarch *gdbarch = get_frame_arch (next_frame); 98 if (trad_frame_addr_p (this_saved_regs, regnum)) 99 { 100 /* The register was saved in memory. */ 101 *optimizedp = 0; 102 *lvalp = lval_memory; 103 *addrp = this_saved_regs[regnum].addr; 104 *realregp = -1; 105 if (bufferp != NULL) 106 { 107 /* Read the value in from memory. */ 108 get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp, 109 register_size (gdbarch, regnum)); 110 } 111 } 112 else if (trad_frame_realreg_p (this_saved_regs, regnum)) 113 { 114 /* Ask the next frame to return the value of the register. */ 115 frame_register_unwind (next_frame, this_saved_regs[regnum].realreg, 116 optimizedp, lvalp, addrp, realregp, bufferp); 117 } 118 else if (trad_frame_value_p (this_saved_regs, regnum)) 119 { 120 /* The register's value is available. */ 121 *optimizedp = 0; 122 *lvalp = not_lval; 123 *addrp = 0; 124 *realregp = -1; 125 if (bufferp != NULL) 126 store_unsigned_integer (bufferp, register_size (gdbarch, regnum), 127 this_saved_regs[regnum].addr); 128 } 129 else 130 { 131 error ("Register %s not available", 132 gdbarch_register_name (gdbarch, regnum)); 133 } 134} 135