[3/4,nto] Fix nto target stopped by watchpoint.
Commit Message
Fix stopped by watchpoint detection: add inferior data, use inferior data
for storing last stopped flags needed for detection.
Add binary sniffing for QNX osabi.
* nto-procfs.c (procfs_wait): Set stopped_flags.
(procfs_stopped_by_watchpoint): Use flags stored in inferior data.
* nto-tdep.c (QNX_NOTE_NAME, QNX_INFO_SECT_NAME): New defines.
(nto_inferior_data_reg): New definition.
(nto_sniff_abi_note_section): New function.
(nto_elf_osabi_sniffer): Use nto_sniff_abi_note_section.
(nto_new_inferior_data, nto_inferior_data_cleanup, nto_inferior_data):
New functions.
(_initialize_nto_tdep): New forward declaration, new function.
* nto-tdep.h (nto_inferior_data): New struct.
(nto_inferior_data): New function declaration.
---
gdb/ChangeLog | 14 +++++++++
gdb/nto-procfs.c | 21 ++++++++++++-
gdb/nto-tdep.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
gdb/nto-tdep.h | 12 ++++++++
4 files changed, 133 insertions(+), 4 deletions(-)
Comments
On 10/13/2015 05:01 PM, Aleksandar Ristovski wrote:
> Fix stopped by watchpoint detection: add inferior data, use inferior data
> for storing last stopped flags needed for detection.
> Add binary sniffing for QNX osabi.
Is the binary sniffing issue any way related to the watchpoint issue?
Thanks,
Pedro Alves
The patch "Fix nto target stopped by watchpoint" is broken into two:
[nto] Fix nto target stopped by watchpoint.
[nto] Improve ABI sniffing.
@@ -1,3 +1,17 @@
+<2015-3> Aleksandar Ristovski <aristovski@qnx.com>
+
+ * nto-procfs.c (procfs_wait): Set stopped_flags.
+ (procfs_stopped_by_watchpoint): Use flags stored in inferior data.
+ * nto-tdep.c (QNX_NOTE_NAME, QNX_INFO_SECT_NAME): New defines.
+ (nto_inferior_data_reg): New definition.
+ (nto_sniff_abi_note_section): New function.
+ (nto_elf_osabi_sniffer): Use nto_sniff_abi_note_section.
+ (nto_new_inferior_data, nto_inferior_data_cleanup, nto_inferior_data):
+ New functions.
+ (_initialize_nto_tdep): New forward declaration, new function.
+ * nto-tdep.h (nto_inferior_data): New struct.
+ (nto_inferior_data): New function declaration.
+
<2015-2> Aleksandar Ristovski <aristovski@qnx.com>
* nto-procfs.c (sys/auxv.h): Include.
@@ -786,6 +786,9 @@ procfs_wait (struct target_ops *ops,
devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
}
+ nto_inferior_data (NULL)->stopped_flags = status.flags;
+ nto_inferior_data (NULL)->stopped_pc = status.ip;
+
if (status.flags & _DEBUG_FLAG_SSTEP)
{
ourstatus->kind = TARGET_WAITKIND_STOPPED;
@@ -1630,5 +1633,21 @@ procfs_insert_hw_watchpoint (struct target_ops *self,
static int
procfs_stopped_by_watchpoint (struct target_ops *ops)
{
- return 0;
+ /* NOTE: nto_stopped_by_watchpoint will be called ONLY while we are
+ stopped due to a SIGTRAP. This assumes gdb works in 'all-stop' mode;
+ future gdb versions will likely run in 'non-stop' mode in which case
+ we will have to store/examine statuses per thread in question.
+ Until then, this will work fine. */
+
+ struct inferior *inf = current_inferior ();
+ struct nto_inferior_data *inf_data;
+
+ gdb_assert (inf != NULL);
+
+ inf_data = nto_inferior_data (inf);
+
+ return inf_data->stopped_flags
+ & (_DEBUG_FLAG_TRACE_RD
+ | _DEBUG_FLAG_TRACE_WR
+ | _DEBUG_FLAG_TRACE_MODIFY);
}
@@ -33,6 +33,9 @@
#include "objfiles.h"
#include "symfile.h"
+#define QNX_NOTE_NAME "QNX"
+#define QNX_INFO_SECT_NAME "QNX_info"
+
#ifdef __CYGWIN__
#include <sys/cygwin.h>
#endif
@@ -47,6 +50,8 @@ static char default_nto_target[] = "";
struct nto_target_ops current_nto_target;
+static const struct inferior_data *nto_inferior_data_reg;
+
static char *
nto_target (void)
{
@@ -331,12 +336,51 @@ nto_dummy_supply_regset (struct regcache *regcache, char *regs)
/* Do nothing. */
}
+static void
+nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj)
+{
+ const char *sectname;
+ unsigned int sectsize;
+ char *note; // buffer holding the section contents
+ unsigned int namelen;
+ const char *name;
+
+ sectname = bfd_get_section_name (abfd, sect);
+ sectsize = bfd_section_size (abfd, sect);
+
+ /* TODO: limit the note size here, for now limit is 128 bytes
+ (enough to check the name and type). */
+ if (sectsize > 128)
+ sectsize = 128;
+
+ if (sectname && strstr (sectname, QNX_INFO_SECT_NAME) != NULL)
+ *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
+
+ if (sectname && strstr (sectname, "note") != NULL)
+ {
+ note = alloca (sectsize);
+ bfd_get_section_contents (abfd, sect, note, 0, sectsize);
+ namelen = (unsigned int) bfd_h_get_32 (abfd, note);
+ name = note + 12;
+
+ if (namelen > 0
+ && (0 == strcmp (name, QNX_NOTE_NAME)))
+ *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
+ }
+}
+
enum gdb_osabi
nto_elf_osabi_sniffer (bfd *abfd)
{
- if (nto_is_nto_target)
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+ bfd_map_over_sections (abfd,
+ nto_sniff_abi_note_section,
+ &osabi);
+
+ if (osabi == GDB_OSABI_UNKNOWN && nto_is_nto_target)
return nto_is_nto_target (abfd);
- return GDB_OSABI_UNKNOWN;
+ return osabi;
}
static const char *nto_thread_state_str[] =
@@ -396,7 +440,6 @@ nto_initialize_signals (void)
#endif
}
-
/* Read AUXV from initial_stack. */
LONGEST
nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf,
@@ -480,4 +523,45 @@ nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf,
return len_read;
}
+static struct nto_inferior_data *
+nto_new_inferior_data (void)
+{
+ struct nto_inferior_data *const inf_data
+ = XCNEW (struct nto_inferior_data);
+
+ return inf_data;
+}
+
+static void
+nto_inferior_data_cleanup (struct inferior *const inf, void *const dat)
+{
+ xfree (dat);
+}
+
+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 = inferior_data (inf, nto_inferior_data_reg);
+ if (inf_data == NULL)
+ {
+ set_inferior_data (inf, nto_inferior_data_reg,
+ (inf_data = nto_new_inferior_data ()));
+ }
+
+ return inf_data;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_nto_tdep;
+void
+_initialize_nto_tdep (void)
+{
+ nto_inferior_data_reg
+ = register_inferior_data_with_cleanup (NULL, nto_inferior_data_cleanup);
+}
@@ -142,6 +142,16 @@ struct private_thread_info
char name[1];
};
+/* Per-inferior data, common for both procfs and remote. */
+struct nto_inferior_data
+{
+ /* Last stopped flags result from wait function */
+ unsigned int stopped_flags;
+
+ /* Last known stopped PC */
+ CORE_ADDR stopped_pc;
+};
+
/* Generic functions in nto-tdep.c. */
void nto_init_solib_absolute_prefix (void);
@@ -172,4 +182,6 @@ LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR inital_stack,
gdb_byte *readbuf,
LONGEST len, size_t sizeof_auxv_t);
+struct nto_inferior_data *nto_inferior_data (struct inferior *inf);
+
#endif