shithub: sl

Download patch

ref: 00b0398b4fb4da73a959649fc3fb8ba81f13a2ae
parent: 8e953a26546248dece2348fd8c98e594b8bfa9df
author: spew <spew@cbza.org>
date: Mon Mar 17 23:33:04 EDT 2025

lsd: asm, disassemble n instructions, add documentation

--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -356,16 +356,26 @@
 BUILTIN("lsd-asm", lsd_asm)
 {
 	static char buf[512];
+	int size;
 	uvlong addr;
+	sl_v r;
 
 	argcount(nargs, 1);
 	if(sl_unlikely(!sl_isnum(args[0])))
 		type_error("num", args[0]);
-	addr = tosize(args[0]);
 
-	if ((*machdata->das)(coremap, addr, 'i', buf, sizeof(buf)) < 0)
+	addr = tosize(args[0]);
+	r = sl_nil;
+	sl_gc_handle(&r);
+	if(machdata->das(coremap, addr, 'i', buf, sizeof(buf)) < 0)
 		lerrorf(sl_errio, "could not disassemble at %ud", addr);
-	return str_from_cstr(buf);
+	r = mk_cons(str_from_cstr(buf), r);
+	size = machdata->instsize(coremap, addr);
+	if(size < 0)
+		lerrorf(sl_errio, "could not get instruction size at %ud", addr);
+	r = mk_cons(size_wrap(size), r);
+	sl_free_gc_handles(1);
+	return r;
 }
 
 BUILTIN("lsd-ctrace", lsd_ctrace)
@@ -383,7 +393,7 @@
 	res = tosize(args[2]);
 	tracelist = sl_nil;
 	sl_gc_handle(&tracelist);
-	if((*machdata->ctrace)(coremap, pc, sp, res, trlist) <= 0)
+	if(machdata->ctrace(coremap, pc, sp, res, trlist) <= 0)
 		lerrorf(sl_errio, "no stack frame: %r");
 	sl_free_gc_handles(1);
 	return tracelist;
--- a/src/plan9/lsd.lsp
+++ b/src/plan9/lsd.lsp
@@ -172,12 +172,27 @@
     (startstop)
     (or (curPC) (void))))
 
-(def (asm addr)
-  (let ((on-bp (has? bptbl addr)))
-    (if on-bp (writecore addr (get bptbl addr)))
-    (princ (lsd-asm addr) "\n")
-    (if on-bp (writecore addr bpinst))
-    (void)))
+(def (asm addr (n 5))
+  "Print the next n disassembled instructions at addr.
+
+   By default n is 5 and it returns the following instruction
+   so it can be called again.
+
+   Examples:
+     (asm (readreg PC)) ; print out 5 from current program instruction.
+     (asm (readreg PC) 10) ; print out 10 from current program instruction.
+     (asm (step)) ; step and then print out 5.
+     (asm (asm (readreg PC)) 3) ; print 3 more."
+  (if (<= n 0)
+      addr
+      (let ((on-bp (has? bptbl addr)))
+        (if on-bp (writecore addr (get bptbl addr)))
+        (let* ((a (lsd-asm addr))
+               (next (car a))
+               (instr (cadr a)))
+          (princ instr "\n")
+          (if on-bp (writecore addr bpinst))
+          (asm (+ addr next) (1- n))))))
 
 (def (at-exit s)
   (if proc-stdin (io-close proc-stdin))