X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Ftarget-disassem.lisp;h=453edf1a54446bc569793b045e2a13951d72c622;hb=8ac4c19014a23665e5842d0a989cb9d22d1592ed;hp=878935359971dbfeda1cd6e9885a0ea210c97428;hpb=56ce3857f7830670d55d2fe17246353dff2e71f7;p=sbcl.git diff --git a/src/compiler/target-disassem.lisp b/src/compiler/target-disassem.lisp index 8789353..453edf1 100644 --- a/src/compiler/target-disassem.lisp +++ b/src/compiler/target-disassem.lisp @@ -44,8 +44,9 @@ (sort insts #'> :key #'specializer-rank)) (defun specialization-error (insts) - (error "~@" - insts)) + (bug + "~@" + insts)) ;;; Given a list of instructions INSTS, Sees if one of these instructions is a ;;; more general form of all the others, in which case they are put into its @@ -252,7 +253,7 @@ (defstruct (offs-hook (:copier nil)) (offset 0 :type offset) - (function (missing-arg) :type function) + (fun (missing-arg) :type function) (before-address nil :type (member t nil))) (defstruct (segment (:conc-name seg-) @@ -268,78 +269,13 @@ (def!method print-object ((seg segment) stream) (print-unreadable-object (seg stream :type t) (let ((addr (sb!sys:sap-int (funcall (seg-sap-maker seg))))) - (format stream "#X~X[~D]~:[ (#X~X)~;~*~]~@[ in ~S~]" + (format stream "#X~X[~W]~:[ (#X~X)~;~*~]~@[ in ~S~]" addr (seg-length seg) (= (seg-virtual-location seg) addr) (seg-virtual-location seg) (seg-code seg))))) -;;; All state during disassembly. We store some seemingly redundant -;;; information so that we can allow garbage collect during disassembly and -;;; not get tripped up by a code block being moved... -(defstruct (disassem-state (:conc-name dstate-) - (:constructor %make-dstate) - (:copier nil)) - ;; offset of current pos in segment - (cur-offs 0 :type offset) - ;; offset of next position - (next-offs 0 :type offset) - ;; a sap pointing to our segment - (segment-sap (missing-arg) :type sb!sys:system-area-pointer) - ;; the current segment - (segment nil :type (or null segment)) - ;; what to align to in most cases - (alignment sb!vm:n-word-bytes :type alignment) - (byte-order :little-endian - :type (member :big-endian :little-endian)) - ;; for user code to hang stuff off of - (properties nil :type list) - (filtered-values (make-array max-filtered-value-index) - :type filtered-value-vector) - ;; used for prettifying printing - (addr-print-len nil :type (or null (integer 0 20))) - (argument-column 0 :type column) - ;; to make output look nicer - (output-state :beginning - :type (member :beginning - :block-boundary - nil)) - - ;; alist of (address . label-number) - (labels nil :type list) - ;; same as LABELS slot data, but in a different form - (label-hash (make-hash-table) :type hash-table) - ;; list of function - (fun-hooks nil :type list) - - ;; alist of (address . label-number), popped as it's used - (cur-labels nil :type list) ; - ;; list of offs-hook, popped as it's used - (cur-offs-hooks nil :type list) - - ;; for the current location - (notes nil :type list) - - ;; currently active source variables - (current-valid-locations nil :type (or null (vector bit)))) -(def!method print-object ((dstate disassem-state) stream) - (print-unreadable-object (dstate stream :type t) - (format stream - "+~D~@[ in ~S~]" - (dstate-cur-offs dstate) - (dstate-segment dstate)))) - -;;; Return the absolute address of the current instruction in DSTATE. -(defun dstate-cur-addr (dstate) - (the address (+ (seg-virtual-location (dstate-segment dstate)) - (dstate-cur-offs dstate)))) - -;;; Return the absolute address of the next instruction in DSTATE. -(defun dstate-next-addr (dstate) - (the address (+ (seg-virtual-location (dstate-segment dstate)) - (dstate-next-offs dstate)))) - ;;;; function ops (defun fun-self (fun) @@ -384,11 +320,14 @@ (declare (type sb!kernel:code-component code-component)) (sb!sys:sap-int (sb!kernel:code-instructions code-component))) +;;; unused as of sbcl-0.pre7.129 +#| ;;; Return the first function in CODE-COMPONENT. (defun code-first-function (code-component) (declare (type sb!kernel:code-component code-component)) (sb!kernel:code-header-ref code-component sb!vm:code-trace-table-offset-slot)) +|# (defun segment-offs-to-code-offs (offset segment) (sb!sys:without-gcing @@ -481,7 +420,7 @@ (alignment (dstate-alignment dstate))) (unless (aligned-p location alignment) (when stream - (format stream "~A~Vt~D~%" '.align + (format stream "~A~Vt~W~%" '.align (dstate-argument-column dstate) alignment)) (incf(dstate-next-offs dstate) @@ -503,7 +442,7 @@ (setf (dstate-cur-offs dstate) 0) (setf (dstate-cur-labels dstate) (dstate-labels dstate))) -(defun do-offs-hooks (before-address stream dstate) +(defun call-offs-hooks (before-address stream dstate) (declare (type (or null stream) stream) (type disassem-state dstate)) (let ((cur-offs (dstate-cur-offs dstate))) @@ -519,12 +458,12 @@ (not (offs-hook-before-address next-hook)))) (return)) (unless (< hook-offs cur-offs) - (funcall (offs-hook-function next-hook) stream dstate)) + (funcall (offs-hook-fun next-hook) stream dstate)) (pop (dstate-cur-offs-hooks dstate)) (unless (= (dstate-next-offs dstate) cur-offs) (return))))))) -(defun do-fun-hooks (chunk stream dstate) +(defun call-fun-hooks (chunk stream dstate) (let ((hooks (dstate-fun-hooks dstate)) (cur-offs (dstate-cur-offs dstate))) (setf (dstate-next-offs dstate) cur-offs) @@ -565,10 +504,10 @@ (setf (dstate-next-offs dstate) (dstate-cur-offs dstate)) - (do-offs-hooks t stream dstate) + (call-offs-hooks t stream dstate) (unless (or prefix-p (null stream)) (print-current-address stream dstate)) - (do-offs-hooks nil stream dstate) + (call-offs-hooks nil stream dstate) (unless (> (dstate-next-offs dstate) (dstate-cur-offs dstate)) (sb!sys:without-gcing @@ -578,7 +517,7 @@ (sap-ref-dchunk (dstate-segment-sap dstate) (dstate-cur-offs dstate) (dstate-byte-order dstate)))) - (let ((fun-prefix-p (do-fun-hooks chunk stream dstate))) + (let ((fun-prefix-p (call-fun-hooks chunk stream dstate))) (if (> (dstate-next-offs dstate) (dstate-cur-offs dstate)) (setf prefix-p fun-prefix-p) (let ((inst (find-inst chunk ispace))) @@ -647,7 +586,7 @@ (incf max) (setf (cdr label) max) (setf (gethash (car label) label-hash) - (format nil "L~D" max))))) + (format nil "L~W" max))))) (setf (dstate-labels dstate) labels)))) ;;; Get the instruction-space, creating it if necessary. @@ -750,7 +689,7 @@ (when (or (null label-location) (> label-location location)) (return)) (unless (< label-location location) - (format stream " L~D:" (cdr next-label))) + (format stream " L~W:" (cdr next-label))) (pop (dstate-cur-labels dstate)))) ;; move to the instruction column @@ -855,7 +794,7 @@ ((null fun)) (let ((offset (code-offs-to-segment-offs (fun-offset fun) segment))) (when (<= 0 offset length) - (push (make-offs-hook :offset offset :function #'fun-header-hook) + (push (make-offs-hook :offset offset :fun #'fun-header-hook) (seg-hooks segment)))))) ;;; A SAP-MAKER is a no-argument function that returns a SAP. @@ -958,7 +897,7 @@ (let ((fun-offset (sb!kernel:get-closure-length fun))) ;; There is function header fun-offset words from the ;; code header. - (format t "Fun-header ~S at offset ~D (words): ~S~A => ~S~%" + (format t "Fun-header ~S at offset ~W (words): ~S~A => ~S~%" fun fun-offset (sb!kernel:code-header-ref @@ -1075,11 +1014,11 @@ (values nil nil) (values (get-source-form loc context cache) t))) -;;;; stuff to use debugging-info to augment the disassembly +;;;; stuff to use debugging info to augment the disassembly (defun code-fun-map (code) (declare (type sb!kernel:code-component code)) - (sb!di::get-debug-info-fun-map (sb!kernel:%code-debug-info code))) + (sb!c::compiled-debug-info-fun-map (sb!kernel:%code-debug-info code))) (defstruct (location-group (:copier nil)) (locations #() :type (vector (or list fixnum)))) @@ -1167,7 +1106,7 @@ :debug-vars debug-vars)) (let ((debug-var (aref debug-vars debug-var-offset))) #+nil - (format t ";;; At offset ~D: ~S~%" debug-var-offset debug-var) + (format t ";;; At offset ~W: ~S~%" debug-var-offset debug-var) (let* ((sc-offset (sb!di::compiled-debug-var-sc-offset debug-var)) (sb-name @@ -1175,7 +1114,7 @@ (sb!c:sc-sb (aref sc-vec (sb!c:sc-offset-scn sc-offset)))))) #+nil - (format t ";;; SET: ~S[~D]~%" + (format t ";;; SET: ~S[~W]~%" sb-name (sb!c:sc-offset-offset sc-offset)) (unless (null sb-name) (let ((group (cdr (assoc sb-name groups)))) @@ -1233,8 +1172,8 @@ (let ((last-block-pc -1)) (flet ((add-hook (pc fun &optional before-address) (push (make-offs-hook - :offset pc ;; ##### FIX to account for non-zero offs in code - :function fun + :offset pc ;; ### FIX to account for non-zero offs in code + :fun fun :before-address before-address) (seg-hooks segment)))) (handler-case @@ -1267,7 +1206,7 @@ (when stream (unless at-block-begin (terpri stream)) - (format stream ";;; [~D] " + (format stream ";;; [~W] " (sb!di:code-location-form-number loc)) (prin1-short form stream) @@ -1300,24 +1239,24 @@ (storage-info-for-debug-fun debug-fun)) (add-source-tracking-hooks segment debug-fun sfcache) (let ((kind (sb!di:debug-fun-kind debug-fun))) - (flet ((anh (n) + (flet ((add-new-hook (n) (push (make-offs-hook :offset 0 - :function (lambda (stream dstate) - (declare (ignore stream)) - (note n dstate))) + :fun (lambda (stream dstate) + (declare (ignore stream)) + (note n dstate))) (seg-hooks segment)))) (case kind (:external) ((nil) - (anh "no-arg-parsing entry point")) + (add-new-hook "no-arg-parsing entry point")) (t - (anh (lambda (stream) - (format stream "~S entry point" kind))))))))) + (add-new-hook (lambda (stream) + (format stream "~S entry point" kind))))))))) ;;; Return a list of the segments of memory containing machine code ;;; instructions for FUNCTION. -(defun get-function-segments (function) +(defun get-fun-segments (function) (declare (type compiled-function function)) (let* ((code (fun-code function)) (fun-map (code-fun-map code)) @@ -1348,7 +1287,7 @@ (let ((name (sb!c::compiled-debug-fun-name fmap-entry)) (kind (sb!c::compiled-debug-fun-kind fmap-entry))) #+nil - (format t ";;; SAW ~S ~S ~S,~S ~D,~D~%" + (format t ";;; SAW ~S ~S ~S,~S ~W,~W~%" name kind first-block-seen-p nil-block-seen-p last-offset (sb!c::compiled-debug-fun-start-pc fmap-entry)) @@ -1364,8 +1303,7 @@ (when first-block-seen-p (setf nil-block-seen-p t)))) (setf last-debug-fun - (sb!di::make-compiled-debug-fun fmap-entry code)) - ))))) + (sb!di::make-compiled-debug-fun fmap-entry code))))))) (let ((max-offset (code-inst-area-length code))) (when (and first-block-seen-p last-debug-fun) (add-seg last-offset @@ -1505,18 +1443,20 @@ ;;;; top level functions ;;; Disassemble the machine code instructions for FUNCTION. -(defun disassemble-function (function &key - (stream *standard-output*) - (use-labels t)) - (declare (type compiled-function function) +(defun disassemble-fun (fun &key + (stream *standard-output*) + (use-labels t)) + (declare (type compiled-function fun) (type stream stream) (type (member t nil) use-labels)) (let* ((dstate (make-dstate)) - (segments (get-function-segments function))) + (segments (get-fun-segments fun))) (when use-labels (label-segments segments dstate)) (disassemble-segments segments stream dstate))) +;;; FIXME: We probably don't need this any more now that there are +;;; no interpreted functions, only compiled ones. (defun compile-function-lambda-expr (function) (declare (type function function)) (multiple-value-bind (lambda closurep name) @@ -1526,11 +1466,11 @@ (error "can't compile a lexical closure")) (compile nil lambda))) -(defun compiled-function-or-lose (thing &optional (name thing)) +(defun compiled-fun-or-lose (thing &optional (name thing)) (cond ((or (symbolp thing) (and (listp thing) (eq (car thing) 'setf))) - (compiled-function-or-lose (fdefinition thing) thing)) + (compiled-fun-or-lose (fdefinition thing) thing)) ((functionp thing) thing) ((and (listp thing) @@ -1551,9 +1491,9 @@ (type (or (member t) stream) stream) (type (member t nil) use-labels)) (pprint-logical-block (*standard-output* nil :per-line-prefix "; ") - (disassemble-function (compiled-function-or-lose object) - :stream stream - :use-labels use-labels) + (disassemble-fun (compiled-fun-or-lose object) + :stream stream + :use-labels use-labels) nil)) ;;; Disassembles the given area of memory starting at ADDRESS and