PATCH: Further gdbserver cleanups

Daniel Jacobowitz
2002-04-06T18:33:26Z

This patch adds -Wall to gdbserver's build options, cleans up everything
that it turned up, and adds the beginnings of a target stack. It also adds
a simplistic mechanism to track child processes opaquely; for instance, for
per-child regcaches. No real new functionality here, but it should be
pretty obvious where I'm going. The next batch of changes are likely to be
more interesting.

I'll check this in in a day or two if no one objects (well, and when Andrew
thinks it's been long enough and checks in the relevant MAINTAINERS patch).

--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer

2002-04-06 Daniel Jacobowitz <drow@mvista.com>

* gdbserver/inferiors.c: New file.
* gdbserver/target.c: New file.
* gdbserver/target.h: New file.
* gdbserver/Makefile.in: Add WARN_CFLAGS. Add target.o and
inferiors.o. Update dependencies.
* gdbserver/configure.in: Check for <string.h>
* gdbserver/configure: Regenerate.
* gdbserver/config.in: Regenerate.
* gdbserver/gdbreplay.c: Include needed system headers.
(remote_open): Remove strchr prototype.
* gdbserver/linux-low.c (inferior_pid): New static variable,
moved from server.c.
(linux_create_inferior): Renamed from create_inferior.
Call add_inferior. Return 0 on success instead of a PID.
(linux_attach): Renamed from myattach.
(linux_kill): Renamed from kill_inferior. Call clear_inferiors ().
(linux_thread_alive): Renamed from mythread_alive.
(linux_wait): Renamed from mywait. Call clear_inferiors () if the
child dies.
(linux_resume): Renamed from myresume. Add missing ``return 0''.
(regsets_store_inferior_registers): Correct error message.
Add missing ``return 0''.
(linux_fetch_registers): Renamed from fetch_inferior_registers.
(linux_store_registers): Renamed from store_inferior_registers.
(linux_read_memory): Renamed from read_inferior_memory.
(linux_write_memory): Renamed from write_inferior_memory.
(linux_target_ops): New structure.
(initialize_low): Call set_target_ops ().
* linux-low.h: Correct #ifdef to HAVE_LINUX_USRREGS.
* regcache.c (supply_register): Change buf argument to const void *.
(supply_register_by_name): Likewise.
(collect_register): Change buf argument to void *.
(collect_register_by_name): Likewise.
* regcache.h: Add missing prototypes.
* remote-utils.c: Include <arpa/inet.h> for inet_ntoa.
(unhexify): New function.
(hexify): New function.
(input_interrupt): Send signals to ``signal_pid''.
* server.c (inferior_pid): Remove.
(start_inferior): Update create_inferior call.
(attach_inferior): Call add_inferior.
(handle_query): New function.
(attached): New static variable, moved out of main.
(main): Quiet longjmp clobber warnings. Call handle_query for `q'
packets.
* server.h: Add ATTR_NORETURN and ATTR_FORMAT. Include "target.h".
Remove obsolete prototypes. Add prototypes for "inferiors.c" and
"target.c". Update prototypes.
* utils.c (error): Remove NORETURN.
(fatal): Likewise.

Index: inferiors.c
===================================================================
RCS file: N/A
diff -u /dev/null inferiors.c
--- /dev/null Wed Dec 31 19:00:00 1969
+++ inferiors.c Sat Apr 6 13:27:23 2002
@@ -0,0 +1,71 @@
+/* Inferior process information for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdlib.h>
+
+#include "server.h"
+
+struct inferior_info
+{
+ int pid;
+ struct inferior_info *next;
+};
+
+static struct inferior_info *inferiors;
+struct inferior_info *current_inferior;
+int signal_pid;
+
+void
+add_inferior (int pid)
+{
+ struct inferior_info *new_inferior
+ = (struct inferior_info *) malloc (sizeof (*new_inferior));
+
+ memset (new_inferior, 0, sizeof (*new_inferior));
+
+ new_inferior->pid = pid;
+
+ new_inferior->next = inferiors;
+ inferiors = new_inferior;
+
+ if (current_inferior == NULL)
+ current_inferior = inferiors;
+
+ if (signal_pid == 0)
+ signal_pid = pid;
+}
+
+void
+clear_inferiors (void)
+{
+ struct inferior_info *inf = inferiors, *next_inf;
+
+ while (inf)
+ {
+ next_inf = inf->next;
+ free (inf);
+ inf = next_inf;
+ }
+
+ inferiors = NULL;
+}
Index: target.h
===================================================================
RCS file: N/A
diff -u /dev/null target.h
--- /dev/null Wed Dec 31 19:00:00 1969
+++ target.h Sat Apr 6 13:27:05 2002
@@ -0,0 +1,133 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef TARGET_H
+#define TARGET_H
+
+struct target_ops
+{
+ /* Start a new process.
+
+ PROGRAM is a path to the program to execute.
+ ARGS is a standard NULL-terminated array of arguments,
+ to be passed to the inferior as ``argv''.
+
+ Returns 0 on success, -1 on failure. Registers the new
+ process with the process list. */
+
+ int (*create_inferior) (char *program, char **args);
+
+ /* Attach to a running process.
+
+ PID is the process ID to attach to, specified by the user
+ or a higher layer. */
+
+ int (*attach) (int pid);
+
+ /* Kill all inferiors. */
+
+ void (*kill) (void);
+
+ /* Return 1 iff the thread with process ID PID is alive. */
+
+ int (*thread_alive) (int pid);
+
+ /* Resume the inferior process.
+
+ If STEP is non-zero, we want to single-step.
+
+ If SIGNAL is nonzero, send the process that signal as we resume it.
+ */
+
+ void (*resume) (int step, int signo);
+
+ /* Wait for the inferior process to change state.
+
+ STATUSP will be filled in with a response code to send to GDB.
+
+ Returns the signal which caused the process to stop. */
+
+ unsigned char (*wait) (char *status);
+
+ /* Fetch registers from the inferior process.
+
+ If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
+
+ void (*fetch_registers) (int regno);
+
+ /* Store registers to the inferior process.
+
+ If REGNO is -1, store all registers; otherwise, store at least REGNO. */
+
+ void (*store_registers) (int regno);
+
+ /* Read memory from the inferior process.
+
+ Read LEN bytes at MEMADDR into a buffer at MYADDR. */
+
+ void (*read_memory) (CORE_ADDR memaddr, char *myaddr, int len);
+
+ /* Write memory to the inferior process.
+
+ Write LEN bytes from the buffer at MYADDR to MEMADDR.
+
+ Returns 0 on success and errno on failure. */
+
+ int (*write_memory) (CORE_ADDR memaddr, char *myaddr, int len);
+};
+
+extern struct target_ops *the_target;
+
+void set_target_ops (struct target_ops *);
+
+#define create_inferior(program, args) \
+ (*the_target->create_inferior) (program, args)
+
+#define myattach(pid) \
+ (*the_target->attach) (pid)
+
+#define kill_inferior() \
+ (*the_target->kill) ()
+
+#define mythread_alive(pid) \
+ (*the_target->thread_alive) (pid)
+
+#define myresume(step,signo) \
+ (*the_target->resume) (step, signo)
+
+#define mywait(statusp) \
+ (*the_target->wait) (statusp)
+
+#define fetch_inferior_registers(regno) \
+ (*the_target->fetch_registers) (regno)
+
+#define store_inferior_registers(regno) \
+ (*the_target->store_registers) (regno)
+
+#define read_inferior_memory(memaddr,myaddr,len) \
+ (*the_target->read_memory) (memaddr, myaddr, len)
+
+#define write_inferior_memory(memaddr,myaddr,len) \
+ (*the_target->write_memory) (memaddr, myaddr, len)
+
+#endif /* TARGET_H */
Index: target.c
===================================================================
RCS file: N/A
diff -u /dev/null target.c
--- /dev/null Wed Dec 31 19:00:00 1969
+++ target.c Sat Apr 6 13:27:11 2002
@@ -0,0 +1,33 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "server.h"
+
+struct target_ops *the_target;
+
+void
+set_target_ops (struct target_ops *target)
+{
+ the_target = (struct target_ops *) malloc (sizeof (*the_target));
+ memcpy (the_target, target, sizeof (*the_target));
+}
Index: changelog
===================================================================
RCS file: N/A
diff -u /dev/null changelog
--- /dev/null Wed Dec 31 19:00:00 1969
+++ changelog Sat Apr 6 13:20:01 2002
@@ -0,0 +1,52 @@
+2002-04-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * gdbserver/inferiors.c: New file.
+ * gdbserver/target.c: New file.
+ * gdbserver/target.h: New file.
+ * gdbserver/Makefile.in: Add WARN_CFLAGS. Add target.o and
+ inferiors.o. Update dependencies.
+ * gdbserver/configure.in: Check for <string.h>
+ * gdbserver/configure: Regenerate.
+ * gdbserver/config.in: Regenerate.
+ * gdbserver/gdbreplay.c: Include needed system headers.
+ (remote_open): Remove strchr prototype.
+ * gdbserver/linux-low.c (inferior_pid): New static variable,
+ moved from server.c.
+ (linux_create_inferior): Renamed from create_inferior.
+ Call add_inferior. Return 0 on success instead of a PID.
+ (linux_attach): Renamed from myattach.
+ (linux_kill): Renamed from kill_inferior. Call clear_inferiors ().
+ (linux_thread_alive): Renamed from mythread_alive.
+ (linux_wait): Renamed from mywait. Call clear_inferiors () if the
+ child dies.
+ (linux_resume): Renamed from myresume. Add missing ``return 0''.
+ (regsets_store_inferior_registers): Correct error message.
+ Add missing ``return 0''.
+ (linux_fetch_registers): Renamed from fetch_inferior_registers.
+ (linux_store_registers): Renamed from store_inferior_registers.
+ (linux_read_memory): Renamed from read_inferior_memory.
+ (linux_write_memory): Renamed from write_inferior_memory.
+ (linux_target_ops): New structure.
+ (initialize_low): Call set_target_ops ().
+ * linux-low.h: Correct #ifdef to HAVE_LINUX_USRREGS.
+ * regcache.c (supply_register): Change buf argument to const void *.
+ (supply_register_by_name): Likewise.
+ (collect_register): Change buf argument to void *.
+ (collect_register_by_name): Likewise.
+ * regcache.h: Add missing prototypes.
+ * remote-utils.c: Include <arpa/inet.h> for inet_ntoa.
+ (unhexify): New function.
+ (hexify): New function.
+ (input_interrupt): Send signals to ``signal_pid''.
+ * server.c (inferior_pid): Remove.
+ (start_inferior): Update create_inferior call.
+ (attach_inferior): Call add_inferior.
+ (handle_query): New function.
+ (attached): New static variable, moved out of main.
+ (main): Quiet longjmp clobber warnings. Call handle_query for `q'
+ packets.
+ * server.h: Add ATTR_NORETURN and ATTR_FORMAT. Include "target.h".
+ Remove obsolete prototypes. Add prototypes for "inferiors.c" and
+ "target.c". Update prototypes.
+ * utils.c (error): Remove NORETURN.
+ (fatal): Likewise.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile.in
--- Makefile.in 2002/03/27 05:15:48 1.13
+++ Makefile.in 2002/04/06 18:27:39
@@ -90,13 +90,15 @@ INCLUDE_CFLAGS = -I. -I${srcdir} -I$(src
GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS}
#PROFILE_CFLAGS = -pg

