Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Sep 2014 16:40:48 +0000 (UTC)
From:      Benno Rice <benno@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271173 - in head/sys: conf gdb libkern sys
Message-ID:  <201409051640.s85Gemme006236@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: benno
Date: Fri Sep  5 16:40:47 2014
New Revision: 271173
URL: http://svnweb.freebsd.org/changeset/base/271173

Log:
  Add support for gdb's memory searching capabilities to our in-kernel gdb
  server.
  
  Submitted by:	Daniel O'Connor <daniel.oconnor@isilon.com>
  Reviewed by:	jhb
  Sponsored by:	EMC Isilon Storage Division

Added:
  head/sys/libkern/memmem.c   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/gdb/gdb_int.h
  head/sys/gdb/gdb_main.c
  head/sys/gdb/gdb_packet.c
  head/sys/sys/libkern.h

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Fri Sep  5 15:45:20 2014	(r271172)
+++ head/sys/conf/files	Fri Sep  5 16:40:47 2014	(r271173)
@@ -3176,8 +3176,9 @@ libkern/inet_pton.c		standard
 libkern/jenkins_hash.c		standard
 libkern/mcount.c		optional profiling-routine
 libkern/memcchr.c		standard
-libkern/memchr.c		optional fdt
+libkern/memchr.c		optional fdt | gdb
 libkern/memcmp.c		standard
+libkern/memmem.c		optional gdb
 libkern/qsort.c			standard
 libkern/qsort_r.c		standard
 libkern/random.c		standard

Modified: head/sys/gdb/gdb_int.h
==============================================================================
--- head/sys/gdb/gdb_int.h	Fri Sep  5 15:45:20 2014	(r271172)
+++ head/sys/gdb/gdb_int.h	Fri Sep  5 16:40:47 2014	(r271173)
@@ -60,6 +60,9 @@ void gdb_tx_begin(char);
 int gdb_tx_end(void);
 int gdb_tx_mem(const unsigned char *, size_t);
 void gdb_tx_reg(int);
+int gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt);
+int gdb_search_mem(const unsigned char *addr, size_t size,
+    const unsigned char *pat, size_t patlen, const unsigned char **found);
 
 static __inline void
 gdb_tx_char(char c)

Modified: head/sys/gdb/gdb_main.c
==============================================================================
--- head/sys/gdb/gdb_main.c	Fri Sep  5 15:45:20 2014	(r271172)
+++ head/sys/gdb/gdb_main.c	Fri Sep  5 16:40:47 2014	(r271173)
@@ -53,6 +53,8 @@ SET_DECLARE(gdb_dbgport_set, struct gdb_
 struct gdb_dbgport *gdb_cur = NULL;
 int gdb_listening = 0;
 
+static unsigned char gdb_bindata[64];
+
 static int
 gdb_init(void)
 {
@@ -254,6 +256,28 @@ gdb_trap(int type, int code)
 					gdb_tx_begin('l');
 					gdb_tx_end();
 				}
+			} else if (gdb_rx_equal("Search:memory:")) {
+				size_t patlen;
+				intmax_t addr, size;
+				const unsigned char *found;
+				if (gdb_rx_varhex(&addr) || gdb_rx_char() != ';' ||
+				    gdb_rx_varhex(&size) || gdb_rx_char() != ';' ||
+				    gdb_rx_bindata(gdb_bindata, sizeof(gdb_bindata), &patlen)) {
+					gdb_tx_err(EINVAL);
+					break;
+				}
+				if (gdb_search_mem((char *)(uintptr_t)addr, size, gdb_bindata, patlen, &found)) {
+					if (found == 0ULL)
+						gdb_tx_begin('0');
+					else {
+						gdb_tx_begin('1');
+						gdb_tx_char(',');
+						gdb_tx_hex((intmax_t)(uintptr_t)found, 8);
+					}
+					gdb_tx_end();
+				} else
+					gdb_tx_err(EIO);
+				break;
 			} else if (!gdb_cpu_query())
 				gdb_tx_empty();
 			break;

Modified: head/sys/gdb/gdb_packet.c
==============================================================================
--- head/sys/gdb/gdb_packet.c	Fri Sep  5 15:45:20 2014	(r271172)
+++ head/sys/gdb/gdb_packet.c	Fri Sep  5 16:40:47 2014	(r271173)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/ctype.h>
 #include <sys/kdb.h>
+#include <sys/libkern.h>
 #include <sys/ttydefaults.h>
 
 #include <machine/gdb_machdep.h>
@@ -320,3 +321,46 @@ gdb_tx_reg(int regnum)
 	} else
 		gdb_tx_mem(regp, regsz);
 }
+
+/* Read binary data up until the end of the packet or until we have datalen decoded bytes */
+int
+gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt)
+{
+	int c;
+
+	*amt = 0;
+
+	while (*amt < datalen) {
+		c = gdb_rx_char();
+		/* End of packet? */
+		if (c == -1)
+			break;
+		/* Escaped character up next */
+		if (c == '}') {
+			/* Truncated packet? Bail out */
+			if ((c = gdb_rx_char()) == -1)
+				return (1);
+			c ^= 0x20;
+		}
+		*(data++) = c & 0xff;
+		(*amt)++;
+	}
+
+	return (0);
+}
+
+int
+gdb_search_mem(const unsigned char *addr, size_t size, const unsigned char *pat, size_t patlen, const unsigned char **found)
+{
+	void *prev;
+	jmp_buf jb;
+	int ret;
+
+	prev = kdb_jmpbuf(jb);
+	ret = setjmp(jb);
+	if (ret == 0)
+		*found = memmem(addr, size, pat, patlen);
+
+	(void)kdb_jmpbuf(prev);
+	return ((ret == 0) ? 1 : 0);
+}

Added: head/sys/libkern/memmem.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/libkern/memmem.c	Fri Sep  5 16:40:47 2014	(r271173)
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/libkern.h>
+#include <sys/param.h>
+
+void *
+memmem(const void *l, size_t l_len, const void *s, size_t s_len)
+{
+        register char *cur, *last;
+        const char *cl = (const char *)l;
+        const char *cs = (const char *)s;
+
+        /* we need something to compare */
+        if (l_len == 0 || s_len == 0)
+                return NULL;
+
+        /* "s" must be smaller or equal to "l" */
+        if (l_len < s_len)
+                return NULL;
+
+        /* special case where s_len == 1 */
+        if (s_len == 1)
+                return memchr(l, (int)*cs, l_len);
+
+        /* the last position where its possible to find "s" in "l" */
+        last = (char *)cl + l_len - s_len;
+
+        for (cur = (char *)cl; cur <= last; cur++)
+                if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
+                        return cur;
+
+        return NULL;
+}

Modified: head/sys/sys/libkern.h
==============================================================================
--- head/sys/sys/libkern.h	Fri Sep  5 15:45:20 2014	(r271172)
+++ head/sys/sys/libkern.h	Fri Sep  5 16:40:47 2014	(r271173)
@@ -103,6 +103,7 @@ int	 locc(int, char *, u_int);
 void	*memchr(const void *s, int c, size_t n);
 void	*memcchr(const void *s, int c, size_t n);
 int	 memcmp(const void *b1, const void *b2, size_t len);
+void	*memmem(const void *l, size_t l_len, const void *s, size_t s_len);
 void	 qsort(void *base, size_t nmemb, size_t size,
 	    int (*compar)(const void *, const void *));
 void	 qsort_r(void *base, size_t nmemb, size_t size, void *thunk,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409051640.s85Gemme006236>