GNU Binutils with patches for OS216
Revision | eea1bed0c6cef8e92a4cafe66b94def2c4d22468 (tree) |
---|---|
Time | 2004-01-01 02:32:25 |
Author | Mark Kettenis <kettenis@gnu....> |
Commiter | Mark Kettenis |
* sparc64-sol2-tdep.c: Include "frame.h", "frame-unwind.h",
"trad-frame.h" and "gdb_assert.h".
(BIAS): Define if not already defined.
(sparc64_sol2_sigtramp_frame_cache)
(sparc64_sol2_sigtramp_frame_this_id)
(sparc64_sol2_sigtramp_frame_prev_register): New functions.
(sparc64_sol2_sigtramp_frame_unwind): New variable.
(sparc64_sol2_sigtramp_frame_sniffer): New function.
(sparc64_sol2_init_abi): Set pc_in_sigtramp and append
sparc64_sol2_sigtramp_sniffer.
@@ -1,5 +1,16 @@ | ||
1 | 1 | 2003-12-31 Mark Kettenis <kettenis@gnu.org> |
2 | 2 | |
3 | + * sparc64-sol2-tdep.c: Include "frame.h", "frame-unwind.h", | |
4 | + "trad-frame.h" and "gdb_assert.h". | |
5 | + (BIAS): Define if not already defined. | |
6 | + (sparc64_sol2_sigtramp_frame_cache) | |
7 | + (sparc64_sol2_sigtramp_frame_this_id) | |
8 | + (sparc64_sol2_sigtramp_frame_prev_register): New functions. | |
9 | + (sparc64_sol2_sigtramp_frame_unwind): New variable. | |
10 | + (sparc64_sol2_sigtramp_frame_sniffer): New function. | |
11 | + (sparc64_sol2_init_abi): Set pc_in_sigtramp and append | |
12 | + sparc64_sol2_sigtramp_sniffer. | |
13 | + | |
3 | 14 | * sparc-tdep.h (sparc_sol2_pc_in_sigtramp): New prototype. |
4 | 15 | * sparc-sol2-tdep.c (sparc_sol2_pc_in_sigtramp): Make global. |
5 | 16 |
@@ -20,13 +20,24 @@ | ||
20 | 20 | Boston, MA 02111-1307, USA. */ |
21 | 21 | |
22 | 22 | #include "defs.h" |
23 | +#include "frame.h" | |
24 | +#include "frame-unwind.h" | |
23 | 25 | #include "gdbarch.h" |
24 | 26 | #include "symtab.h" |
25 | 27 | #include "objfiles.h" |
26 | 28 | #include "osabi.h" |
29 | +#include "trad-frame.h" | |
30 | + | |
31 | +#include "gdb_assert.h" | |
27 | 32 | |
28 | 33 | #include "sparc64-tdep.h" |
29 | 34 | |
35 | +/* The stack pointer is offset from the stack frame by a BIAS of 2047 | |
36 | + (0x7ff) for 64-bit code. BIAS is likely to be defined on SPARC | |
37 | + hosts, so undefine it first. */ | |
38 | +#undef BIAS | |
39 | +#define BIAS 2047 | |
40 | + | |
30 | 41 | /* From <sys/regset.h>. */ |
31 | 42 | const struct sparc_gregset sparc64_sol2_gregset = |
32 | 43 | { |
@@ -42,11 +53,115 @@ const struct sparc_gregset sparc64_sol2_gregset = | ||
42 | 53 | }; |
43 | 54 | |
44 | 55 | |
56 | +static struct sparc_frame_cache * | |
57 | +sparc64_sol2_sigtramp_frame_cache (struct frame_info *next_frame, | |
58 | + void **this_cache) | |
59 | +{ | |
60 | + struct sparc_frame_cache *cache; | |
61 | + CORE_ADDR mcontext_addr, addr; | |
62 | + int regnum; | |
63 | + | |
64 | + if (*this_cache) | |
65 | + return *this_cache; | |
66 | + | |
67 | + cache = sparc_frame_cache (next_frame, this_cache); | |
68 | + gdb_assert (cache == *this_cache); | |
69 | + | |
70 | + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); | |
71 | + | |
72 | + /* The third argument is a pointer to an instance of `ucontext_t', | |
73 | + which has a member `uc_mcontext' that contains the saved | |
74 | + registers. */ | |
75 | + regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); | |
76 | + mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 64; | |
77 | + | |
78 | + cache->saved_regs[SPARC64_CCR_REGNUM].addr = mcontext_addr + 0 * 8; | |
79 | + cache->saved_regs[SPARC64_PC_REGNUM].addr = mcontext_addr + 1 * 8; | |
80 | + cache->saved_regs[SPARC64_NPC_REGNUM].addr = mcontext_addr + 2 * 8; | |
81 | + cache->saved_regs[SPARC64_Y_REGNUM].addr = mcontext_addr + 3 * 8; | |
82 | + cache->saved_regs[SPARC64_ASI_REGNUM].addr = mcontext_addr + 19 * 8; | |
83 | + cache->saved_regs[SPARC64_FPRS_REGNUM].addr = mcontext_addr + 20 * 8; | |
84 | + | |
85 | + /* Since %g0 is always zero, keep the identity encoding. */ | |
86 | + for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 8; | |
87 | + regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) | |
88 | + cache->saved_regs[regnum].addr = addr; | |
89 | + | |
90 | + if (get_frame_memory_unsigned (next_frame, mcontext_addr + 21 * 8, 8)) | |
91 | + { | |
92 | + /* The register windows haven't been flushed. */ | |
93 | + for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) | |
94 | + trad_frame_set_unknown (cache->saved_regs, regnum); | |
95 | + } | |
96 | + else | |
97 | + { | |
98 | + CORE_ADDR sp; | |
99 | + | |
100 | + addr = cache->saved_regs[SPARC_SP_REGNUM].addr; | |
101 | + sp = get_frame_memory_unsigned (next_frame, addr, 8); | |
102 | + for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; | |
103 | + regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) | |
104 | + cache->saved_regs[regnum].addr = addr; | |
105 | + } | |
106 | + | |
107 | + return cache; | |
108 | +} | |
109 | + | |
110 | +static void | |
111 | +sparc64_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, | |
112 | + void **this_cache, | |
113 | + struct frame_id *this_id) | |
114 | +{ | |
115 | + struct sparc_frame_cache *cache = | |
116 | + sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); | |
117 | + | |
118 | + (*this_id) = frame_id_build (cache->base, cache->pc); | |
119 | +} | |
120 | + | |
121 | +static void | |
122 | +sparc64_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, | |
123 | + void **this_cache, | |
124 | + int regnum, int *optimizedp, | |
125 | + enum lval_type *lvalp, | |
126 | + CORE_ADDR *addrp, | |
127 | + int *realnump, void *valuep) | |
128 | +{ | |
129 | + struct sparc_frame_cache *cache = | |
130 | + sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); | |
131 | + | |
132 | + trad_frame_prev_register (next_frame, cache->saved_regs, regnum, | |
133 | + optimizedp, lvalp, addrp, realnump, valuep); | |
134 | +} | |
135 | + | |
136 | +static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = | |
137 | +{ | |
138 | + SIGTRAMP_FRAME, | |
139 | + sparc64_sol2_sigtramp_frame_this_id, | |
140 | + sparc64_sol2_sigtramp_frame_prev_register | |
141 | +}; | |
142 | + | |
143 | +static const struct frame_unwind * | |
144 | +sparc64_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) | |
145 | +{ | |
146 | + CORE_ADDR pc = frame_pc_unwind (next_frame); | |
147 | + char *name; | |
148 | + | |
149 | + find_pc_partial_function (pc, &name, NULL, NULL); | |
150 | + if (sparc_sol2_pc_in_sigtramp (pc, name)) | |
151 | + return &sparc64_sol2_sigtramp_frame_unwind; | |
152 | + | |
153 | + return NULL; | |
154 | +} | |
155 | + | |
156 | + | |
45 | 157 | void |
46 | 158 | sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) |
47 | 159 | { |
48 | 160 | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); |
49 | 161 | |
162 | + set_gdbarch_pc_in_sigtramp (gdbarch, sparc_sol2_pc_in_sigtramp); | |
163 | + frame_unwind_append_sniffer (gdbarch, sparc64_sol2_sigtramp_frame_sniffer); | |
164 | + | |
50 | 165 | sparc64_init_abi (info, gdbarch); |
51 | 166 | |
52 | 167 | /* Solaris has SVR4-style shared libraries... */ |