]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/nto-tdep.c
constify gdbserver/tracepoint.c
[thirdparty/binutils-gdb.git] / gdb / nto-tdep.c
CommitLineData
1b883d35
KW
1/* nto-tdep.c - general QNX Neutrino target functionality.
2
32d0add0 3 Copyright (C) 2003-2015 Free Software Foundation, Inc.
1b883d35
KW
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
1b883d35
KW
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
1b883d35 21
b4d5ed91 22#include "defs.h"
53ce3c39 23#include <sys/stat.h>
1b883d35
KW
24#include "nto-tdep.h"
25#include "top.h"
1b883d35 26#include "inferior.h"
45741a9c 27#include "infrun.h"
1b883d35
KW
28#include "gdbarch.h"
29#include "bfd.h"
30#include "elf-bfd.h"
31#include "solib-svr4.h"
32#include "gdbcore.h"
238ae9af
UW
33#include "objfiles.h"
34
1b883d35
KW
35#ifdef __CYGWIN__
36#include <sys/cygwin.h>
37#endif
38
39#ifdef __CYGWIN__
40static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
41#elif defined(__sun__) || defined(linux)
42static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
43#else
44static char default_nto_target[] = "";
45#endif
46
47struct nto_target_ops current_nto_target;
48
49static char *
50nto_target (void)
51{
52 char *p = getenv ("QNX_TARGET");
53
54#ifdef __CYGWIN__
55 static char buf[PATH_MAX];
56 if (p)
90375a0e 57 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
1b883d35 58 else
90375a0e 59 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
1b883d35
KW
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. */
68int
69nto_map_arch_to_cputype (const char *arch)
70{
71 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
72 return CPUTYPE_X86;
192cdb19 73 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
1b883d35
KW
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
84int
85nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
86{
91495617
PA
87 char *buf, *arch_path, *nto_root, *endian;
88 const char *base;
1b883d35 89 const char *arch;
08850b56 90 int arch_len, len, ret;
0df8b418
MS
91#define PATH_FMT \
92 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
1b883d35
KW
93
94 nto_root = nto_target ();
f5656ead 95 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
1b883d35
KW
96 {
97 arch = "x86";
98 endian = "";
99 }
f5656ead 100 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 101 "rs6000") == 0
f5656ead 102 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 103 "powerpc") == 0)
1b883d35
KW
104 {
105 arch = "ppc";
106 endian = "be";
107 }
108 else
109 {
f5656ead
TT
110 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
111 endian = gdbarch_byte_order (target_gdbarch ())
4c6b5505 112 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
113 }
114
d737fd7f
KW
115 /* In case nto_root is short, add strlen(solib)
116 so we can reuse arch_path below. */
1b883d35 117
08850b56
PM
118 arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
119 + strlen (solib));
120 arch_path = alloca (arch_len);
121 xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
122
123 len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
124 buf = alloca (len);
125 xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
126 arch_path);
1b883d35 127
9f37bbcc 128 base = lbasename (solib);
492c0ab7
JK
129 ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
130 temp_pathname);
d737fd7f
KW
131 if (ret < 0 && base != solib)
132 {
08850b56 133 xsnprintf (arch_path, arch_len, "/%s", solib);
d737fd7f
KW
134 ret = open (arch_path, o_flags, 0);
135 if (temp_pathname)
136 {
137 if (ret >= 0)
138 *temp_pathname = gdb_realpath (arch_path);
139 else
2c571006 140 *temp_pathname = NULL;
d737fd7f
KW
141 }
142 }
143 return ret;
1b883d35
KW
144}
145
146void
147nto_init_solib_absolute_prefix (void)
148{
149 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
150 char *nto_root, *endian;
151 const char *arch;
152
153 nto_root = nto_target ();
f5656ead 154 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
1b883d35
KW
155 {
156 arch = "x86";
157 endian = "";
158 }
f5656ead 159 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 160 "rs6000") == 0
f5656ead 161 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 162 "powerpc") == 0)
1b883d35
KW
163 {
164 arch = "ppc";
165 endian = "be";
166 }
167 else
168 {
f5656ead
TT
169 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
170 endian = gdbarch_byte_order (target_gdbarch ())
4c6b5505 171 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
172 }
173
08850b56 174 xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
1b883d35 175
08850b56 176 xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
1b883d35
KW
177 execute_command (buf, 0);
178}
179
180char **
14ef7606
AR
181nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
182 const char **perr)
1b883d35
KW
183{
184 char **argv;
185 char *in, *out, *err, *p;
186 int argc, i, n;
187
188 for (n = 0; pargv[n]; n++);
189 if (n == 0)
190 return NULL;
191 in = "";
192 out = "";
193 err = "";
194
195 argv = xcalloc (n + 1, sizeof argv[0]);
196 argc = n;
197 for (i = 0, n = 0; n < argc; n++)
198 {
199 p = pargv[n];
200 if (*p == '>')
201 {
202 p++;
203 if (*p)
204 out = p;
205 else
206 out = pargv[++n];
207 }
208 else if (*p == '<')
209 {
210 p++;
211 if (*p)
212 in = p;
213 else
214 in = pargv[++n];
215 }
216 else if (*p++ == '2' && *p++ == '>')
217 {
218 if (*p == '&' && *(p + 1) == '1')
219 err = out;
220 else if (*p)
221 err = p;
222 else
223 err = pargv[++n];
224 }
225 else
226 argv[i++] = pargv[n];
227 }
228 *pin = in;
229 *pout = out;
230 *perr = err;
231 return argv;
232}
233
b23518f0 234/* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
1b883d35
KW
235 solib-svr4.c to support nto_relocate_section_addresses
236 which is different from the svr4 version. */
237
ebd67d87
AR
238/* Link map info to include in an allocated so_list entry */
239
1b883d35 240struct lm_info
ebd67d87
AR
241 {
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. */
245 gdb_byte *lm;
246
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. */
252 CORE_ADDR l_addr;
253
254 /* The target location of lm. */
255 CORE_ADDR lm_addr;
256 };
257
1b883d35
KW
258
259static CORE_ADDR
b23518f0 260lm_addr (struct so_list *so)
1b883d35 261{
ebd67d87
AR
262 if (so->lm_info->l_addr == (CORE_ADDR)-1)
263 {
264 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
f5656ead 265 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
1b883d35 266
ebd67d87 267 so->lm_info->l_addr =
b6da22b0 268 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
ebd67d87
AR
269 }
270 return so->lm_info->l_addr;
1b883d35
KW
271}
272
273static CORE_ADDR
274nto_truncate_ptr (CORE_ADDR addr)
275{
f5656ead 276 if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
1b883d35
KW
277 /* We don't need to truncate anything, and the bit twiddling below
278 will fail due to overflow problems. */
279 return addr;
280 else
f5656ead 281 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
1b883d35
KW
282}
283
63807e1d 284static Elf_Internal_Phdr *
1b883d35
KW
285find_load_phdr (bfd *abfd)
286{
287 Elf_Internal_Phdr *phdr;
288 unsigned int i;
289
290 if (!elf_tdata (abfd))
291 return NULL;
292
293 phdr = elf_tdata (abfd)->phdr;
294 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
295 {
296 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
297 return phdr;
298 }
299 return NULL;
300}
301
302void
0542c86d 303nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
1b883d35
KW
304{
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. */
57e6060e 308 Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
1b883d35
KW
309 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
310
b23518f0
PM
311 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
312 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
1b883d35
KW
313}
314
d737fd7f
KW
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. */
317int
318nto_in_dynsym_resolve_code (CORE_ADDR pc)
319{
3e5d3a5a 320 if (in_plt_section (pc))
d737fd7f
KW
321 return 1;
322 return 0;
323}
324
d737fd7f 325void
468e3d51 326nto_dummy_supply_regset (struct regcache *regcache, char *regs)
d737fd7f
KW
327{
328 /* Do nothing. */
329}
330
331enum gdb_osabi
332nto_elf_osabi_sniffer (bfd *abfd)
333{
334 if (nto_is_nto_target)
3d171c85 335 return nto_is_nto_target (abfd);
d737fd7f
KW
336 return GDB_OSABI_UNKNOWN;
337}
338
745a434e
AR
339static const char *nto_thread_state_str[] =
340{
341 "DEAD", /* 0 0x00 */
342 "RUNNING", /* 1 0x01 */
343 "READY", /* 2 0x02 */
344 "STOPPED", /* 3 0x03 */
345 "SEND", /* 4 0x04 */
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 */
358 "SEM", /* 17 0x11 */
359 "WAITCTX", /* 18 0x12 */
360 "NET_SEND", /* 19 0x13 */
361 "NET_REPLY" /* 20 0x14 */
362};
363
364char *
c15906d8 365nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
745a434e 366{
fe978cb0
PA
367 if (ti && ti->priv
368 && ti->priv->state < ARRAY_SIZE (nto_thread_state_str))
369 return (char *)nto_thread_state_str [ti->priv->state];
745a434e
AR
370 return "";
371}
372
1b883d35 373void
d737fd7f 374nto_initialize_signals (void)
1b883d35 375{
1b883d35
KW
376 /* We use SIG45 for pulses, or something, so nostop, noprint
377 and pass them. */
2ea28649
PA
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);
1b883d35
KW
381
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);
387#endif
388
389#if defined(SIGPHOTON)
390 signal_stop_update (SIGPHOTON, 0);
391 signal_print_update (SIGPHOTON, 0);
392 signal_pass_update (SIGPHOTON, 1);
393#endif
d737fd7f 394}