+WARN_CFLAGS = -Wall
+
# CFLAGS is specifically reserved for setting from the command line
# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
CFLAGS = @CFLAGS@

# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
-INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \
- ${INCLUDE_CFLAGS} ${BFD_CFLAGS}
+INTERNAL_CFLAGS = $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \
+ ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${BFD_CFLAGS}

# LDFLAGS is specifically reserved for setting from the command line
# when running make.
@@ -120,7 +122,9 @@ DEPFILES = @GDBSERVER_DEPFILES@
SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}

-OBS = utils.o $(DEPFILES) server.o remote-utils.o regcache.o signals.o
+OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
+ utils.o \
+ $(DEPFILES)

# Prevent Sun make from putting in the machine type. Setting
# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
@@ -195,8 +199,11 @@ maintainer-clean realclean: clean

STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb

+config.h: config.in config.status
+ CONFIG_FILES="" $(SHELL) ./config.status
+
Makefile: Makefile.in config.status
- $(SHELL) ./config.status
+ CONFIG_HEADERS="" $(SHELL) ./config.status

config.status: configure configure.srv
$(SHELL) ./config.status --recheck
@@ -225,12 +232,14 @@ unexport CHILLFLAGS CHILL_LIB CHILL_FOR_
regdat_sh = $(srcdir)/../regformats/regdat.sh
regdef_h = $(srcdir)/../regformats/regdef.h
regcache_h = $(srcdir)/regcache.h
-server_h = $(srcdir)/server.h $(regcache_h) config.h
+server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h

