Extracted kernel structures for device addressing in ifconfig.
[virt-mem.git] / lib / virt_mem_ksyms.ml
index d70ace1..0c4daf7 100644 (file)
@@ -45,7 +45,7 @@ let common_ksyms = [
   "schedule";                          (* scheduler entry point *)
 ]
 
-let find_kernel_symbols debug (domid, name, arch, mem) =
+let find_kernel_symbols debug ({ mem = mem; domname = domname } as image) =
   (* Searching for <NUL>string<NUL> *)
   let common_ksyms_nul = List.map (sprintf "\000%s\000") common_ksyms in
 
@@ -127,11 +127,11 @@ let find_kernel_symbols debug (domid, name, arch, mem) =
   let ksymtabs = List.filter (fun (_, size) -> size > 64L) ksymtabs in
 
   if debug then (
-    eprintf "%s: candidate symbol tables at:\n" name;
+    eprintf "%s: candidate symbol tables at:\n" domname;
     List.iter (
       fun (addr, size) ->
        eprintf "\t%Lx\t%Lx\t%!" addr size;
-       eprintf "first symbol: %s\n%!"
+       eprintf "first symbol: %S\n%!"
          (Virt_mem_mmap.get_string mem
             (Virt_mem_mmap.follow_pointer mem
                (Virt_mem_mmap.succ_long mem addr)))
@@ -141,18 +141,18 @@ let find_kernel_symbols debug (domid, name, arch, mem) =
   (* Vote for the most popular symbol table candidate and from this
    * generate a function to look up ksyms.
    *)
-  let lookup_ksym =
+  let ksymmap =
     let freqs = frequency ksymtabs in
     match freqs with
     | [] ->
-       eprintf (f_"%s: cannot find start of kernel symbol table\n") name;
-       (fun _ -> raise Not_found)
+       eprintf (f_"%s: cannot find start of kernel symbol table\n") domname;
+       None
 
     | (_, (ksymtab_addr, ksymtab_size)) :: _ ->
        if debug then
          eprintf
            "%s: Kernel symbol table found at %Lx, size %Lx bytes\n%!"
-           name ksymtab_addr ksymtab_size;
+           domname ksymtab_addr ksymtab_size;
 
        (* Load the whole symbol table as a bitstring. *)
        let ksymtab =
@@ -160,26 +160,24 @@ let find_kernel_symbols debug (domid, name, arch, mem) =
            (Virt_mem_mmap.get_bytes mem ksymtab_addr
               (Int64.to_int ksymtab_size)) in
 
-       (* Function to look up an address in the symbol table. *)
-       let lookup_ksym sym =
+       (* Construct kernel symbol map. *)
+       let ksymmap =
          let bits = bits_of_wordsize (Virt_mem_mmap.get_wordsize mem) in
          let e = Virt_mem_mmap.get_endian mem in
-         let rec loop bs =
+         let rec loop ksymmap bs =
            bitmatch bs with
            | { value : bits : endian(e);
-               name_ptr : bits : endian(e) }
-               when Virt_mem_mmap.get_string mem name_ptr = sym ->
-               value
-           | { _ : bits : endian(e);
-               _ : bits : endian(e);
+               name_ptr : bits : endian(e);
                bs : -1 : bitstring } ->
-               loop bs
-           | { _ } -> raise Not_found
+               let name = Virt_mem_mmap.get_string mem name_ptr in
+               let ksymmap = Ksymmap.add name value ksymmap in
+               loop ksymmap bs
+           | { _ } ->
+               ksymmap
          in
-         loop ksymtab
-       in
+         loop Ksymmap.empty ksymtab in
 
-       lookup_ksym
+       Some ksymmap
   in
 
   if debug then (
@@ -188,4 +186,4 @@ let find_kernel_symbols debug (domid, name, arch, mem) =
       (end_t -. start_t)
   );
 
-  ((domid, name, arch, mem, lookup_ksym) : image1)
+  (image, ksymmap)