1 /* nto-tdep.c - general QNX Neutrino target functionality.
3 Copyright (C) 2003-2015 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
;
49 static const struct inferior_data
*nto_inferior_data_reg
;
54 char *p
= getenv ("QNX_TARGET");
57 static char buf
[PATH_MAX
];
59 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, p
, buf
, PATH_MAX
);
61 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, default_nto_target
, buf
, PATH_MAX
);
64 return p
? p
: default_nto_target
;
68 /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
69 CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
71 nto_map_arch_to_cputype (const char *arch
)
73 if (!strcmp (arch
, "i386") || !strcmp (arch
, "x86"))
75 if (!strcmp (arch
, "rs6000") || !strcmp (arch
, "powerpc"))
77 if (!strcmp (arch
, "mips"))
79 if (!strcmp (arch
, "arm"))
81 if (!strcmp (arch
, "sh"))
83 return CPUTYPE_UNKNOWN
;
87 nto_find_and_open_solib (char *solib
, unsigned o_flags
, char **temp_pathname
)
89 char *buf
, *arch_path
, *nto_root
;
93 int arch_len
, len
, ret
;
95 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
97 nto_root
= nto_target ();
98 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
, "i386") == 0)
103 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
,
105 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
,
113 arch
= gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
;
114 endian
= gdbarch_byte_order (target_gdbarch ())
115 == BFD_ENDIAN_BIG
? "be" : "le";
118 /* In case nto_root is short, add strlen(solib)
119 so we can reuse arch_path below. */
121 arch_len
= (strlen (nto_root
) + strlen (arch
) + strlen (endian
) + 2
123 arch_path
= (char *) alloca (arch_len
);
124 xsnprintf (arch_path
, arch_len
, "%s/%s%s", nto_root
, arch
, endian
);
126 len
= strlen (PATH_FMT
) + strlen (arch_path
) * 5 + 1;
127 buf
= (char *) alloca (len
);
128 xsnprintf (buf
, len
, PATH_FMT
, arch_path
, arch_path
, arch_path
, arch_path
,
131 base
= lbasename (solib
);
132 ret
= openp (buf
, OPF_TRY_CWD_FIRST
| OPF_RETURN_REALPATH
, base
, o_flags
,
134 if (ret
< 0 && base
!= solib
)
136 xsnprintf (arch_path
, arch_len
, "/%s", solib
);
137 ret
= open (arch_path
, o_flags
, 0);
141 *temp_pathname
= gdb_realpath (arch_path
);
143 *temp_pathname
= NULL
;
150 nto_init_solib_absolute_prefix (void)
152 char buf
[PATH_MAX
* 2], arch_path
[PATH_MAX
];
157 nto_root
= nto_target ();
158 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
, "i386") == 0)
163 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
,
165 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
,
173 arch
= gdbarch_bfd_arch_info (target_gdbarch ())->arch_name
;
174 endian
= gdbarch_byte_order (target_gdbarch ())
175 == BFD_ENDIAN_BIG
? "be" : "le";
178 xsnprintf (arch_path
, sizeof (arch_path
), "%s/%s%s", nto_root
, arch
, endian
);
180 xsnprintf (buf
, sizeof (buf
), "set solib-absolute-prefix %s", arch_path
);
181 execute_command (buf
, 0);
185 nto_parse_redirection (char *pargv
[], const char **pin
, const char **pout
,
189 char *in
, *out
, *err
, *p
;
192 for (n
= 0; pargv
[n
]; n
++);
199 argv
= XCNEWVEC (char *, n
+ 1);
201 for (i
= 0, n
= 0; n
< argc
; n
++)
220 else if (*p
++ == '2' && *p
++ == '>')
222 if (*p
== '&' && *(p
+ 1) == '1')
230 argv
[i
++] = pargv
[n
];
238 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
239 solib-svr4.c to support nto_relocate_section_addresses
240 which is different from the svr4 version. */
242 /* Link map info to include in an allocated so_list entry */
246 /* Pointer to copy of link map from inferior. The type is char *
247 rather than void *, so that we may use byte offsets to find the
248 various fields without the need for a cast. */
251 /* Amount by which addresses in the binary should be relocated to
252 match the inferior. This could most often be taken directly
253 from lm, but when prelinking is involved and the prelink base
254 address changes, we may need a different offset, we want to
255 warn about the difference and compute it only once. */
258 /* The target location of lm. */
264 lm_addr (struct so_list
*so
)
266 if (so
->lm_info
->l_addr
== (CORE_ADDR
)-1)
268 struct link_map_offsets
*lmo
= nto_fetch_link_map_offsets ();
269 struct type
*ptr_type
= builtin_type (target_gdbarch ())->builtin_data_ptr
;
271 so
->lm_info
->l_addr
=
272 extract_typed_address (so
->lm_info
->lm
+ lmo
->l_addr_offset
, ptr_type
);
274 return so
->lm_info
->l_addr
;
278 nto_truncate_ptr (CORE_ADDR addr
)
280 if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR
) * 8)
281 /* We don't need to truncate anything, and the bit twiddling below
282 will fail due to overflow problems. */
285 return addr
& (((CORE_ADDR
) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
288 static Elf_Internal_Phdr
*
289 find_load_phdr (bfd
*abfd
)
291 Elf_Internal_Phdr
*phdr
;
294 if (!elf_tdata (abfd
))
297 phdr
= elf_tdata (abfd
)->phdr
;
298 for (i
= 0; i
< elf_elfheader (abfd
)->e_phnum
; i
++, phdr
++)
300 if (phdr
->p_type
== PT_LOAD
&& (phdr
->p_flags
& PF_X
))
307 nto_relocate_section_addresses (struct so_list
*so
, struct target_section
*sec
)
309 /* Neutrino treats the l_addr base address field in link.h as different than
310 the base address in the System V ABI and so the offset needs to be
311 calculated and applied to relocations. */
312 Elf_Internal_Phdr
*phdr
= find_load_phdr (sec
->the_bfd_section
->owner
);
313 unsigned vaddr
= phdr
? phdr
->p_vaddr
: 0;
315 sec
->addr
= nto_truncate_ptr (sec
->addr
+ lm_addr (so
) - vaddr
);
316 sec
->endaddr
= nto_truncate_ptr (sec
->endaddr
+ lm_addr (so
) - vaddr
);
319 /* This is cheating a bit because our linker code is in libc.so. If we
320 ever implement lazy linking, this may need to be re-examined. */
322 nto_in_dynsym_resolve_code (CORE_ADDR pc
)
324 if (in_plt_section (pc
))
330 nto_dummy_supply_regset (struct regcache
*regcache
, char *regs
)
336 nto_elf_osabi_sniffer (bfd
*abfd
)
338 if (nto_is_nto_target
)
339 return nto_is_nto_target (abfd
);
340 return GDB_OSABI_UNKNOWN
;
343 static const char *nto_thread_state_str
[] =
346 "RUNNING", /* 1 0x01 */
347 "READY", /* 2 0x02 */
348 "STOPPED", /* 3 0x03 */
350 "RECEIVE", /* 5 0x05 */
351 "REPLY", /* 6 0x06 */
352 "STACK", /* 7 0x07 */
353 "WAITTHREAD", /* 8 0x08 */
354 "WAITPAGE", /* 9 0x09 */
355 "SIGSUSPEND", /* 10 0x0a */
356 "SIGWAITINFO", /* 11 0x0b */
357 "NANOSLEEP", /* 12 0x0c */
358 "MUTEX", /* 13 0x0d */
359 "CONDVAR", /* 14 0x0e */
360 "JOIN", /* 15 0x0f */
361 "INTR", /* 16 0x10 */
363 "WAITCTX", /* 18 0x12 */
364 "NET_SEND", /* 19 0x13 */
365 "NET_REPLY" /* 20 0x14 */
369 nto_extra_thread_info (struct target_ops
*self
, struct thread_info
*ti
)
372 && ti
->priv
->state
< ARRAY_SIZE (nto_thread_state_str
))
373 return (char *)nto_thread_state_str
[ti
->priv
->state
];
378 nto_initialize_signals (void)
380 /* We use SIG45 for pulses, or something, so nostop, noprint
382 signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
383 signal_print_update (gdb_signal_from_name ("SIG45"), 0);
384 signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
386 /* By default we don't want to stop on these two, but we do want to pass. */
387 #if defined(SIGSELECT)
388 signal_stop_update (SIGSELECT
, 0);
389 signal_print_update (SIGSELECT
, 0);
390 signal_pass_update (SIGSELECT
, 1);
393 #if defined(SIGPHOTON)
394 signal_stop_update (SIGPHOTON
, 0);
395 signal_print_update (SIGPHOTON
, 0);
396 signal_pass_update (SIGPHOTON
, 1);
400 /* Read AUXV from initial_stack. */
402 nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack
, gdb_byte
*readbuf
,
403 LONGEST len
, size_t sizeof_auxv_t
)
405 gdb_byte targ32
[4]; /* For 32 bit target values. */
406 gdb_byte targ64
[8]; /* For 64 bit target values. */
407 CORE_ADDR data_ofs
= 0;
409 LONGEST len_read
= 0;
411 enum bfd_endian byte_order
;
414 if (sizeof_auxv_t
== 16)
419 /* Skip over argc, argv and envp... Comment from ldd.c:
421 The startup frame is set-up so that we have:
426 envp1 <----- void *frame + (argc + 2) * sizeof(char *)
431 argc <------ void * frame
433 On entry to ldd, frame gives the address of argc on the stack. */
434 /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little
435 * endian. So we just read first 4 bytes. */
436 if (target_read_memory (initial_stack
+ data_ofs
, targ32
, 4) != 0)
439 byte_order
= gdbarch_byte_order (target_gdbarch ());
441 anint
= extract_unsigned_integer (targ32
, sizeof (targ32
), byte_order
);
443 /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */
444 data_ofs
+= (anint
+ 2) * ptr_size
; /* + 2 comes from argc itself and
445 NULL terminating pointer in
448 /* Now loop over env table: */
450 while (target_read_memory (initial_stack
+ data_ofs
, targ64
, ptr_size
)
453 if (extract_unsigned_integer (targ64
, ptr_size
, byte_order
) == 0)
454 anint
= 1; /* Keep looping until non-null entry is found. */
457 data_ofs
+= ptr_size
;
459 initial_stack
+= data_ofs
;
461 memset (readbuf
, 0, len
);
463 while (len_read
<= len
-sizeof_auxv_t
)
465 if (target_read_memory (initial_stack
+ len_read
, buff
, sizeof_auxv_t
)
468 /* Both 32 and 64 bit structures have int as the first field. */
469 const ULONGEST a_type
470 = extract_unsigned_integer (buff
, sizeof (targ32
), byte_order
);
472 if (a_type
== AT_NULL
)
474 buff
+= sizeof_auxv_t
;
475 len_read
+= sizeof_auxv_t
;
483 /* Allocate new nto_inferior_data object. */
485 static struct nto_inferior_data
*
486 nto_new_inferior_data (void)
488 struct nto_inferior_data
*const inf_data
489 = XCNEW (struct nto_inferior_data
);
494 /* Free inferior data. */
497 nto_inferior_data_cleanup (struct inferior
*const inf
, void *const dat
)
502 /* Return nto_inferior_data for the given INFERIOR. If not yet created,
505 struct nto_inferior_data
*
506 nto_inferior_data (struct inferior
*const inferior
)
508 struct inferior
*const inf
= inferior
? inferior
: current_inferior ();
509 struct nto_inferior_data
*inf_data
;
511 gdb_assert (inf
!= NULL
);
513 inf_data
= inferior_data (inf
, nto_inferior_data_reg
);
514 if (inf_data
== NULL
)
516 set_inferior_data (inf
, nto_inferior_data_reg
,
517 (inf_data
= nto_new_inferior_data ()));
523 /* Provide a prototype to silence -Wmissing-prototypes. */
524 extern initialize_file_ftype _initialize_nto_tdep
;
527 _initialize_nto_tdep (void)
529 nto_inferior_data_reg
530 = register_inferior_data_with_cleanup (NULL
, nto_inferior_data_cleanup
);