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