source: trunk/ccl/lib/x86-backtrace.lisp @ 7224

Last change on this file since 7224 was 7224, checked in by gb, 14 years ago

Revert to older version.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1;;;-*-Mode: LISP; Package: CCL -*-
2;;;
3;;;   Copyright (C) 2006 Clozure Associates and contributors
4;;;   This file is part of OpenMCL. 
5;;;
6;;;   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;;   License , known as the LLGPL and distributed with OpenMCL as the
8;;;   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
9;;;   which is distributed with OpenMCL as the file "LGPL".  Where these
10;;;   conflict, the preamble takes precedence. 
11;;;
12;;;   OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;;   The LLGPL is also available online at
15;;;   http://opensource.franz.com/preamble.html
16
17
18(in-package "CCL")
19
20
21;;; Returns two values:
22;;;  [nil, nil] if it can be reliably determined that function uses no registers at PC
23;;;  [mask, saved-location]  if it can be reliably determined that the registers specified by "mask"
24;;;      were saved at "saved-location" in the function's stack frame
25;;;  [mask, nil] if registers in "mask" MAY have been saved, but we don't know how to restore them
26;;;      (perhaps because the "at-pc" argument wasn't specified.
27
28
29(defun registers-used-by (function &optional at-pc)
30  (multiple-value-bind (mask stack-location rpc)
31      (%function-register-usage function)
32    (if (null mask)
33      (values nil nil)
34      (values (canonicalize-register-mask mask) (if (and at-pc rpc (> at-pc rpc)) stack-location)))))
35
36(defun canonicalize-register-mask (mask)
37  (dpb (ldb (byte 2 14) mask) (byte 2 2) (ldb (byte 2 11) mask)))
38
39(defun xcf-p (p)
40  (eql 0 (%fixnum-ref p x8664::lisp-frame.return-address)))
41
42(defun %current-xcf ()
43  (do* ((q (%get-frame-ptr) (%%frame-backlink q)))
44       ((zerop q))
45    (declare (fixnum q))
46    (when (xcf-p q) (return q))))
47
48;;; Try to determine the program counter value, relative to an xcf's nominal function.
49(defun pc-from-xcf (xcf)
50  (let* ((nominal-function (%fixnum-ref xcf x8664::xcf.nominal-function))
51         (containing-object (%fixnum-ref xcf x8664::xcf.containing-object)))
52    (when (typep nominal-function 'function)
53      (if (eq containing-object (function-to-function-vector nominal-function))
54        (- (%fixnum-ref xcf x8664::xcf.relative-pc)
55           x8664::tag-function)
56        (let* ((tra (%fixnum-ref xcf x8664::xcf.ra0)))
57          (if (and (= (lisptag tra) x8664::tag-tra)
58                   (eq nominal-function (%return-address-function tra)))
59            (%return-address-offset tra)))))))
60           
61(defun cfp-lfun (p)
62  (if (xcf-p p)
63    (values
64     (%fixnum-ref p x8664::xcf.nominal-function)
65     (pc-from-xcf p))
66    (%cfp-lfun p)))
67
68;;; On PPC, some frames on the control stack are associated with catch
69;;; frames rather than with function calls.  The whole concept doesn't
70;;; really apply here (e.g., nothing we encounter while walking frame
71;;; pointer links belongs to a catch frame.)
72(defun catch-csp-p (p context)
73  (declare (ignore p context)))
74
75(defun %raw-frame-ref (frame context idx bad)
76  (declare (fixnum frame idx))
77  (let* ((base (parent-frame frame context))
78         (raw-size (- base frame)))
79    (declare (fixnum base raw-size))
80    (if (and (>= idx 0)
81             (< idx raw-size))
82      (let* ((addr (- (the fixnum (1- base))
83                      idx)))
84        (multiple-value-bind (db-count first-db last-db)
85            (count-db-links-in-frame frame base context)
86          (let* ((is-db-link
87                  (unless (zerop db-count)
88                    (do* ((last last-db (previous-db-link last first-db)))
89                         ((null last))
90                      (when (= addr last)
91                        (return t))))))
92            (if is-db-link
93              (oldest-binding-frame-value context addr)
94              (%fixnum-ref addr)))))
95      bad)))
96
97(defun %stack< (index1 index2 &optional context)
98  (let* ((tcr (if context (bt.tcr context) (%current-tcr)))
99         (vs-area (%fixnum-ref tcr target::tcr.vs-area)))
100    (and (%ptr-in-area-p index1 vs-area)
101         (%ptr-in-area-p index2 vs-area)
102         (< (the fixnum index1) (the fixnum index2)))))
103
104
105
106
107(defun register-number->saved-register-index (regnum)
108  (ecase regnum
109    (#.x8664::save3 0)
110    (#.x8664::save2 1)
111    (#.x8664::save1 2)
112    (#.x8664::save0 3)))
113
114
115(defun get-register-value (address last-catch index)
116  (if address
117    (%fixnum-ref address)
118    (uvref last-catch (+ index target::catch-frame.save-save3-cell))))
119
120;;; Inverse of get-register-value
121
122(defun set-register-value (value address last-catch index)
123  (if address
124    (%fixnum-set address value)
125    (setf (uvref last-catch (+ index target::catch-frame.save-save3-cell))
126          value)))
127
128(defun %find-register-argument-value (context cfp regval bad)
129  (let* ((last-catch (last-catch-since cfp context))
130         (index (register-number->saved-register-index regval)))
131    (do* ((frame cfp (child-frame frame context))
132          (first t))
133         ((null frame))
134      (if (xcf-p frame)
135        (with-macptrs (xp)
136          (%setf-macptr-to-object xp (%fixnum-ref frame x8664::xcf.xp))
137          (return-from %find-register-argument-value
138            (encoded-gpr-lisp xp regval)))
139        (progn
140          (unless first
141            (multiple-value-bind (lfun pc)
142                (cfp-lfun frame)
143              (when lfun
144                (multiple-value-bind (mask where)
145                    (registers-used-by lfun pc)
146                  (when (if mask (logbitp index mask))
147                    (incf where (logcount (logandc2 mask (1- (ash 1 (1+ index))))))
148
149
150                    (return-from %find-register-argument-value
151                      (raw-frame-ref frame context where bad)))))))
152          (setq first nil))))
153    (get-register-value nil last-catch index)))
154
155;;; Used for printing only.
156(defun index->address (p)
157  (ldb (byte #+32-bit-target 32 #+64-bit-target 64 0)  (ash p target::fixnumshift)))
158
159(defun vsp-limits (frame context)
160  (let* ((parent (parent-frame frame context)))
161    (if (xcf-p frame)
162      (values (+ frame (ash x8664::xcf.size (- x8664::word-shift)))
163              parent)
164      (let* ((tra (%fixnum-ref frame x8664::lisp-frame.return-address)))
165        (values (+ frame 2 (if (eq tra (%get-kernel-global ret1valaddr)) 1 0))
166                parent)))))
167
168(defun last-catch-since (fp context)
169  (let* ((tcr (if context (bt.tcr context) (%current-tcr)))
170         (catch (%catch-top tcr))
171         (last-catch nil))
172    (loop
173      (unless catch (return last-catch))
174      (let ((catch-fp (uvref catch target::catch-frame.rbp-cell)))
175        (when (%stack< fp catch-fp context) (return last-catch))
176        (setq last-catch catch
177              catch (next-catch catch))))))
178
179(defun match-local-name (cellno info pc)
180  (when info
181    (let* ((syms (%car info))
182           (ptrs (%cdr info)))
183      (dotimes (i (length syms))
184        (let ((j (%i+ i (%i+ i i ))))
185          (and (eq (uvref ptrs j) (%ilogior (%ilsl (+ 6 target::word-shift) cellno) #o77))
186               (%i>= pc (uvref ptrs (%i+ j 1)))
187               (%i< pc (uvref ptrs (%i+ j 2)))
188               (return (aref syms i))))))))
Note: See TracBrowser for help on using the repository browser.