• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revision65207ebfee67bacd35564143e66f9c1ab0f0b59d (tree)
Zeit2003-05-30 08:02:54
Autornobody <>
Commiternobody <>

Log Message

This commit was manufactured by cvs2svn to create branch
'kettenis_i386newframe-20030419-branch'.

Cherrypick from master 2003-05-29 23:02:53 UTC Richard Henderson <rth@redhat.com> ' * alpha-linux-tdep.c (alpha_linux_sigtramp_offset_1): New.':

gdb/alpha-mdebug-tdep.c

Ändern Zusammenfassung

Diff

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