X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fvirt_mem.ml;h=a65d95e5efe75567ec1108a10df602870ac7a1fa;hb=48a85384daa4089f6d310293ab3f8d713740f962;hp=2ed0c5ac91b755581a4bfd6b57964b4af83bb8c1;hpb=fa333da9b9d5338cb18c0077ba10dffd2cc4d464;p=virt-mem.git diff --git a/lib/virt_mem.ml b/lib/virt_mem.ml index 2ed0c5a..a65d95e 100644 --- a/lib/virt_mem.ml +++ b/lib/virt_mem.ml @@ -330,7 +330,7 @@ Use 'virt-mem --help' for more help or read the manual page virt-mem(1)"); ); (* Get the kernel images. *) - let images = + let kimages = if testimages = [] then ( let conn = let name = uri in @@ -425,7 +425,7 @@ Use 'virt-mem --help' for more help or read the manual page virt-mem(1)"); (* 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 @@ -444,7 +444,7 @@ Possibly the '-T' command line parameter was used inconsistently."); (end_t -. start_t) ); - image + kimage ) xmls ) else ( @@ -494,19 +494,15 @@ Possibly the '-T' command line parameter was used inconsistently."); 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 @@ -521,141 +517,130 @@ Possibly the '-T' command line parameter was used inconsistently."); 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.task_struct_follower kversion load 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.net_device_follower kversion load 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 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 kernel_version + load addrmap dev_base) with Not_found -> try - let init_net = Ksymmap.find "init_net" ksyms in - let map = - Kernel.net_follower kversion load 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 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)