-server.o: server.c $(server_h)
+inferiors.o: inferiors.c $(server_h)
+regcache.o: regcache.c $(server_h) $(regdef_h)
remote-utils.o: remote-utils.c terminal.h $(server_h)
+server.o: server.c $(server_h)
+target.o: target.c $(server_h)
utils.o: utils.c $(server_h)
-regcache.o: regcache.c $(server_h) $(regdef_h)

signals.o: ../signals/signals.c $(server_h)
$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
Index: config.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/config.in,v
retrieving revision 1.2
diff -u -p -r1.2 config.in
--- config.in 2002/02/27 07:07:38 1.2
+++ config.in 2002/04/06 18:27:39
@@ -16,6 +16,9 @@
/* Define if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H

+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
/* Define if you have the <sys/reg.h> header file. */
#undef HAVE_SYS_REG_H

Index: configure
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure,v
retrieving revision 1.6
diff -u -p -r1.6 configure
--- configure 2002/02/27 07:07:38 1.6
+++ configure 2002/04/06 18:27:40
@@ -1105,7 +1105,7 @@ EOF
fi

-for ac_hdr in sgtty.h termio.h termios.h sys/reg.h
+for ac_hdr in sgtty.h termio.h termios.h sys/reg.h string.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
Index: configure.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.in,v
retrieving revision 1.7
diff -u -p -r1.7 configure.in
--- configure.in 2002/02/27 07:07:38 1.7
+++ configure.in 2002/04/06 18:27:40
@@ -30,7 +30,7 @@ AC_PROG_INSTALL

