]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/nto-tdep.c
gdb, testsuite: Fix return value in gdb.base/foll-fork.exp
[thirdparty/binutils-gdb.git] / gdb / nto-tdep.c
CommitLineData
1b883d35
KW
1/* nto-tdep.c - general QNX Neutrino target functionality.
2
1d506c26 3 Copyright (C) 2003-2024 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
53ce3c39 22#include <sys/stat.h>
1b883d35 23#include "nto-tdep.h"
ec452525 24#include "extract-store-integer.h"
1b883d35 25#include "top.h"
1b883d35 26#include "inferior.h"
45741a9c 27#include "infrun.h"
1b883d35
KW
28#include "gdbarch.h"
29#include "bfd.h"
30#include "elf-bfd.h"
31#include "solib-svr4.h"
32#include "gdbcore.h"
238ae9af 33#include "objfiles.h"
b46a8d7c 34#include "source.h"
268a13a5 35#include "gdbsupport/pathstuff.h"
238ae9af 36
d7161de4
AR
37#define QNX_NOTE_NAME "QNX"
38#define QNX_INFO_SECT_NAME "QNX_info"
39
1b883d35
KW
40#ifdef __CYGWIN__
41#include <sys/cygwin.h>
42#endif
43
44#ifdef __CYGWIN__
45static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
46#elif defined(__sun__) || defined(linux)
47static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
48#else
49static char default_nto_target[] = "";
50#endif
51
52struct nto_target_ops current_nto_target;
53
08b8a139 54static const registry<inferior>::key<struct nto_inferior_data>
bdb3ed9e 55 nto_inferior_data_reg;
a9889169 56
1b883d35
KW
57static char *
58nto_target (void)
59{
60 char *p = getenv ("QNX_TARGET");
61
62#ifdef __CYGWIN__
63 static char buf[PATH_MAX];
64 if (p)
90375a0e 65 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
1b883d35 66 else
90375a0e 67 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
1b883d35
KW
68 return buf;
69#else
70 return p ? p : default_nto_target;
71#endif
72}
73
74/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
75 CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
76int
77nto_map_arch_to_cputype (const char *arch)
78{
79 if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
80 return CPUTYPE_X86;
192cdb19 81 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
1b883d35
KW
82 return CPUTYPE_PPC;
83 if (!strcmp (arch, "mips"))
84 return CPUTYPE_MIPS;
85 if (!strcmp (arch, "arm"))
86 return CPUTYPE_ARM;
87 if (!strcmp (arch, "sh"))
88 return CPUTYPE_SH;
89 return CPUTYPE_UNKNOWN;
90}
91
92int
992f1ddc 93nto_find_and_open_solib (const char *solib, unsigned o_flags,
e0cc99a6 94 gdb::unique_xmalloc_ptr<char> *temp_pathname)
1b883d35 95{
c32ed3ef
PA
96 char *buf, *arch_path, *nto_root;
97 const char *endian;
91495617 98 const char *base;
1b883d35 99 const char *arch;
08850b56 100 int arch_len, len, ret;
0df8b418
MS
101#define PATH_FMT \
102 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
1b883d35
KW
103
104 nto_root = nto_target ();
99d9c3b9
SM
105 gdbarch *gdbarch = current_inferior ()->arch ();
106 if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0)
1b883d35
KW
107 {
108 arch = "x86";
109 endian = "";
110 }
99d9c3b9 111 else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
1143fffb 112 "rs6000") == 0
99d9c3b9 113 || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
1143fffb 114 "powerpc") == 0)
1b883d35
KW
115 {
116 arch = "ppc";
117 endian = "be";
118 }
119 else
120 {
99d9c3b9
SM
121 arch = gdbarch_bfd_arch_info (gdbarch)->arch_name;
122 endian = gdbarch_byte_order (gdbarch)
4c6b5505 123 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
124 }
125
d737fd7f
KW
126 /* In case nto_root is short, add strlen(solib)
127 so we can reuse arch_path below. */
1b883d35 128
08850b56
PM
129 arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
130 + strlen (solib));
224c3ddb 131 arch_path = (char *) alloca (arch_len);
08850b56
PM
132 xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
133
134 len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
224c3ddb 135 buf = (char *) alloca (len);
08850b56
PM
136 xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
137 arch_path);
1b883d35 138
9f37bbcc 139 base = lbasename (solib);
492c0ab7
JK
140 ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
141 temp_pathname);
d737fd7f
KW
142 if (ret < 0 && base != solib)
143 {
08850b56 144 xsnprintf (arch_path, arch_len, "/%s", solib);
d737fd7f
KW
145 ret = open (arch_path, o_flags, 0);
146 if (temp_pathname)
147 {
148 if (ret >= 0)
e0cc99a6 149 *temp_pathname = gdb_realpath (arch_path);
d737fd7f 150 else
e0cc99a6 151 temp_pathname->reset (NULL);
d737fd7f
KW
152 }
153 }
154 return ret;
1b883d35
KW
155}
156
157void
158nto_init_solib_absolute_prefix (void)
159{
160 char buf[PATH_MAX * 2], arch_path[PATH_MAX];
c32ed3ef
PA
161 char *nto_root;
162 const char *endian;
1b883d35
KW
163 const char *arch;
164
165 nto_root = nto_target ();
99d9c3b9
SM
166 gdbarch *gdbarch = current_inferior ()->arch ();
167 if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0)
1b883d35
KW
168 {
169 arch = "x86";
170 endian = "";
171 }
99d9c3b9 172 else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
1143fffb 173 "rs6000") == 0
99d9c3b9 174 || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
1143fffb 175 "powerpc") == 0)
1b883d35
KW
176 {
177 arch = "ppc";
178 endian = "be";
179 }
180 else
181 {
99d9c3b9
SM
182 arch = gdbarch_bfd_arch_info (gdbarch)->arch_name;
183 endian = gdbarch_byte_order (gdbarch)
4c6b5505 184 == BFD_ENDIAN_BIG ? "be" : "le";
1b883d35
KW
185 }
186
08850b56 187 xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
1b883d35 188
08850b56 189 xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
1b883d35
KW
190 execute_command (buf, 0);
191}
192
193char **
14ef7606
AR
194nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
195 const char **perr)
1b883d35
KW
196{
197 char **argv;
a121b7c1 198 const char *in, *out, *err, *p;
1b883d35
KW
199 int argc, i, n;
200
201 for (n = 0; pargv[n]; n++);
202 if (n == 0)
203 return NULL;
204 in = "";
205 out = "";
206 err = "";
207
224c3ddb 208 argv = XCNEWVEC (char *, n + 1);
1b883d35
KW
209 argc = n;
210 for (i = 0, n = 0; n < argc; n++)
211 {
212 p = pargv[n];
213 if (*p == '>')
214 {
215 p++;
216 if (*p)
217 out = p;
218 else
219 out = pargv[++n];
220 }
221 else if (*p == '<')
222 {
223 p++;
224 if (*p)
225 in = p;
226 else
227 in = pargv[++n];
228 }
229 else if (*p++ == '2' && *p++ == '>')
230 {
231 if (*p == '&' && *(p + 1) == '1')
232 err = out;
233 else if (*p)
234 err = p;
235 else
236 err = pargv[++n];
237 }
238 else
239 argv[i++] = pargv[n];
240 }
241 *pin = in;
242 *pout = out;
243 *perr = err;
244 return argv;
245}
246
1b883d35 247static CORE_ADDR
7b323785 248lm_addr (const solib &so)
1b883d35 249{
7ad0a42e 250 auto *li = gdb::checked_static_cast<const lm_info_svr4 *> (so.lm_info.get ());
1b883d35 251
d0e449a1 252 return li->l_addr;
1b883d35
KW
253}
254
255static CORE_ADDR
256nto_truncate_ptr (CORE_ADDR addr)
257{
99d9c3b9
SM
258 gdbarch *gdbarch = current_inferior ()->arch ();
259 if (gdbarch_ptr_bit (gdbarch) == sizeof (CORE_ADDR) * 8)
1b883d35
KW
260 /* We don't need to truncate anything, and the bit twiddling below
261 will fail due to overflow problems. */
262 return addr;
263 else
99d9c3b9 264 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (gdbarch)) - 1);
1b883d35
KW
265}
266
63807e1d 267static Elf_Internal_Phdr *
1b883d35
KW
268find_load_phdr (bfd *abfd)
269{
270 Elf_Internal_Phdr *phdr;
271 unsigned int i;
272
273 if (!elf_tdata (abfd))
274 return NULL;
275
276 phdr = elf_tdata (abfd)->phdr;
277 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
278 {
279 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
280 return phdr;
281 }
282 return NULL;
283}
284
285void
7b323785 286nto_relocate_section_addresses (solib &so, target_section *sec)
1b883d35
KW
287{
288 /* Neutrino treats the l_addr base address field in link.h as different than
289 the base address in the System V ABI and so the offset needs to be
290 calculated and applied to relocations. */
57e6060e 291 Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
1b883d35
KW
292 unsigned vaddr = phdr ? phdr->p_vaddr : 0;
293
b23518f0
PM
294 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
295 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
1b883d35
KW
296}
297
d737fd7f
KW
298/* This is cheating a bit because our linker code is in libc.so. If we
299 ever implement lazy linking, this may need to be re-examined. */
300int
301nto_in_dynsym_resolve_code (CORE_ADDR pc)
302{
3e5d3a5a 303 if (in_plt_section (pc))
d737fd7f
KW
304 return 1;
305 return 0;
306}
307
d737fd7f 308void
468e3d51 309nto_dummy_supply_regset (struct regcache *regcache, char *regs)
d737fd7f
KW
310{
311 /* Do nothing. */
312}
313
d7161de4
AR
314static void
315nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj)
316{
317 const char *sectname;
318 unsigned int sectsize;
319 /* Buffer holding the section contents. */
320 char *note;
321 unsigned int namelen;
322 const char *name;
323 const unsigned sizeof_Elf_Nhdr = 12;
324
fd361982
AM
325 sectname = bfd_section_name (sect);
326 sectsize = bfd_section_size (sect);
d7161de4
AR
327
328 if (sectsize > 128)
329 sectsize = 128;
330
331 if (sectname != NULL && strstr (sectname, QNX_INFO_SECT_NAME) != NULL)
332 *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
333 else if (sectname != NULL && strstr (sectname, "note") != NULL
334 && sectsize > sizeof_Elf_Nhdr)
335 {
336 note = XNEWVEC (char, sectsize);
337 bfd_get_section_contents (abfd, sect, note, 0, sectsize);
338 namelen = (unsigned int) bfd_h_get_32 (abfd, note);
339 name = note + sizeof_Elf_Nhdr;
340 if (sectsize >= namelen + sizeof_Elf_Nhdr
341 && namelen == sizeof (QNX_NOTE_NAME)
342 && 0 == strcmp (name, QNX_NOTE_NAME))
dda83cd7 343 *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
d7161de4
AR
344
345 XDELETEVEC (note);
346 }
347}
348
d737fd7f
KW
349enum gdb_osabi
350nto_elf_osabi_sniffer (bfd *abfd)
351{
d7161de4
AR
352 enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
353
354 bfd_map_over_sections (abfd,
355 nto_sniff_abi_note_section,
356 &osabi);
357
358 return osabi;
d737fd7f
KW
359}
360
27087b7f 361static const char * const nto_thread_state_str[] =
745a434e
AR
362{
363 "DEAD", /* 0 0x00 */
364 "RUNNING", /* 1 0x01 */
365 "READY", /* 2 0x02 */
366 "STOPPED", /* 3 0x03 */
367 "SEND", /* 4 0x04 */
368 "RECEIVE", /* 5 0x05 */
369 "REPLY", /* 6 0x06 */
370 "STACK", /* 7 0x07 */
371 "WAITTHREAD", /* 8 0x08 */
372 "WAITPAGE", /* 9 0x09 */
373 "SIGSUSPEND", /* 10 0x0a */
374 "SIGWAITINFO", /* 11 0x0b */
375 "NANOSLEEP", /* 12 0x0c */
376 "MUTEX", /* 13 0x0d */
377 "CONDVAR", /* 14 0x0e */
378 "JOIN", /* 15 0x0f */
379 "INTR", /* 16 0x10 */
380 "SEM", /* 17 0x11 */
381 "WAITCTX", /* 18 0x12 */
382 "NET_SEND", /* 19 0x13 */
383 "NET_REPLY" /* 20 0x14 */
384};
385
7a114964 386const char *
c15906d8 387nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
745a434e 388{
7aabaf9d
SM
389 if (ti != NULL && ti->priv != NULL)
390 {
391 nto_thread_info *priv = get_nto_thread_info (ti);
392
393 if (priv->state < ARRAY_SIZE (nto_thread_state_str))
394 return nto_thread_state_str [priv->state];
395 }
745a434e
AR
396 return "";
397}
398
1b883d35 399void
d737fd7f 400nto_initialize_signals (void)
1b883d35 401{
1b883d35
KW
402 /* We use SIG45 for pulses, or something, so nostop, noprint
403 and pass them. */
2ea28649
PA
404 signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
405 signal_print_update (gdb_signal_from_name ("SIG45"), 0);
406 signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
1b883d35
KW
407
408 /* By default we don't want to stop on these two, but we do want to pass. */
409#if defined(SIGSELECT)
410 signal_stop_update (SIGSELECT, 0);
411 signal_print_update (SIGSELECT, 0);
412 signal_pass_update (SIGSELECT, 1);
413#endif
414
415#if defined(SIGPHOTON)
416 signal_stop_update (SIGPHOTON, 0);
417 signal_print_update (SIGPHOTON, 0);
418 signal_pass_update (SIGPHOTON, 1);
419#endif
d737fd7f 420}
8a6c0ccd
AR
421
422/* Read AUXV from initial_stack. */
423LONGEST
424nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf,
dda83cd7 425 LONGEST len, size_t sizeof_auxv_t)
8a6c0ccd
AR
426{
427 gdb_byte targ32[4]; /* For 32 bit target values. */
428 gdb_byte targ64[8]; /* For 64 bit target values. */
429 CORE_ADDR data_ofs = 0;
430 ULONGEST anint;
431 LONGEST len_read = 0;
432 gdb_byte *buff;
433 enum bfd_endian byte_order;
434 int ptr_size;
435
436 if (sizeof_auxv_t == 16)
437 ptr_size = 8;
438 else
439 ptr_size = 4;
440
441 /* Skip over argc, argv and envp... Comment from ldd.c:
442
443 The startup frame is set-up so that we have:
444 auxv
445 NULL
446 ...
447 envp2
448 envp1 <----- void *frame + (argc + 2) * sizeof(char *)
449 NULL
450 ...
451 argv2
452 argv1
453 argc <------ void * frame
454
455 On entry to ldd, frame gives the address of argc on the stack. */
456 /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little
457 * endian. So we just read first 4 bytes. */
458 if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0)
459 return 0;
460
99d9c3b9 461 byte_order = gdbarch_byte_order (current_inferior ()->arch ());
8a6c0ccd
AR
462
463 anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order);
464
465 /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */
466 data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and
dda83cd7
SM
467 NULL terminating pointer in
468 argv. */
8a6c0ccd
AR
469
470 /* Now loop over env table: */
471 anint = 0;
472 while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size)
dda83cd7 473 == 0)
8a6c0ccd
AR
474 {
475 if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0)
476 anint = 1; /* Keep looping until non-null entry is found. */
477 else if (anint)
478 break;
479 data_ofs += ptr_size;
480 }
481 initial_stack += data_ofs;
482
483 memset (readbuf, 0, len);
484 buff = readbuf;
485 while (len_read <= len-sizeof_auxv_t)
486 {
487 if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t)
488 == 0)
dda83cd7 489 {
8a6c0ccd 490 /* Both 32 and 64 bit structures have int as the first field. */
dda83cd7 491 const ULONGEST a_type
8a6c0ccd
AR
492 = extract_unsigned_integer (buff, sizeof (targ32), byte_order);
493
dda83cd7 494 if (a_type == AT_NULL)
8a6c0ccd
AR
495 break;
496 buff += sizeof_auxv_t;
497 len_read += sizeof_auxv_t;
dda83cd7 498 }
8a6c0ccd 499 else
dda83cd7 500 break;
8a6c0ccd
AR
501 }
502 return len_read;
503}
a9889169 504
a9889169
AR
505/* Return nto_inferior_data for the given INFERIOR. If not yet created,
506 construct it. */
507
508struct nto_inferior_data *
509nto_inferior_data (struct inferior *const inferior)
510{
511 struct inferior *const inf = inferior ? inferior : current_inferior ();
512 struct nto_inferior_data *inf_data;
513
514 gdb_assert (inf != NULL);
515
bdb3ed9e 516 inf_data = nto_inferior_data_reg.get (inf);
a9889169 517 if (inf_data == NULL)
bdb3ed9e 518 inf_data = nto_inferior_data_reg.emplace (inf);
a9889169
AR
519
520 return inf_data;
521}