1.0.39.7: Make TRACE :ENCAPSULATE NIL work on PPC.
authorAlastair Bridgewater <lisphacker@users.sourceforge.net>
Sun, 6 Jun 2010 19:51:18 +0000 (19:51 +0000)
committerAlastair Bridgewater <lisphacker@users.sourceforge.net>
Sun, 6 Jun 2010 19:51:18 +0000 (19:51 +0000)
  * SIGNAL-CONTEXT-FRAME (debug-int.lisp) was passing a bogus
parameter to COMPUTE-CALLING-FRAME on non-x86oids, causing an
unknown immediate object to be constructed.  Fixed, and KLUDGEd
to still work on x86oids.

  * fun_end_breakpoint_guts (ppc-assem.S) wasn't implemented at
all, just stubbed out to provide the symbols that the core looks
for when compiling MAKE-BOGUS-LRA (debug-int.lisp).

  * The implementation of fun_end_breakpoint_guts on non-PPC is
sparsely explained at best.  Addressed in the new PPC version.

  * The usual implementation of fun_end_breakpoint_guts leaves
setting the LRA header data to MAKE-BOGUS-LRA but this is done
after attempting to create the LRA object, which fails on GENCGC
systems due to the sanity checking of the pointer.  On PPC, this
is addressed by setting the LRA header data by dead reckoning in
ppc-assem.S.

  * In MAKE-BOGUS-LRA, don't bother setting the LRA header data
if it is known to already be correct.

NEWS
src/code/debug-int.lisp
src/runtime/ppc-assem.S
tests/debug.impure.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 87c8c0e..02c97ab 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ single call to IMPORT no longer add multiple symbols with the same name
 to the package (detectable via DO-SYMBOLS).
   * bug fix: support building without the dlshim on darwin x86 and x86-64
     (lp#533470).
+  * bug fix: TRACE :ENCAPSULATE NIL now works on ppc/linux.
 
 changes in sbcl-1.0.39 relative to sbcl-1.0.38:
   * bug fix: Backtrace from undefined function on x86 and x86-64 now show
index 9554efe..89d1b7a 100644 (file)
@@ -3018,7 +3018,11 @@ register."
             (sb!alien:sap-alien signal-context (* os-context-t))))
          (cfp (int-sap (sb!vm:context-register scp sb!vm::cfp-offset))))
     (compute-calling-frame cfp
-                           (sb!vm:context-pc scp)
+                           ;; KLUDGE: This argument is ignored on
+                           ;; x86oids in this scenario, but is
+                           ;; declared to be a SAP.
+                           #!+(or x86 x86-64) (sb!vm:context-pc scp)
+                           #!-(or x86 x86-64) nil
                            nil)))
 
 (defun handle-fun-end-breakpoint (offset component context)
@@ -3115,11 +3119,20 @@ register."
      #!-(or x86 x86-64)
      (let ((new-lra (make-lisp-obj (+ (sap-int dst-start)
                                       sb!vm:other-pointer-lowtag))))
-       (set-header-data
-        new-lra
-        (logandc2 (+ sb!vm:code-constants-offset bogus-lra-constants 1)
-                  1))
-       (sb!vm:sanctify-for-execution code-object)
+       #!-(or gencgc ppc)
+       (progn
+         ;; Set the offset from the LRA to the enclosing component.
+         ;; This does not need to be done on GENCGC targets, as the
+         ;; pointer validation done in MAKE-LISP-OBJ requires that it
+         ;; already have been set before we get here.  It does not
+         ;; need to be done on CHENEYGC PPC as it's easier to use the
+         ;; same fun_end_breakpoint_guts on both, including the LRA
+         ;; header.
+         (set-header-data
+          new-lra
+          (logandc2 (+ sb!vm:code-constants-offset bogus-lra-constants 1)
+                    1))
+         (sb!vm:sanctify-for-execution code-object))
        (values new-lra code-object (sap- trap-loc src-start))))))
 \f
 ;;;; miscellaneous
index c95fa0e..13175df 100644 (file)
@@ -574,23 +574,75 @@ CSYMBOL(funcallable_instance_tramp) = . + 1
        mtctr reg_LIP
        bctr
        SET_SIZE(funcallable_instance_tramp)