AC_HEADER_STDC

-AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h)
+AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h)

. ${srcdir}/configure.srv

Index: gdbreplay.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/gdbreplay.c,v
retrieving revision 1.5
diff -u -p -r1.5 gdbreplay.c
--- gdbreplay.c 2002/03/21 02:11:03 1.5
+++ gdbreplay.c 2002/04/06 18:27:40
@@ -30,7 +30,13 @@
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>

+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
/* Sort of a hack... */
#define EOL (EOF - 1)

@@ -83,8 +89,6 @@ remote_close (void)
void
remote_open (char *name)
{
- extern char *strchr ();
-
if (!strchr (name, ':'))
{
fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.10
diff -u -p -r1.10 linux-low.c
--- linux-low.c 2002/03/04 16:28:35 1.10
+++ linux-low.c 2002/04/06 18:27:40
@@ -49,11 +49,13 @@ extern int num_regs;
extern int regmap[];
#endif

+static int inferior_pid;
+
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args. */

-int
-create_inferior (char *program, char **allargs)
+static int
+linux_create_inferior (char *program, char **allargs)
{
int pid;

@@ -73,13 +75,16 @@ create_inferior (char *program, char **a
_exit (0177);
}

- return pid;
+ add_inferior (pid);
+ /* FIXME remove */
+ inferior_pid = pid;
+ return 0;
}

/* Attach to an inferior process. */

-int
-myattach (int pid)
+static int
+linux_attach (int pid)
{
if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
{
@@ -95,26 +100,27 @@ myattach (int pid)

/* Kill the inferior process. Make us have no inferior. */

-void
-kill_inferior (void)
+static void
+linux_kill (void)
{
if (inferior_pid == 0)
return;
ptrace (PTRACE_KILL, inferior_pid, 0, 0);
wait (0);
+ clear_inferiors ();
}

/* Return nonzero if the given thread is still alive. */
-int
-mythread_alive (int pid)
+static int
+linux_thread_alive (int pid)
{
return 1;
}

/* Wait for process, returns status */

-unsigned char
-mywait (char *status)
+static unsigned char
+linux_wait (char *status)
{
int pid;
int w;
@@ -129,11 +135,13 @@ mywait (char *status)
{
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
*status = 'W';
+ clear_inferiors ();
return ((unsigned char) WEXITSTATUS (w));
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ clear_inferiors ();
*status = 'X';
return ((unsigned char) WTERMSIG (w));
}
@@ -148,8 +156,8 @@ mywait (char *status)
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */

-void
-myresume (int step, int signal)
+static void
+linux_resume (int step, int signal)
{
errno = 0;
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
@@ -318,6 +326,7 @@ regsets_fetch_inferior_registers (void)
regset->store_function (buf);
regset ++;
}
+ return 0;
}

static int
@@ -360,18 +369,19 @@ regsets_store_inferior_registers (void)
}
else
{
- perror ("Warning: ptrace(regsets_fetch_inferior_registers)");
+ perror ("Warning: ptrace(regsets_store_inferior_registers)");
}
}
regset ++;
}
+ return 0;
}

