GDB (xrefs)
/tmp/gdb-7.10/gdb/nto-tdep.c
Go to the documentation of this file.
1 /* nto-tdep.c - general QNX Neutrino target functionality.
2 
3  Copyright (C) 2003-2015 Free Software Foundation, Inc.
4 
5  Contributed by QNX Software Systems Ltd.
6 
7  This file is part of GDB.
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 
22 #include "defs.h"
23 #include <sys/stat.h>
24 #include "nto-tdep.h"
25 #include "top.h"
26 #include "inferior.h"
27 #include "infrun.h"
28 #include "gdbarch.h"
29 #include "bfd.h"
30 #include "elf-bfd.h"
31 #include "solib-svr4.h"
32 #include "gdbcore.h"
33 #include "objfiles.h"
34 
35 #ifdef __CYGWIN__
36 #include <sys/cygwin.h>
37 #endif
38 
39 #ifdef __CYGWIN__
40 static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
41 #elif defined(__sun__) || defined(linux)
42 static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
43 #else
44 static char default_nto_target[] = "";
45 #endif
46 
48 
49 static char *
50 nto_target (void)
51 {
52  char *p = getenv ("QNX_TARGET");
53 
54 #ifdef __CYGWIN__
55  static char buf[PATH_MAX];
56  if (p)
57  cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
58  else
59  cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
60  return buf;
61 #else
62  return p ? p : default_nto_target;
63 #endif
64 }
65 
66 /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
67  CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
68 int
69 nto_map_arch_to_cputype (const char *arch)
70 {
71  if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
72  return CPUTYPE_X86;
73  if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
74  return CPUTYPE_PPC;
75  if (!strcmp (arch, "mips"))
76  return CPUTYPE_MIPS;
77  if (!strcmp (arch, "arm"))
78  return CPUTYPE_ARM;
79  if (!strcmp (arch, "sh"))
80  return CPUTYPE_SH;
81  return CPUTYPE_UNKNOWN;
82 }
83 
84 int
85 nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
86 {
87  char *buf, *arch_path, *nto_root;
88  const char *endian;
89  const char *base;
90  const char *arch;
91  int arch_len, len, ret;
92 #define PATH_FMT \
93  "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
94 
95  nto_root = nto_target ();
96  if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
97  {
98  arch = "x86";
99  endian = "";
100  }
101  else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
102  "rs6000") == 0
103  || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
104  "powerpc") == 0)
105  {
106  arch = "ppc";
107  endian = "be";
108  }
109  else
110  {
111  arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
112  endian = gdbarch_byte_order (target_gdbarch ())
113  == BFD_ENDIAN_BIG ? "be" : "le";
114  }
115 
116  /* In case nto_root is short, add strlen(solib)
117  so we can reuse arch_path below. */
118 
119  arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
120  + strlen (solib));
121  arch_path = alloca (arch_len);
122  xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
123 
124  len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
125  buf = alloca (len);
126  xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
127  arch_path);
128 
129  base = lbasename (solib);
130  ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
131  temp_pathname);
132  if (ret < 0 && base != solib)
133  {
134  xsnprintf (arch_path, arch_len, "/%s", solib);
135  ret = open (arch_path, o_flags, 0);
136  if (temp_pathname)
137  {
138  if (ret >= 0)
139  *temp_pathname = gdb_realpath (arch_path);
140  else
141  *temp_pathname = NULL;
142  }
143  }
144  return ret;
145 }
146 
147 void
149 {
150  char buf[PATH_MAX * 2], arch_path[PATH_MAX];
151  char *nto_root;
152  const char *endian;
153  const char *arch;
154 
155  nto_root = nto_target ();
156  if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
157  {
158  arch = "x86";
159  endian = "";
160  }
161  else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
162  "rs6000") == 0
163  || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
164  "powerpc") == 0)
165  {
166  arch = "ppc";
167  endian = "be";
168  }
169  else
170  {
171  arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
172  endian = gdbarch_byte_order (target_gdbarch ())
173  == BFD_ENDIAN_BIG ? "be" : "le";
174  }
175 
176  xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
177 
178  xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
179  execute_command (buf, 0);
180 }
181 
182 char **
183 nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
184  const char **perr)
185 {
186  char **argv;
187  char *in, *out, *err, *p;
188  int argc, i, n;
189 
190  for (n = 0; pargv[n]; n++);
191  if (n == 0)
192  return NULL;
193  in = "";
194  out = "";
195  err = "";
196 
197  argv = xcalloc (n + 1, sizeof argv[0]);
198  argc = n;
199  for (i = 0, n = 0; n < argc; n++)
200  {
201  p = pargv[n];
202  if (*p == '>')
203  {
204  p++;
205  if (*p)
206  out = p;
207  else
208  out = pargv[++n];
209  }
210  else if (*p == '<')
211  {
212  p++;
213  if (*p)
214  in = p;
215  else
216  in = pargv[++n];
217  }
218  else if (*p++ == '2' && *p++ == '>')
219  {
220  if (*p == '&' && *(p + 1) == '1')
221  err = out;
222  else if (*p)
223  err = p;
224  else
225  err = pargv[++n];
226  }
227  else
228  argv[i++] = pargv[n];
229  }
230  *pin = in;
231  *pout = out;
232  *perr = err;
233  return argv;
234 }
235 
236 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
237  solib-svr4.c to support nto_relocate_section_addresses
238  which is different from the svr4 version. */
239 
240 /* Link map info to include in an allocated so_list entry */
241 
242 struct lm_info
243  {
244  /* Pointer to copy of link map from inferior. The type is char *
245  rather than void *, so that we may use byte offsets to find the
246  various fields without the need for a cast. */
248 
249  /* Amount by which addresses in the binary should be relocated to
250  match the inferior. This could most often be taken directly
251  from lm, but when prelinking is involved and the prelink base
252  address changes, we may need a different offset, we want to
253  warn about the difference and compute it only once. */
255 
256  /* The target location of lm. */
258  };
259 
260 
261 static CORE_ADDR
262 lm_addr (struct so_list *so)
263 {
264  if (so->lm_info->l_addr == (CORE_ADDR)-1)
265  {
267  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
268 
269  so->lm_info->l_addr =
270  extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
271  }
272  return so->lm_info->l_addr;
273 }
274 
275 static CORE_ADDR
277 {
278  if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
279  /* We don't need to truncate anything, and the bit twiddling below
280  will fail due to overflow problems. */
281  return addr;
282  else
283  return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
284 }
285 
286 static Elf_Internal_Phdr *
287 find_load_phdr (bfd *abfd)
288 {
289  Elf_Internal_Phdr *phdr;
290  unsigned int i;
291 
292  if (!elf_tdata (abfd))
293  return NULL;
294 
295  phdr = elf_tdata (abfd)->phdr;
296  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
297  {
298  if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
299  return phdr;
300  }
301  return NULL;
302 }
303 
304 void
306 {
307  /* Neutrino treats the l_addr base address field in link.h as different than
308  the base address in the System V ABI and so the offset needs to be
309  calculated and applied to relocations. */
310  Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
311  unsigned vaddr = phdr ? phdr->p_vaddr : 0;
312 
313  sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
314  sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
315 }
316 
317 /* This is cheating a bit because our linker code is in libc.so. If we
318  ever implement lazy linking, this may need to be re-examined. */
319 int
321 {
322  if (in_plt_section (pc))
323  return 1;
324  return 0;
325 }
326 
327 void
329 {
330  /* Do nothing. */
331 }
332 
333 enum gdb_osabi
335 {
336  if (nto_is_nto_target)
337  return nto_is_nto_target (abfd);
338  return GDB_OSABI_UNKNOWN;
339 }
340 
341 static const char *nto_thread_state_str[] =
342 {
343  "DEAD", /* 0 0x00 */
344  "RUNNING", /* 1 0x01 */
345  "READY", /* 2 0x02 */
346  "STOPPED", /* 3 0x03 */
347  "SEND", /* 4 0x04 */
348  "RECEIVE", /* 5 0x05 */
349  "REPLY", /* 6 0x06 */
350  "STACK", /* 7 0x07 */
351  "WAITTHREAD", /* 8 0x08 */
352  "WAITPAGE", /* 9 0x09 */
353  "SIGSUSPEND", /* 10 0x0a */
354  "SIGWAITINFO", /* 11 0x0b */
355  "NANOSLEEP", /* 12 0x0c */
356  "MUTEX", /* 13 0x0d */
357  "CONDVAR", /* 14 0x0e */
358  "JOIN", /* 15 0x0f */
359  "INTR", /* 16 0x10 */
360  "SEM", /* 17 0x11 */
361  "WAITCTX", /* 18 0x12 */
362  "NET_SEND", /* 19 0x13 */
363  "NET_REPLY" /* 20 0x14 */
364 };
365 
366 char *
367 nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
368 {
369  if (ti && ti->priv
370  && ti->priv->state < ARRAY_SIZE (nto_thread_state_str))
371  return (char *)nto_thread_state_str [ti->priv->state];
372  return "";
373 }
374 
375 void
377 {
378  /* We use SIG45 for pulses, or something, so nostop, noprint
379  and pass them. */
383 
384  /* By default we don't want to stop on these two, but we do want to pass. */
385 #if defined(SIGSELECT)
386  signal_stop_update (SIGSELECT, 0);
387  signal_print_update (SIGSELECT, 0);
388  signal_pass_update (SIGSELECT, 1);
389 #endif
390 
391 #if defined(SIGPHOTON)
392  signal_stop_update (SIGPHOTON, 0);
393  signal_print_update (SIGPHOTON, 0);
394  signal_pass_update (SIGPHOTON, 1);
395 #endif
396 }
struct gdbarch * target_gdbarch(void)
Definition: gdbarch.c:5143
struct private_thread_info * priv
Definition: gdbthread.h:270
char * gdb_realpath(const char *filename)
Definition: utils.c:2840
CORE_ADDR extract_typed_address(const gdb_byte *buf, struct type *type)
Definition: findvar.c:169
static CORE_ADDR nto_truncate_ptr(CORE_ADDR addr)
Definition: nto-tdep.c:276
bfd_vma CORE_ADDR
Definition: common-types.h:41
int gdbarch_ptr_bit(struct gdbarch *gdbarch)
Definition: gdbarch.c:1690
static char default_nto_target[]
Definition: nto-tdep.c:44
const struct builtin_type * builtin_type(struct gdbarch *gdbarch)
Definition: gdbtypes.c:4766
#define pin(FLD)
static const char * nto_thread_state_str[]
Definition: nto-tdep.c:341
Definition: solist.h:30
static CORE_ADDR lm_addr(struct so_list *so)
Definition: nto-tdep.c:262
void execute_command(char *, int)
Definition: top.c:388
struct lm_info * lm_info
Definition: solist.h:42
#define OPF_TRY_CWD_FIRST
Definition: defs.h:317
struct nto_target_ops current_nto_target
Definition: nto-tdep.c:47
void nto_initialize_signals(void)
Definition: nto-tdep.c:376
int openp(const char *, int, const char *, int, char **)
Definition: source.c:739
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t err
Definition: gnu-nat.c:1816
int signal_pass_update(int signo, int state)
Definition: infrun.c:6835
CORE_ADDR l_addr
Definition: nto-tdep.c:254
gdb_byte * lm
Definition: nto-tdep.c:247
int nto_map_arch_to_cputype(const char *arch)
Definition: nto-tdep.c:69
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1420
static Elf_Internal_Phdr * find_load_phdr(bfd *abfd)
Definition: nto-tdep.c:287
#define nto_fetch_link_map_offsets
Definition: nto-tdep.h:97
Definition: gdbtypes.h:749
char ** nto_parse_redirection(char *pargv[], const char **pin, const char **pout, const char **perr)
Definition: nto-tdep.c:183
int nto_find_and_open_solib(char *solib, unsigned o_flags, char **temp_pathname)
Definition: nto-tdep.c:85
int nto_in_dynsym_resolve_code(CORE_ADDR pc)
Definition: nto-tdep.c:320
CORE_ADDR endaddr
Definition: target.h:2260
unsigned char state
Definition: nto-tdep.h:140
enum gdb_osabi nto_elf_osabi_sniffer(bfd *abfd)
Definition: nto-tdep.c:334
void nto_init_solib_absolute_prefix(void)
Definition: nto-tdep.c:148
struct bfd_section * the_bfd_section
Definition: target.h:2262
CORE_ADDR addr
Definition: target.h:2259
enum gdb_signal gdb_signal_from_name(const char *)
Definition: signals.c:91
static char * nto_target(void)
Definition: nto-tdep.c:50
bfd_byte gdb_byte
Definition: common-types.h:38
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
void nto_relocate_section_addresses(struct so_list *so, struct target_section *sec)
Definition: nto-tdep.c:305
#define PATH_FMT
struct type * builtin_data_ptr
Definition: gdbtypes.h:1533
static int in_plt_section(CORE_ADDR pc)
Definition: objfiles.h:539
#define OPF_RETURN_REALPATH
Definition: defs.h:319
CORE_ADDR lm_addr
Definition: nto-tdep.c:257
const struct bfd_arch_info * gdbarch_bfd_arch_info(struct gdbarch *gdbarch)
Definition: gdbarch.c:1411
int signal_print_update(int signo, int state)
Definition: infrun.c:6825
void nto_dummy_supply_regset(struct regcache *regcache, char *regs)
Definition: nto-tdep.c:328
int signal_stop_update(int signo, int state)
Definition: infrun.c:6815
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
#define nto_is_nto_target
Definition: nto-tdep.h:100
char * nto_extra_thread_info(struct target_ops *self, struct thread_info *ti)
Definition: nto-tdep.c:367
gdb_osabi
Definition: defs.h:540
const ULONGEST const LONGEST len
Definition: target.h:309