GDB (API)
/home/stan/gdb/src/gdb/frv-linux-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for GNU/Linux running on the Fujitsu FR-V,
00002    for GDB.
00003 
00004    Copyright (C) 2004-2013 Free Software Foundation, Inc.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 #include "defs.h"
00022 #include "gdbcore.h"
00023 #include "target.h"
00024 #include "frame.h"
00025 #include "osabi.h"
00026 #include "regcache.h"
00027 #include "elf-bfd.h"
00028 #include "elf/frv.h"
00029 #include "frv-tdep.h"
00030 #include "trad-frame.h"
00031 #include "frame-unwind.h"
00032 #include "regset.h"
00033 #include "gdb_string.h"
00034 #include "linux-tdep.h"
00035 
00036 /* Define the size (in bytes) of an FR-V instruction.  */
00037 static const int frv_instr_size = 4;
00038 
00039 enum {
00040   NORMAL_SIGTRAMP = 1,
00041   RT_SIGTRAMP = 2
00042 };
00043 
00044 static int
00045 frv_linux_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc,
00046                           const char *name)
00047 {
00048   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00049   gdb_byte buf[frv_instr_size];
00050   LONGEST instr;
00051   int retval = 0;
00052 
00053   if (target_read_memory (pc, buf, sizeof buf) != 0)
00054     return 0;
00055 
00056   instr = extract_unsigned_integer (buf, sizeof buf, byte_order);
00057 
00058   if (instr == 0x8efc0077)      /* setlos #__NR_sigreturn, gr7 */
00059     retval = NORMAL_SIGTRAMP;
00060   else if (instr == 0x8efc00ad) /* setlos #__NR_rt_sigreturn, gr7 */
00061     retval = RT_SIGTRAMP;
00062   else
00063     return 0;
00064 
00065   if (target_read_memory (pc + frv_instr_size, buf, sizeof buf) != 0)
00066     return 0;
00067   instr = extract_unsigned_integer (buf, sizeof buf, byte_order);
00068   if (instr != 0xc0700000)      /* tira gr0, 0 */
00069     return 0;
00070 
00071   /* If we get this far, we'll return a non-zero value, either
00072      NORMAL_SIGTRAMP (1) or RT_SIGTRAMP (2).  */
00073   return retval;
00074 }
00075 
00076 /* Given NEXT_FRAME, the "callee" frame of the sigtramp frame that we
00077    wish to decode, and REGNO, one of the frv register numbers defined
00078    in frv-tdep.h, return the address of the saved register (corresponding
00079    to REGNO) in the sigtramp frame.  Return -1 if the register is not
00080    found in the sigtramp frame.  The magic numbers in the code below
00081    were computed by examining the following kernel structs:
00082 
00083    From arch/frv/kernel/signal.c:
00084 
00085       struct sigframe
00086       {
00087               void (*pretcode)(void);
00088               int sig;
00089               struct sigcontext sc;
00090               unsigned long extramask[_NSIG_WORDS-1];
00091               uint32_t retcode[2];
00092       };
00093 
00094       struct rt_sigframe
00095       {
00096               void (*pretcode)(void);
00097               int sig;
00098               struct siginfo *pinfo;
00099               void *puc;
00100               struct siginfo info;
00101               struct ucontext uc;
00102               uint32_t retcode[2];
00103       };
00104 
00105    From include/asm-frv/ucontext.h:
00106 
00107       struct ucontext {
00108               unsigned long             uc_flags;
00109               struct ucontext           *uc_link;
00110               stack_t                   uc_stack;
00111               struct sigcontext uc_mcontext;
00112               sigset_t          uc_sigmask;
00113       };
00114 
00115    From include/asm-frv/signal.h:
00116 
00117       typedef struct sigaltstack {
00118               void *ss_sp;
00119               int ss_flags;
00120               size_t ss_size;
00121       } stack_t;
00122 
00123    From include/asm-frv/sigcontext.h:
00124 
00125       struct sigcontext {
00126               struct user_context       sc_context;
00127               unsigned long             sc_oldmask;
00128       } __attribute__((aligned(8)));
00129 
00130    From include/asm-frv/registers.h:
00131       struct user_int_regs
00132       {
00133               unsigned long             psr;
00134               unsigned long             isr;
00135               unsigned long             ccr;
00136               unsigned long             cccr;
00137               unsigned long             lr;
00138               unsigned long             lcr;
00139               unsigned long             pc;
00140               unsigned long             __status;
00141               unsigned long             syscallno;
00142               unsigned long             orig_gr8;
00143               unsigned long             gner[2];
00144               unsigned long long        iacc[1];
00145 
00146               union {
00147                       unsigned long     tbr;
00148                       unsigned long     gr[64];
00149               };
00150       };
00151 
00152       struct user_fpmedia_regs
00153       {
00154               unsigned long     fr[64];
00155               unsigned long     fner[2];
00156               unsigned long     msr[2];
00157               unsigned long     acc[8];
00158               unsigned char     accg[8];
00159               unsigned long     fsr[1];
00160       };
00161 
00162       struct user_context
00163       {
00164               struct user_int_regs              i;
00165               struct user_fpmedia_regs  f;
00166 
00167               void *extension;
00168       } __attribute__((aligned(8)));  */
00169 
00170 static LONGEST
00171 frv_linux_sigcontext_reg_addr (struct frame_info *this_frame, int regno,
00172                                CORE_ADDR *sc_addr_cache_ptr)
00173 {
00174   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00175   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00176   CORE_ADDR sc_addr;
00177 
00178   if (sc_addr_cache_ptr && *sc_addr_cache_ptr)
00179     {
00180       sc_addr = *sc_addr_cache_ptr;
00181     }
00182   else
00183     {
00184       CORE_ADDR pc, sp;
00185       gdb_byte buf[4];
00186       int tramp_type;
00187 
00188       pc = get_frame_pc (this_frame);
00189       tramp_type = frv_linux_pc_in_sigtramp (gdbarch, pc, 0);
00190 
00191       get_frame_register (this_frame, sp_regnum, buf);
00192       sp = extract_unsigned_integer (buf, sizeof buf, byte_order);
00193 
00194       if (tramp_type == NORMAL_SIGTRAMP)
00195         {
00196           /* For a normal sigtramp frame, the sigcontext struct starts
00197              at SP + 8.  */
00198           sc_addr = sp + 8;
00199         }
00200       else if (tramp_type == RT_SIGTRAMP)
00201         {
00202           /* For a realtime sigtramp frame, SP + 12 contains a pointer
00203              to a ucontext struct.  The ucontext struct contains a
00204              sigcontext struct starting 24 bytes in.  (The offset of
00205              uc_mcontext within struct ucontext is derived as follows: 
00206              stack_t is a 12-byte struct and struct sigcontext is
00207              8-byte aligned.  This gives an offset of 8 + 12 + 4 (for
00208              padding) = 24.)  */
00209           if (target_read_memory (sp + 12, buf, sizeof buf) != 0)
00210             {
00211               warning (_("Can't read realtime sigtramp frame."));
00212               return 0;
00213             }
00214           sc_addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
00215           sc_addr += 24;
00216         }
00217       else
00218         internal_error (__FILE__, __LINE__, _("not a signal trampoline"));
00219 
00220       if (sc_addr_cache_ptr)
00221         *sc_addr_cache_ptr = sc_addr;
00222     }
00223 
00224   switch (regno)
00225     {
00226     case psr_regnum :
00227       return sc_addr + 0;
00228     /* sc_addr + 4 has "isr", the Integer Status Register.  */
00229     case ccr_regnum :
00230       return sc_addr + 8;
00231     case cccr_regnum :
00232       return sc_addr + 12;
00233     case lr_regnum :
00234       return sc_addr + 16;
00235     case lcr_regnum :
00236       return sc_addr + 20;
00237     case pc_regnum :
00238       return sc_addr + 24;
00239     /* sc_addr + 28 is __status, the exception status.
00240        sc_addr + 32 is syscallno, the syscall number or -1.
00241        sc_addr + 36 is orig_gr8, the original syscall arg #1.
00242        sc_addr + 40 is gner[0].
00243        sc_addr + 44 is gner[1].  */
00244     case iacc0h_regnum :
00245       return sc_addr + 48;
00246     case iacc0l_regnum :
00247       return sc_addr + 52;
00248     default : 
00249       if (first_gpr_regnum <= regno && regno <= last_gpr_regnum)
00250         return sc_addr + 56 + 4 * (regno - first_gpr_regnum);
00251       else if (first_fpr_regnum <= regno && regno <= last_fpr_regnum)
00252         return sc_addr + 312 + 4 * (regno - first_fpr_regnum);
00253       else
00254         return -1;  /* not saved.  */
00255     }
00256 }
00257 
00258 /* Signal trampolines.  */
00259 
00260 static struct trad_frame_cache *
00261 frv_linux_sigtramp_frame_cache (struct frame_info *this_frame,
00262                                 void **this_cache)
00263 {
00264   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00265   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00266   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00267   struct trad_frame_cache *cache;
00268   CORE_ADDR addr;
00269   gdb_byte buf[4];
00270   int regnum;
00271   CORE_ADDR sc_addr_cache_val = 0;
00272   struct frame_id this_id;
00273 
00274   if (*this_cache)
00275     return *this_cache;
00276 
00277   cache = trad_frame_cache_zalloc (this_frame);
00278 
00279   /* FIXME: cagney/2004-05-01: This is is long standing broken code.
00280      The frame ID's code address should be the start-address of the
00281      signal trampoline and not the current PC within that
00282      trampoline.  */
00283   get_frame_register (this_frame, sp_regnum, buf);
00284   addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
00285   this_id = frame_id_build (addr, get_frame_pc (this_frame));
00286   trad_frame_set_id (cache, this_id);
00287 
00288   for (regnum = 0; regnum < frv_num_regs; regnum++)
00289     {
00290       LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum,
00291                                                         &sc_addr_cache_val);
00292       if (reg_addr != -1)
00293         trad_frame_set_reg_addr (cache, regnum, reg_addr);
00294     }
00295 
00296   *this_cache = cache;
00297   return cache;
00298 }
00299 
00300 static void
00301 frv_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
00302                                   void **this_cache,
00303                                   struct frame_id *this_id)
00304 {
00305   struct trad_frame_cache *cache
00306     = frv_linux_sigtramp_frame_cache (this_frame, this_cache);
00307   trad_frame_get_id (cache, this_id);
00308 }
00309 
00310 static struct value *
00311 frv_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
00312                                         void **this_cache, int regnum)
00313 {
00314   /* Make sure we've initialized the cache.  */
00315   struct trad_frame_cache *cache
00316     = frv_linux_sigtramp_frame_cache (this_frame, this_cache);
00317   return trad_frame_get_register (cache, this_frame, regnum);
00318 }
00319 
00320 static int
00321 frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
00322                                   struct frame_info *this_frame,
00323                                   void **this_cache)
00324 {
00325   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00326   CORE_ADDR pc = get_frame_pc (this_frame);
00327   const char *name;
00328 
00329   find_pc_partial_function (pc, &name, NULL, NULL);
00330   if (frv_linux_pc_in_sigtramp (gdbarch, pc, name))
00331     return 1;
00332 
00333   return 0;
00334 }
00335 
00336 static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
00337 {
00338   SIGTRAMP_FRAME,
00339   default_frame_unwind_stop_reason,
00340   frv_linux_sigtramp_frame_this_id,
00341   frv_linux_sigtramp_frame_prev_register,
00342   NULL,
00343   frv_linux_sigtramp_frame_sniffer
00344 };
00345 
00346 /* The FRV kernel defines ELF_NGREG as 46.  We add 2 in order to include
00347    the loadmap addresses in the register set.  (See below for more info.)  */
00348 #define FRV_ELF_NGREG (46 + 2)
00349 typedef unsigned char frv_elf_greg_t[4];
00350 typedef struct { frv_elf_greg_t reg[FRV_ELF_NGREG]; } frv_elf_gregset_t;
00351 
00352 typedef unsigned char frv_elf_fpreg_t[4];
00353 typedef struct
00354 {
00355   frv_elf_fpreg_t fr[64];
00356   frv_elf_fpreg_t fner[2];
00357   frv_elf_fpreg_t msr[2];
00358   frv_elf_fpreg_t acc[8];
00359   unsigned char accg[8];
00360   frv_elf_fpreg_t fsr[1];
00361 } frv_elf_fpregset_t;
00362 
00363 /* Constants for accessing elements of frv_elf_gregset_t.  */
00364 
00365 #define FRV_PT_PSR 0
00366 #define FRV_PT_ISR 1
00367 #define FRV_PT_CCR 2
00368 #define FRV_PT_CCCR 3
00369 #define FRV_PT_LR 4
00370 #define FRV_PT_LCR 5
00371 #define FRV_PT_PC 6
00372 #define FRV_PT_GNER0 10
00373 #define FRV_PT_GNER1 11
00374 #define FRV_PT_IACC0H 12
00375 #define FRV_PT_IACC0L 13
00376 
00377 /* Note: Only 32 of the GRs will be found in the corefile.  */
00378 #define FRV_PT_GR(j)    ( 14 + (j))     /* GRj for 0<=j<=63.  */
00379 
00380 #define FRV_PT_TBR FRV_PT_GR(0)         /* gr0 is always 0, so TBR is stuffed
00381                                            there.  */
00382 
00383 /* Technically, the loadmap addresses are not part of `pr_reg' as
00384    found in the elf_prstatus struct.  The fields which communicate the
00385    loadmap address appear (by design) immediately after `pr_reg'
00386    though, and the BFD function elf32_frv_grok_prstatus() has been
00387    implemented to include these fields in the register section that it
00388    extracts from the core file.  So, for our purposes, they may be
00389    viewed as registers.  */
00390 
00391 #define FRV_PT_EXEC_FDPIC_LOADMAP 46
00392 #define FRV_PT_INTERP_FDPIC_LOADMAP 47
00393 
00394 
00395 /* Unpack an frv_elf_gregset_t into GDB's register cache.  */
00396 
00397 static void 
00398 frv_linux_supply_gregset (const struct regset *regset,
00399                           struct regcache *regcache,
00400                           int regnum, const void *gregs, size_t len)
00401 {
00402   int regi;
00403   char zerobuf[MAX_REGISTER_SIZE];
00404   const frv_elf_gregset_t *gregsetp = gregs;
00405 
00406   memset (zerobuf, 0, MAX_REGISTER_SIZE);
00407 
00408   /* gr0 always contains 0.  Also, the kernel passes the TBR value in
00409      this slot.  */
00410   regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);
00411 
00412   for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
00413     {
00414       if (regi >= first_gpr_regnum + 32)
00415         regcache_raw_supply (regcache, regi, zerobuf);
00416       else
00417         regcache_raw_supply (regcache, regi,
00418                              gregsetp->reg[FRV_PT_GR (regi
00419                                                       - first_gpr_regnum)]);
00420     }
00421 
00422   regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
00423   regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
00424   regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
00425   regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
00426   regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
00427   regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
00428   regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
00429   regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
00430   regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
00431   regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
00432                        gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
00433   regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
00434                        gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
00435 }
00436 
00437 /* Unpack an frv_elf_fpregset_t into GDB's register cache.  */
00438 
00439 static void
00440 frv_linux_supply_fpregset (const struct regset *regset,
00441                            struct regcache *regcache,
00442                            int regnum, const void *gregs, size_t len)
00443 {
00444   int regi;
00445   const frv_elf_fpregset_t *fpregsetp = gregs;
00446 
00447   for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
00448     regcache_raw_supply (regcache, regi,
00449                          fpregsetp->fr[regi - first_fpr_regnum]);
00450 
00451   regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
00452   regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);
00453 
00454   regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
00455   regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);
00456 
00457   for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
00458     regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);
00459 
00460   regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
00461   regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);
00462 
00463   regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
00464 }
00465 
00466 /* FRV Linux kernel register sets.  */
00467 
00468 static struct regset frv_linux_gregset =
00469 {
00470   NULL,
00471   frv_linux_supply_gregset
00472 };
00473 
00474 static struct regset frv_linux_fpregset =
00475 {
00476   NULL,
00477   frv_linux_supply_fpregset
00478 };
00479 
00480 static const struct regset *
00481 frv_linux_regset_from_core_section (struct gdbarch *gdbarch,
00482                                     const char *sect_name, size_t sect_size)
00483 {
00484   if (strcmp (sect_name, ".reg") == 0 
00485       && sect_size >= sizeof (frv_elf_gregset_t))
00486     return &frv_linux_gregset;
00487 
00488   if (strcmp (sect_name, ".reg2") == 0 
00489       && sect_size >= sizeof (frv_elf_fpregset_t))
00490     return &frv_linux_fpregset;
00491 
00492   return NULL;
00493 }
00494 
00495 
00496 static void
00497 frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00498 {
00499   linux_init_abi (info, gdbarch);
00500 
00501   /* Set the sigtramp frame sniffer.  */
00502   frame_unwind_append_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind); 
00503 
00504   set_gdbarch_regset_from_core_section (gdbarch,
00505                                         frv_linux_regset_from_core_section);
00506 }
00507 
00508 static enum gdb_osabi
00509 frv_linux_elf_osabi_sniffer (bfd *abfd)
00510 {
00511   int elf_flags;
00512 
00513   elf_flags = elf_elfheader (abfd)->e_flags;
00514 
00515   /* Assume GNU/Linux if using the FDPIC ABI.  If/when another OS shows
00516      up that uses this ABI, we'll need to start using .note sections
00517      or some such.  */
00518   if (elf_flags & EF_FRV_FDPIC)
00519     return GDB_OSABI_LINUX;
00520   else
00521     return GDB_OSABI_UNKNOWN;
00522 }
00523 
00524 /* Provide a prototype to silence -Wmissing-prototypes.  */
00525 void _initialize_frv_linux_tdep (void);
00526 
00527 void
00528 _initialize_frv_linux_tdep (void)
00529 {
00530   gdbarch_register_osabi (bfd_arch_frv, 0, GDB_OSABI_LINUX,
00531                           frv_linux_init_abi);
00532   gdbarch_register_osabi_sniffer (bfd_arch_frv,
00533                                   bfd_target_elf_flavour,
00534                                   frv_linux_elf_osabi_sniffer);
00535 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines