import gnulib sys/stat.h module
[deliverable/binutils-gdb.git] / gdb / nto-tdep.c
CommitLineData
1b883d35
KW
1/* nto-tdep.c - general QNX Neutrino target functionality.
2
28e7fd62 3 Copyright (C) 2003-2013 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"
47979a4b 23#include "gdb_stat.h"
0e9f083f 24#include <string.h>
1b883d35
KW
25#include "nto-tdep.h"
26#include "top.h"
1b883d35
KW
27#include "inferior.h"
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
35#include <string.h>
1b883d35
KW
36
37#ifdef __CYGWIN__
38#include <sys/cygwin.h>
39#endif
40
41#ifdef __CYGWIN__
42static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
43#elif defined(__sun__) || defined(linux)
44static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
45#else
46static char default_nto_target[] = "";
47#endif
48
49struct nto_target_ops current_nto_target;
50
51static char *
52nto_target (void)
53{
54 char *p = getenv ("QNX_TARGET");
55
56#ifdef __CYGWIN__
57 static char buf[PATH_MAX];
58 if (p)
90375a0e 59 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
1b883d35 60 else
90375a0e 61 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
1b883d35
KW
62 return buf;
63#else
64 return p ? p : default_nto_target;
65#endif
66}
67
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. */
70int
71nto_map_arch_to_cputype (const char *arch)
72{
73 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
74 return CPUTYPE_X86;
192cdb19 75 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
1b883d35
KW
76 return CPUTYPE_PPC;
77 if (!strcmp (arch, "mips"))
78 return CPUTYPE_MIPS;
79 if (!strcmp (arch, "arm"))
80 return CPUTYPE_ARM;
81 if (!strcmp (arch, "sh"))
82 return CPUTYPE_SH;
83 return CPUTYPE_UNKNOWN;
84}
85
86int
87nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
88{
91495617
PA
89 char *buf, *arch_path, *nto_root, *endian;
90 const char *base;
1b883d35 91 const char *arch;
08850b56 92 int arch_len, len, ret;
0df8b418
MS
93#define PATH_FMT \
94 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
1b883d35
KW
95
96 nto_root = nto_target ();
f5656ead 97 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
1b883d35
KW
98 {
99 arch = "x86";
100 endian = "";
101 }
f5656ead 102 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 103 "rs6000") == 0
f5656ead 104 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 105 "powerpc") == 0)
1b883d35
KW
106 {
107 arch = "ppc";
108 endian = "be";
109 }
110 else
111 {
f5656ead
TT
112 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
113 endian = gdbarch_byte_order (target_gdbarch ())
4c6b5505 114 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
115 }
116
d737fd7f
KW
117 /* In case nto_root is short, add strlen(solib)
118 so we can reuse arch_path below. */
1b883d35 119
08850b56
PM
120 arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
121 + strlen (solib));
122 arch_path = alloca (arch_len);
123 xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
124
125 len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
126 buf = alloca (len);
127 xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
128 arch_path);
1b883d35 129
9f37bbcc 130 base = lbasename (solib);
492c0ab7
JK
131 ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
132 temp_pathname);
d737fd7f
KW
133 if (ret < 0 && base != solib)
134 {
08850b56 135 xsnprintf (arch_path, arch_len, "/%s", solib);
d737fd7f
KW
136 ret = open (arch_path, o_flags, 0);
137 if (temp_pathname)
138 {
139 if (ret >= 0)
140 *temp_pathname = gdb_realpath (arch_path);
141 else
2c571006 142 *temp_pathname = NULL;
d737fd7f
KW
143 }
144 }
145 return ret;
1b883d35
KW
146}
147
148void
149nto_init_solib_absolute_prefix (void)
150{
151 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
152 char *nto_root, *endian;
153 const char *arch;
154
155 nto_root = nto_target ();
f5656ead 156 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
1b883d35
KW
157 {
158 arch = "x86";
159 endian = "";
160 }
f5656ead 161 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 162 "rs6000") == 0
f5656ead 163 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
1143fffb 164 "powerpc") == 0)
1b883d35
KW
165 {
166 arch = "ppc";
167 endian = "be";
168 }
169 else
170 {
f5656ead
TT
171 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
172 endian = gdbarch_byte_order (target_gdbarch ())
4c6b5505 173 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
174 }
175
08850b56 176 xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
1b883d35 177
08850b56 178 xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
1b883d35
KW
179 execute_command (buf, 0);
180}
181
182char **
14ef7606
AR
183nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
184 const char **perr)
1b883d35
KW
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
b23518f0 236/* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
1b883d35
KW
237 solib-svr4.c to support nto_relocate_section_addresses
238 which is different from the svr4 version. */
239
ebd67d87
AR
240/* Link map info to include in an allocated so_list entry */
241
1b883d35 242struct lm_info
ebd67d87
AR
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. */
247 gdb_byte *lm;
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. */
254 CORE_ADDR l_addr;
255
256 /* The target location of lm. */
257 CORE_ADDR lm_addr;
258 };
259
1b883d35
KW
260
261static CORE_ADDR
b23518f0 262lm_addr (struct so_list *so)
1b883d35 263{
ebd67d87
AR
264 if (so->lm_info->l_addr == (CORE_ADDR)-1)
265 {
266 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
f5656ead 267 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
1b883d35 268
ebd67d87 269 so->lm_info->l_addr =
b6da22b0 270 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
ebd67d87
AR
271 }
272 return so->lm_info->l_addr;
1b883d35
KW
273}
274
275static CORE_ADDR
276nto_truncate_ptr (CORE_ADDR addr)
277{
f5656ead 278 if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
1b883d35
KW
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
f5656ead 283 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
1b883d35
KW
284}
285
63807e1d 286static Elf_Internal_Phdr *
1b883d35
KW
287find_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
304void
0542c86d 305nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
1b883d35
KW
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. */
57e6060e 310 Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
1b883d35
KW
311 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
312
b23518f0
PM
313 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
314 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
1b883d35
KW
315}
316
d737fd7f
KW
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. */
319int
320nto_in_dynsym_resolve_code (CORE_ADDR pc)
321{
3e5d3a5a 322 if (in_plt_section (pc))
d737fd7f
KW
323 return 1;
324 return 0;
325}
326
d737fd7f 327void
468e3d51 328nto_dummy_supply_regset (struct regcache *regcache, char *regs)
d737fd7f
KW
329{
330 /* Do nothing. */
331}
332
333enum gdb_osabi
334nto_elf_osabi_sniffer (bfd *abfd)
335{
336 if (nto_is_nto_target)
3d171c85 337 return nto_is_nto_target (abfd);
d737fd7f
KW
338 return GDB_OSABI_UNKNOWN;
339}
340
745a434e
AR
341static 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
366char *
367nto_extra_thread_info (struct thread_info *ti)
368{
369 if (ti && ti->private
370 && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
371 return (char *)nto_thread_state_str [ti->private->state];
372 return "";
373}
374
1b883d35 375void
d737fd7f 376nto_initialize_signals (void)
1b883d35 377{
1b883d35
KW
378 /* We use SIG45 for pulses, or something, so nostop, noprint
379 and pass them. */
2ea28649
PA
380 signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
381 signal_print_update (gdb_signal_from_name ("SIG45"), 0);
382 signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
1b883d35
KW
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
d737fd7f 396}
This page took 0.959211 seconds and 4 git commands to generate.