#include "agent.h"
#include "auxv.h"
#include "target-debug.h"
+#include "top.h"
+#include "event-top.h"
static void target_info (char *, int);
void
target_terminal_inferior (void)
{
+ struct ui *ui = current_ui;
+
/* A background resume (``run&'') should leave GDB in control of the
- terminal. Use target_can_async_p, not target_is_async_p, since at
- this point the target is not async yet. However, if sync_execution
- is not set, we know it will become async prior to resume. */
- if (target_can_async_p () && !sync_execution)
+ terminal. */
+ if (ui->prompt_state != PROMPT_BLOCKED)
+ return;
+
+ /* Always delete the current UI's input file handler, regardless of
+ terminal_state, because terminal_state is only valid for the main
+ UI. */
+ delete_file_handler (ui->input_fd);
+
+ /* Since we always run the inferior in the main console (unless "set
+ inferior-tty" is in effect), when some UI other than the main one
+ calls target_terminal_inferior/target_terminal_inferior, then we
+ only register/unregister the UI's input from the event loop, but
+ leave the main UI's terminal settings as is. */
+ if (ui != main_ui)
return;
if (terminal_state == terminal_is_inferior)
void
target_terminal_ours (void)
{
+ struct ui *ui = current_ui;
+
+ /* Always add the current UI's input file handler, regardless of
+ terminal_state, because terminal_state is only valid for the main
+ UI. */
+ add_file_handler (ui->input_fd, stdin_event_handler, ui);
+
+ /* See target_terminal_inferior. */
+ if (ui != main_ui)
+ return;
+
if (terminal_state == terminal_is_ours)
return;
void
target_terminal_ours_for_output (void)
{
+ struct ui *ui = current_ui;
+
+ /* See target_terminal_inferior. */
+ if (ui != main_ui)
+ return;
+
if (terminal_state != terminal_is_inferior)
return;
(*current_target.to_terminal_ours_for_output) (¤t_target);
by memory_xfer_partial_1. We will continually malloc
and free a copy of the entire write request for breakpoint
shadow handling even though we only end up writing a small
- subset of it. Cap writes to 4KB to mitigate this. */
- len = min (4096, len);
+ subset of it. Cap writes to a limit specified by the target
+ to mitigate this. */
+ len = min (ops->to_get_memory_xfer_limit (ops), len);
buf = (gdb_byte *) xmalloc (len);
old_chain = make_cleanup (xfree, buf);
VEC(mem_region_s) *result;
struct mem_region *last_one, *this_one;
int ix;
- struct target_ops *t;
-
result = current_target.to_memory_map (¤t_target);
if (result == NULL)
return NULL;
void
free_memory_read_result_vector (void *x)
{
- VEC(memory_read_result_s) *v = (VEC(memory_read_result_s) *) x;
+ VEC(memory_read_result_s) **v = (VEC(memory_read_result_s) **) x;
memory_read_result_s *current;
int ix;
- for (ix = 0; VEC_iterate (memory_read_result_s, v, ix, current); ++ix)
+ for (ix = 0; VEC_iterate (memory_read_result_s, *v, ix, current); ++ix)
{
xfree (current->data);
}
- VEC_free (memory_read_result_s, v);
+ VEC_free (memory_read_result_s, *v);
}
VEC(memory_read_result_s) *
{
VEC(memory_read_result_s) *result = 0;
int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
+ struct cleanup *cleanup = make_cleanup (free_memory_read_result_vector,
+ &result);
LONGEST xfered_total = 0;
while (xfered_total < len)
{
LONGEST to_read = min (len - xfered_total, region_len);
gdb_byte *buffer = (gdb_byte *) xmalloc (to_read * unit_size);
+ struct cleanup *inner_cleanup = make_cleanup (xfree, buffer);
LONGEST xfered_partial =
target_read (ops, TARGET_OBJECT_MEMORY, NULL,
{
/* Got an error reading full chunk. See if maybe we can read
some subrange. */
- xfree (buffer);
+ do_cleanups (inner_cleanup);
read_whatever_is_readable (ops, offset + xfered_total,
offset + xfered_total + to_read,
unit_size, &result);
else
{
struct memory_read_result r;
+
+ discard_cleanups (inner_cleanup);
r.data = buffer;
r.begin = offset + xfered_total;
r.end = r.begin + xfered_partial;
QUIT;
}
}
+
+ discard_cleanups (cleanup);
return result;
}
void
target_detach (const char *args, int from_tty)
{
- struct target_ops* t;
-
if (gdbarch_has_global_breakpoints (target_gdbarch ()))
/* Don't remove global breakpoints here. They're removed on
disconnection from the target. */
void
target_resume (ptid_t ptid, int step, enum gdb_signal signal)
{
- struct target_ops *t;
-
target_dcache_invalidate ();
current_target.to_resume (¤t_target, ptid, step, signal);
static int
acquire_fileio_fd (struct target_ops *t, int fd)
{
- fileio_fh_t *fh, buf;
+ fileio_fh_t *fh;
gdb_assert (!is_closed_fileio_fh (fd));
}
\f
+
+/* See target.h */
+
+void
+target_announce_detach (int from_tty)
+{
+ pid_t pid;
+ char *exec_file;
+
+ if (!from_tty)
+ return;
+
+ exec_file = get_exec_file (0);
+ if (exec_file == NULL)
+ exec_file = "";
+
+ pid = ptid_get_pid (inferior_ptid);
+ printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ gdb_flush (gdb_stdout);
+}
+
/* The inferior process has died. Long live the inferior! */
void
target_interrupt (inferior_ptid);
}
-/* See target.h. */
-
-void
-target_check_pending_interrupt (void)
-{
- (*current_target.to_check_pending_interrupt) (¤t_target);
-}
-
/* See target/target.h. */
void
void
target_store_registers (struct regcache *regcache, int regno)
{
- struct target_ops *t;
-
if (!may_write_registers)
error (_("Writing to registers is not allowed (regno %d)"), regno);