gdb/
[deliverable/binutils-gdb.git] / gdb / nto-tdep.c
1 /* nto-tdep.c - general QNX Neutrino target functionality.
2
3 Copyright (C) 2003-2004, 2007-2012 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 "gdb_stat.h"
24 #include "gdb_string.h"
25 #include "nto-tdep.h"
26 #include "top.h"
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"
33 #include "objfiles.h"
34
35 #include <string.h>
36
37 #ifdef __CYGWIN__
38 #include <sys/cygwin.h>
39 #endif
40
41 #ifdef __CYGWIN__
42 static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
43 #elif defined(__sun__) || defined(linux)
44 static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
45 #else
46 static char default_nto_target[] = "";
47 #endif
48
49 struct nto_target_ops current_nto_target;
50
51 static char *
52 nto_target (void)
53 {
54 char *p = getenv ("QNX_TARGET");
55
56 #ifdef __CYGWIN__
57 static char buf[PATH_MAX];
58 if (p)
59 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
60 else
61 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
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. */
70 int
71 nto_map_arch_to_cputype (const char *arch)
72 {
73 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
74 return CPUTYPE_X86;
75 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
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
86 int
87 nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
88 {
89 char *buf, *arch_path, *nto_root, *endian;
90 const char *base;
91 const char *arch;
92 int ret;
93 #define PATH_FMT \
94 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
95
96 nto_root = nto_target ();
97 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
98 {
99 arch = "x86";
100 endian = "";
101 }
102 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
103 "rs6000") == 0
104 || strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
105 "powerpc") == 0)
106 {
107 arch = "ppc";
108 endian = "be";
109 }
110 else
111 {
112 arch = gdbarch_bfd_arch_info (target_gdbarch)->arch_name;
113 endian = gdbarch_byte_order (target_gdbarch)
114 == BFD_ENDIAN_BIG ? "be" : "le";
115 }
116
117 /* In case nto_root is short, add strlen(solib)
118 so we can reuse arch_path below. */
119 arch_path =
120 alloca (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 +
121 strlen (solib));
122 sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
123
124 buf = alloca (strlen (PATH_FMT) + strlen (arch_path) * 5 + 1);
125 sprintf (buf, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
126 arch_path);
127
128 base = lbasename (solib);
129 ret = openp (buf, 1, base, o_flags, temp_pathname);
130 if (ret < 0 && base != solib)
131 {
132 sprintf (arch_path, "/%s", solib);
133 ret = open (arch_path, o_flags, 0);
134 if (temp_pathname)
135 {
136 if (ret >= 0)
137 *temp_pathname = gdb_realpath (arch_path);
138 else
139 **temp_pathname = '\0';
140 }
141 }
142 return ret;
143 }
144
145 void
146 nto_init_solib_absolute_prefix (void)
147 {
148 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
149 char *nto_root, *endian;
150 const char *arch;
151
152 nto_root = nto_target ();
153 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
154 {
155 arch = "x86";
156 endian = "";
157 }
158 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
159 "rs6000") == 0
160 || strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
161 "powerpc") == 0)
162 {
163 arch = "ppc";
164 endian = "be";
165 }
166 else
167 {
168 arch = gdbarch_bfd_arch_info (target_gdbarch)->arch_name;
169 endian = gdbarch_byte_order (target_gdbarch)
170 == BFD_ENDIAN_BIG ? "be" : "le";
171 }
172
173 sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
174
175 sprintf (buf, "set solib-absolute-prefix %s", arch_path);
176 execute_command (buf, 0);
177 }
178
179 char **
180 nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
181 const char **perr)
182 {
183 char **argv;
184 char *in, *out, *err, *p;
185 int argc, i, n;
186
187 for (n = 0; pargv[n]; n++);
188 if (n == 0)
189 return NULL;
190 in = "";
191 out = "";
192 err = "";
193
194 argv = xcalloc (n + 1, sizeof argv[0]);
195 argc = n;
196 for (i = 0, n = 0; n < argc; n++)
197 {
198 p = pargv[n];
199 if (*p == '>')
200 {
201 p++;
202 if (*p)
203 out = p;
204 else
205 out = pargv[++n];
206 }
207 else if (*p == '<')
208 {
209 p++;
210 if (*p)
211 in = p;
212 else
213 in = pargv[++n];
214 }
215 else if (*p++ == '2' && *p++ == '>')
216 {
217 if (*p == '&' && *(p + 1) == '1')
218 err = out;
219 else if (*p)
220 err = p;
221 else
222 err = pargv[++n];
223 }
224 else
225 argv[i++] = pargv[n];
226 }
227 *pin = in;
228 *pout = out;
229 *perr = err;
230 return argv;
231 }
232
233 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
234 solib-svr4.c to support nto_relocate_section_addresses
235 which is different from the svr4 version. */
236
237 /* Link map info to include in an allocated so_list entry */
238
239 struct lm_info
240 {
241 /* Pointer to copy of link map from inferior. The type is char *
242 rather than void *, so that we may use byte offsets to find the
243 various fields without the need for a cast. */
244 gdb_byte *lm;
245
246 /* Amount by which addresses in the binary should be relocated to
247 match the inferior. This could most often be taken directly
248 from lm, but when prelinking is involved and the prelink base
249 address changes, we may need a different offset, we want to
250 warn about the difference and compute it only once. */
251 CORE_ADDR l_addr;
252
253 /* The target location of lm. */
254 CORE_ADDR lm_addr;
255 };
256
257
258 static CORE_ADDR
259 lm_addr (struct so_list *so)
260 {
261 if (so->lm_info->l_addr == (CORE_ADDR)-1)
262 {
263 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
264 struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
265
266 so->lm_info->l_addr =
267 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
268 }
269 return so->lm_info->l_addr;
270 }
271
272 static CORE_ADDR
273 nto_truncate_ptr (CORE_ADDR addr)
274 {
275 if (gdbarch_ptr_bit (target_gdbarch) == sizeof (CORE_ADDR) * 8)
276 /* We don't need to truncate anything, and the bit twiddling below
277 will fail due to overflow problems. */
278 return addr;
279 else
280 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch)) - 1);
281 }
282
283 static Elf_Internal_Phdr *
284 find_load_phdr (bfd *abfd)
285 {
286 Elf_Internal_Phdr *phdr;
287 unsigned int i;
288
289 if (!elf_tdata (abfd))
290 return NULL;
291
292 phdr = elf_tdata (abfd)->phdr;
293 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
294 {
295 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
296 return phdr;
297 }
298 return NULL;
299 }
300
301 void
302 nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
303 {
304 /* Neutrino treats the l_addr base address field in link.h as different than
305 the base address in the System V ABI and so the offset needs to be
306 calculated and applied to relocations. */
307 Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
308 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
309
310 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
311 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
312 }
313
314 /* This is cheating a bit because our linker code is in libc.so. If we
315 ever implement lazy linking, this may need to be re-examined. */
316 int
317 nto_in_dynsym_resolve_code (CORE_ADDR pc)
318 {
319 if (in_plt_section (pc, NULL))
320 return 1;
321 return 0;
322 }
323
324 void
325 nto_dummy_supply_regset (struct regcache *regcache, char *regs)
326 {
327 /* Do nothing. */
328 }
329
330 enum gdb_osabi
331 nto_elf_osabi_sniffer (bfd *abfd)
332 {
333 if (nto_is_nto_target)
334 return nto_is_nto_target (abfd);
335 return GDB_OSABI_UNKNOWN;
336 }
337
338 static const char *nto_thread_state_str[] =
339 {
340 "DEAD", /* 0 0x00 */
341 "RUNNING", /* 1 0x01 */
342 "READY", /* 2 0x02 */
343 "STOPPED", /* 3 0x03 */
344 "SEND", /* 4 0x04 */
345 "RECEIVE", /* 5 0x05 */
346 "REPLY", /* 6 0x06 */
347 "STACK", /* 7 0x07 */
348 "WAITTHREAD", /* 8 0x08 */
349 "WAITPAGE", /* 9 0x09 */
350 "SIGSUSPEND", /* 10 0x0a */
351 "SIGWAITINFO", /* 11 0x0b */
352 "NANOSLEEP", /* 12 0x0c */
353 "MUTEX", /* 13 0x0d */
354 "CONDVAR", /* 14 0x0e */
355 "JOIN", /* 15 0x0f */
356 "INTR", /* 16 0x10 */
357 "SEM", /* 17 0x11 */
358 "WAITCTX", /* 18 0x12 */
359 "NET_SEND", /* 19 0x13 */
360 "NET_REPLY" /* 20 0x14 */
361 };
362
363 char *
364 nto_extra_thread_info (struct thread_info *ti)
365 {
366 if (ti && ti->private
367 && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
368 return (char *)nto_thread_state_str [ti->private->state];
369 return "";
370 }
371
372 void
373 nto_initialize_signals (void)
374 {
375 /* We use SIG45 for pulses, or something, so nostop, noprint
376 and pass them. */
377 signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
378 signal_print_update (gdb_signal_from_name ("SIG45"), 0);
379 signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
380
381 /* By default we don't want to stop on these two, but we do want to pass. */
382 #if defined(SIGSELECT)
383 signal_stop_update (SIGSELECT, 0);
384 signal_print_update (SIGSELECT, 0);
385 signal_pass_update (SIGSELECT, 1);
386 #endif
387
388 #if defined(SIGPHOTON)
389 signal_stop_update (SIGPHOTON, 0);
390 signal_print_update (SIGPHOTON, 0);
391 signal_pass_update (SIGPHOTON, 1);
392 #endif
393 }
This page took 0.038671 seconds and 5 git commands to generate.