GDB (API)
/home/stan/gdb/src/gdb/microblaze-linux-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for Xilinx MicroBlaze.
00002 
00003    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "frame.h"
00022 #include "inferior.h"
00023 #include "symtab.h"
00024 #include "target.h"
00025 #include "gdbcore.h"
00026 #include "gdbcmd.h"
00027 #include "symfile.h"
00028 #include "objfiles.h"
00029 #include "regcache.h"
00030 #include "value.h"
00031 #include "osabi.h"
00032 #include "regset.h"
00033 #include "solib-svr4.h"
00034 #include "microblaze-tdep.h"
00035 #include "trad-frame.h"
00036 #include "frame-unwind.h"
00037 #include "tramp-frame.h"
00038 #include "linux-tdep.h"
00039 
00040 static int
00041 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, 
00042                                            struct bp_target_info *bp_tgt)
00043 {
00044   CORE_ADDR addr = bp_tgt->placed_address;
00045   const gdb_byte *bp;
00046   int val;
00047   int bplen;
00048   gdb_byte old_contents[BREAKPOINT_MAX];
00049 
00050   /* Determine appropriate breakpoint contents and size for this address.  */
00051   bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
00052   if (bp == NULL)
00053     error (_("Software breakpoints not implemented for this target."));
00054 
00055   val = target_read_memory (addr, old_contents, bplen);
00056 
00057   /* If our breakpoint is no longer at the address, this means that the
00058      program modified the code on us, so it is wrong to put back the
00059      old value.  */
00060   if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
00061     val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
00062 
00063   return val;
00064 }
00065 
00066 static void
00067 microblaze_linux_sigtramp_cache (struct frame_info *next_frame,
00068                                  struct trad_frame_cache *this_cache,
00069                                  CORE_ADDR func, LONGEST offset,
00070                                  int bias)
00071 {
00072   CORE_ADDR base;
00073   CORE_ADDR gpregs;
00074   int regnum;
00075   struct gdbarch *gdbarch = get_frame_arch (next_frame);
00076   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00077 
00078   base = frame_unwind_register_unsigned (next_frame, MICROBLAZE_SP_REGNUM);
00079   if (bias > 0 && get_frame_address_in_block (next_frame) != func)
00080     /* See below, some signal trampolines increment the stack as their
00081        first instruction, need to compensate for that.  */
00082     base -= bias;
00083 
00084   /* Find the address of the register buffer.  */
00085   gpregs = base + offset;
00086 
00087   /* Registers saved on stack.  */
00088   for (regnum = 0; regnum < MICROBLAZE_BTR_REGNUM; regnum++)
00089     trad_frame_set_reg_addr (this_cache, regnum, 
00090                              gpregs + regnum * MICROBLAZE_REGISTER_SIZE);
00091   trad_frame_set_id (this_cache, frame_id_build (base, func));
00092 }
00093 
00094 
00095 static void
00096 microblaze_linux_sighandler_cache_init (const struct tramp_frame *self,
00097                                         struct frame_info *next_frame,
00098                                         struct trad_frame_cache *this_cache,
00099                                         CORE_ADDR func)
00100 {
00101   microblaze_linux_sigtramp_cache (next_frame, this_cache, func,
00102                                    0 /* Offset to ucontext_t.  */
00103                                    + 24 /* Offset to .reg.  */,
00104                                    0);
00105 }
00106 
00107 static struct tramp_frame microblaze_linux_sighandler_tramp_frame = 
00108 {
00109   SIGTRAMP_FRAME,
00110   4,
00111   {
00112     { 0x31800077, -1 }, /* addik R12,R0,119.  */
00113     { 0xb9cc0008, -1 }, /* brki R14,8.  */
00114     { TRAMP_SENTINEL_INSN },
00115   },
00116   microblaze_linux_sighandler_cache_init
00117 };
00118 
00119 
00120 static void
00121 microblaze_linux_init_abi (struct gdbarch_info info,
00122                            struct gdbarch *gdbarch)
00123 {
00124   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00125 
00126   linux_init_abi (info, gdbarch);
00127 
00128   set_gdbarch_memory_remove_breakpoint (gdbarch,
00129                                         microblaze_linux_memory_remove_breakpoint);
00130 
00131   /* Shared library handling.  */
00132   set_solib_svr4_fetch_link_map_offsets (gdbarch,
00133                                          svr4_ilp32_fetch_link_map_offsets);
00134 
00135   /* Trampolines.  */
00136   tramp_frame_prepend_unwinder (gdbarch,
00137                                 &microblaze_linux_sighandler_tramp_frame);
00138 }
00139 
00140 /* -Wmissing-prototypes */
00141 extern initialize_file_ftype _initialize_microblaze_linux_tdep;
00142 
00143 void
00144 _initialize_microblaze_linux_tdep (void)
00145 {
00146   gdbarch_register_osabi (bfd_arch_microblaze, 0, GDB_OSABI_LINUX, 
00147                           microblaze_linux_init_abi);
00148 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines