From 9860e1f7cc0f5e63d5e2bfb487ef4533d5b8516b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Jan 1970 00:00:00 +0000
Subject: [PATCH] virt-dmesg working.

---
 dmesg/virt_dmesg.ml | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/dmesg/virt_dmesg.ml b/dmesg/virt_dmesg.ml
index 2435bbc..10d231f 100644
--- a/dmesg/virt_dmesg.ml
+++ b/dmesg/virt_dmesg.ml
@@ -45,13 +45,42 @@ let () =
 	 * It's possible we can fall back to memory scanning. XXX
 	 *)
 	let log_buf = lookup_ksym "log_buf" in
+	let log_buf = follow_pointer mem log_buf in
 	let log_buf_len = lookup_ksym "log_buf_len" in
-	let log_start = lookup_ksym "log_start" in
+	let log_buf_len = Int64.of_int32 (get_C_int mem log_buf_len) in
+(*	let log_start = lookup_ksym "log_start" in
+	let log_start = get_C_long mem log_start in *)
 	let log_end = lookup_ksym "log_end" in
-	let con_start = lookup_ksym "con_start" in
+	let log_end = get_C_long mem log_end in
+(*	let con_start = lookup_ksym "con_start" in
+	let con_start = get_C_long mem con_start in *)
+	let logged_chars = lookup_ksym "logged_chars" in
+	let logged_chars = get_C_long mem logged_chars in
 
-	()
+	(* This is basically the same algorithm from printk.c:do_syslog
+	 * type=3, translated into OCaml.  Unlike the kernel version
+	 * however we don't copy the buffer backwards.
+	 *)
+	let get_log_buf idx =
+	  let addr = log_buf +^ (idx &^ (log_buf_len -^ 1L)) in
+	  Char.chr (get_byte mem addr)
+	in
+
+	let count = log_buf_len in
+	let count = if count > logged_chars then logged_chars else count in
+	let limit = log_end in
 
+	let rec loop i =
+	  if i >= 0L then (
+	    let j = limit-^1L-^i in
+	    if j +^ log_buf_len >= log_end then (
+	      let c = get_log_buf j in
+	      printf "%c" c;
+	      loop (i-^1L)
+	    )
+	  )
+	in
+	loop (count-^1L)
       with
 	Not_found ->
 	  eprintf (f_"%s: could not find kernel log buffer in kernel image\n")
-- 
1.8.3.1