#endif /* HAVE_LINUX_REGSETS */

void
-fetch_inferior_registers (int regno)
+linux_fetch_registers (int regno)
{
#ifdef HAVE_LINUX_REGSETS
if (use_regsets_p)
@@ -386,7 +396,7 @@ fetch_inferior_registers (int regno)
}

void
-store_inferior_registers (int regno)
+linux_store_registers (int regno)
{
#ifdef HAVE_LINUX_REGSETS
if (use_regsets_p)
@@ -404,8 +414,8 @@ store_inferior_registers (int regno)
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */

-void
-read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+static void
+linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
@@ -433,8 +443,8 @@ read_inferior_memory (CORE_ADDR memaddr,
On failure (cannot write the inferior)
returns the value of errno. */

-int
-write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+static int
+linux_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
@@ -477,8 +487,22 @@ write_inferior_memory (CORE_ADDR memaddr
return 0;
}
\f
+static struct target_ops linux_target_ops = {
+ linux_create_inferior,
+ linux_attach,
+ linux_kill,
+ linux_thread_alive,
+ linux_resume,
+ linux_wait,
+ linux_fetch_registers,
+ linux_store_registers,
+ linux_read_memory,
+ linux_write_memory,
+};
+
void
initialize_low (void)
{
+ set_target_ops (&linux_target_ops);
init_registers ();
}
Index: linux-low.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.h,v
retrieving revision 1.1
diff -u -p -r1.1 linux-low.h
--- linux-low.h 2002/02/27 07:07:39 1.1
+++ linux-low.h 2002/04/06 18:27:40
@@ -18,7 +18,7 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

-#ifdef HAVE_LINUX_USR_REGISTERS
+#ifdef HAVE_LINUX_USRREGS
extern int regmap[];
extern int num_regs;
int cannot_fetch_register (int regno);
Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/regcache.c,v
retrieving revision 1.2
diff -u -p -r1.2 regcache.c
--- regcache.c 2002/02/27 07:07:39 1.2
+++ regcache.c 2002/04/06 18:27:40
@@ -123,25 +123,25 @@ register_data (int n)
}

void
-supply_register (int n, const char *buf)
+supply_register (int n, const void *buf)
{
memcpy (register_data (n), buf, register_size (n));
}

void
-supply_register_by_name (const char *name, const char *buf)
+supply_register_by_name (const char *name, const void *buf)
{
supply_register (find_regno (name), buf);
}

void
-collect_register (int n, char *buf)
+collect_register (int n, void *buf)
{
memcpy (buf, register_data (n), register_size (n));
}

void
-collect_register_by_name (const char *name, char *buf)
+collect_register_by_name (const char *name, void *buf)
{
collect_register (find_regno (name), buf);
}
Index: regcache.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/regcache.h,v
retrieving revision 1.1
diff -u -p -r1.1 regcache.h
--- regcache.h 2002/02/14 06:21:22 1.1
+++ regcache.h 2002/04/06 18:27:40
@@ -46,4 +46,12 @@ int find_regno (const char *name);

extern const char **gdbserver_expedite_regs;

+void supply_register (int n, const void *buf);
+
+void supply_register_by_name (const char *name, const void *buf);
+
+void collect_register (int n, void *buf);
+
+void collect_register_by_name (const char *name, void *buf);
+
#endif /* REGCACHE_H */
Index: remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.11
diff -u -p -r1.11 remote-utils.c
--- remote-utils.c 2002/03/27 05:15:49 1.11
+++ remote-utils.c 2002/04/06 18:27:40
@@ -35,6 +35,7 @@
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
+#include <arpa/inet.h>

int remote_debug = 0;
struct ui_file *gdb_stdlog;
@@ -185,6 +186,25 @@ fromhex (int a)
return 0;
}

