forked from davazp/eulex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
debugger.fs
127 lines (102 loc) · 3.51 KB
/
debugger.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
\ debugger.fs --
\ Copyright 2012 (C) David Vazquez
\ This file is part of Eulex.
\ Eulex is free software: you can redistribute it and/or modify
\ it under the terms of the GNU General Public License as published by
\ the Free Software Foundation, either version 3 of the License, or
\ (at your option) any later version.
\ Eulex is distributed in the hope that it will be useful,
\ but WITHOUT ANY WARRANTY; without even the implied warranty of
\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\ GNU General Public License for more details.
\ You should have received a copy of the GNU General Public License
\ along with Eulex. If not, see <http://www.gnu.org/licenses/>.
require @structures.fs
require @kernel/interrupts.fs
variable last-breakpoint
struct
cell field breakpoint-nt
cell field breakpoint-addr
cell field breakpoint-byte
cell field breakpoint-previous
cell field breakpoint-next
cell field breakpoint-oneshot?
end-struct breakpoint%
: breakpoint-enable? ( breakpoint -- )
breakpoint-addr @ c@ $cc = ;
: enable-breakpoint ( breakpoint -- )
dup breakpoint-enable? if drop else
dup breakpoint-addr @ c@ over breakpoint-byte !
$cc swap breakpoint-addr @ c!
endif ;
: disable-breakpoint ( breakpoint -- )
dup breakpoint-enable? not if drop else
dup breakpoint-byte @ swap breakpoint-addr @ c!
endif ;
: find-breakpoint ( addr -- breakpoint% )
last-breakpoint @
begin dup while
2dup breakpoint-addr @ = if nip exit endif
breakpoint-next @
repeat
nip ;
: install-breakpoint ( nt addr -- breakpoint%|0 )
dup find-breakpoint if 2drop 0 else
breakpoint% allocate throw
tuck breakpoint-addr !
tuck breakpoint-nt !
last-breakpoint @ over breakpoint-next !
0 over breakpoint-previous !
dup last-breakpoint !
dup enable-breakpoint
endif ;
: delete-breakpoint ( breakpoint% -- )
dup breakpoint-next @ ?dup if
over breakpoint-previous @ ?dup if breakpoint-next ! endif
endif
dup breakpoint-previous @ ?dup if
over breakpoint-next @ ?dup if breakpoint-previous ! endif
endif
dup disable-breakpoint
free throw ;
: breakpoints
last-breakpoint @
begin dup while
dup breakpoint-nt @ id. breakpoint-previous @
repeat
drop ;
variable reseting-breakpoing
: debug-exception ( isrinfo -- )
[ $100 invert ]L over isrinfo-eflags and!
reseting-breakpoing @ ?dup if
dup breakpoint-oneshot? @ if
reseting-breakpoing 0!
else
enable-breakpoint
endif
endif
; 1 ISR
: traced-function-hook ( nt -- )
CR ." TRACE: The word " id. ." was called." ;
: breakpoint-exception ( isrinfo -- )
\ Set trap flag (single-step mode). It will generate ISR#1
\ interruption to be called, so we can replace the original byte
\ with the breakpoint instruction again.
$100 over isrinfo-eflags or!
\ Replace the break instruction with the original byte.
dup isrinfo-eip @ 1- find-breakpoint
dup disable-breakpoint
dup reseting-breakpoing !
dup breakpoint-nt @ traced-function-hook
breakpoint-addr @ swap isrinfo-eip !
; 3 ISR
: parse-and-trace
nt' dup nt>xt install-breakpoint
dup 0= if ." This word is being traced." CR endif ;
: trace parse-and-trace drop ;
: trace1 parse-and-trace breakpoint-oneshot? on ;
: untrace '
find-breakpoint ?dup if
delete-breakpoint
else ." This word is not traced." CR endif ;
\ debugger.fs ends here