poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discussion] Side-by-side dump format


From: Jose E. Marchesi
Subject: Re: [Discussion] Side-by-side dump format
Date: Mon, 21 Aug 2023 17:00:06 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

New version below.  In this version the contents of the global array are
reset after each dump command, which can be inconvenient.  This is to
simplify in the prototype.  The logic can be made way better.

  (poke) type Thing = struct { int[2] one; struct { int i; long l; } two; }
  (poke) dump :val Thing @ 0#B
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................ 1=one 
2=two
  00000010: 0000 0000                                ....            
  (poke) dump :val 1
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000000: 0000 0000 0000 0000                      ........         [0] [1]
  (poke) dump :val Thing @ 0#B
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................ 1=one 
2=two
  00000010: 0000 0000                                ....            
  (poke) dump :val 2
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000008: 0000 0000 0000 0000 0000 0000            ............     i l

It would be also nice to have an easy way to add new values to the
`dump' list other than :val, something like:

  (poke) dump_watch_value myvalue

Then all calls to `dump' will show that value whenever appropriate.

Actually, this whole mechanism could be a particular case of a more
general mechanism to define "interesting" areas for dump in IO spaces.
Other than using :val, these areas could also be registered by other
commands specificying a region, style and some sort of action (a
function):

  (poke) dump_watch :from 23#B :size 128#B :style "red" \
         :text lambda void: { print "Probably framebuffer\n"; }

This could be leveraged by a notes.pk pickle implementing "notes":

  (poke) load notes
  (poke) note_add :from 23#B :size 128#B :msg "Probably framebuffer"

Then next time dump finds a note (or part of a note) it will actually
show it:

  (poke) dump ...
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................ 1=#<note>

And then:

  (poke) dump :val 1
  76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
  00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................ Probably 
Framebuffer

also cliking in the hyperlink under '1' above.

The array of dump "interesting" areas would need to be kept per
IO-space, sorted so binary search can be done, etc etc.

And etc etc.