+int
+unhexify (char *bin, const char *hex, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (hex[0] == 0 || hex[1] == 0)
+ {
+ /* Hex string is short, or of uneven length.
+ Return the count that has been converted so far. */
+ return i;
+ }
+ *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+ return i;
+}
+
/* Convert number NIB to a hex digit. */

static int
@@ -196,6 +216,24 @@ tohex (int nib)
return 'a' + nib - 10;
}

+int
+hexify (char *hex, const char *bin, int count)
+{
+ int i;
+
+ /* May use a length, or a nul-terminated string as input. */
+ if (count == 0)
+ count = strlen (bin);
+
+ for (i = 0; i < count; i++)
+ {
+ *hex++ = tohex ((*bin >> 4) & 0xf);
+ *hex++ = tohex (*bin++ & 0xf);
+ }
+ *hex = 0;
+ return i;
+}
+
/* Send a packet to the remote machine, with error checking.
The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */

@@ -291,7 +329,7 @@ input_interrupt (int unused)
return;
}

- kill (inferior_pid, SIGINT);
+ kill (signal_pid, SIGINT);
}
}

Index: server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.7
diff -u -p -r1.7 server.c
--- server.c 2002/03/27 05:15:49 1.7
+++ server.c 2002/04/06 18:27:40
@@ -27,13 +27,14 @@ int thread_from_wait;
int old_thread_from_wait;
int extended_protocol;
jmp_buf toplevel;
-int inferior_pid;

static unsigned char
start_inferior (char *argv[], char *statusptr)
{
- inferior_pid = create_inferior (argv[0], argv);
- fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid);
+ /* FIXME Check error? Or turn to void. */
+ create_inferior (argv[0], argv);
+ /* FIXME Print pid properly. */
+ fprintf (stderr, "Process %s created; pid = %d\n", argv[0], signal_pid);

