GDB (xrefs)
/tmp/gdb-7.10/gdb/sh-linux-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for GNU/Linux Super-H.
2 
3  Copyright (C) 2005-2015 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 "osabi.h"
22 
23 #include "solib-svr4.h"
24 #include "symtab.h"
25 
26 #include "trad-frame.h"
27 #include "tramp-frame.h"
28 
29 #include "glibc-tdep.h"
30 #include "sh-tdep.h"
31 #include "linux-tdep.h"
32 
33 #define REGSx16(base) \
34  {(base), 0}, \
35  {(base) + 1, 4}, \
36  {(base) + 2, 8}, \
37  {(base) + 3, 12}, \
38  {(base) + 4, 16}, \
39  {(base) + 5, 20}, \
40  {(base) + 6, 24}, \
41  {(base) + 7, 28}, \
42  {(base) + 8, 32}, \
43  {(base) + 9, 36}, \
44  {(base) + 10, 40}, \
45  {(base) + 11, 44}, \
46  {(base) + 12, 48}, \
47  {(base) + 13, 52}, \
48  {(base) + 14, 56}, \
49  {(base) + 15, 60}
50 
51 /* Describe the contents of the .reg section of the core file. */
52 
53 static const struct sh_corefile_regmap gregs_table[] =
54 {
56  {PC_REGNUM, 64},
57  {PR_REGNUM, 68},
58  {SR_REGNUM, 72},
59  {GBR_REGNUM, 76},
60  {MACH_REGNUM, 80},
61  {MACL_REGNUM, 84},
62  {-1 /* Terminator. */, 0}
63 };
64 
65 /* Describe the contents of the .reg2 section of the core file. */
66 
67 static const struct sh_corefile_regmap fpregs_table[] =
68 {
70  /* REGSx16 xfp_regs omitted. */
71  {FPSCR_REGNUM, 128},
72  {FPUL_REGNUM, 132},
73  {-1 /* Terminator. */, 0}
74 };
75 
76 /* SH signal handler frame support. */
77 
78 static void
79 sh_linux_sigtramp_cache (struct frame_info *this_frame,
80  struct trad_frame_cache *this_cache,
81  CORE_ADDR func, int regs_offset)
82 {
83  int i;
84  struct gdbarch *gdbarch = get_frame_arch (this_frame);
85  CORE_ADDR base = get_frame_register_unsigned (this_frame,
86  gdbarch_sp_regnum (gdbarch));
87  CORE_ADDR regs = base + regs_offset;
88 
89  for (i = 0; i < 18; i++)
90  trad_frame_set_reg_addr (this_cache, i, regs + i * 4);
91 
92  trad_frame_set_reg_addr (this_cache, SR_REGNUM, regs + 18 * 4);
93  trad_frame_set_reg_addr (this_cache, GBR_REGNUM, regs + 19 * 4);
94  trad_frame_set_reg_addr (this_cache, MACH_REGNUM, regs + 20 * 4);
95  trad_frame_set_reg_addr (this_cache, MACL_REGNUM, regs + 21 * 4);
96 
97  /* Restore FP state if we have an FPU. */
98  if (gdbarch_fp0_regnum (gdbarch) != -1)
99  {
100  CORE_ADDR fpregs = regs + 22 * 4;
101  for (i = FR0_REGNUM; i <= FP_LAST_REGNUM; i++)
102  trad_frame_set_reg_addr (this_cache, i, fpregs + i * 4);
103  trad_frame_set_reg_addr (this_cache, FPSCR_REGNUM, fpregs + 32 * 4);
104  trad_frame_set_reg_addr (this_cache, FPUL_REGNUM, fpregs + 33 * 4);
105  }
106 
107  /* Save a frame ID. */
108  trad_frame_set_id (this_cache, frame_id_build (base, func));
109 }
110 
111 /* Implement struct tramp_frame "init" callbacks for signal
112  trampolines on 32-bit SH. */
113 
114 static void
116  struct frame_info *this_frame,
117  struct trad_frame_cache *this_cache,
118  CORE_ADDR func)
119 {
120  /* SH 32-bit sigframe: sigcontext at start of sigframe,
121  registers start after a single 'oldmask' word. */
122  sh_linux_sigtramp_cache (this_frame, this_cache, func, 4);
123 }
124 
125 static void
127  struct frame_info *this_frame,
128  struct trad_frame_cache *this_cache,
129  CORE_ADDR func)
130 {
131  /* SH 32-bit rt_sigframe: starts with a siginfo (128 bytes), then
132  we can find sigcontext embedded within a ucontext (offset 20 bytes).
133  Then registers start after a single 'oldmask' word. */
134  sh_linux_sigtramp_cache (this_frame, this_cache, func,
135  128 /* sizeof (struct siginfo) */
136  + 20 /* offsetof (struct ucontext, uc_mcontext) */
137  + 4 /* oldmask word at start of sigcontext */);
138 }
139 
140 /* Instruction patterns. */
141 #define SH_MOVW 0x9305
142 #define SH_TRAP 0xc300
143 #define SH_OR_R0_R0 0x200b
144 
145 /* SH sigreturn syscall numbers. */
146 #define SH_NR_SIGRETURN 0x0077
147 #define SH_NR_RT_SIGRETURN 0x00ad
148 
149 static struct tramp_frame sh_linux_sigreturn_tramp_frame = {
151  2,
152  {
153  { SH_MOVW, 0xffff },
154  { SH_TRAP, 0xff00 }, /* #imm argument part filtered out. */
155  { SH_OR_R0_R0, 0xffff },
156  { SH_OR_R0_R0, 0xffff },
157  { SH_OR_R0_R0, 0xffff },
158  { SH_OR_R0_R0, 0xffff },
159  { SH_OR_R0_R0, 0xffff },
160  { SH_NR_SIGRETURN, 0xffff },
162  },
164 };
165 
166 static struct tramp_frame sh_linux_rt_sigreturn_tramp_frame = {
168  2,
169  {
170  { SH_MOVW, 0xffff },
171  { SH_TRAP, 0xff00 }, /* #imm argument part filtered out. */
172  { SH_OR_R0_R0, 0xffff },
173  { SH_OR_R0_R0, 0xffff },
174  { SH_OR_R0_R0, 0xffff },
175  { SH_OR_R0_R0, 0xffff },
176  { SH_OR_R0_R0, 0xffff },
177  { SH_NR_RT_SIGRETURN, 0xffff },
179  },
181 };
182 
183 static void
185 {
186  linux_init_abi (info, gdbarch);
187 
188  /* GNU/Linux uses SVR4-style shared libraries. */
193 
196 
197  /* Core files and signal handler frame unwinding are supported for
198  32-bit SH only, at present. */
199  if (info.bfd_arch_info->mach != bfd_mach_sh5)
200  {
201  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
202 
203  /* Remember regset characteristics. The sizes should match
204  elf_gregset_t and elf_fpregset_t from Linux. */
205  tdep->core_gregmap = (struct sh_corefile_regmap *)gregs_table;
206  tdep->sizeof_gregset = 92;
207  tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregs_table;
208  tdep->sizeof_fpregset = 136;
209 
210  tramp_frame_prepend_unwinder (gdbarch, &sh_linux_sigreturn_tramp_frame);
211  tramp_frame_prepend_unwinder (gdbarch, &sh_linux_rt_sigreturn_tramp_frame);
212  }
213 }
214 
215 /* Provide a prototype to silence -Wmissing-prototypes. */
216 extern void _initialize_sh_linux_tdep (void);
217 
218 void
220 {
222 }
#define SH_NR_SIGRETURN
#define REGSx16(base)
Definition: sh-linux-tdep.c:33
void trad_frame_set_reg_addr(struct trad_frame_cache *this_trad_cache, int regnum, CORE_ADDR addr)
Definition: trad-frame.c:119
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:554
bfd_vma CORE_ADDR
Definition: common-types.h:41
void set_gdbarch_fetch_tls_load_module_address(struct gdbarch *gdbarch, gdbarch_fetch_tls_load_module_address_ftype fetch_tls_load_module_address)
Definition: gdbarch.c:2822
#define TRAMP_SENTINEL_INSN
Definition: tramp-frame.h:44
void(* func)(char *)
static void sh_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
void set_gdbarch_skip_trampoline_code(struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype skip_trampoline_code)
Definition: gdbarch.c:3084
CORE_ADDR glibc_skip_solib_resolver(struct gdbarch *gdbarch, CORE_ADDR pc)
Definition: glibc-tdep.c:38
void trad_frame_set_id(struct trad_frame_cache *this_trad_cache, struct frame_id this_id)
Definition: trad-frame.c:164
struct sh_corefile_regmap * core_fpregmap
Definition: sh-tdep.h:102
struct sh_corefile_regmap * core_gregmap
Definition: sh-tdep.h:97
#define SH_MOVW
void linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: linux-tdep.c:2427
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3149
#define SH_TRAP
size_t sizeof_fpregset
Definition: i386-tdep.h:64
const struct bfd_arch_info * bfd_arch_info
Definition: gdbarch.h:1549
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
CORE_ADDR svr4_fetch_objfile_link_map(struct objfile *objfile)
Definition: solib-svr4.c:1573
int gdbarch_sp_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:1981
CORE_ADDR find_solib_trampoline_target(struct frame_info *frame, CORE_ADDR pc)
Definition: minsyms.c:1394
static void sh_linux_rt_sigreturn_init(const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func)
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3108
static void sh_linux_sigreturn_init(const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func)
static void sh_linux_sigtramp_cache(struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, int regs_offset)
Definition: sh-linux-tdep.c:79
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
int gdbarch_fp0_regnum(struct gdbarch *gdbarch)
Definition: gdbarch.c:2032
void _initialize_sh_linux_tdep(void)
void tramp_frame_prepend_unwinder(struct gdbarch *gdbarch, const struct tramp_frame *tramp_frame)
Definition: tramp-frame.c:145
size_t sizeof_gregset
Definition: i386-tdep.h:61
#define SH_NR_RT_SIGRETURN
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype skip_solib_resolver)
Definition: gdbarch.c:3101
#define SH_OR_R0_R0
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition: osabi.c:148
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2535