X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fnto-procfs.c;h=7fb7095745fda2d15a32ce5e424018a357fa6fa7;hb=2f91880f3afb3cc521111dfcc99b214c77aa97a1;hp=264d88b40fd74e883222128a7425e259a41baea0;hpb=609c3040c2df944239d4d96644d736df605a6831;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 264d88b40f..7fb7095745 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -1,7 +1,7 @@ /* Machine independent support for QNX Neutrino /proc (process file system) for GDB. Written by Colin Burgess at QNX Software Systems Limited. - Copyright (C) 2003-2015 Free Software Foundation, Inc. + Copyright (C) 2003-2017 Free Software Foundation, Inc. Contributed by QNX Software Systems Ltd. @@ -30,6 +30,8 @@ #include #include #include +#include + #include "gdbcore.h" #include "inferior.h" #include "target.h" @@ -514,7 +516,7 @@ procfs_meminfo (char *args, int from_tty) return; } - num = min (num, num_mapinfos); + num = std::min (num, num_mapinfos); /* Run through the list of mapinfos, and store the data and text info so we can print it at the bottom of the loop. */ @@ -615,6 +617,33 @@ procfs_files_info (struct target_ops *ignore) (nodestr != NULL) ? nodestr : "local node"); } +/* Target to_pid_to_exec_file implementation. */ + +static char * +procfs_pid_to_exec_file (struct target_ops *ops, const int pid) +{ + int proc_fd; + static char proc_path[PATH_MAX]; + ssize_t rd; + + /* Read exe file name. */ + snprintf (proc_path, sizeof (proc_path), "%s/proc/%d/exefile", + (nodestr != NULL) ? nodestr : "", pid); + proc_fd = open (proc_path, O_RDONLY); + if (proc_fd == -1) + return NULL; + + rd = read (proc_fd, proc_path, sizeof (proc_path) - 1); + close (proc_fd); + if (rd <= 0) + { + proc_path[0] = '\0'; + return NULL; + } + proc_path[rd] = '\0'; + return proc_path; +} + /* Attach to process PID, then initialize for debugging it. */ static void procfs_attach (struct target_ops *ops, const char *args, int from_tty) @@ -694,16 +723,12 @@ do_attach (ptid_t ptid) static void interrupt_query (void) { - target_terminal_ours (); - if (query (_("Interrupted while waiting for the program.\n\ Give up (and stop debugging it)? "))) { - target_mourn_inferior (); + target_mourn_inferior (inferior_ptid); quit (); } - - target_terminal_inferior (); } /* The user typed ^C twice. */ @@ -755,6 +780,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; @@ -840,7 +868,7 @@ procfs_fetch_registers (struct target_ops *ops, reg; int regsize; - procfs_set_thread (inferior_ptid); + procfs_set_thread (regcache_get_ptid (regcache)); if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK) nto_supply_gregset (regcache, (char *) ®.greg); if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) @@ -885,6 +913,38 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, { case TARGET_OBJECT_MEMORY: return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); + case TARGET_OBJECT_AUXV: + if (readbuf != NULL) + { + int err; + CORE_ADDR initial_stack; + debug_process_t procinfo; + /* For 32-bit architecture, size of auxv_t is 8 bytes. */ + const unsigned int sizeof_auxv_t = sizeof (auxv_t); + const unsigned int sizeof_tempbuf = 20 * sizeof_auxv_t; + int tempread; + gdb_byte *const tempbuf = alloca (sizeof_tempbuf); + + if (tempbuf == NULL) + return TARGET_XFER_E_IO; + + err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, + sizeof procinfo, 0); + if (err != EOK) + return TARGET_XFER_E_IO; + + initial_stack = procinfo.initial_stack; + + /* procfs is always 'self-hosted', no byte-order manipulation. */ + tempread = nto_read_auxv_from_initial_stack (initial_stack, tempbuf, + sizeof_tempbuf, + sizeof (auxv_t)); + tempread = std::min (tempread, len) - offset; + memcpy (readbuf, tempbuf + offset, tempread); + *xfered_len = tempread; + return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; + } + /* Fallthru */ default: return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf, writebuf, offset, len, @@ -902,15 +962,8 @@ procfs_detach (struct target_ops *ops, const char *args, int from_tty) int siggnal = 0; int pid; - if (from_tty) - { - char *exec_file = get_exec_file (0); - if (exec_file == 0) - exec_file = ""; - printf_unfiltered ("Detaching from program: %s %s\n", - exec_file, target_pid_to_str (inferior_ptid)); - gdb_flush (gdb_stdout); - } + target_announce_detach (); + if (args) siggnal = atoi (args); @@ -951,7 +1004,8 @@ procfs_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch, static int procfs_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) + struct bp_target_info *bp_tgt, + enum remove_bp_reason reason) { return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); } @@ -1109,8 +1163,9 @@ breakup_args (char *scratch, char **argv) } static void -procfs_create_inferior (struct target_ops *ops, char *exec_file, - char *allargs, char **env, int from_tty) +procfs_create_inferior (struct target_ops *ops, const char *exec_file, + const std::string &allargs, + char **env, int from_tty) { struct inheritance inherit; pid_t pid; @@ -1122,7 +1177,7 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file, const char *inferior_io_terminal = get_inferior_io_terminal (); struct inferior *inf; - argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) * + argv = xmalloc ((allargs.size () / (unsigned) 2 + 2) * sizeof (*argv)); argv[0] = get_exec_file (1); if (!argv[0]) @@ -1133,7 +1188,7 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file, return; } - args = xstrdup (allargs); + args = xstrdup (allargs.c_str ()); breakup_args (args, (exec_file != NULL) ? &argv[1] : &argv[0]); argv = nto_parse_redirection (argv, &in, &out, &err); @@ -1246,7 +1301,7 @@ procfs_interrupt (struct target_ops *self, ptid_t ptid) static void procfs_kill_inferior (struct target_ops *ops) { - target_mourn_inferior (); + target_mourn_inferior (inferior_ptid); } /* Fill buf with regset and return devctl cmd to do the setting. Return @@ -1296,10 +1351,11 @@ procfs_store_registers (struct target_ops *ops, unsigned off; int len, regset, regsize, dev_set, err; char *data; + ptid_t ptid = regcache_get_ptid (regcache); - if (ptid_equal (inferior_ptid, null_ptid)) + if (ptid_equal (ptid, null_ptid)) return; - procfs_set_thread (inferior_ptid); + procfs_set_thread (ptid); if (regno == -1) { @@ -1457,6 +1513,7 @@ init_procfs_targets (void) t->to_interrupt = procfs_interrupt; t->to_have_continuable_watchpoint = 1; t->to_extra_thread_info = nto_extra_thread_info; + t->to_pid_to_exec_file = procfs_pid_to_exec_file; nto_native_ops = t; @@ -1564,5 +1621,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); }