From owner-svn-src-head@FreeBSD.ORG Fri Sep 5 16:40:49 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 98E7E1B6; Fri, 5 Sep 2014 16:40:49 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 77DB71DE9; Fri, 5 Sep 2014 16:40:49 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s85GenX1006245; Fri, 5 Sep 2014 16:40:49 GMT (envelope-from benno@FreeBSD.org) Received: (from benno@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s85Gemme006236; Fri, 5 Sep 2014 16:40:48 GMT (envelope-from benno@FreeBSD.org) Message-Id: <201409051640.s85Gemme006236@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: benno set sender to benno@FreeBSD.org using -f From: Benno Rice Date: Fri, 5 Sep 2014 16:40:48 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Sep 2014 16:40:49 -0000 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 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 #include #include +#include #include #include @@ -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 + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +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,