-       
-       GFUNCDEF(fun_end_breakpoint_trap)
-       .long 0
-       SET_SIZE(fun_end_breakpoint_trap)
-
-       GFUNCDEF(fun_end_breakpoint)
-       .long 0
-       SET_SIZE(fun_end_breakpoint)
-
+\f
+       /* The fun_end_breakpoint support here is considered by the
+       authors of the other $ARCH-assem.S files to be magic, and it
+       is.  It is a small fragment of code that is copied into a heap
+       code-object when needed, and contains an LRA object, code to
+       convert a single-value return to unknown-values format, and a
+       trap_FunEndBreakpoint. */
        GFUNCDEF(fun_end_breakpoint_guts)
-       .long 0
-       SET_SIZE(fun_end_breakpoint_guts)
-
-       GFUNCDEF(fun_end_breakpoint_end)
-       .long 0
-       SET_SIZE(fun_end_breakpoint_end)
+       .globl CSYMBOL(fun_end_breakpoint_trap)
+       .globl CSYMBOL(fun_end_breakpoint_end)
+
+       /* Due to pointer verification in MAKE-LISP-OBJ on GENCGC
+       targets, which includes PPC, this must include its header data
+       (the offset from the start of the code-object to the LRA).
+       The code-object header is five words, there are two words of
+       constants, and the instruction space is doubleword-aligned,
+       making an offset of eight.  This is header data for a widetag,
+       so shift left eight bits and add. */
+       .long RETURN_PC_HEADER_WIDETAG + 0x800
+
+       /* We are receiving unknown multiple values, thus must deal
+       with the single-value and multiple-value cases separately. */
+       b fun_end_breakpoint_multiple_values
+       nop
 
+       /* Compute the correct value for reg_CODE based on the LRA.
+       This is a "simple" matter of subtracting a constant from
+       reg_CODE (where the LRA is stored by the return sequence) to
+       obtain a tagged pointer to the enclosing code component.  Both
+       values are tagged OTHER_POINTER_LOWTAG, so we just have to
+       account for the eight words (see calculation for
+       RETURN_PC_HEADER_WIDETAG, above) between the two addresses.
+       Restoring reg_CODE doesn't appear to be strictly necessary
+       here, but let's observe the niceties.*/
+       addi reg_CODE, reg_CODE, -32
+
+       /* Multiple values are stored relative to reg_OCFP, which we
+       set to be the current top-of-stack. */
+       mr reg_OCFP, reg_CSP
+
+       /* Reserve a save location for the one value we have. */
+       addi reg_CSP, reg_CSP, 4
+
+       /* Record the number of values we have as a FIXNUM. */
+       li reg_NARGS, 4
+
+       /* Blank the remaining arg-passing registers. */
+       mr reg_A1, reg_NULL
+       mr reg_A2, reg_NULL
+       mr reg_A3, reg_NULL
+
+       /* And branch to our trap. */
+       b CSYMBOL(fun_end_breakpoint_trap)
+
+fun_end_breakpoint_multiple_values:
+       /* Compute the correct value for reg_CODE.  See the
+       explanation for the single-value case, above. */
+       addi reg_CODE, reg_CODE, -32
+
+       /* The actual magic trap. */
+CSYMBOL(fun_end_breakpoint_trap):
+       twllei  reg_ZERO, trap_FunEndBreakpoint
+
+       /* Finally, the debugger needs to know where the end of the
+       fun_end_breakpoint_guts are, so that it may calculate its size
+       in order to populate out a suitably-sized code object. */
+CSYMBOL(fun_end_breakpoint_end):
+       SET_SIZE(fun_end_breakpoint_guts)
+\f
 
        GFUNCDEF(ppc_flush_cache_line)
        dcbf 0,REG(3)
index 67303cc..27283ae 100644 (file)
 ;;; on that platform.
 #-(and (or ppc x86 x86-64) darwin)
 (with-test (:name (trace :encapsulate nil)
-            :fails-on '(or :ppc :sparc :mips))
+            :fails-on '(or (and :ppc (not :linux)) :sparc :mips))
   (let ((out (with-output-to-string (*trace-output*)
                (trace trace-this :encapsulate nil)
                (assert (eq 'ok (trace-this)))
 
 #-(and (or ppc x86 x86-64) darwin)
 (with-test (:name (trace-recursive :encapsulate nil)
-            :fails-on '(or :ppc :sparc :mips))
+            :fails-on '(or (and :ppc (not :linux)) :sparc :mips))
   (let ((out (with-output-to-string (*trace-output*)
                (trace trace-fact :encapsulate nil)
                (assert (= 120 (trace-fact 5)))
index 4b1d5b8..268032b 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.39.6"
+"1.0.39.7"