Many ideas, lots of fun, infinite possibilities :)
But not that much time on my side right now :(

Enjoy.

diff --git a/etc/poke-dark.css b/etc/poke-dark.css
index e1fff1dc..6880e53a 100644
--- a/etc/poke-dark.css
+++ b/etc/poke-dark.css
@@ -26,6 +26,10 @@
 .dump-address { color : green; }
 .dump-ascii { color : brown; }
 .dump-unknown { color : yellow; }
+.dump-val1 { color : green; }
+.dump-val2 { color : red; }
+.dump-val3 { color : yellow; }
+.dump-val4 { color : brown; }
 
 .diff-thunk-header { font-weight: bold; }
 .diff-minus { color : red; }
diff --git a/pickles/ios.pk b/pickles/ios.pk
index be7fad3e..9f1ab4b9 100644
--- a/pickles/ios.pk
+++ b/pickles/ios.pk
@@ -18,6 +18,24 @@
 
 /* This pickle contains utilities related to poke IO spaces.  */
 
+var ios_dumpval_styles
+  = ["dump-val1", "dump-val2", "dump-val3", "dump-val4"];
+
+var ios_next_dumpval = 1;
+
+type IOS_Dumpval_Info =
+  struct
+  {
+    string name;
+    uint<32> index; /* 0 means non-mapped.  */
+    int<32> style;
+    offset<uint<64>,b> offset;
+    offset<uint<64>,b> size;
+  };
+
+var ios_dumpval = any[]();
+var ios_dumpval_info = IOS_Dumpval_Info[]();
+
 /* Print a byte dump of an area in a given IO space.
 
    IOS is the IO space from which dump bytes.
@@ -53,6 +71,7 @@
 fun ios_dump_bytes = (int<32> ios,
                       offset<uint<64>,b> from,
                       offset<uint<64>,b> size,
+                      any val = 0,
                       offset<uint<64>,b> group_by = 2#B,
                       int<32> cluster_by = 8,
                       int<32> ruler_p = 0,
@@ -60,6 +79,8 @@ fun ios_dump_bytes = (int<32> ios,
                       string unknown_byte = "??",
                       uint<8> nonprintable_char = '.') void:
 {
+  var print_val_p = 0;
+
   fun print_ruler = (offset<uint<64>,b> offset) void:
   {
     var o = 0#B;
@@ -131,6 +152,38 @@ fun ios_dump_bytes = (int<32> ios,
       }
   }
 
+  fun print_values = (offset<uint<64>,b> offset,
+                      offset<uint<64>,b> top) void:
+  {
+    var o = 0#B;
+    while (offset + o < top)
+      {
+        for (var idx = 1; idx < ios_dumpval'length; ++idx)
+          {
+            var info = ios_dumpval_info[idx];
+            if (info.offset == offset + o)
+              {
+                var val = ios_dumpval[idx];
+                var style = ios_dumpval_styles[info.style % 
ios_dumpval_styles'length];
+
+                print " ";
+                if (info.index > 0)
+                  {
+                    hserver_print_hl ('e',
+                                       format ("%i32d", idx),
+                                       format (".dump :val %i32d", idx));
+                    print ("=");
+                  }
+                term_begin_class (style);
+                print (info.name);
+                term_end_class (style);
+                break;
+              }
+          }
+        o += 1#B;
+      }
+  }
+
   fun print_data = (offset<uint<64>,b> offset,
                     offset<uint<64>,b> top,
                     offset<uint<64>,b> step,
@@ -154,7 +207,27 @@ fun ios_dump_bytes = (int<32> ios,
                 var b = uint<8> @ ios : (offset + o);
                 if (o % group_by == 0#B)
                      print " ";
+
+                var style = "";
+                if (print_val_p)
+                  {
+                    for (var idx = 1; idx < ios_dumpval'length; ++idx)
+                      {
+                        var info = ios_dumpval_info[idx];
+                        if (offset + o >= info.offset
+                            && offset + o < info.offset + info.size)
+                          {
+                            style = ios_dumpval_styles[info.style % 
ios_dumpval_styles'length];
+                            break;
+                          }
+                      }
+                  }
+
+                if (style != "")
+                  term_begin_class (style);
                 printf ("%u8x", b);
+                if (style != "")
+                  term_end_class (style);
              }
               catch if E_io
               {
@@ -171,15 +244,38 @@ fun ios_dump_bytes = (int<32> ios,
        catch if E_eof {}
        if (ascii_p)
          {
-           while (o < step)
+            var ob = o, ot = o;
+           while (ot < step)
              {
-               if (o % group_by == 0#B)
+               if (ot % group_by == 0#B)
                  print " ";
                print ("  ");
-                o++;
+                ot++;
              }
            print_ascii (offset, top, step, group_by, cluster_by);
+            if (print_val_p)
+              {
+                while (ob < step)
+                  {
+                    print " ";
+                    ob++;
+                  }
+              }
          }
+        if (print_val_p)
+          {
+            if (!ascii_p)
+              {
+               while (o < step)
+                 {
+                   if (o % group_by == 0#B)
+                     print " ";
+                   print ("  ");
+                    o++;
+                  }
+             }
+            print_values (offset, top);
+          }
        print "\n";
       }
   }
@@ -188,6 +284,71 @@ fun ios_dump_bytes = (int<32> ios,
   if (! (ioflags (ios) & IOS_F_READ))
     raise E_perm;
 
+  /* If `val' is specified, it can be:
+     0       -> for "no value".
+     int<32> -> for a mapped value stored in ios_dumpval.
+     other   -> mapped value from which to derive `from'
+                and `size'.
+   */
+  if (val isa int<32>)
+    {
+      if (val as int<32> < 0
+          || (val as int<32>) > ios_dumpval'length)
+        raise Exception { code = EC_inval,
+                          name = "invalid argument",
+                          msg = "invalid VAL index" };
+
+      if (val as int<32> > 0)
+        {
+          val = ios_dumpval[val as int<32>];
+
+          if (!val'mapped)
+            raise Exception { code = EC_inval,
+                              name = "invalid argument",
+                              msg = "indexed VAL is not mapped" };
+        }
+    }
+
+  if (val'mapped)
+    {
+      from = val'offset;
+      size = val'size;
+      print_val_p = 1;
+
+      /* Reset ios_dumpval and ios_dumpval_info.  */
+      ios_dumpval = any[]();
+      ios_dumpval_info = IOS_Dumpval_Info[]();
+
+      /* The first entry is not used.  */
+      apush (ios_dumpval, 0);
+      apush (ios_dumpval_info, IOS_Dumpval_Info {});
+      ios_next_dumpval = 1;
+
+      /* Populate the array with the fields of VAL.  */
+      for (var idx = 0UL, style = 0; idx < val'length; ++idx)
+        {
+          /* If the field is optional, check it is actually present.  If it
+             is not, do not add it to the array.  */
+          if (val'elem (idx) ?! E_inval)
+            continue;
+
+          /* Add the element and its info to the arrays.  */
+          var elem = val'elem (idx);
+          apush (ios_dumpval, val'elem (idx));
+          apush (ios_dumpval_info,
+                 IOS_Dumpval_Info {
+                   name = val'ename (idx) == "" ? "<anon>" : val'ename (idx),
+                   index = elem'mapped ? ios_next_dumpval++ : 0,
+                   offset = val'eoffset (idx),
+                   size = val'esize (idx),
+                   style = style++ });
+        }
+    }
+  else
+    raise Exception { code = EC_inval,
+                      name = "invalid argument",
+                      msg = "VAL argument to ios_dump_bytes shall be mapped" };
+
   /* The `dump' command is byte-oriented.
      The base offset is truncated to bytes.
      The offset is rounded up to the next byte.  */
diff --git a/poke/pk-dump.pk b/poke/pk-dump.pk
index 62eb8035..9a052933 100644
--- a/poke/pk-dump.pk
+++ b/poke/pk-dump.pk
@@ -117,12 +117,13 @@ fun pk_dump_set_offset = (int<32> ios, offset<int<64>,b> 
offset) void:
 fun dump = (int<32> ios = get_ios,
             offset<int<64>,b> from = pk_dump_get_offset (ios),
             offset<int<64>,b> size = pk_dump_size,
+            any val = 0,
             offset<int<64>,b> group_by = pk_dump_group_by,
             int<32> cluster_by = pk_dump_cluster_by,
             int<32> ruler = pk_dump_ruler,
             int<32> ascii = pk_dump_ascii) void:
 {
-  ios_dump_bytes :ios ios :from from :size size :group_by group_by
+  ios_dump_bytes :ios ios :from from :size size :group_by group_by :val val
                  :cluster_by cluster_by :ruler_p ruler :ascii_p ascii
                  :unknown_byte pk_dump_unknown_byte;
   pk_dump_set_offset (ios, from);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]