OSDN Git Service

23b573eb556821b792858d18467a49af122a39c1
[pf3gnuchains/pf3gnuchains3x.git] / gdb / moxie-tdep.c
1 /* Target-dependent code for Moxie.
2
3    Copyright (C) 2009 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 "frame-unwind.h"
23 #include "frame-base.h"
24 #include "symtab.h"
25 #include "gdbtypes.h"
26 #include "gdbcmd.h"
27 #include "gdbcore.h"
28 #include "gdb_string.h"
29 #include "value.h"
30 #include "inferior.h"
31 #include "symfile.h"
32 #include "objfiles.h"
33 #include "osabi.h"
34 #include "language.h"
35 #include "arch-utils.h"
36 #include "regcache.h"
37 #include "trad-frame.h"
38 #include "dis-asm.h"
39
40 #include "gdb_assert.h"
41
42 #include "moxie-tdep.h"
43
44 /* Local functions.  */
45
46 extern void _initialize_moxie_tdep (void);
47
48 /* Use an invalid address value as 'not available' marker.  */
49 enum { REG_UNAVAIL = (CORE_ADDR) -1 };
50
51 struct moxie_frame_cache
52 {
53   /* Base address.  */
54   CORE_ADDR base;
55   CORE_ADDR pc;
56   LONGEST framesize;
57   CORE_ADDR saved_regs[MOXIE_NUM_REGS];
58   CORE_ADDR saved_sp;
59 };
60
61 /* Implement the "frame_align" gdbarch method.  */
62
63 static CORE_ADDR
64 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
65 {
66   /* Align to the size of an instruction (so that they can safely be
67      pushed onto the stack.  */
68   return sp & ~1;
69 }
70
71 /* Implement the "breakpoint_from_pc" gdbarch method.  */
72
73 const static unsigned char *
74 moxie_breakpoint_from_pc (struct gdbarch *gdbarch, 
75                           CORE_ADDR *pcptr, int *lenptr)
76 {
77   static unsigned char breakpoint[] = { 0x35, 0x00 };
78
79   *lenptr = sizeof (breakpoint);
80   return breakpoint;
81 }
82
83 /* Moxie register names.  */
84
85 char *moxie_register_names[] = {
86   "$fp",  "$sp",  "$r0",  "$r1",  "$r2",
87   "$r3",  "$r4",  "$r5", "$r6", "$r7",
88   "$r8", "$r9", "$r10", "$r11", "$r12",
89   "$r13", "$pc", "$cc" };
90
91 /* Implement the "register_name" gdbarch method.  */
92
93 static const char *
94 moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
95 {
96   if (reg_nr < 0)
97     return NULL;
98   if (reg_nr >= MOXIE_NUM_REGS)
99     return NULL;
100   return moxie_register_names[reg_nr];
101 }
102
103 /* Implement the "register_type" gdbarch method.  */
104
105 static struct type *
106 moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
107 {
108   if (reg_nr == MOXIE_PC_REGNUM)
109     return  builtin_type (gdbarch)->builtin_func_ptr;
110   else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
111     return builtin_type (gdbarch)->builtin_data_ptr;
112   else
113     return builtin_type_int32;
114 }
115
116 /* Write into appropriate registers a function return value
117    of type TYPE, given in virtual format.  */
118
119 static void
120 moxie_store_return_value (struct type *type, struct regcache *regcache,
121                          const void *valbuf)
122 {
123   CORE_ADDR regval;
124   int len = TYPE_LENGTH (type);
125
126   /* Things always get returned in RET1_REGNUM, RET2_REGNUM.  */
127   regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len);
128   regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
129   if (len > 4)
130     {
131       regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4, len - 4);
132       regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
133     }
134 }
135
136 /* Decode the instructions within the given address range.  Decide
137    when we must have reached the end of the function prologue.  If a
138    frame_info pointer is provided, fill in its saved_regs etc.
139
140    Returns the address of the first instruction after the prologue.  */
141
142 static CORE_ADDR
143 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
144                       struct moxie_frame_cache *cache,
145                       struct frame_info *this_frame)
146 {
147   CORE_ADDR next_addr;
148   ULONGEST inst, inst2;
149   LONGEST offset;
150   int regnum;
151
152   /* Record where the jsra instruction saves the PC and FP.  */
153   cache->saved_regs[MOXIE_PC_REGNUM] = -4;
154   cache->saved_regs[MOXIE_FP_REGNUM] = 0;
155   cache->framesize = 0;
156
157   if (start_addr >= end_addr)
158     return end_addr;
159
160   for (next_addr = start_addr; next_addr < end_addr; )
161     {
162       inst = read_memory_unsigned_integer (next_addr, 2);
163
164       /* Match "push $rN" where N is between 2 and 13 inclusive.  */
165       if (inst >= 0x0614 && inst <= 0x061f)
166         {
167           regnum = inst & 0x000f;
168           cache->framesize += 4;
169           cache->saved_regs[regnum] = cache->framesize;
170           next_addr += 2;
171         }
172
173       /* Optional stack allocation for args and local vars <= 4
174          byte.  */
175       else if (inst == 0x01f0)           /* ldi.l $r12, X */
176         {
177           offset = read_memory_integer (next_addr + 2, 4);
178           inst2 = read_memory_unsigned_integer (next_addr + 6, 2);
179
180           if (inst2 == 0x051f)           /* add.l $sp, $r12 */
181             {
182               cache->framesize += offset;
183             }
184
185           return (next_addr + 8);
186         }
187       else  /* This is not a prologue instruction.  */
188         break;
189     }
190
191   return next_addr;
192 }
193
194 /* Find the end of function prologue.  */
195
196 static CORE_ADDR
197 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
198 {
199   CORE_ADDR func_addr = 0, func_end = 0;
200   char *func_name;
201
202   /* See if we can determine the end of the prologue via the symbol table.
203      If so, then return either PC, or the PC after the prologue, whichever
204      is greater.  */
205   if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
206     {
207       CORE_ADDR post_prologue_pc
208         = skip_prologue_using_sal (gdbarch, func_addr);
209       if (post_prologue_pc != 0)
210         return max (pc, post_prologue_pc);
211       else
212         {
213           /* Can't determine prologue from the symbol table, need to examine
214              instructions.  */
215           struct symtab_and_line sal;
216           struct symbol *sym;
217           struct moxie_frame_cache cache;
218           CORE_ADDR plg_end;
219           
220           memset (&cache, 0, sizeof cache);
221           
222           plg_end = moxie_analyze_prologue (func_addr, 
223                                             func_end, &cache, NULL);
224           /* Found a function.  */
225           sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
226           /* Don't use line number debug info for assembly source
227              files. */
228           if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
229             {
230               sal = find_pc_line (func_addr, 0);
231               if (sal.end && sal.end < func_end)
232                 {
233                   /* Found a line number, use it as end of
234                      prologue.  */
235                   return sal.end;
236                 }
237             }
238           /* No useable line symbol.  Use result of prologue parsing
239              method.  */
240           return plg_end;
241         }
242     }
243
244   /* No function symbol -- just return the PC.  */
245   return (CORE_ADDR) pc;
246 }
247
248 struct moxie_unwind_cache
249 {
250   /* The previous frame's inner most stack address.  Used as this
251      frame ID's stack_addr.  */
252   CORE_ADDR prev_sp;
253   /* The frame's base, optionally used by the high-level debug info.  */
254   CORE_ADDR base;
255   int size;
256   /* How far the SP and r13 (FP) have been offset from the start of
257      the stack frame (as defined by the previous frame's stack
258      pointer).  */
259   LONGEST sp_offset;
260   LONGEST r13_offset;
261   int uses_frame;
262   /* Table indicating the location of each and every register.  */
263   struct trad_frame_saved_reg *saved_regs;
264 };
265
266 /* Implement the "read_pc" gdbarch method.  */
267
268 static CORE_ADDR
269 moxie_read_pc (struct regcache *regcache)
270 {
271   ULONGEST pc;
272
273   regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc);
274   return pc;
275 }
276
277 /* Implement the "write_pc" gdbarch method.  */
278
279 static void
280 moxie_write_pc (struct regcache *regcache, CORE_ADDR val)
281 {
282   regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val);
283 }
284
285 /* Implement the "unwind_pc" gdbarch method.  */
286
287 static CORE_ADDR
288 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
289 {
290   return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
291 }
292
293 /* Given a return value in `regbuf' with a type `valtype', 
294    extract and copy its value into `valbuf'.  */
295
296 static void
297 moxie_extract_return_value (struct type *type, struct regcache *regcache,
298                            void *dst)
299 {
300   bfd_byte *valbuf = dst;
301   int len = TYPE_LENGTH (type);
302   ULONGEST tmp;
303
304   /* By using store_unsigned_integer we avoid having to do
305      anything special for small big-endian values.  */
306   regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
307   store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), tmp);
308
309   /* Ignore return values more than 8 bytes in size because the moxie
310      returns anything more than 8 bytes in the stack.  */
311   if (len > 4)
312     {
313       regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
314       store_unsigned_integer (valbuf + len - 4, 4, tmp);
315     }
316 }
317
318 /* Implement the "return_value" gdbarch method.  */
319
320 static enum return_value_convention
321 moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
322                    struct type *valtype, struct regcache *regcache,
323                    gdb_byte *readbuf, const gdb_byte *writebuf)
324 {
325   if (TYPE_LENGTH (valtype) > 8)
326     return RETURN_VALUE_STRUCT_CONVENTION;
327   else
328     {
329       if (readbuf != NULL)
330         moxie_extract_return_value (valtype, regcache, readbuf);
331       if (writebuf != NULL)
332         moxie_store_return_value (valtype, regcache, writebuf);
333       return RETURN_VALUE_REGISTER_CONVENTION;
334     }
335 }
336
337 /* Allocate and initialize a moxie_frame_cache object.  */
338
339 static struct moxie_frame_cache *
340 moxie_alloc_frame_cache (void)
341 {
342   struct moxie_frame_cache *cache;
343   int i;
344
345   cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);
346
347   cache->base = 0;
348   cache->saved_sp = 0;
349   cache->pc = 0;
350   cache->framesize = 0;
351   for (i = 0; i < MOXIE_NUM_REGS; ++i)
352     cache->saved_regs[i] = REG_UNAVAIL;
353
354   return cache;
355 }
356
357 /* Populate a moxie_frame_cache object for this_frame.  */
358
359 static struct moxie_frame_cache *
360 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
361 {
362   struct moxie_frame_cache *cache;
363   CORE_ADDR current_pc;
364   int i;
365
366   if (*this_cache)
367     return *this_cache;
368
369   cache = moxie_alloc_frame_cache ();
370   *this_cache = cache;
371
372   cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
373   if (cache->base == 0)
374     return cache;
375
376   cache->pc = get_frame_func (this_frame);
377   current_pc = get_frame_pc (this_frame);
378   if (cache->pc)
379     moxie_analyze_prologue (cache->pc, current_pc, cache, this_frame);
380
381   cache->saved_sp = cache->base - cache->framesize;
382
383   for (i = 0; i < MOXIE_NUM_REGS; ++i)
384     if (cache->saved_regs[i] != REG_UNAVAIL)
385       cache->saved_regs[i] = cache->base - cache->saved_regs[i];
386
387   return cache;
388 }
389
390 /* Implement the "unwind_pc" gdbarch method.  */
391
392 static CORE_ADDR
393 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
394 {
395   return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
396 }
397
398 /* Given a GDB frame, determine the address of the calling function's
399    frame.  This will be used to create a new GDB frame struct.  */
400
401 static void
402 moxie_frame_this_id (struct frame_info *this_frame,
403                     void **this_prologue_cache, struct frame_id *this_id)
404 {
405   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
406                                                    this_prologue_cache);
407
408   /* This marks the outermost frame.  */
409   if (cache->base == 0)
410     return;
411
412   *this_id = frame_id_build (cache->saved_sp, cache->pc);
413 }
414
415 /* Get the value of register regnum in the previous stack frame.  */
416
417 static struct value *
418 moxie_frame_prev_register (struct frame_info *this_frame,
419                           void **this_prologue_cache, int regnum)
420 {
421   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
422                                                    this_prologue_cache);
423
424   gdb_assert (regnum >= 0);
425
426   if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
427     return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
428
429   if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
430     return frame_unwind_got_memory (this_frame, regnum,
431                                     cache->saved_regs[regnum]);
432
433   return frame_unwind_got_register (this_frame, regnum, regnum);
434 }
435
436 static const struct frame_unwind moxie_frame_unwind = {
437   NORMAL_FRAME,
438   moxie_frame_this_id,
439   moxie_frame_prev_register,
440   NULL,
441   default_frame_sniffer
442 };
443
444 /* Return the base address of this_frame.  */
445
446 static CORE_ADDR
447 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
448 {
449   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
450                                                        this_cache);
451
452   return cache->base;
453 }
454
455 static const struct frame_base moxie_frame_base = {
456   &moxie_frame_unwind,
457   moxie_frame_base_address,
458   moxie_frame_base_address,
459   moxie_frame_base_address
460 };
461
462 static struct frame_id
463 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
464 {
465   CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);
466
467   return frame_id_build (sp, get_frame_pc (this_frame));
468 }
469
470 /* Allocate and initialize the moxie gdbarch object.  */
471
472 static struct gdbarch *
473 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
474 {
475   struct gdbarch *gdbarch;
476   struct gdbarch_tdep *tdep;
477
478   /* If there is already a candidate, use it.  */
479   arches = gdbarch_list_lookup_by_info (arches, &info);
480   if (arches != NULL)
481     return arches->gdbarch;
482
483   /* Allocate space for the new architecture.  */
484   tdep = XMALLOC (struct gdbarch_tdep);
485   gdbarch = gdbarch_alloc (&info, tdep);
486
487   set_gdbarch_read_pc (gdbarch, moxie_read_pc);
488   set_gdbarch_write_pc (gdbarch, moxie_write_pc);
489   set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);
490
491   set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
492   set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
493   set_gdbarch_register_name (gdbarch, moxie_register_name);
494   set_gdbarch_register_type (gdbarch, moxie_register_type);
495
496   set_gdbarch_return_value (gdbarch, moxie_return_value);
497
498   set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
499   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
500   set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc);
501   set_gdbarch_frame_align (gdbarch, moxie_frame_align);
502
503   frame_base_set_default (gdbarch, &moxie_frame_base);
504
505   /* Methods for saving / extracting a dummy frame's ID.  The ID's
506      stack address must match the SP value returned by
507      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
508   set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
509
510   set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
511
512   set_gdbarch_print_insn (gdbarch, print_insn_moxie);
513
514   /* Hook in ABI-specific overrides, if they have been registered.  */
515   gdbarch_init_osabi (info, gdbarch);
516
517   /* Hook in the default unwinders.  */
518   frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);
519
520   /* Support simple overlay manager.  */
521   set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
522
523   return gdbarch;
524 }
525
526 /* Register this machine's init routine.  */
527
528 void
529 _initialize_moxie_tdep (void)
530 {
531   register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
532 }