Added 'virt-mem dump' command allowing you to hexdump arbitrary
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 12 Aug 2008 13:49:29 +0000 (14:49 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 12 Aug 2008 13:49:29 +0000 (14:49 +0100)
regions of virtual memory.

MANIFEST
lib/.depend
lib/Makefile.in
lib/virt_mem_dump.ml [new file with mode: 0644]
mem/.depend
mem/virt_mem_main.ml

index dfaccfd..5c95026 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -27,6 +27,7 @@ lib/kernel_task_struct.mli
 lib/Makefile.in
 lib/test_mmap.ml
 lib/virt_mem_capture.ml
+lib/virt_mem_dump.ml
 lib/virt_mem_kallsyms.ml
 lib/virt_mem_kallsyms.mli
 lib/virt_mem_kernels.ml
index 3fbd7c9..6262905 100644 (file)
@@ -23,6 +23,10 @@ test_mmap.cmo: virt_mem_mmap.cmi
 test_mmap.cmx: virt_mem_mmap.cmx 
 virt_mem_capture.cmo: virt_mem_types.cmi virt_mem_gettext.cmo virt_mem.cmi 
 virt_mem_capture.cmx: virt_mem_types.cmx virt_mem_gettext.cmx virt_mem.cmx 
+virt_mem_dump.cmo: virt_mem_types.cmi virt_mem_mmap.cmi virt_mem_gettext.cmo \
+    virt_mem.cmi 
+virt_mem_dump.cmx: virt_mem_types.cmx virt_mem_mmap.cmx virt_mem_gettext.cmx \
+    virt_mem.cmx 
 virt_mem_kallsyms.cmo: virt_mem_utils.cmo virt_mem_types.cmi \
     virt_mem_mmap.cmi virt_mem_ksyms.cmi virt_mem_gettext.cmo \
     virt_mem_kallsyms.cmi 
index 5232ee7..b1f09d2 100644 (file)
@@ -63,7 +63,9 @@ OBJS          = virt_mem_gettext.cmo \
                  virt_mem_tasks.cmo \
                  virt_mem_net_devices.cmo \
                  virt_mem.cmo \
-                 virt_mem_capture.cmo
+                 virt_mem_capture.cmo \
+                 virt_mem_dump.cmo
+
 XOBJS          = $(OBJS:%.cmo=%.cmx)
 
 all:   $(TARGETS)
diff --git a/lib/virt_mem_dump.ml b/lib/virt_mem_dump.ml
new file mode 100644 (file)
index 0000000..615bc34
--- /dev/null
@@ -0,0 +1,132 @@
+(* 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.
+
+   Implements 'virt-mem dump' command.
+ *)
+
+open Printf
+open ExtString
+
+module D = Libvirt.Domain
+
+open Virt_mem_types
+open Virt_mem_gettext.Gettext
+
+let start_addr = ref None
+let size = ref None
+
+let set_start_addr addr = start_addr := Some (Int64.of_string addr)
+let set_size n = size := Some (int_of_string n)
+
+(* Early argument check. *)
+let argcheck debug =
+  (* --start flag must have been specified. *)
+  if !start_addr = None then (
+    prerr_endline (s_"virt-mem dump: '--start' option is required");
+    exit 1
+  )
+
+(* Capture the image. *)
+let rec run debug image kdata =
+  let start_addr = !start_addr in
+  let size = !size in
+
+  let start_addr =
+    match start_addr with
+    | None -> assert false   (* should have been caught by argcheck *)
+    | Some addr -> addr in
+  let size =
+    match size with
+    | None -> 1 lsl 20      (* large, but not unlimited *)
+    | Some size -> size in
+
+  (* Load the memory. *)
+  let is_mapped = Virt_mem_mmap.is_mapped_range image.mem start_addr size in
+  let image =
+    if not is_mapped then
+      load_memory image start_addr size
+    else
+      image in
+
+  (* Get the bytes. *)
+  let bytes = Virt_mem_mmap.get_bytes image.mem start_addr size in
+
+  hexdump stdout start_addr bytes size
+
+(* Modified from the version in bitstring library. *)
+and hexdump chan count data len =
+  let count = ref count in
+  let off = ref 0 in
+  let len = ref len in
+  let linelen = ref 0 in
+  let linechars = String.make 16 ' ' in
+
+  fprintf chan "%08Lx  " !count;
+
+  while !len > 0 do
+    let bits = min !len 8 in
+    let byte, off', len' =
+      Bitstring.extract_char_unsigned data !off !len bits in
+    off := off'; len := len';
+
+    let byte = byte lsl (8-bits) in
+    fprintf chan "%02x " byte;
+
+    count := Int64.succ !count;
+    linechars.[!linelen] <-
+      (let c = Char.chr byte in
+       if isprint c then c else '.');
+    incr linelen;
+    if !linelen = 8 then fprintf chan " ";
+    if !linelen = 16 then (
+      fprintf chan " |%s|\n%08Lx  " linechars !count;
+      linelen := 0;
+      for i = 0 to 15 do linechars.[i] <- ' ' done
+    )
+  done;
+
+  if !linelen > 0 then (
+    let skip = (16 - !linelen) * 3 + if !linelen < 8 then 1 else 0 in
+    for i = 0 to skip-1 do fprintf chan " " done;
+    fprintf chan " |%s|\n%!" linechars
+  ) else
+    fprintf chan "\n%!"
+
+and isprint c =
+  let c = Char.code c in
+  c >= 32 && c < 127
+
+let summary = s_"dump parts of virtual memory"
+let description = s_"Dump parts of virtual memory for debugging purposes.
+
+Use the --start and --size parameters to specify the start address
+and size of the region to dump.  Hexadecimal numbers can be specified
+using '0x..' notation.
+"
+
+let extra_args = [
+  "--start", Arg.String set_start_addr,
+    "addr " ^s_"Set start address to dump";
+  "--size", Arg.String set_size,
+    "size " ^s_"Set size (in bytes) to dump";
+]
+
+let () =
+  Virt_mem.register ~run
+    ~external_cmd:false ~extra_args ~argcheck
+    "dump" summary description
index fd7322a..ca3abf3 100644 (file)
@@ -1,2 +1,4 @@
-virt_mem_main.cmo: ../lib/virt_mem_capture.cmo ../lib/virt_mem.cmi 
-virt_mem_main.cmx: ../lib/virt_mem_capture.cmx ../lib/virt_mem.cmx 
+virt_mem_main.cmo: ../lib/virt_mem_dump.cmo ../lib/virt_mem_capture.cmo \
+    ../lib/virt_mem.cmi 
+virt_mem_main.cmx: ../lib/virt_mem_dump.cmx ../lib/virt_mem_capture.cmx \
+    ../lib/virt_mem.cmx 
index 78c7ab7..c2255b4 100644 (file)
@@ -27,6 +27,7 @@
  * files.
  *)
 let _ = Virt_mem_capture.summary
+let _ = Virt_mem_dump.summary
 
 (* Call main program. *)
 let () = Virt_mem.main ()