1130803Smarcel/* Traditional frame unwind support, for GDB the GNU Debugger. 2130803Smarcel 3130803Smarcel Copyright 2003 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "frame.h" 24130803Smarcel#include "trad-frame.h" 25130803Smarcel#include "regcache.h" 26130803Smarcel 27130803Smarcel/* A traditional frame is unwound by analysing the function prologue 28130803Smarcel and using the information gathered to track registers. For 29130803Smarcel non-optimized frames, the technique is reliable (just need to check 30130803Smarcel for all potential instruction sequences). */ 31130803Smarcel 32130803Smarcelstruct trad_frame_saved_reg * 33130803Smarceltrad_frame_alloc_saved_regs (struct frame_info *next_frame) 34130803Smarcel{ 35130803Smarcel int regnum; 36130803Smarcel struct gdbarch *gdbarch = get_frame_arch (next_frame); 37130803Smarcel int numregs = NUM_REGS + NUM_PSEUDO_REGS; 38130803Smarcel struct trad_frame_saved_reg *this_saved_regs 39130803Smarcel = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg); 40130803Smarcel for (regnum = 0; regnum < numregs; regnum++) 41130803Smarcel { 42130803Smarcel this_saved_regs[regnum].realreg = regnum; 43130803Smarcel this_saved_regs[regnum].addr = -1; 44130803Smarcel } 45130803Smarcel return this_saved_regs; 46130803Smarcel} 47130803Smarcel 48130803Smarcelenum { REG_VALUE = -1, REG_UNKNOWN = -2 }; 49130803Smarcel 50130803Smarcelint 51130803Smarceltrad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) 52130803Smarcel{ 53130803Smarcel return (this_saved_regs[regnum].realreg == REG_VALUE); 54130803Smarcel} 55130803Smarcel 56130803Smarcelint 57130803Smarceltrad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum) 58130803Smarcel{ 59130803Smarcel return (this_saved_regs[regnum].realreg >= 0 60130803Smarcel && this_saved_regs[regnum].addr != -1); 61130803Smarcel} 62130803Smarcel 63130803Smarcelint 64130803Smarceltrad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[], 65130803Smarcel int regnum) 66130803Smarcel{ 67130803Smarcel return (this_saved_regs[regnum].realreg >= 0 68130803Smarcel && this_saved_regs[regnum].addr == -1); 69130803Smarcel} 70130803Smarcel 71130803Smarcelvoid 72130803Smarceltrad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[], 73130803Smarcel int regnum, LONGEST val) 74130803Smarcel{ 75130803Smarcel /* Make the REALREG invalid, indicating that the ADDR contains the 76130803Smarcel register's value. */ 77130803Smarcel this_saved_regs[regnum].realreg = REG_VALUE; 78130803Smarcel this_saved_regs[regnum].addr = val; 79130803Smarcel} 80130803Smarcel 81130803Smarcelvoid 82130803Smarceltrad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[], 83130803Smarcel int regnum) 84130803Smarcel{ 85130803Smarcel /* Make the REALREG invalid, indicating that the value is not known. */ 86130803Smarcel this_saved_regs[regnum].realreg = REG_UNKNOWN; 87130803Smarcel this_saved_regs[regnum].addr = -1; 88130803Smarcel} 89130803Smarcel 90130803Smarcelvoid 91130803Smarceltrad_frame_prev_register (struct frame_info *next_frame, 92130803Smarcel struct trad_frame_saved_reg this_saved_regs[], 93130803Smarcel int regnum, int *optimizedp, 94130803Smarcel enum lval_type *lvalp, CORE_ADDR *addrp, 95130803Smarcel int *realregp, void *bufferp) 96130803Smarcel{ 97130803Smarcel struct gdbarch *gdbarch = get_frame_arch (next_frame); 98130803Smarcel if (trad_frame_addr_p (this_saved_regs, regnum)) 99130803Smarcel { 100130803Smarcel /* The register was saved in memory. */ 101130803Smarcel *optimizedp = 0; 102130803Smarcel *lvalp = lval_memory; 103130803Smarcel *addrp = this_saved_regs[regnum].addr; 104130803Smarcel *realregp = -1; 105130803Smarcel if (bufferp != NULL) 106130803Smarcel { 107130803Smarcel /* Read the value in from memory. */ 108130803Smarcel get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp, 109130803Smarcel register_size (gdbarch, regnum)); 110130803Smarcel } 111130803Smarcel } 112130803Smarcel else if (trad_frame_realreg_p (this_saved_regs, regnum)) 113130803Smarcel { 114130803Smarcel /* Ask the next frame to return the value of the register. */ 115130803Smarcel frame_register_unwind (next_frame, this_saved_regs[regnum].realreg, 116130803Smarcel optimizedp, lvalp, addrp, realregp, bufferp); 117130803Smarcel } 118130803Smarcel else if (trad_frame_value_p (this_saved_regs, regnum)) 119130803Smarcel { 120130803Smarcel /* The register's value is available. */ 121130803Smarcel *optimizedp = 0; 122130803Smarcel *lvalp = not_lval; 123130803Smarcel *addrp = 0; 124130803Smarcel *realregp = -1; 125130803Smarcel if (bufferp != NULL) 126130803Smarcel store_unsigned_integer (bufferp, register_size (gdbarch, regnum), 127130803Smarcel this_saved_regs[regnum].addr); 128130803Smarcel } 129130803Smarcel else 130130803Smarcel { 131130803Smarcel error ("Register %s not available", 132130803Smarcel gdbarch_register_name (gdbarch, regnum)); 133130803Smarcel } 134130803Smarcel} 135