Use kinfo_getvmmap on FreeBSD to enumerate memory regions.
authorJohn Baldwin <jhb@FreeBSD.org>
Wed, 18 Feb 2015 00:15:45 +0000 (19:15 -0500)
committerJohn Baldwin <jhb@FreeBSD.org>
Fri, 13 Mar 2015 18:08:15 +0000 (14:08 -0400)
Use kinfo_getvmmap from libutil on FreeBSD to enumerate memory
regions in a running process instead of /proc/<pid>/map.  FreeBSD systems
do not mount procfs by default, but kinfo_getvmmap uses a sysctl that
is always available.

Skip memory regions for devices as well as regions an application has
requested to not be dumped via the MAP_NOCORE flag to mmap or
MADV_NOCORE advice to madvise.

gdb/ChangeLog:

* configure.ac: AC_CHECK_LIB(util, kinfo_getvmmap).
* configure: Regenerate.
* config.in: Regenerate.
* fbsd-nat.c [!HAVE_KINFO_GETVMMAP] (fbsd_read_mapping): Don't
        define.
(fbsd_find_memory_regions): Use kinfo_getvmmap to
enumerate memory regions if present.

gdb/ChangeLog
gdb/config.in
gdb/configure
gdb/configure.ac
gdb/fbsd-nat.c

index ed21f3f923df76222b4045710d41c9910e683021..dd9d9e2429621b8f067183b4048b465d48f13b82 100644 (file)
@@ -1,3 +1,13 @@
+2015-03-13  John Baldwin  <jhb@FreeBSD.org>
+
+       * configure.ac: AC_SEARCH_LIBS(kinfo_getvmmap, util).
+       * config.in: Regenerate.
+       * configure: Regenerate.
+       * fbsd-nat.c [!HAVE_KINFO_GETVMMAP] (fbsd_read_mapping): Don't
+        define.
+       (fbsd_find_memory_regions): Use kinfo_getvmmap to
+       enumerate memory regions if present.
+
 2015-03-13  John Baldwin  <jhb@FreeBSD.org>
 
        * amd64fbsd-tdep.c (amd64fbsd_sigtramp_p): Style fixes.
index 3ccac37e2384b8657906fbd1561440408b7c7dce..8a27df0c1e339f543429650d9eeff12dcab371e5 100644 (file)
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if your system has the kinfo_getvmmap function. */
+#undef HAVE_KINFO_GETVMMAP
+
 /* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
 #undef HAVE_LANGINFO_CODESET
 
index cca0aebd5cc9070d4a11f462da94398a19e7f6fc..78d206b837adeaa5665b9b3dc3a0a20d7657dd6d 100755 (executable)
@@ -7159,6 +7159,66 @@ if test "$ac_res" != no; then :
 fi
 
 
+# On FreeBSD we may need libutil for kinfo_getvmmap (used by fbsd-nat.c).
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kinfo_getvmmap" >&5
+$as_echo_n "checking for library containing kinfo_getvmmap... " >&6; }
+if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char kinfo_getvmmap ();
+int
+main ()
+{
+return kinfo_getvmmap ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' util; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_kinfo_getvmmap=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then :
+
+else
+  ac_cv_search_kinfo_getvmmap=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kinfo_getvmmap" >&5
+$as_echo "$ac_cv_search_kinfo_getvmmap" >&6; }
+ac_res=$ac_cv_search_kinfo_getvmmap
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h
+
+fi
+
+
 
 
 
index 4a0b6a3413cf3c49253e34aff3523c07ba5e9469..38747e8b03d93f7f0cf4dbbfb46d8939a5001c0f 100644 (file)
@@ -537,6 +537,11 @@ AM_ZLIB
 # On HP/UX we may need libxpdl for dlgetmodinfo (used by solib-pa64.c).
 AC_SEARCH_LIBS(dlgetmodinfo, [dl xpdl])
 
+# On FreeBSD we may need libutil for kinfo_getvmmap (used by fbsd-nat.c).
+AC_SEARCH_LIBS(kinfo_getvmmap, util,
+  [AC_DEFINE(HAVE_KINFO_GETVMMAP, 1,
+            [Define to 1 if your system has the kinfo_getvmmap function. ])])
+
 AM_ICONV
 
 # GDB may fork/exec the iconv program to get the list of supported character
index 062eede891e1e6a967f2e2c84c6050e95a9158dc..1ce197d18f6f210279cdc40084e78e72bacf4665 100644 (file)
 #include <sys/types.h>
 #include <sys/procfs.h>
 #include <sys/sysctl.h>
+#ifdef HAVE_KINFO_GETVMMAP
+#include <sys/user.h>
+#include <libutil.h>
+#endif
 
 #include "elf-bfd.h"
 #include "fbsd-nat.h"
@@ -62,6 +66,64 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid)
   return NULL;
 }
 
+#ifdef HAVE_KINFO_GETVMMAP
+/* Iterate over all the memory regions in the current inferior,
+   calling FUNC for each memory region.  OBFD is passed as the last
+   argument to FUNC.  */
+
+int
+fbsd_find_memory_regions (struct target_ops *self,
+                         find_memory_region_ftype func, void *obfd)
+{
+  pid_t pid = ptid_get_pid (inferior_ptid);
+  struct kinfo_vmentry *vmentl, *kve;
+  uint64_t size;
+  struct cleanup *cleanup;
+  int i, nitems;
+
+  vmentl = kinfo_getvmmap (pid, &nitems);
+  if (vmentl == NULL)
+    perror_with_name (_("Couldn't fetch VM map entries."));
+  cleanup = make_cleanup (free, vmentl);
+
+  for (i = 0; i < nitems; i++)
+    {
+      kve = &vmentl[i];
+
+      /* Skip unreadable segments and those where MAP_NOCORE has been set.  */
+      if (!(kve->kve_protection & KVME_PROT_READ)
+         || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
+       continue;
+
+      /* Skip segments with an invalid type.  */
+      if (kve->kve_type != KVME_TYPE_DEFAULT
+         && kve->kve_type != KVME_TYPE_VNODE
+         && kve->kve_type != KVME_TYPE_SWAP
+         && kve->kve_type != KVME_TYPE_PHYS)
+       continue;
+
+      size = kve->kve_end - kve->kve_start;
+      if (info_verbose)
+       {
+         fprintf_filtered (gdb_stdout, 
+                           "Save segment, %ld bytes at %s (%c%c%c)\n",
+                           (long) size,
+                           paddress (target_gdbarch (), kve->kve_start),
+                           kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
+                           kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
+                           kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
+       }
+
+      /* Invoke the callback function to create the corefile segment.
+        Pass MODIFIED as true, we do not know the real modification state.  */
+      func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
+           kve->kve_protection & KVME_PROT_WRITE,
+           kve->kve_protection & KVME_PROT_EXEC, 1, obfd);
+    }
+  do_cleanups (cleanup);
+  return 0;
+}
+#else
 static int
 fbsd_read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end,
                   char *protection)
@@ -137,3 +199,4 @@ fbsd_find_memory_regions (struct target_ops *self,
   do_cleanups (cleanup);
   return 0;
 }
+#endif
This page took 0.044566 seconds and 4 git commands to generate.