/* nto-tdep.c - general QNX Neutrino target functionality.
- Copyright (C) 2003-2015 Free Software Foundation, Inc.
+ Copyright (C) 2003-2020 Free Software Foundation, Inc.
Contributed by QNX Software Systems Ltd.
#include "solib-svr4.h"
#include "gdbcore.h"
#include "objfiles.h"
+#include "source.h"
+#include "gdbsupport/pathstuff.h"
+
+#define QNX_NOTE_NAME "QNX"
+#define QNX_INFO_SECT_NAME "QNX_info"
#ifdef __CYGWIN__
#include <sys/cygwin.h>
struct nto_target_ops current_nto_target;
+static const struct inferior_key<struct nto_inferior_data>
+ nto_inferior_data_reg;
+
static char *
nto_target (void)
{
}
int
-nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
+nto_find_and_open_solib (const char *solib, unsigned o_flags,
+ gdb::unique_xmalloc_ptr<char> *temp_pathname)
{
char *buf, *arch_path, *nto_root;
const char *endian;
if (ret >= 0)
*temp_pathname = gdb_realpath (arch_path);
else
- *temp_pathname = NULL;
+ temp_pathname->reset (NULL);
}
}
return ret;
const char **perr)
{
char **argv;
- char *in, *out, *err, *p;
+ const char *in, *out, *err, *p;
int argc, i, n;
for (n = 0; pargv[n]; n++);
return argv;
}
-/* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
- solib-svr4.c to support nto_relocate_section_addresses
- which is different from the svr4 version. */
-
-/* Link map info to include in an allocated so_list entry */
-
-struct lm_info
- {
- /* Pointer to copy of link map from inferior. The type is char *
- rather than void *, so that we may use byte offsets to find the
- various fields without the need for a cast. */
- gdb_byte *lm;
-
- /* Amount by which addresses in the binary should be relocated to
- match the inferior. This could most often be taken directly
- from lm, but when prelinking is involved and the prelink base
- address changes, we may need a different offset, we want to
- warn about the difference and compute it only once. */
- CORE_ADDR l_addr;
-
- /* The target location of lm. */
- CORE_ADDR lm_addr;
- };
-
-
static CORE_ADDR
lm_addr (struct so_list *so)
{
- if (so->lm_info->l_addr == (CORE_ADDR)-1)
- {
- struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
- struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+ lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
- so->lm_info->l_addr =
- extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
- }
- return so->lm_info->l_addr;
+ return li->l_addr;
}
static CORE_ADDR
/* Do nothing. */
}
+static void
+nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj)
+{
+ const char *sectname;
+ unsigned int sectsize;
+ /* Buffer holding the section contents. */
+ char *note;
+ unsigned int namelen;
+ const char *name;
+ const unsigned sizeof_Elf_Nhdr = 12;
+
+ sectname = bfd_section_name (sect);
+ sectsize = bfd_section_size (sect);
+
+ if (sectsize > 128)
+ sectsize = 128;
+
+ if (sectname != NULL && strstr (sectname, QNX_INFO_SECT_NAME) != NULL)
+ *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
+ else if (sectname != NULL && strstr (sectname, "note") != NULL
+ && sectsize > sizeof_Elf_Nhdr)
+ {
+ note = XNEWVEC (char, sectsize);
+ bfd_get_section_contents (abfd, sect, note, 0, sectsize);
+ namelen = (unsigned int) bfd_h_get_32 (abfd, note);
+ name = note + sizeof_Elf_Nhdr;
+ if (sectsize >= namelen + sizeof_Elf_Nhdr
+ && namelen == sizeof (QNX_NOTE_NAME)
+ && 0 == strcmp (name, QNX_NOTE_NAME))
+ *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
+
+ XDELETEVEC (note);
+ }
+}
+
enum gdb_osabi
nto_elf_osabi_sniffer (bfd *abfd)
{
- if (nto_is_nto_target)
- return nto_is_nto_target (abfd);
- return GDB_OSABI_UNKNOWN;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ bfd_map_over_sections (abfd,
+ nto_sniff_abi_note_section,
+ &osabi);
+
+ return osabi;
}
static const char *nto_thread_state_str[] =
"NET_REPLY" /* 20 0x14 */
};
-char *
+const char *
nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
{
- if (ti && ti->priv
- && ti->priv->state < ARRAY_SIZE (nto_thread_state_str))
- return (char *)nto_thread_state_str [ti->priv->state];
+ if (ti != NULL && ti->priv != NULL)
+ {
+ nto_thread_info *priv = get_nto_thread_info (ti);
+
+ if (priv->state < ARRAY_SIZE (nto_thread_state_str))
+ return nto_thread_state_str [priv->state];
+ }
return "";
}
}
return len_read;
}
+
+/* Return nto_inferior_data for the given INFERIOR. If not yet created,
+ construct it. */
+
+struct nto_inferior_data *
+nto_inferior_data (struct inferior *const inferior)
+{
+ struct inferior *const inf = inferior ? inferior : current_inferior ();
+ struct nto_inferior_data *inf_data;
+
+ gdb_assert (inf != NULL);
+
+ inf_data = nto_inferior_data_reg.get (inf);
+ if (inf_data == NULL)
+ inf_data = nto_inferior_data_reg.emplace (inf);
+
+ return inf_data;
+}