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