constify nto-tdep.c
[deliverable/binutils-gdb.git] / gdb / nto-tdep.c
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
47 struct nto_target_ops current_nto_target;
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
148 nto_init_solib_absolute_prefix (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. */
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
260
261 static CORE_ADDR
262 lm_addr (struct so_list *so)
263 {
264 if (so->lm_info->l_addr == (CORE_ADDR)-1)
265 {
266 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
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
276 nto_truncate_ptr (CORE_ADDR 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
305 nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
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
320 nto_in_dynsym_resolve_code (CORE_ADDR pc)
321 {
322 if (in_plt_section (pc))
323 return 1;
324 return 0;
325 }
326
327 void
328 nto_dummy_supply_regset (struct regcache *regcache, char *regs)
329 {
330 /* Do nothing. */
331 }
332
333 enum gdb_osabi
334 nto_elf_osabi_sniffer (bfd *abfd)
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
376 nto_initialize_signals (void)
377 {
378 /* We use SIG45 for pulses, or something, so nostop, noprint
379 and pass them. */
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);
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 }
This page took 0.039676 seconds and 5 git commands to generate.