);
(* Get the kernel images. *)
- let images =
+ let kimages =
if testimages = [] then (
let conn =
let name = uri in
(* Download the static part of the kernel. *)
let start_t = gettimeofday () in
- let image =
+ let kimage =
try
load_static_memory ~dom ~domname ~arch
~wordsize ~endian
(end_t -. start_t)
);
- image
+ kimage
) xmls
) else (
let mem = Virt_mem_mmap.set_wordsize mem wordsize in
let mem = Virt_mem_mmap.set_endian mem endian in
- { dom = None; domname = filename; mem = mem; arch = arch;
- kernel_min = kernel_min; kernel_max = kernel_max }
+ { dom = None; domname = filename; arch = arch;
+ kernel_min = kernel_min; kernel_max = kernel_max;
+ mem = mem; addrmap = Kernel.AddrMap.empty;
+ ksyms = Ksymmap.empty; have_ksyms = false; have_kallsyms = false;
+ utsname = None;
+ have_tasks = false; have_net_devices = false }
) testimages
) in
- (* Now build the kdata, depending on what the tool asked for. *)
- let images =
- List.map (
- fun image ->
- let kdata = { ksyms = None; utsname = None; tasks = None;
- net_devices = None } in
- image, kdata
- ) images in
(* Certain needs are dependent on others ... *)
let needs_ksyms =
if needs_utsname then true
if needs_everything then true, true, true, true
else needs_ksyms, needs_utsname, needs_tasks, needs_net_devices in
- (* Do the kernel symbol analysis. *)
- let images =
- if not needs_ksyms then images
- else
- List.map (
- fun (image, kdata) ->
- (* Look for ordinary kernel symbols: *)
- let image, ksyms =
- Virt_mem_ksyms.find_kernel_symbols debug image in
-
- match ksyms with
- | None -> image, kdata
- | Some ksyms ->
- (* Look for kallsyms: *)
- let image, kallsyms =
- Virt_mem_kallsyms.find_kallsyms debug image ksyms in
-
- let ksyms =
- match kallsyms with
- | None -> ksyms (* no kallsyms, just use module symbols *)
- | Some kallsyms -> kallsyms (* ksyms + kallsyms *) in
-
- image, { kdata with ksyms = Some ksyms }
- ) images in
+ let errors = ref 0 in
- (* Get the kernel version (utsname analysis). *)
- let images =
- if not needs_utsname then images
- else
- List.map (
- fun (image, ({ ksyms = ksyms } as kdata)) ->
- match ksyms with
- | None -> image, kdata
- | Some ksyms ->
- let image, utsname =
- Virt_mem_utsname.find_utsname debug image ksyms in
- let kdata = { kdata with utsname = utsname } in
- image, kdata
- ) images in
-
- (* Get the tasks. *)
- let images =
- if not needs_tasks then images
- else
- List.map (
- fun (image, ({ ksyms = ksyms; utsname = utsname } as kdata)) ->
- match ksyms, utsname with
- | Some ksyms, Some { uts_kernel_release = kversion } ->
- let image = ref image in
- let load struct_name addr size =
- printf "load for task, %s: %Lx %d ...\n" struct_name addr size;
- let mapped =
- Virt_mem_mmap.is_mapped_range !image.mem addr size in
- if not mapped then image := load_memory !image addr size;
- let bits = Virt_mem_mmap.get_bytes !image.mem addr size in
- Bitstring.bitstring_of_string bits
- in
- let init_task = Ksymmap.find "init_task" ksyms in
- let map = Kernel.AddrMap.empty in
- let map =
- Kernel.task_struct_follower kversion load map init_task in
-
- (*
- let image, tasks =
- Virt_mem_tasks.find_tasks debug image ksyms kversion in
- let kdata = { kdata with tasks = tasks } in
- *)
- !image, kdata
- | _, _ -> image, kdata
- ) images in
-
- (* Get the net devices. *)
- let images =
- if not needs_net_devices then images
- else
- List.map (
- fun (image, ({ ksyms = ksyms; utsname = utsname } as kdata)) ->
- match ksyms, utsname with
- | Some ksyms, Some { uts_kernel_release = kversion } ->
- let image = ref image in
- let load struct_name addr size =
- printf "load for net dev, %s: %Lx %d ...\n" struct_name addr size;
- let mapped =
- Virt_mem_mmap.is_mapped_range !image.mem addr size in
- if not mapped then image := load_memory !image addr size;
- let bits = Virt_mem_mmap.get_bytes !image.mem addr size in
- Bitstring.bitstring_of_string bits
- in
- let map =
- try
- let dev_base = Ksymmap.find "dev_base" ksyms in
- let map = Kernel.AddrMap.empty in
- let map =
- Kernel.net_device_follower kversion load map dev_base in
- Some map
- with Not_found ->
+ List.iter (
+ fun kimage ->
+ try
+ (* Do the kernel symbol analysis. *)
+ let kimage =
+ if not needs_ksyms then kimage
+ else (
+ (* Look for ordinary kernel symbols: *)
+ let kimage = Virt_mem_ksyms.find_kernel_symbols debug kimage in
+
+ if kimage.have_ksyms then
+ (* Look for kallsyms: *)
+ Virt_mem_kallsyms.find_kallsyms debug kimage
+ else kimage
+ ) in
+
+ (* Get the kernel version (utsname analysis). *)
+ let kimage =
+ if not needs_utsname then kimage
+ else (
+ if kimage.have_ksyms then
+ Virt_mem_utsname.find_utsname debug kimage
+ else
+ kimage
+ ) in
+
+ (* Get the tasks. *)
+ let kimage =
+ if not needs_tasks then kimage
+ else (
+ let { ksyms = ksyms; have_ksyms = have_ksyms; utsname = utsname;
+ addrmap = addrmap } = kimage in
+ match have_ksyms, utsname with
+ | true, Some { uts_kernel_release = kernel_version } ->
+ let kimage = ref kimage in
+ let load struct_name addr size =
+ if debug then
+ eprintf "load for task, %s: %Lx %d ...\n"
+ struct_name addr size;
+ let mapped =
+ Virt_mem_mmap.is_mapped_range !kimage.mem addr size in
+ if not mapped then kimage := load_memory !kimage addr size;
+ let bits = Virt_mem_mmap.get_bytes !kimage.mem addr size in
+ Bitstring.bitstring_of_string bits
+ in
+ let addrmap =
try
- let dev_base_head = Ksymmap.find "dev_base_head" ksyms in
- (* XXX adjust to get offset of start of net_device *)
- assert false
+ let init_task = Ksymmap.find "init_task" ksyms in
+ Some (Kernel.task_struct_follower debug 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
+
+ (* Get the net devices. *)
+ let kimage =
+ if not needs_net_devices then kimage
+ else (
+ let { ksyms = ksyms; have_ksyms = have_ksyms; utsname = utsname;
+ addrmap = addrmap } = kimage in
+ match have_ksyms, utsname with
+ | true, Some { uts_kernel_release = kernel_version } ->
+ let kimage = ref kimage in
+ let load struct_name addr size =
+ if debug then
+ eprintf "load for net dev, %s: %Lx %d ...\n"
+ struct_name addr size;
+ let mapped =
+ Virt_mem_mmap.is_mapped_range !kimage.mem addr size in
+ if not mapped then kimage := load_memory !kimage addr size;
+ let bits = Virt_mem_mmap.get_bytes !kimage.mem addr size in
+ Bitstring.bitstring_of_string bits
+ in
+ let addrmap =
+ try
+ let dev_base = Ksymmap.find "dev_base" ksyms in
+ Some (Kernel.net_device_follower debug kernel_version
+ load addrmap dev_base)
with Not_found ->
try
- let init_net = Ksymmap.find "init_net" ksyms in
- let map = Kernel.AddrMap.empty in
- let map =
- Kernel.net_follower kversion load map init_net in
- Some map
+ let dev_base_head = Ksymmap.find "dev_base_head" ksyms in
+ (* XXX adjust to get offset of start of net_device *)
+ assert false
with Not_found ->
- eprintf (f_"%s: cannot find dev_base, dev_base_head or init_net symbols in kernel image.\n") !image.domname;
- None in
-(*
- let image, net_devices =
- Virt_mem_net_devices.find_net_devices debug
- image ksyms kversion in
- let kdata = { kdata with net_devices = net_devices } in
-*)
- !image, kdata
- | _, _ -> image, kdata
- ) images in
-
- (* Run the tool's main function. *)
- let errors = ref 0 in
- List.iter (
- fun (image, kdata) ->
- try
+ try
+ let init_net = Ksymmap.find "init_net" ksyms in
+ Some (Kernel.net_follower debug 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;
+ None in
+ (match addrmap with
+ | None -> !kimage
+ | Some addrmap ->
+ { !kimage with addrmap = addrmap; have_net_devices = true }
+ )
+ | _, _ -> kimage
+ ) in
+
+ (* Run the tool's main function. *)
if not needs_everything then (
- if needs_ksyms && kdata.ksyms = None then
+ if needs_ksyms && kimage.have_ksyms = false then
failwith (s_"could not read kernel symbols")
- else if needs_utsname && kdata.utsname = None then
+ else if needs_utsname && kimage.utsname = None then
failwith (s_"could not read kernel version")
- else if needs_tasks && kdata.tasks = None then
+ else if needs_tasks && kimage.have_tasks = false then
failwith (s_"could not read process table")
- else if needs_net_devices && kdata.net_devices = None then
+ else if needs_net_devices && kimage.have_net_devices = false then
failwith (s_"could not read net device table")
);
- run debug image kdata
+ run debug kimage
with exn ->
- eprintf "%s: %s\n" image.domname (Printexc.to_string exn);
+ eprintf "%s: %s\n" kimage.domname (Printexc.to_string exn);
incr errors
- ) images;
+ ) kimages;
+
exit (if !errors > 0 then 1 else 0)