* dwarf2read.c (dwarf2_symbol_mark_computed): Handle corrupted
[platform/upstream/binutils.git] / gdb / frv-linux-tdep.c
1 /* Target-dependent code for GNU/Linux running on the Fujitsu FR-V,
2    for GDB.
3    Copyright (C) 2004 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., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "defs.h"
23 #include "gdbcore.h"
24 #include "target.h"
25 #include "frame.h"
26 #include "osabi.h"
27 #include "regcache.h"
28 #include "elf-bfd.h"
29 #include "elf/frv.h"
30 #include "frv-tdep.h"
31 #include "trad-frame.h"
32 #include "frame-unwind.h"
33 #include "regset.h"
34 #include "gdb_string.h"
35
36 /* Define the size (in bytes) of an FR-V instruction.  */
37 static const int frv_instr_size = 4;
38
39 enum {
40   NORMAL_SIGTRAMP = 1,
41   RT_SIGTRAMP = 2
42 };
43
44 static int
45 frv_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
46 {
47   char buf[frv_instr_size];
48   LONGEST instr;
49   int retval = 0;
50
51   if (target_read_memory (pc, buf, sizeof buf) != 0)
52     return 0;
53
54   instr = extract_unsigned_integer (buf, sizeof buf);
55
56   if (instr == 0x8efc0077)      /* setlos #__NR_sigreturn, gr7 */
57     retval = NORMAL_SIGTRAMP;
58   else if (instr -= 0x8efc00ad) /* setlos #__NR_rt_sigreturn, gr7 */
59     retval = RT_SIGTRAMP;
60   else
61     return 0;
62
63   if (target_read_memory (pc + frv_instr_size, buf, sizeof buf) != 0)
64     return 0;
65   instr = extract_unsigned_integer (buf, sizeof buf);
66   if (instr != 0xc0700000)      /* tira gr0, 0 */
67     return 0;
68
69   /* If we get this far, we'll return a non-zero value, either
70      NORMAL_SIGTRAMP (1) or RT_SIGTRAMP (2).  */
71   return retval;
72 }
73
74 /* Given NEXT_FRAME, the "callee" frame of the sigtramp frame that we
75    wish to decode, and REGNO, one of the frv register numbers defined
76    in frv-tdep.h, return the address of the saved register (corresponding
77    to REGNO) in the sigtramp frame.  Return -1 if the register is not
78    found in the sigtramp frame.  The magic numbers in the code below
79    were computed by examining the following kernel structs:
80
81    From arch/frv/kernel/signal.c:
82
83       struct sigframe
84       {
85               void (*pretcode)(void);
86               int sig;
87               struct sigcontext sc;
88               unsigned long extramask[_NSIG_WORDS-1];
89               uint32_t retcode[2];
90       };
91
92       struct rt_sigframe
93       {
94               void (*pretcode)(void);
95               int sig;
96               struct siginfo *pinfo;
97               void *puc;
98               struct siginfo info;
99               struct ucontext uc;
100               uint32_t retcode[2];
101       };
102
103    From include/asm-frv/ucontext.h:
104
105       struct ucontext {
106               unsigned long             uc_flags;
107               struct ucontext           *uc_link;
108               stack_t                   uc_stack;
109               struct sigcontext uc_mcontext;
110               sigset_t          uc_sigmask;
111       };
112
113    From include/asm-frv/signal.h:
114
115       typedef struct sigaltstack {
116               void *ss_sp;
117               int ss_flags;
118               size_t ss_size;
119       } stack_t;
120
121    From include/asm-frv/sigcontext.h:
122
123       struct sigcontext {
124               struct user_context       sc_context;
125               unsigned long             sc_oldmask;
126       } __attribute__((aligned(8)));
127
128    From include/asm-frv/registers.h:
129       struct user_int_regs
130       {
131               unsigned long             psr;
132               unsigned long             isr;
133               unsigned long             ccr;
134               unsigned long             cccr;
135               unsigned long             lr;
136               unsigned long             lcr;
137               unsigned long             pc;
138               unsigned long             __status;
139               unsigned long             syscallno;
140               unsigned long             orig_gr8;
141               unsigned long             gner[2];
142               unsigned long long        iacc[1];
143
144               union {
145                       unsigned long     tbr;
146                       unsigned long     gr[64];
147               };
148       };
149
150       struct user_fpmedia_regs
151       {
152               unsigned long     fr[64];
153               unsigned long     fner[2];
154               unsigned long     msr[2];
155               unsigned long     acc[8];
156               unsigned char     accg[8];
157               unsigned long     fsr[1];
158       };
159
160       struct user_context
161       {
162               struct user_int_regs              i;
163               struct user_fpmedia_regs  f;
164
165               void *extension;
166       } __attribute__((aligned(8)));  */
167
168 static LONGEST
169 frv_linux_sigcontext_reg_addr (struct frame_info *next_frame, int regno,
170                                CORE_ADDR *sc_addr_cache_ptr)
171 {
172   CORE_ADDR sc_addr;
173
174   if (sc_addr_cache_ptr && *sc_addr_cache_ptr)
175     {
176       sc_addr = *sc_addr_cache_ptr;
177     }
178   else
179     {
180       CORE_ADDR pc, sp;
181       char buf[4];
182       int tramp_type;
183
184       pc = frame_pc_unwind (next_frame);
185       tramp_type = frv_linux_pc_in_sigtramp (pc, 0);
186
187       frame_unwind_register (next_frame, sp_regnum, buf);
188       sp = extract_unsigned_integer (buf, sizeof buf);
189
190       if (tramp_type == NORMAL_SIGTRAMP)
191         {
192           /* For a normal sigtramp frame, the sigcontext struct starts
193              at SP + 8.  */
194           sc_addr = sp + 8;
195         }
196       else if (tramp_type == RT_SIGTRAMP)
197         {
198           /* For a realtime sigtramp frame, SP + 12 contains a pointer
199              to a ucontext struct.  The ucontext struct contains a
200              sigcontext struct starting 24 bytes in.  (The offset of
201              uc_mcontext within struct ucontext is derived as follows: 
202              stack_t is a 12-byte struct and struct sigcontext is
203              8-byte aligned.  This gives an offset of 8 + 12 + 4 (for
204              padding) = 24.) */
205           if (target_read_memory (sp + 12, buf, sizeof buf) != 0)
206             {
207               warning (_("Can't read realtime sigtramp frame."));
208               return 0;
209             }
210           sc_addr = extract_unsigned_integer (buf, sizeof buf);
211           sc_addr += 24;
212         }
213       else
214         internal_error (__FILE__, __LINE__, _("not a signal trampoline"));
215
216       if (sc_addr_cache_ptr)
217         *sc_addr_cache_ptr = sc_addr;
218     }
219
220   switch (regno)
221     {
222     case psr_regnum :
223       return sc_addr + 0;
224     /* sc_addr + 4 has "isr", the Integer Status Register.  */
225     case ccr_regnum :
226       return sc_addr + 8;
227     case cccr_regnum :
228       return sc_addr + 12;
229     case lr_regnum :
230       return sc_addr + 16;
231     case lcr_regnum :
232       return sc_addr + 20;
233     case pc_regnum :
234       return sc_addr + 24;
235     /* sc_addr + 28 is __status, the exception status.
236        sc_addr + 32 is syscallno, the syscall number or -1.
237        sc_addr + 36 is orig_gr8, the original syscall arg #1.
238        sc_addr + 40 is gner[0].
239        sc_addr + 44 is gner[1]. */
240     case iacc0h_regnum :
241       return sc_addr + 48;
242     case iacc0l_regnum :
243       return sc_addr + 52;
244     default : 
245       if (first_gpr_regnum <= regno && regno <= last_gpr_regnum)
246         return sc_addr + 56 + 4 * (regno - first_gpr_regnum);
247       else if (first_fpr_regnum <= regno && regno <= last_fpr_regnum)
248         return sc_addr + 312 + 4 * (regno - first_fpr_regnum);
249       else
250         return -1;  /* not saved. */
251     }
252 }
253
254 /* Signal trampolines.  */
255
256 static struct trad_frame_cache *
257 frv_linux_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
258 {
259   struct trad_frame_cache *cache;
260   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
261   CORE_ADDR addr;
262   char buf[4];
263   int regnum;
264   CORE_ADDR sc_addr_cache_val = 0;
265   struct frame_id this_id;
266
267   if (*this_cache)
268     return *this_cache;
269
270   cache = trad_frame_cache_zalloc (next_frame);
271
272   /* FIXME: cagney/2004-05-01: This is is long standing broken code.
273      The frame ID's code address should be the start-address of the
274      signal trampoline and not the current PC within that
275      trampoline.  */
276   frame_unwind_register (next_frame, sp_regnum, buf);
277   this_id = frame_id_build (extract_unsigned_integer (buf, sizeof buf),
278                             frame_pc_unwind (next_frame));
279   trad_frame_set_id (cache, this_id);
280
281   for (regnum = 0; regnum < frv_num_regs; regnum++)
282     {
283       LONGEST reg_addr = frv_linux_sigcontext_reg_addr (next_frame, regnum,
284                                                         &sc_addr_cache_val);
285       if (reg_addr != -1)
286         trad_frame_set_reg_addr (cache, regnum, reg_addr);
287     }
288
289   *this_cache = cache;
290   return cache;
291 }
292
293 static void
294 frv_linux_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
295                              struct frame_id *this_id)
296 {
297   struct trad_frame_cache *cache =
298     frv_linux_sigtramp_frame_cache (next_frame, this_cache);
299   trad_frame_get_id (cache, this_id);
300 }
301
302 static void
303 frv_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
304                                    void **this_cache,
305                                    int regnum, int *optimizedp,
306                                    enum lval_type *lvalp, CORE_ADDR *addrp,
307                                    int *realnump, gdb_byte *valuep)
308 {
309   /* Make sure we've initialized the cache.  */
310   struct trad_frame_cache *cache =
311     frv_linux_sigtramp_frame_cache (next_frame, this_cache);
312   trad_frame_get_register (cache, next_frame, regnum, optimizedp, lvalp,
313                            addrp, realnump, valuep);
314 }
315
316 static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
317 {
318   SIGTRAMP_FRAME,
319   frv_linux_sigtramp_frame_this_id,
320   frv_linux_sigtramp_frame_prev_register
321 };
322
323 static const struct frame_unwind *
324 frv_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
325 {
326   CORE_ADDR pc = frame_pc_unwind (next_frame);
327   char *name;
328
329   find_pc_partial_function (pc, &name, NULL, NULL);
330   if (frv_linux_pc_in_sigtramp (pc, name))
331     return &frv_linux_sigtramp_frame_unwind;
332
333   return NULL;
334 }
335
336 \f
337 /* The FRV kernel defines ELF_NGREG as 46.  We add 2 in order to include
338    the loadmap addresses in the register set.  (See below for more info.)  */
339 #define FRV_ELF_NGREG (46 + 2)
340 typedef unsigned char frv_elf_greg_t[4];
341 typedef struct { frv_elf_greg_t reg[FRV_ELF_NGREG]; } frv_elf_gregset_t;
342
343 typedef unsigned char frv_elf_fpreg_t[4];
344 typedef struct
345 {
346   frv_elf_fpreg_t fr[64];
347   frv_elf_fpreg_t fner[2];
348   frv_elf_fpreg_t msr[2];
349   frv_elf_fpreg_t acc[8];
350   unsigned char accg[8];
351   frv_elf_fpreg_t fsr[1];
352 } frv_elf_fpregset_t;
353
354 /* Constants for accessing elements of frv_elf_gregset_t.  */
355
356 #define FRV_PT_PSR 0
357 #define FRV_PT_ISR 1
358 #define FRV_PT_CCR 2
359 #define FRV_PT_CCCR 3
360 #define FRV_PT_LR 4
361 #define FRV_PT_LCR 5
362 #define FRV_PT_PC 6
363 #define FRV_PT_GNER0 10
364 #define FRV_PT_GNER1 11
365 #define FRV_PT_IACC0H 12
366 #define FRV_PT_IACC0L 13
367
368 /* Note: Only 32 of the GRs will be found in the corefile.  */
369 #define FRV_PT_GR(j)    ( 14 + (j))     /* GRj for 0<=j<=63. */
370
371 #define FRV_PT_TBR FRV_PT_GR(0)         /* gr0 is always 0, so TBR is stuffed
372                                            there.  */
373
374 /* Technically, the loadmap addresses are not part of `pr_reg' as
375    found in the elf_prstatus struct.  The fields which communicate the
376    loadmap address appear (by design) immediately after `pr_reg'
377    though, and the BFD function elf32_frv_grok_prstatus() has been
378    implemented to include these fields in the register section that it
379    extracts from the core file.  So, for our purposes, they may be
380    viewed as registers.  */
381
382 #define FRV_PT_EXEC_FDPIC_LOADMAP 46
383 #define FRV_PT_INTERP_FDPIC_LOADMAP 47
384
385
386 /* Unpack an frv_elf_gregset_t into GDB's register cache.  */
387
388 static void 
389 frv_linux_supply_gregset (const struct regset *regset,
390                           struct regcache *regcache,
391                           int regnum, const void *gregs, size_t len)
392 {
393   int regi;
394   char zerobuf[MAX_REGISTER_SIZE];
395   const frv_elf_gregset_t *gregsetp = gregs;
396
397   memset (zerobuf, 0, MAX_REGISTER_SIZE);
398
399   /* gr0 always contains 0.  Also, the kernel passes the TBR value in
400      this slot.  */
401   regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);
402
403   for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
404     {
405       if (regi >= first_gpr_regnum + 32)
406         regcache_raw_supply (regcache, regi, zerobuf);
407       else
408         regcache_raw_supply (regcache, regi,
409                              gregsetp->reg[FRV_PT_GR (regi - first_gpr_regnum)]);
410     }
411
412   regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
413   regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
414   regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
415   regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
416   regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
417   regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
418   regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
419   regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
420   regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
421   regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
422                        gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
423   regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
424                        gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
425 }
426
427 /* Unpack an frv_elf_fpregset_t into GDB's register cache.  */
428
429 static void
430 frv_linux_supply_fpregset (const struct regset *regset,
431                            struct regcache *regcache,
432                            int regnum, const void *gregs, size_t len)
433 {
434   int regi;
435   const frv_elf_fpregset_t *fpregsetp = gregs;
436
437   for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
438     regcache_raw_supply (regcache, regi, fpregsetp->fr[regi - first_fpr_regnum]);
439
440   regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
441   regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);
442
443   regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
444   regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);
445
446   for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
447     regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);
448
449   regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
450   regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);
451
452   regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
453 }
454
455 /* FRV Linux register sets.  */
456
457 static struct regset frv_linux_gregset =
458 {
459   NULL,
460   frv_linux_supply_gregset
461 };
462
463 static struct regset frv_linux_fpregset =
464 {
465   NULL,
466   frv_linux_supply_fpregset
467 };
468
469 static const struct regset *
470 frv_linux_regset_from_core_section (struct gdbarch *gdbarch,
471                                     const char *sect_name, size_t sect_size)
472 {
473   if (strcmp (sect_name, ".reg") == 0 
474       && sect_size >= sizeof (frv_elf_gregset_t))
475     return &frv_linux_gregset;
476
477   if (strcmp (sect_name, ".reg2") == 0 
478       && sect_size >= sizeof (frv_elf_fpregset_t))
479     return &frv_linux_fpregset;
480
481   return NULL;
482 }
483
484 \f
485 static void
486 frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
487 {
488   /* Set the sigtramp frame sniffer.  */
489   frame_unwind_append_sniffer (gdbarch, frv_linux_sigtramp_frame_sniffer); 
490   set_gdbarch_regset_from_core_section (gdbarch,
491                                         frv_linux_regset_from_core_section);
492 }
493
494 static enum gdb_osabi
495 frv_linux_elf_osabi_sniffer (bfd *abfd)
496 {
497   int elf_flags;
498
499   elf_flags = elf_elfheader (abfd)->e_flags;
500
501   /* Assume GNU/Linux if using the FDPIC ABI.  If/when another OS shows
502      up that uses this ABI, we'll need to start using .note sections
503      or some such.  */
504   if (elf_flags & EF_FRV_FDPIC)
505     return GDB_OSABI_LINUX;
506   else
507     return GDB_OSABI_UNKNOWN;
508 }
509
510 /* Provide a prototype to silence -Wmissing-prototypes.  */
511 void _initialize_frv_linux_tdep (void);
512
513 void
514 _initialize_frv_linux_tdep (void)
515 {
516   gdbarch_register_osabi (bfd_arch_frv, 0, GDB_OSABI_LINUX, frv_linux_init_abi);
517   gdbarch_register_osabi_sniffer (bfd_arch_frv,
518                                   bfd_target_elf_flavour,
519                                   frv_linux_elf_osabi_sniffer);
520 }