--- /dev/null
+/* Memory info command for virtual domains.
+ (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
+ http://libvirt.org/
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ This contains hand-coded C functions written for speed.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <caml/config.h>
+#include <caml/alloc.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+#include <caml/bigarray.h>
+
+CAMLprim value
+virt_mem_mmap_find_in (value startv, value alignv, value strv, value arrv)
+{
+ CAMLparam4 (startv, alignv, strv, arrv);
+ CAMLlocal2 (rv, vv);
+ long start = Long_val (startv); /* Start offset for search. */
+ long align = Long_val (alignv); /* Alignment for search. */
+ char *str = String_val (strv); /* String to search for. */
+ int strlen = caml_string_length (strv);
+ void *data = Data_bigarray_val (arrv); /* Data in bigarray. */
+ int datalen = Bigarray_val(arrv)->dim[0]; /* Total length of bigarray. */
+ long i, r = -1;
+ void *p;
+
+ /* memmem is a GNU extension. Note that we cannot use strstr because
+ * OCaml strings may contain NULs, and in this case it is very likely
+ * that it does contain NULs.
+ */
+#ifdef HAVE_MEMMEM
+ if (align == 1) {
+ p = memmem (data+start, datalen-start, str, strlen);
+ r = p ? p-data : -1;
+ goto ret;
+ }
+#endif
+
+ p = data+start;
+ for (i = start; i < datalen-strlen; i += align) {
+ if (memcmp (p, str, strlen) == 0) {
+ r = p-data;
+ goto ret;
+ }
+ p += align;
+ }
+
+ ret:
+ if (r == -1)
+ rv = Val_int (0); /* None */
+ else {
+ vv = Val_long (r); /* Some r */
+ rv = caml_alloc (1, 0);
+ Store_field (rv, 0, vv);
+ }
+
+ CAMLreturn (rv);
+}