OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [trad-frame.c] - Blame information for rev 308

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Traditional frame unwind support, for GDB the GNU Debugger.
2
 
3
   Copyright (C) 2003, 2004, 2007, 2008 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 3 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, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "frame.h"
22
#include "trad-frame.h"
23
#include "regcache.h"
24
 
25
struct trad_frame_cache
26
{
27
  struct frame_info *next_frame;
28
  CORE_ADDR this_base;
29
  struct trad_frame_saved_reg *prev_regs;
30
  struct frame_id this_id;
31
};
32
 
33
struct trad_frame_cache *
34
trad_frame_cache_zalloc (struct frame_info *next_frame)
35
{
36
  struct trad_frame_cache *this_trad_cache;
37
 
38
  this_trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
39
  this_trad_cache->prev_regs = trad_frame_alloc_saved_regs (next_frame);
40
  this_trad_cache->next_frame = next_frame;
41
  return this_trad_cache;
42
}
43
 
44
/* A traditional frame is unwound by analysing the function prologue
45
   and using the information gathered to track registers.  For
46
   non-optimized frames, the technique is reliable (just need to check
47
   for all potential instruction sequences).  */
48
 
49
struct trad_frame_saved_reg *
50
trad_frame_alloc_saved_regs (struct frame_info *next_frame)
51
{
52
  int regnum;
53
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
54
  int numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
55
  struct trad_frame_saved_reg *this_saved_regs
56
    = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
57
  for (regnum = 0; regnum < numregs; regnum++)
58
    {
59
      this_saved_regs[regnum].realreg = regnum;
60
      this_saved_regs[regnum].addr = -1;
61
    }
62
  return this_saved_regs;
63
}
64
 
65
enum { REG_VALUE = -1, REG_UNKNOWN = -2 };
66
 
67
int
68
trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
69
{
70
  return (this_saved_regs[regnum].realreg == REG_VALUE);
71
}
72
 
73
int
74
trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
75
{
76
  return (this_saved_regs[regnum].realreg >= 0
77
          && this_saved_regs[regnum].addr != -1);
78
}
79
 
80
int
81
trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[],
82
                      int regnum)
83
{
84
  return (this_saved_regs[regnum].realreg >= 0
85
          && this_saved_regs[regnum].addr == -1);
86
}
87
 
88
void
89
trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[],
90
                      int regnum, LONGEST val)
91
{
92
  /* Make the REALREG invalid, indicating that the ADDR contains the
93
     register's value.  */
94
  this_saved_regs[regnum].realreg = REG_VALUE;
95
  this_saved_regs[regnum].addr = val;
96
}
97
 
98
void
99
trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
100
                          int regnum, LONGEST val)
101
{
102
  /* External interface for users of trad_frame_cache
103
     (who cannot access the prev_regs object directly).  */
104
  trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
105
}
106
 
107
void
108
trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
109
                            int regnum, int realreg)
110
{
111
  this_trad_cache->prev_regs[regnum].realreg = realreg;
112
  this_trad_cache->prev_regs[regnum].addr = -1;
113
}
114
 
115
void
116
trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
117
                         int regnum, CORE_ADDR addr)
118
{
119
  this_trad_cache->prev_regs[regnum].addr = addr;
120
}
121
 
122
void
123
trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
124
                        int regnum)
125
{
126
  /* Make the REALREG invalid, indicating that the value is not known.  */
127
  this_saved_regs[regnum].realreg = REG_UNKNOWN;
128
  this_saved_regs[regnum].addr = -1;
129
}
130
 
131
void
132
trad_frame_get_prev_register (struct frame_info *next_frame,
133
                              struct trad_frame_saved_reg this_saved_regs[],
134
                              int regnum, int *optimizedp,
135
                              enum lval_type *lvalp, CORE_ADDR *addrp,
136
                              int *realregp, gdb_byte *bufferp)
137
{
138
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
139
  if (trad_frame_addr_p (this_saved_regs, regnum))
140
    {
141
      /* The register was saved in memory.  */
142
      *optimizedp = 0;
143
      *lvalp = lval_memory;
144
      *addrp = this_saved_regs[regnum].addr;
145
      *realregp = -1;
146
      if (bufferp != NULL)
147
        {
148
          /* Read the value in from memory.  */
149
          get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
150
                            register_size (gdbarch, regnum));
151
        }
152
    }
153
  else if (trad_frame_realreg_p (this_saved_regs, regnum))
154
    {
155
      *optimizedp = 0;
156
      *lvalp = lval_register;
157
      *addrp = 0;
158
      *realregp = this_saved_regs[regnum].realreg;
159
      /* Ask the next frame to return the value of the register.  */
160
      if (bufferp)
161
        frame_unwind_register (next_frame, (*realregp), bufferp);
162
    }
163
  else if (trad_frame_value_p (this_saved_regs, regnum))
164
    {
165
      /* The register's value is available.  */
166
      *optimizedp = 0;
167
      *lvalp = not_lval;
168
      *addrp = 0;
169
      *realregp = -1;
170
      if (bufferp != NULL)
171
        store_unsigned_integer (bufferp, register_size (gdbarch, regnum),
172
                                this_saved_regs[regnum].addr);
173
    }
174
  else
175
    {
176
      error (_("Register %s not available"),
177
             gdbarch_register_name (gdbarch, regnum));
178
    }
179
}
180
 
181
void
182
trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
183
                         struct frame_info *next_frame,
184
                         int regnum, int *optimizedp,
185
                         enum lval_type *lvalp, CORE_ADDR *addrp,
186
                         int *realregp, gdb_byte *bufferp)
187
{
188
  trad_frame_get_prev_register (next_frame, this_trad_cache->prev_regs,
189
                                regnum, optimizedp, lvalp, addrp, realregp,
190
                                bufferp);
191
}
192
 
193
void
194
trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
195
                   struct frame_id this_id)
196
{
197
  this_trad_cache->this_id = this_id;
198
}
199
 
200
void
201
trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
202
                   struct frame_id *this_id)
203
{
204
  (*this_id) = this_trad_cache->this_id;
205
}
206
 
207
void
208
trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
209
                          CORE_ADDR this_base)
210
{
211
  this_trad_cache->this_base = this_base;
212
}
213
 
214
CORE_ADDR
215
trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
216
{
217
  return this_trad_cache->this_base;
218
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.