[Git][cmucl/cmucl][issue-97-define-ud2-inst] 3 commits: Change disassembly note for trap codes
Raymond Toy
gitlab at common-lisp.net
Sat Apr 10 16:17:13 UTC 2021
Raymond Toy pushed to branch issue-97-define-ud2-inst at cmucl / cmucl
Commits:
9a86d9f0 by Raymond Toy at 2021-04-10T08:42:04-07:00
Change disassembly note for trap codes
Minor tweak to print the trap number first before the description of
the trap.
- - - - -
9b09c6d9 by Raymond Toy at 2021-04-10T08:50:17-07:00
Add comments
- - - - -
46620f56 by Raymond Toy at 2021-04-10T09:15:38-07:00
Address review comments and add more comments
Fixed up a few things mentioned in the review.
Add a more comments on how things work, and added a TODO on computing
the instruction length and inserting a int3/ud1 after it, kind of like
how other archs handle it.
- - - - -
2 changed files:
- src/compiler/x86/insts.lisp
- src/lisp/x86-arch.c
Changes:
=====================================
src/compiler/x86/insts.lisp
=====================================
@@ -2110,32 +2110,39 @@
(defun ud1-control (chunk inst stream dstate)
(declare (ignore inst))
(flet ((nt (x) (if stream (disassem:note x dstate))))
- (case (ldb (byte 6 16) chunk)
- (#.vm:error-trap
- (nt #.(format nil "Error trap: ~D" vm:error-trap))
- (disassem:handle-break-args #'snarf-error-junk stream dstate))
- (#.vm:cerror-trap
- (nt #.(format nil "Cerror trap: ~D" vm:cerror-trap))
- (disassem:handle-break-args #'snarf-error-junk stream dstate))
- (#.vm:breakpoint-trap
- (nt #.(format nil "Breakpoint trap: ~D" vm:breakpoint-trap)))
- (#.vm:pending-interrupt-trap
- (nt #.(format nil "Pending interrupt trap: ~D" vm:pending-interrupt-trap)))
- (#.vm:halt-trap
- (nt #.(format nil "Halt trap: ~D" vm:halt-trap)))
- (#.vm:function-end-breakpoint-trap
- (nt #.(format nil "Function end breakpoint trap: ~D" vm:function-end-breakpoint-trap)))
- )))
+ (let ((code (ldb (byte 6 16) chunk)))
+ (case code
+ (#.vm:error-trap
+ (nt #.(format nil "Trap ~D: Error trap" vm:error-trap))
+ (disassem:handle-break-args #'snarf-error-junk stream dstate))
+ (#.vm:cerror-trap
+ (nt #.(format nil "Trap ~D: Cerror trap" vm:cerror-trap))
+ (disassem:handle-break-args #'snarf-error-junk stream dstate))
+ (#.vm:pending-interrupt-trap
+ (nt #.(format nil "Trap ~D: Pending interrupt trap" vm:pending-interrupt-trap)))
+ (#.vm:halt-trap
+ (nt #.(format nil "Trap ~D: Halt trap" vm:halt-trap)))
+ (#.vm:function-end-breakpoint-trap
+ (nt #.(format nil "Trap ~D: Function end breakpoint trap"
+ vm:function-end-breakpoint-trap)))
+ (t
+ (nt #.(format nil "Trap ~D: Unexpected trap type!!!!" )))))))
;; The ud1 instruction where we smash the code (trap type) into the
-;; mod r/m byte. We don't care about what that actually encodes to.
-;; We just want the trap code in the third byte of the instruction.
+;; low 6 bits of the mod r/m byte. The mod bits are set to #b11 to
+;; make sure the reg/mem part is interpreted to be a register and not
+;; memory.
(define-instruction ud1 (segment code)
(:declare (type (unsigned-byte 8) code))
(:printer ud1 ((op #b10111001) (reg nil :type 'word-reg))
:default
:control #'ud1-control)
(:emitter
+ ;; We should not be using the breakpoint trap with UD1 anymore.
+ ;; Breakpoint traps are handled in C now, using plain int3.
+ (assert (/= code vm:breakpoint-trap))
+
+ ;; Emit the bytes of the instruction.
(emit-byte segment #x0f)
(emit-byte segment #xb9)
(emit-mod-reg-r/m-byte segment
=====================================
src/lisp/x86-arch.c
=====================================
@@ -260,6 +260,23 @@ unsigned int single_step_save2;
unsigned int single_step_save3;
#endif
+/*
+ * This is called when we need to continue after a breakpoint. This
+ * works by putting the original byte back into the code, and then
+ * enabling single-step mode to step one instruction. When we return,
+ * the instruction will get run and a sigtrap will get triggered when
+ * the one instruction is done.
+ *
+ * TODO: Be more like other archs where the original inst is put back,
+ * and the next inst is replaced with a afterBreakpoint trap. When we
+ * run, the afterBreakpoint trap is hit at the next instruction and
+ * then we can put back the original breakpoint and replace the
+ * afterBreakpoint trap with the original inst there too.
+ *
+ * For x86, this means computing how many bytes are used in the
+ * current instruction, and then placing an int3 (or maybe ud1) after
+ * it.
+ */
void
arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
{
@@ -273,7 +290,7 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
* Put the original instruction back.
*/
- *((char *) pc) = orig_inst & 0xff;
+ *pc = orig_inst & 0xff;
/*
* If we have the SC_EFLAGS macro, we can enable single-stepping
@@ -318,9 +335,8 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
/*
- * Handles the break instruction from lisp, which is now UD2 followed
- * by the trap code. In particular, this does not handle the
- * breakpoint traps.
+ * Handles the ud1 instruction from lisp that is used to signal
+ * errors. In particular, this does not handle the breakpoint traps.
*/
void
sigill_handler(HANDLER_ARGS)
@@ -351,10 +367,10 @@ sigill_handler(HANDLER_ARGS)
RESTORE_FPU(os_context);
/*
- * On entry %eip points just after the INT3 byte and aims at the
- * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a
- * number of bytes will follow, the first is the length of the byte
- * arguments to follow.
+ * On entry %eip points just to the beginning of the UD1
+ * instruction. For error-trap and cerror-trap a number of bytes
+ * will follow, the first is the length of the byte arguments to
+ * follow.
*/
DPRINTF(debug_handlers,
@@ -459,7 +475,13 @@ sigtrap_handler(HANDLER_ARGS)
*((unsigned char*)SC_PC(context) + 3),
*(unsigned char*)(SC_PC(context) + 4)));
- if (single_stepping && (signal == SIGTRAP)) {
+ if (single_stepping) {
+ /*
+ * We were single-stepping so we now need to disable
+ * single-stepping. We want to put back the breakpoint (int3)
+ * instruction so that the next time the breakpoint will be
+ * hit again as expected.
+ */
DPRINTF(debug_handlers, (stderr, "* Single step trap %p\n", single_stepping));
#ifdef SC_EFLAGS
@@ -492,6 +514,9 @@ sigtrap_handler(HANDLER_ARGS)
return;
}
+ /*
+ * We weren't single-stepping, so this we've just hit the breakpoint (int3). Handle it.
+ */
DPRINTF(debug_handlers, (stderr, "*C break\n"));
/*
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/cfb35624edee9113a81d900066dc2a9d70e7117c...46620f562160be1e6adcb6490eb993f612c18a39
--
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/cfb35624edee9113a81d900066dc2a9d70e7117c...46620f562160be1e6adcb6490eb993f612c18a39
You're receiving this email because of your account on gitlab.common-lisp.net.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cmucl-cvs/attachments/20210410/99a8edaf/attachment-0001.html>
More information about the cmucl-cvs
mailing list