]> Git Repo - binutils.git/blob - gdb/sh-tdep.c
* elfcode.h (elf_bfd_final_link): If trying to generate a shared
[binutils.git] / gdb / sh-tdep.c
1 /* Target-machine dependent code for Hitachi Super-H, for GDB.
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /*
21  Contributed by Steve Chamberlain
22                 [email protected]
23  */
24
25 #include "defs.h"
26 #include "frame.h"
27 #include "obstack.h"
28 #include "symtab.h"
29 #include "gdbtypes.h"
30 #include "gdbcmd.h"
31 #include "value.h"
32 #include "dis-asm.h"
33 #include "../opcodes/sh-opc.h"
34
35
36
37
38 /* Prologue looks like
39    [mov.l       <regs>,@-r15]...
40    [sts.l       pr,@-r15]
41    [mov.l       r14,@-r15]
42    [mov         r15,r14]
43 */
44
45 #define IS_STS(x)               ((x) == 0x4f22)
46 #define IS_PUSH(x)              (((x) & 0xff0f) == 0x2f06)
47 #define GET_PUSHED_REG(x)       (((x) >> 4) & 0xf)
48 #define IS_MOV_SP_FP(x)         ((x) == 0x6ef3)
49 #define IS_ADD_SP(x)            (((x) & 0xff00) == 0x7f00)
50
51
52 /* Skip any prologue before the guts of a function */
53
54 CORE_ADDR
55 sh_skip_prologue (start_pc)
56      CORE_ADDR start_pc;
57
58 {
59   int w;
60
61   w = read_memory_integer (start_pc, 2);
62   while (IS_STS (w)
63          || IS_PUSH (w)
64          || IS_MOV_SP_FP (w))
65     {
66       start_pc += 2;
67       w = read_memory_integer (start_pc, 2);
68     }
69
70   return start_pc;
71 }
72
73 /* Disassemble an instruction */
74
75 int
76 print_insn (memaddr, stream)
77      CORE_ADDR memaddr;
78      GDB_FILE *stream;
79 {
80   disassemble_info info;
81   GDB_INIT_DISASSEMBLE_INFO (info, stream);
82   return print_insn_sh (memaddr, &info);
83 }
84
85 /* Given a GDB frame, determine the address of the calling function's frame.
86    This will be used to create a new GDB frame struct, and then
87    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
88
89    For us, the frame address is its stack pointer value, so we look up
90    the function prologue to determine the caller's sp value, and return it.  */
91
92 FRAME_ADDR
93 sh_frame_chain (thisframe)
94      FRAME thisframe;
95 {
96   if (!inside_entry_file (thisframe->pc))
97     return (read_memory_integer (FRAME_FP (thisframe), 4));
98   else
99     return 0;
100 }
101
102 /* Put here the code to store, into a struct frame_saved_regs,
103    the addresses of the saved registers of frame described by FRAME_INFO.
104    This includes special registers such as pc and fp saved in special
105    ways in the stack frame.  sp is even more special:
106    the address we return for it IS the sp for the next frame. */
107
108
109 void
110 frame_find_saved_regs (fi, fsr)
111      struct frame_info *fi;
112      struct frame_saved_regs *fsr;
113 {
114   int where[NUM_REGS];
115   int rn;
116   int have_fp = 0;
117   int depth;
118   int pc;
119   int opc;
120   int insn;
121
122   opc = pc = get_pc_function_start (fi->pc);
123
124   insn = read_memory_integer (pc, 2);
125
126   for (rn = 0; rn < NUM_REGS; rn++)
127     where[rn] = -1;
128
129   depth = 0;
130
131   /* Loop around examining the prologue insns, but give up
132      after 15 of them, since we're getting silly then */
133   while (pc < opc + 15 * 2)
134     {
135       /* See where the registers will be saved to */
136       if (IS_PUSH (insn))
137         {
138           pc += 2;
139           rn = GET_PUSHED_REG (insn);
140           where[rn] = depth;
141           insn = read_memory_integer (pc, 2);
142           depth += 4;
143         }
144       else if (IS_STS (insn))
145         {
146           pc += 2;
147           where[PR_REGNUM] = depth;
148           insn = read_memory_integer (pc, 2);
149           depth += 4;
150         }
151       else if (IS_ADD_SP (insn))
152         {
153           pc += 2;
154           depth += -((char) (insn & 0xff));
155           insn = read_memory_integer (pc, 2);
156         }
157       else
158         break;
159     }
160
161   /* Now we know how deep things are, we can work out their addresses */
162
163   for (rn = 0; rn < NUM_REGS; rn++)
164     {
165       if (where[rn] >= 0)
166         {
167           if (rn == FP_REGNUM)
168             have_fp = 1;
169
170           fsr->regs[rn] = fi->frame - where[rn] + depth - 4;
171         }
172       else
173         {
174           fsr->regs[rn] = 0;
175         }
176     }
177
178   if (have_fp)
179     {
180       fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[FP_REGNUM], 4);
181     }
182   else
183     {
184       fsr->regs[SP_REGNUM] = fi->frame - 4;
185     }
186
187
188   /* Work out the return pc - either from the saved pr or the pr
189      value */
190
191   if (fsr->regs[PR_REGNUM])
192     {
193       fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4) + 4;
194     }
195   else
196     {
197       fi->return_pc = read_register (PR_REGNUM) + 4;
198     }
199 }
200
201 /* initialize the extra info saved in a FRAME */
202
203 void
204 init_extra_frame_info (fromleaf, fi)
205      int fromleaf;
206      struct frame_info *fi;
207 {
208   struct frame_saved_regs dummy;
209   frame_find_saved_regs (fi, &dummy);
210 }
211
212
213 /* Discard from the stack the innermost frame,
214    restoring all saved registers.  */
215
216 void
217 pop_frame ()
218 {
219   register FRAME frame = get_current_frame ();
220   register CORE_ADDR fp;
221   register int regnum;
222   struct frame_saved_regs fsr;
223   struct frame_info *fi;
224
225   fi = get_frame_info (frame);
226   fp = fi->frame;
227   get_frame_saved_regs (fi, &fsr);
228
229   /* Copy regs from where they were saved in the frame */
230   for (regnum = 0; regnum < NUM_REGS; regnum++)
231     {
232       if (fsr.regs[regnum])
233         {
234           write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
235         }
236     }
237
238   write_register (PC_REGNUM, fi->return_pc);
239   write_register (SP_REGNUM, fp + 4);
240   flush_cached_frames ();
241   set_current_frame (create_new_frame (read_register (FP_REGNUM),
242                                        read_pc ()));
243 }
244
245 /* Print the registers in a form similar to the E7000 */
246 static void
247 show_regs (args, from_tty)
248 char *args;
249 int from_tty;
250 {
251   printf_filtered("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
252                   read_register(PC_REGNUM),
253                   read_register(SR_REGNUM),
254                   read_register(PR_REGNUM),
255                   read_register(MACH_REGNUM),
256                   read_register(MACL_REGNUM));
257
258   printf_filtered("R0-R7  %08x %08x %08x %08x %08x %08x %08x %08x\n",
259                   read_register(0),
260                   read_register(1),
261                   read_register(2),
262                   read_register(3),
263                   read_register(4),
264                   read_register(5),
265                   read_register(6),
266                   read_register(7));
267   printf_filtered("R8-R15 %08x %08x %08x %08x %08x %08x %08x %08x\n",
268                   read_register(8),
269                   read_register(9),
270                   read_register(10),
271                   read_register(11),
272                   read_register(12),
273                   read_register(13),
274                   read_register(14),
275                   read_register(15));
276 }
277 \f
278
279 void
280 _initialize_sh_tdep ()
281 {
282   extern int sim_memory_size;
283   /* FIXME, there should be a way to make a CORE_ADDR variable settable. */
284   add_show_from_set
285     (add_set_cmd ("memory_size", class_support, var_uinteger,
286                   (char *) &sim_memory_size,
287                 "Set simulated memory size of simulator target.", &setlist),
288      &showlist);
289
290   add_com("regs", class_vars, show_regs, "Print all registers");
291 }
This page took 0.039131 seconds and 4 git commands to generate.