* gdbtypes.h (builtin_type_true_char): Remove.
[deliverable/binutils-gdb.git] / gdb / nto-tdep.c
CommitLineData
1b883d35
KW
1/* nto-tdep.c - general QNX Neutrino target functionality.
2
0fb0cc75 3 Copyright (C) 2003, 2004, 2007, 2008, 2009 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"
1b883d35
KW
24#include "gdb_string.h"
25#include "nto-tdep.h"
26#include "top.h"
27#include "cli/cli-decode.h"
28#include "cli/cli-cmds.h"
29#include "inferior.h"
30#include "gdbarch.h"
31#include "bfd.h"
32#include "elf-bfd.h"
33#include "solib-svr4.h"
34#include "gdbcore.h"
238ae9af
UW
35#include "objfiles.h"
36
37#include <string.h>
1b883d35
KW
38
39#ifdef __CYGWIN__
40#include <sys/cygwin.h>
41#endif
42
43#ifdef __CYGWIN__
44static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
45#elif defined(__sun__) || defined(linux)
46static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
47#else
48static char default_nto_target[] = "";
49#endif
50
51struct nto_target_ops current_nto_target;
52
53static char *
54nto_target (void)
55{
56 char *p = getenv ("QNX_TARGET");
57
58#ifdef __CYGWIN__
59 static char buf[PATH_MAX];
60 if (p)
61 cygwin_conv_to_posix_path (p, buf);
62 else
63 cygwin_conv_to_posix_path (default_nto_target, buf);
64 return buf;
65#else
66 return p ? p : default_nto_target;
67#endif
68}
69
70/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
71 CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
72int
73nto_map_arch_to_cputype (const char *arch)
74{
75 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
76 return CPUTYPE_X86;
192cdb19 77 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
1b883d35
KW
78 return CPUTYPE_PPC;
79 if (!strcmp (arch, "mips"))
80 return CPUTYPE_MIPS;
81 if (!strcmp (arch, "arm"))
82 return CPUTYPE_ARM;
83 if (!strcmp (arch, "sh"))
84 return CPUTYPE_SH;
85 return CPUTYPE_UNKNOWN;
86}
87
88int
89nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
90{
d737fd7f 91 char *buf, *arch_path, *nto_root, *endian, *base;
1b883d35 92 const char *arch;
d737fd7f
KW
93 int ret;
94#define PATH_FMT "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
1b883d35
KW
95
96 nto_root = nto_target ();
1cf3db46 97 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
1b883d35
KW
98 {
99 arch = "x86";
100 endian = "";
101 }
1cf3db46 102 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
1143fffb 103 "rs6000") == 0
1cf3db46 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 {
1cf3db46
UW
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. */
119 arch_path =
120 alloca (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 +
121 strlen (solib));
1b883d35
KW
122 sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
123
d737fd7f
KW
124 buf = alloca (strlen (PATH_FMT) + strlen (arch_path) * 5 + 1);
125 sprintf (buf, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
1b883d35
KW
126 arch_path);
127
d737fd7f
KW
128 /* Don't assume basename() isn't destructive. */
129 base = strrchr (solib, '/');
130 if (!base)
131 base = solib;
132 else
133 base++; /* Skip over '/'. */
134
fbdebf46 135 ret = openp (buf, 1, base, o_flags, temp_pathname);
d737fd7f
KW
136 if (ret < 0 && base != solib)
137 {
138 sprintf (arch_path, "/%s", solib);
139 ret = open (arch_path, o_flags, 0);
140 if (temp_pathname)
141 {
142 if (ret >= 0)
143 *temp_pathname = gdb_realpath (arch_path);
144 else
145 **temp_pathname = '\0';
146 }
147 }
148 return ret;
1b883d35
KW
149}
150
151void
152nto_init_solib_absolute_prefix (void)
153{
154 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
155 char *nto_root, *endian;
156 const char *arch;
157
158 nto_root = nto_target ();
1cf3db46 159 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
1b883d35
KW
160 {
161 arch = "x86";
162 endian = "";
163 }
1cf3db46 164 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
1143fffb 165 "rs6000") == 0
1cf3db46 166 || strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
1143fffb 167 "powerpc") == 0)
1b883d35
KW
168 {
169 arch = "ppc";
170 endian = "be";
171 }
172 else
173 {
1cf3db46
UW
174 arch = gdbarch_bfd_arch_info (target_gdbarch)->arch_name;
175 endian = gdbarch_byte_order (target_gdbarch)
4c6b5505 176 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
177 }
178
179 sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
180
181 sprintf (buf, "set solib-absolute-prefix %s", arch_path);
182 execute_command (buf, 0);
183}
184
185char **
14ef7606
AR
186nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
187 const char **perr)
1b883d35
KW
188{
189 char **argv;
190 char *in, *out, *err, *p;
191 int argc, i, n;
192
193 for (n = 0; pargv[n]; n++);
194 if (n == 0)
195 return NULL;
196 in = "";
197 out = "";
198 err = "";
199
200 argv = xcalloc (n + 1, sizeof argv[0]);
201 argc = n;
202 for (i = 0, n = 0; n < argc; n++)
203 {
204 p = pargv[n];
205 if (*p == '>')
206 {
207 p++;
208 if (*p)
209 out = p;
210 else
211 out = pargv[++n];
212 }
213 else if (*p == '<')
214 {
215 p++;
216 if (*p)
217 in = p;
218 else
219 in = pargv[++n];
220 }
221 else if (*p++ == '2' && *p++ == '>')
222 {
223 if (*p == '&' && *(p + 1) == '1')
224 err = out;
225 else if (*p)
226 err = p;
227 else
228 err = pargv[++n];
229 }
230 else
231 argv[i++] = pargv[n];
232 }
233 *pin = in;
234 *pout = out;
235 *perr = err;
236 return argv;
237}
238
239/* The struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from
240 solib-svr4.c to support nto_relocate_section_addresses
241 which is different from the svr4 version. */
242
ebd67d87
AR
243/* Link map info to include in an allocated so_list entry */
244
1b883d35 245struct lm_info
ebd67d87
AR
246 {
247 /* Pointer to copy of link map from inferior. The type is char *
248 rather than void *, so that we may use byte offsets to find the
249 various fields without the need for a cast. */
250 gdb_byte *lm;
251
252 /* Amount by which addresses in the binary should be relocated to
253 match the inferior. This could most often be taken directly
254 from lm, but when prelinking is involved and the prelink base
255 address changes, we may need a different offset, we want to
256 warn about the difference and compute it only once. */
257 CORE_ADDR l_addr;
258
259 /* The target location of lm. */
260 CORE_ADDR lm_addr;
261 };
262
1b883d35
KW
263
264static CORE_ADDR
265LM_ADDR (struct so_list *so)
266{
ebd67d87
AR
267 if (so->lm_info->l_addr == (CORE_ADDR)-1)
268 {
269 struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
b6da22b0 270 struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
1b883d35 271
ebd67d87 272 so->lm_info->l_addr =
b6da22b0 273 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
ebd67d87
AR
274 }
275 return so->lm_info->l_addr;
1b883d35
KW
276}
277
278static CORE_ADDR
279nto_truncate_ptr (CORE_ADDR addr)
280{
1cf3db46 281 if (gdbarch_ptr_bit (target_gdbarch) == sizeof (CORE_ADDR) * 8)
1b883d35
KW
282 /* We don't need to truncate anything, and the bit twiddling below
283 will fail due to overflow problems. */
284 return addr;
285 else
1cf3db46 286 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch)) - 1);
1b883d35
KW
287}
288
63807e1d 289static Elf_Internal_Phdr *
1b883d35
KW
290find_load_phdr (bfd *abfd)
291{
292 Elf_Internal_Phdr *phdr;
293 unsigned int i;
294
295 if (!elf_tdata (abfd))
296 return NULL;
297
298 phdr = elf_tdata (abfd)->phdr;
299 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
300 {
301 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
302 return phdr;
303 }
304 return NULL;
305}
306
307void
0542c86d 308nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
1b883d35
KW
309{
310 /* Neutrino treats the l_addr base address field in link.h as different than
311 the base address in the System V ABI and so the offset needs to be
312 calculated and applied to relocations. */
313 Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
314 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
315
316 sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
317 sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
318}
319
d737fd7f
KW
320/* This is cheating a bit because our linker code is in libc.so. If we
321 ever implement lazy linking, this may need to be re-examined. */
322int
323nto_in_dynsym_resolve_code (CORE_ADDR pc)
324{
325 if (in_plt_section (pc, NULL))
326 return 1;
327 return 0;
328}
329
d737fd7f 330void
468e3d51 331nto_dummy_supply_regset (struct regcache *regcache, char *regs)
d737fd7f
KW
332{
333 /* Do nothing. */
334}
335
336enum gdb_osabi
337nto_elf_osabi_sniffer (bfd *abfd)
338{
339 if (nto_is_nto_target)
3d171c85 340 return nto_is_nto_target (abfd);
d737fd7f
KW
341 return GDB_OSABI_UNKNOWN;
342}
343
1b883d35 344void
d737fd7f 345nto_initialize_signals (void)
1b883d35 346{
1b883d35
KW
347 /* We use SIG45 for pulses, or something, so nostop, noprint
348 and pass them. */
349 signal_stop_update (target_signal_from_name ("SIG45"), 0);
350 signal_print_update (target_signal_from_name ("SIG45"), 0);
351 signal_pass_update (target_signal_from_name ("SIG45"), 1);
352
353 /* By default we don't want to stop on these two, but we do want to pass. */
354#if defined(SIGSELECT)
355 signal_stop_update (SIGSELECT, 0);
356 signal_print_update (SIGSELECT, 0);
357 signal_pass_update (SIGSELECT, 1);
358#endif
359
360#if defined(SIGPHOTON)
361 signal_stop_update (SIGPHOTON, 0);
362 signal_print_update (SIGPHOTON, 0);
363 signal_pass_update (SIGPHOTON, 1);
364#endif
d737fd7f 365}
1b883d35 366
63807e1d
PA
367/* Provide a prototype to silence -Wmissing-prototypes. */
368extern initialize_file_ftype _initialize_nto_tdep;
369
d737fd7f
KW
370void
371_initialize_nto_tdep (void)
372{
373 add_setshow_zinteger_cmd ("nto-debug", class_maintenance,
7915a72c
AC
374 &nto_internal_debugging, _("\
375Set QNX NTO internal debugging."), _("\
376Show QNX NTO internal debugging."), _("\
d737fd7f
KW
377When non-zero, nto specific debug info is\n\
378displayed. Different information is displayed\n\
7915a72c 379for different positive values."),
2c5b56ce 380 NULL,
7915a72c 381 NULL, /* FIXME: i18n: QNX NTO internal debugging is %s. */
2c5b56ce 382 &setdebuglist, &showdebuglist);
1b883d35 383}
This page took 0.534436 seconds and 4 git commands to generate.