/* Main code for remote server for GDB.
- Copyright (C) 1989-2015 Free Software Foundation, Inc.
+ Copyright (C) 1989-2016 Free Software Foundation, Inc.
This file is part of GDB.
int server_waiting;
-int extended_protocol;
+static int extended_protocol;
static int response_needed;
static int exit_requested;
static struct target_waitstatus last_status;
static ptid_t last_ptid;
-static char *own_buf;
+char *own_buf;
static unsigned char *mem_buf;
/* A sub-class of 'struct notif_event' for stop, holding information
}
while (last_status.value.sig != GDB_SIGNAL_TRAP);
}
- target_arch_setup ();
+ target_post_create_inferior ();
return signal_pid;
}
(assuming success). */
last_ptid = mywait (pid_to_ptid (signal_pid), &last_status, 0, 0);
- target_arch_setup ();
+ target_post_create_inferior ();
if (last_status.kind != TARGET_WAITKIND_EXITED
&& last_status.kind != TARGET_WAITKIND_SIGNALLED)
return NULL;
}
-/* Handle btrace enabling in Intel(R) Processor Trace format. */
+/* Handle btrace enabling in Intel Processor Trace format. */
static const char *
handle_btrace_enable_pt (struct thread_info *thread)
return;
}
+ if (startswith (own_buf, "QCatchSyscalls:"))
+ {
+ const char *p = own_buf + sizeof ("QCatchSyscalls:") - 1;
+ int enabled = -1;
+ CORE_ADDR sysno;
+ struct process_info *process;
+
+ if (!target_running () || !target_supports_catch_syscall ())
+ {
+ write_enn (own_buf);
+ return;
+ }
+
+ if (strcmp (p, "0") == 0)
+ enabled = 0;
+ else if (p[0] == '1' && (p[1] == ';' || p[1] == '\0'))
+ enabled = 1;
+ else
+ {
+ fprintf (stderr, "Unknown catch-syscalls mode requested: %s\n",
+ own_buf);
+ write_enn (own_buf);
+ return;
+ }
+
+ process = current_process ();
+ VEC_truncate (int, process->syscalls_to_catch, 0);
+
+ if (enabled)
+ {
+ p += 1;
+ if (*p == ';')
+ {
+ p += 1;
+ while (*p != '\0')
+ {
+ p = decode_address_to_semicolon (&sysno, p);
+ VEC_safe_push (int, process->syscalls_to_catch, (int) sysno);
+ }
+ }
+ else
+ VEC_safe_push (int, process->syscalls_to_catch, ANY_SYSCALL);
+ }
+
+ write_ok (own_buf);
+ return;
+ }
+
if (strcmp (own_buf, "QStartNoAckMode") == 0)
{
if (remote_debug)
return NULL;
}
-void
+static void
monitor_show_help (void)
{
monitor_output ("The following monitor commands are supported:\n");
return 0;
}
-/* Table used by the crc32 function to calcuate the checksum. */
-
-static unsigned int crc32_table[256] =
-{0, 0};
-
/* Compute 32 bit CRC from inferior memory.
On success, return 32 bit CRC.
static unsigned long long
crc32 (CORE_ADDR base, int len, unsigned int crc)
{
- if (!crc32_table[1])
- {
- /* Initialize the CRC table and the decoding table. */
- int i, j;
- unsigned int c;
-
- for (i = 0; i < 256; i++)
- {
- for (c = i << 24, j = 8; j > 0; --j)
- c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
- crc32_table[i] = c;
- }
- }
-
while (len--)
{
unsigned char byte = 0;
if (read_inferior_memory (base, &byte, 1) != 0)
return (unsigned long long) -1;
- crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ byte) & 255];
+ crc = xcrc32 (&byte, 1, crc);
base++;
}
return (unsigned long long) crc;
/* Handle all of the extended 'q' packets. */
-void
+static void
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
static struct inferior_list_entry *thread_ptr;
"PacketSize=%x;QPassSignals+;QProgramSignals+",
PBUFSIZ - 1);
+ if (target_supports_catch_syscall ())
+ strcat (own_buf, ";QCatchSyscalls+");
+
if (the_target->qxfer_libraries_svr4 != NULL)
strcat (own_buf, ";qXfer:libraries-svr4:read+"
";augmented-libraries-svr4-read+");
strcat (own_buf, ";tracenz+");
}
- if (target_supports_hardware_single_step ())
+ if (target_supports_hardware_single_step ()
+ || target_supports_software_single_step () )
{
- /* Support target-side breakpoint conditions and commands.
- GDBserver needs to step over the breakpoint if the condition
- is false. GDBserver software single step is too simple, so
- disable conditional breakpoints if the target doesn't have
- hardware single step. */
strcat (own_buf, ";ConditionalBreakpoints+");
}
strcat (own_buf, ";BreakpointCommands+");
}
/* Parse vCont packets. */
-void
+static void
handle_v_cont (char *own_buf)
{
char *p, *q;
}
/* Attach to a new program. Return 1 if successful, 0 if failure. */
-int
+static int
handle_v_attach (char *own_buf)
{
int pid;
}
/* Kill process. Return 1 if successful, 0 if failure. */
-int
+static int
handle_v_kill (char *own_buf)
{
int pid;
gdbserver_version (void)
{
printf ("GNU gdbserver %s%s\n"
- "Copyright (C) 2015 Free Software Foundation, Inc.\n"
+ "Copyright (C) 2016 Free Software Foundation, Inc.\n"
"gdbserver is free software, covered by the "
"GNU General Public License.\n"
"This gdbserver was configured as \"%s\"\n",
gdb_assert_not_reached ("captured_main should never return");
}
-/* Skip PACKET until the next semi-colon (or end of string). */
-
-static void
-skip_to_semicolon (char **packet)
-{
- while (**packet != '\0' && **packet != ';')
- (*packet)++;
-}
-
/* Process options coming from Z packets for a breakpoint. PACKET is
the packet buffer. *PACKET is updated to point to the first char
after the last processed option. */
if (debug_threads)
debug_printf ("Found breakpoint condition.\n");
if (!add_breakpoint_condition (bp, &dataptr))
- skip_to_semicolon (&dataptr);
+ dataptr = strchrnul (dataptr, ';');
}
else if (startswith (dataptr, "cmds:"))
{
persist = (*dataptr == '1');
dataptr += 2;
if (add_breakpoint_commands (bp, &dataptr, persist))
- skip_to_semicolon (&dataptr);
+ dataptr = strchrnul (dataptr, ';');
}
else
{
fprintf (stderr, "Unknown token %c, ignoring.\n",
*dataptr);
/* Skip tokens until we find one that we recognize. */
- skip_to_semicolon (&dataptr);
+ dataptr = strchrnul (dataptr, ';');
}
}
*packet = dataptr;
discard_queued_stop_replies (pid_to_ptid (pid));
write_ok (own_buf);
- if (extended_protocol)
+ if (extended_protocol || target_running ())
{
- /* Treat this like a normal program exit. */
+ /* There is still at least one inferior remaining or
+ we are in extended mode, so don't terminate gdbserver,
+ and instead treat this like a normal program exit. */
last_status.kind = TARGET_WAITKIND_EXITED;
last_status.value.integer = 0;
last_ptid = pid_to_ptid (pid);