--- /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.
+
+ 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