1 /* nto-tdep.c - general QNX Neutrino target functionality.
3 Copyright (C) 2003-2014 Free Software Foundation, Inc.
5 Contributed by QNX Software Systems Ltd.
7 This file is part of GDB.
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.
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.
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/>. */
31 #include "solib-svr4.h"
36 #include <sys/cygwin.h>
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";
44 static char default_nto_target[] = "";
47 struct nto_target_ops current_nto_target;
52 char *p = getenv ("QNX_TARGET");
55 static char buf[PATH_MAX];
57 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
59 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
62 return p ? p : default_nto_target;
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. */
69 nto_map_arch_to_cputype (const char *arch)
71 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
73 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
75 if (!strcmp (arch, "mips"))
77 if (!strcmp (arch, "arm"))
79 if (!strcmp (arch, "sh"))
81 return CPUTYPE_UNKNOWN;
85 nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
87 char *buf, *arch_path, *nto_root, *endian;
90 int arch_len, len, ret;
92 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
94 nto_root = nto_target ();
95 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
100 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
102 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
110 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
111 endian = gdbarch_byte_order (target_gdbarch ())
112 == BFD_ENDIAN_BIG ? "be" : "le";
115 /* In case nto_root is short, add strlen(solib)
116 so we can reuse arch_path below. */
118 arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
120 arch_path = alloca (arch_len);
121 xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
123 len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
125 xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
128 base = lbasename (solib);
129 ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
131 if (ret < 0 && base != solib)
133 xsnprintf (arch_path, arch_len, "/%s", solib);
134 ret = open (arch_path, o_flags, 0);
138 *temp_pathname = gdb_realpath (arch_path);
140 *temp_pathname = NULL;
147 nto_init_solib_absolute_prefix (void)
149 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
150 char *nto_root, *endian;
153 nto_root = nto_target ();
154 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
159 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
161 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
169 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
170 endian = gdbarch_byte_order (target_gdbarch ())
171 == BFD_ENDIAN_BIG ? "be" : "le";
174 xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
176 xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
177 execute_command (buf, 0);
181 nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
185 char *in, *out, *err, *p;
188 for (n = 0; pargv[n]; n++);
195 argv = xcalloc (n + 1, sizeof argv[0]);
197 for (i = 0, n = 0; n < argc; n++)
216 else if (*p++ == '2' && *p++ == '>')
218 if (*p == '&' && *(p + 1) == '1')
226 argv[i++] = pargv[n];
234 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
235 solib-svr4.c to support nto_relocate_section_addresses
236 which is different from the svr4 version. */
238 /* Link map info to include in an allocated so_list entry */
242 /* Pointer to copy of link map from inferior. The type is char *
243 rather than void *, so that we may use byte offsets to find the
244 various fields without the need for a cast. */
247 /* Amount by which addresses in the binary should be relocated to
248 match the inferior. This could most often be taken directly
249 from lm, but when prelinking is involved and the prelink base
250 address changes, we may need a different offset, we want to
251 warn about the difference and compute it only once. */
254 /* The target location of lm. */
260 lm_addr (struct so_list *so)
262 if (so->lm_info->l_addr == (CORE_ADDR)-1)
264 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
265 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
267 so->lm_info->l_addr =
268 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
270 return so->lm_info->l_addr;
274 nto_truncate_ptr (CORE_ADDR addr)
276 if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
277 /* We don't need to truncate anything, and the bit twiddling below
278 will fail due to overflow problems. */
281 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
284 static Elf_Internal_Phdr *
285 find_load_phdr (bfd *abfd)
287 Elf_Internal_Phdr *phdr;
290 if (!elf_tdata (abfd))
293 phdr = elf_tdata (abfd)->phdr;
294 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
296 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
303 nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
305 /* Neutrino treats the l_addr base address field in link.h as different than
306 the base address in the System V ABI and so the offset needs to be
307 calculated and applied to relocations. */
308 Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
309 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
311 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
312 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
315 /* This is cheating a bit because our linker code is in libc.so. If we
316 ever implement lazy linking, this may need to be re-examined. */
318 nto_in_dynsym_resolve_code (CORE_ADDR pc)
320 if (in_plt_section (pc))
326 nto_dummy_supply_regset (struct regcache *regcache, char *regs)
332 nto_elf_osabi_sniffer (bfd *abfd)
334 if (nto_is_nto_target)
335 return nto_is_nto_target (abfd);
336 return GDB_OSABI_UNKNOWN;
339 static const char *nto_thread_state_str[] =
342 "RUNNING", /* 1 0x01 */
343 "READY", /* 2 0x02 */
344 "STOPPED", /* 3 0x03 */
346 "RECEIVE", /* 5 0x05 */
347 "REPLY", /* 6 0x06 */
348 "STACK", /* 7 0x07 */
349 "WAITTHREAD", /* 8 0x08 */
350 "WAITPAGE", /* 9 0x09 */
351 "SIGSUSPEND", /* 10 0x0a */
352 "SIGWAITINFO", /* 11 0x0b */
353 "NANOSLEEP", /* 12 0x0c */
354 "MUTEX", /* 13 0x0d */
355 "CONDVAR", /* 14 0x0e */
356 "JOIN", /* 15 0x0f */
357 "INTR", /* 16 0x10 */
359 "WAITCTX", /* 18 0x12 */
360 "NET_SEND", /* 19 0x13 */
361 "NET_REPLY" /* 20 0x14 */
365 nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
367 if (ti && ti->private
368 && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
369 return (char *)nto_thread_state_str [ti->private->state];
374 nto_initialize_signals (void)
376 /* We use SIG45 for pulses, or something, so nostop, noprint
378 signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
379 signal_print_update (gdb_signal_from_name ("SIG45"), 0);
380 signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
382 /* By default we don't want to stop on these two, but we do want to pass. */
383 #if defined(SIGSELECT)
384 signal_stop_update (SIGSELECT, 0);
385 signal_print_update (SIGSELECT, 0);
386 signal_pass_update (SIGSELECT, 1);
389 #if defined(SIGPHOTON)
390 signal_stop_update (SIGPHOTON, 0);
391 signal_print_update (SIGPHOTON, 0);
392 signal_pass_update (SIGPHOTON, 1);