svn commit: r271173 - in head/sys: conf gdb libkern sys
Benno Rice
benno at FreeBSD.org
Fri Sep 5 16:40:49 UTC 2014
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 at 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 at 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,
More information about the svn-src-all
mailing list