/* Wait till we are at 1st instruction in program, return signal number. */
return mywait (statusptr);
@@ -47,7 +48,7 @@ attach_inferior (int pid, char *statuspt
if (myattach (pid) != 0)
return -1;

- inferior_pid = pid;
+ add_inferior (pid);

*sigptr = mywait (statusptr);

@@ -56,6 +57,30 @@ attach_inferior (int pid, char *statuspt

extern int remote_debug;

+/* Handle all of the extended 'q' packets. */
+void
+handle_query (char *own_buf)
+{
+ if (strcmp ("qSymbol::", own_buf) == 0)
+ {
+#if 0
+ strcpy (own_buf, "qSymbol:");
+ hexify (own_buf + strlen ("qSymbol:"), "main", 4);
+ putpkt (own_buf);
+ getpkt (own_buf);
+ fprintf (stderr, "Got %s", own_buf);
+#endif
+ strcpy (own_buf, "OK");
+ return;
+ }
+
+ /* Otherwise we didn't know what packet it was. Say we didn't
+ understand it. */
+ own_buf[0] = 0;
+}
+
+static int attached;
+
int
main (int argc, char *argv[])
{
@@ -64,9 +89,8 @@ main (int argc, char *argv[])
unsigned char signal;
unsigned int len;
CORE_ADDR mem_addr;
- int bad_attach = 0;
- int pid = 0;
- int attached = 0;
+ int bad_attach;
+ int pid;
char *arg_end;

if (setjmp (toplevel))
@@ -75,6 +99,9 @@ main (int argc, char *argv[])
exit (1);
}

+ bad_attach = 0;
+ pid = 0;
+ attached = 0;
if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
{
if (argc == 4
@@ -129,6 +156,9 @@ main (int argc, char *argv[])
ch = own_buf[i++];
switch (ch)
{
+ case 'q':
+ handle_query (own_buf);
+ break;
case 'd':
remote_debug = !remote_debug;
break;
Index: server.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.h,v
retrieving revision 1.5
diff -u -p -r1.5 server.h
--- server.h 2002/03/27 05:15:49 1.5
+++ server.h 2002/04/06 18:27:40
@@ -23,39 +23,54 @@
#define SERVER_H

#include "config.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <setjmp.h>

+#ifndef ATTR_NORETURN
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
+#define ATTR_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTR_NORETURN /* nothing */
+#endif
+#endif
+
+#ifndef ATTR_FORMAT
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4))
+#define ATTR_FORMAT(type, x, y) __attribute__ ((format(type, x, y)))
+#else
+#define ATTR_FORMAT(type, x, y) /* nothing */
+#endif
+#endif

-/* FIXME: Both of these should be autoconf'd for. */
-#define NORETURN
+/* FIXME: This should probably be autoconf'd for. It's an integer type at
+ least the size of a (void *). */
typedef long long CORE_ADDR;

#include "regcache.h"
#include "gdb/signals.h"

-#include <setjmp.h>
+#include "target.h"

/* Target-specific functions */

-int create_inferior (char *program, char **allargs);
-void kill_inferior (void);
-void fetch_inferior_registers (int regno);
-void store_inferior_registers (int regno);
-int mythread_alive (int pid);
-void myresume (int step, int signo);
-unsigned char mywait (char *status);
-void read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
-int write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
-int create_inferior ();
void initialize_low ();

/* Target-specific variables */

extern char *registers;

+/* From inferiors.c. */
+
+struct inferior_info;
+extern struct inferior_info *current_inferior;
+extern int signal_pid;
+void add_inferior (int pid);
+void clear_inferiors (void);
+
/* Public variables in server.c */

extern int cont_thread;
@@ -64,7 +79,6 @@ extern int thread_from_wait;
extern int old_thread_from_wait;

extern jmp_buf toplevel;
-extern int inferior_pid;

/* Functions from remote-utils.c */

@@ -85,6 +99,10 @@ void decode_m_packet (char *from, CORE_A
void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
unsigned int *len_ptr, char *to);

+int unhexify (char *bin, const char *hex, int count);
+int hexify (char *hex, const char *bin, int count);
+
+
/* Functions from ``signals.c''. */
enum target_signal target_signal_from_host (int hostsig);
int target_signal_to_host_p (enum target_signal oursig);
@@ -93,11 +111,13 @@ int target_signal_to_host (enum target_s
/* Functions from utils.c */

void perror_with_name (char *string);
-void error (const char *string,...);
-void fatal (const char *string,...);
+void error (const char *string,...) ATTR_NORETURN;
+void fatal (const char *string,...) ATTR_NORETURN;
void warning (const char *string,...);

+/* Functions from the register cache definition. */

+void init_registers (void);

/* Maximum number of bytes to read/write at once. The value here
is chosen to fill up a packet (the headers account for the 32). */
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/utils.c,v
retrieving revision 1.5
diff -u -p -r1.5 utils.c
--- utils.c 2002/02/14 06:21:22 1.5
+++ utils.c 2002/04/06 18:27:40
@@ -57,7 +57,7 @@ perror_with_name (char *string)
STRING is the error message, used as a fprintf string,
and ARG is passed as an argument to it. */

-NORETURN void
+void
error (const char *string,...)
{
extern jmp_buf toplevel;
@@ -74,7 +74,7 @@ error (const char *string,...)
STRING and ARG are passed to fprintf. */

/* VARARGS */
-NORETURN void
+void
fatal (const char *string,...)
{
va_list args;