GDB (API)
|
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 µblaze_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 }