(* 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 kimage = 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 kimage.mem start_addr size in let kimage = if not is_mapped then load_memory kimage start_addr size else kimage in (* Get the bytes. *) let bytes = Virt_mem_mmap.get_bytes kimage.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