From fea04ba6838a7fb1f7f6df9ea5b9603603205f3d Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] virt-ps working again. --- extract/codegen/code_generation.ml | 17 +++++++++++++--- lib/kernel.ml | 40 ++++++++++++++++++++++++++++---------- lib/virt_mem.ml | 34 +++++++++++++++++++++++--------- ps/.depend | 4 ++-- ps/virt_ps.ml | 23 ++++++++++++---------- 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/extract/codegen/code_generation.ml b/extract/codegen/code_generation.ml index 41520dc..d451349 100644 --- a/extract/codegen/code_generation.ml +++ b/extract/codegen/code_generation.ml @@ -539,10 +539,21 @@ let generate_followers names xs = and adj = data.$lid:struct_name^"_"^name^"_adjustment"$ in let offset = Int64.of_int offset and adj = Int64.of_int adj in - (* 'addr' is base of the virtual struct *) - let addr = Int64.sub (Int64.add addr offset) adj in + + (* 'addr' is base of the virtual struct, but when + * adding it to the map make sure we don't splat + * the real structure (can happen if offset=adj). + *) let map = - AddrMap.add addr ($str:dest_struct_name$, None) map in + if offset <> adj then ( + let addr = Int64.sub (Int64.add addr offset) adj in + AddrMap.add addr ($str:dest_struct_name$, None) map + ) else map in + + (* 'dest_addr' is the destination address of + * this pointer. It needs the usual list_head + * adjustment applied. + *) let dest_addr = Int64.sub dest_addr adj in let map = $lid:dest_struct_name^"_follower"$ diff --git a/lib/kernel.ml b/lib/kernel.ml index efdd413..9b7d3bc 100644 --- a/lib/kernel.ml +++ b/lib/kernel.ml @@ -1255,8 +1255,12 @@ let rec task_struct_follower kernel_version load map addr = let offset = data.task_struct_run_list'next_offset and adj = data.task_struct_run_list'next_adjustment in let offset = Int64.of_int offset and adj = Int64.of_int adj in - let addr = Int64.sub (Int64.add addr offset) adj in - let map = AddrMap.add addr ("task_struct", None) map in + let map = + if offset <> adj + then + (let addr = Int64.sub (Int64.add addr offset) adj + in AddrMap.add addr ("task_struct", None) map) + else map in let dest_addr = Int64.sub dest_addr adj in let map = task_struct_follower kernel_version load map dest_addr in map in @@ -1265,8 +1269,12 @@ let rec task_struct_follower kernel_version load map addr = let offset = data.task_struct_tasks'next_offset and adj = data.task_struct_tasks'next_adjustment in let offset = Int64.of_int offset and adj = Int64.of_int adj in - let addr = Int64.sub (Int64.add addr offset) adj in - let map = AddrMap.add addr ("task_struct", None) map in + let map = + if offset <> adj + then + (let addr = Int64.sub (Int64.add addr offset) adj + in AddrMap.add addr ("task_struct", None) map) + else map in let dest_addr = Int64.sub dest_addr adj in let map = task_struct_follower kernel_version load map dest_addr in map @@ -1289,8 +1297,12 @@ and net_device_follower kernel_version load map addr = let offset = data.net_device_dev_list'next_offset and adj = data.net_device_dev_list'next_adjustment in let offset = Int64.of_int offset and adj = Int64.of_int adj in - let addr = Int64.sub (Int64.add addr offset) adj in - let map = AddrMap.add addr ("net_device", None) map in + let map = + if offset <> adj + then + (let addr = Int64.sub (Int64.add addr offset) adj + in AddrMap.add addr ("net_device", None) map) + else map in let dest_addr = Int64.sub dest_addr adj in let map = net_device_follower kernel_version load map dest_addr in map in @@ -1322,8 +1334,12 @@ and net_follower kernel_version load map addr = let offset = data.net_dev_base_head'next_offset and adj = data.net_dev_base_head'next_adjustment in let offset = Int64.of_int offset and adj = Int64.of_int adj in - let addr = Int64.sub (Int64.add addr offset) adj in - let map = AddrMap.add addr ("net_device", None) map in + let map = + if offset <> adj + then + (let addr = Int64.sub (Int64.add addr offset) adj + in AddrMap.add addr ("net_device", None) map) + else map in let dest_addr = Int64.sub dest_addr adj in let map = net_device_follower kernel_version load map dest_addr in map in let dest_addr = data.net_dev_base_head'prev in @@ -1331,8 +1347,12 @@ and net_follower kernel_version load map addr = let offset = data.net_dev_base_head'prev_offset and adj = data.net_dev_base_head'prev_adjustment in let offset = Int64.of_int offset and adj = Int64.of_int adj in - let addr = Int64.sub (Int64.add addr offset) adj in - let map = AddrMap.add addr ("net_device", None) map in + let map = + if offset <> adj + then + (let addr = Int64.sub (Int64.add addr offset) adj + in AddrMap.add addr ("net_device", None) map) + else map in let dest_addr = Int64.sub dest_addr adj in let map = net_device_follower kernel_version load map dest_addr in map in map) diff --git a/lib/virt_mem.ml b/lib/virt_mem.ml index c00face..a65d95e 100644 --- a/lib/virt_mem.ml +++ b/lib/virt_mem.ml @@ -552,7 +552,7 @@ Possibly the '-T' command line parameter was used inconsistently."); let { ksyms = ksyms; have_ksyms = have_ksyms; utsname = utsname; addrmap = addrmap } = kimage in match have_ksyms, utsname with - | true, Some { uts_kernel_release = kversion } -> + | true, Some { uts_kernel_release = kernel_version } -> let kimage = ref kimage in let load struct_name addr size = if debug then @@ -564,10 +564,20 @@ Possibly the '-T' command line parameter was used inconsistently."); let bits = Virt_mem_mmap.get_bytes !kimage.mem addr size in Bitstring.bitstring_of_string bits in - let init_task = Ksymmap.find "init_task" ksyms in let addrmap = - Kernel.task_struct_follower kversion load addrmap init_task in - { !kimage with addrmap = addrmap } + try + let init_task = Ksymmap.find "init_task" ksyms in + Some (Kernel.task_struct_follower kernel_version + load addrmap init_task) + with + Not_found -> + eprintf (f_"%s: cannot find init_task symbol in kernel image.\n") !kimage.domname; + None in + (match addrmap with + | None -> !kimage + | Some addrmap -> + { !kimage with addrmap = addrmap; have_tasks = true } + ) | _, _ -> kimage ) in @@ -578,7 +588,7 @@ Possibly the '-T' command line parameter was used inconsistently."); let { ksyms = ksyms; have_ksyms = have_ksyms; utsname = utsname; addrmap = addrmap } = kimage in match have_ksyms, utsname with - | true, Some { uts_kernel_release = kversion } -> + | true, Some { uts_kernel_release = kernel_version } -> let kimage = ref kimage in let load struct_name addr size = if debug then @@ -593,7 +603,8 @@ Possibly the '-T' command line parameter was used inconsistently."); let addrmap = try let dev_base = Ksymmap.find "dev_base" ksyms in - Kernel.net_device_follower kversion load addrmap dev_base + Some (Kernel.net_device_follower kernel_version + load addrmap dev_base) with Not_found -> try let dev_base_head = Ksymmap.find "dev_base_head" ksyms in @@ -602,11 +613,16 @@ Possibly the '-T' command line parameter was used inconsistently."); with Not_found -> try let init_net = Ksymmap.find "init_net" ksyms in - Kernel.net_follower kversion load addrmap init_net + Some (Kernel.net_follower kernel_version + load addrmap init_net) with Not_found -> eprintf (f_"%s: cannot find dev_base, dev_base_head or init_net symbols in kernel image.\n") !kimage.domname; - addrmap in - { !kimage with addrmap = addrmap } + None in + (match addrmap with + | None -> !kimage + | Some addrmap -> + { !kimage with addrmap = addrmap; have_net_devices = true } + ) | _, _ -> kimage ) in diff --git a/ps/.depend b/ps/.depend index 0614d06..b916783 100644 --- a/ps/.depend +++ b/ps/.depend @@ -1,4 +1,4 @@ virt_ps.cmo: ../lib/virt_mem_utils.cmo ../lib/virt_mem_types.cmi \ - ../lib/virt_mem_gettext.cmo ../lib/virt_mem.cmi + ../lib/virt_mem_gettext.cmo ../lib/virt_mem.cmi ../lib/kernel.cmi virt_ps.cmx: ../lib/virt_mem_utils.cmx ../lib/virt_mem_types.cmx \ - ../lib/virt_mem_gettext.cmx ../lib/virt_mem.cmx + ../lib/virt_mem_gettext.cmx ../lib/virt_mem.cmx ../lib/kernel.cmx diff --git a/ps/virt_ps.ml b/ps/virt_ps.ml index ccdd972..07e5e76 100644 --- a/ps/virt_ps.ml +++ b/ps/virt_ps.ml @@ -23,25 +23,28 @@ open Virt_mem_gettext.Gettext open Virt_mem_utils open Virt_mem_types -(* -open Kernel_task_struct +open Kernel -let run debug { domname = domname; mem = mem } { tasks = tasks } = - let tasks = Option.get tasks in +let run debug { addrmap = addrmap } = + (* Grab all the task_struct structures. *) + let tasks = AddrMap.fold ( + fun _ v tasks -> + match v with + | _, Some (_, _, Task_struct task) -> task :: tasks + | _ -> tasks + ) addrmap [] in (* Sort tasks by PID. *) - let cmp { task_pid = p1 } { task_pid = p2 } = compare p1 p2 in + let cmp { task_struct_pid = p1 } { task_struct_pid = p2 } = compare p1 p2 in let tasks = List.sort cmp tasks in printf " PID STAT COMMAND\n"; List.iter ( - fun task -> - printf "%5Ld %s\n" task.task_pid task.task_comm + fun { task_struct_pid = pid; task_struct_comm = comm } -> + let comm = truncate_c_string comm in + printf "%5Ld %s\n" pid comm ) tasks -*) - -let run debug _ = () let summary = s_"list processes in virtual machine" let description = s_"\ -- 1.8.3.1