Skip to content

Commit f88b799

Browse files
committed
Start of log-based debugger.
1 parent 010f6c3 commit f88b799

1 file changed

Lines changed: 100 additions & 15 deletions

File tree

langs/a86/interp.rkt

Lines changed: 100 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
[asm-interp (-> (listof instruction?) any/c)]
55
[asm-interp/io (-> (listof instruction?) string? any/c)])
66

7+
(define-logger a86)
8+
79
(require "printer.rkt" "ast.rkt" "callback.rkt" "check-nasm.rkt"
810
(rename-in ffi/unsafe [-> _->]))
911
(require (submod "printer.rkt" private))
1012

1113
;; Check NASM availability when required to fail fast.
1214
(check-nasm-available)
1315

16+
(define *debug*?
17+
(let ((r (getenv "PLTSTDERR")))
18+
(and r
19+
(string=? r "info@a86"))))
20+
1421
;; Assembly code is linked with object files in this parameter
1522
(define current-objs
1623
(make-parameter '()))
@@ -39,29 +46,36 @@
3946
(malloc _int64 20000 'raw))
4047

4148

42-
;; Integer -> String
43-
(define (number->binary n)
49+
;; Integer64 -> String
50+
(define (int64->binary-string n)
4451
(format "#b~a"
4552
(~r n #:base 2 #:min-width 64 #:pad-string "0")))
4653

47-
;; Integer -> String
48-
(define (number->octal n)
54+
;; Integer64 -> String
55+
(define (int64->octal-string n)
4956
(format "#o~a"
5057
(~r n #:base 8 #:min-width 22 #:pad-string "0")))
5158

52-
(define (number->hex n)
59+
;; Integer64
60+
(define (int64->hex-string n)
5361
(format "#x~a"
5462
(~r n #:base 16 #:min-width 16 #:pad-string "0")))
5563

5664
(define (show-state . regs)
57-
(for-each (lambda (v)
58-
(printf "reg: ~a\n" (number->hex v)))
59-
regs))
65+
(format "\n~a"
66+
(map (lambda (r v)
67+
(format "(~a ~a)" r (int64->hex-string v)))
68+
'(rax rbx rcx rdx rbp rsp rsi rdi
69+
r8 r9 r10 r11 r12 r13 r14 r15 instr flags)
70+
regs)))
6071

6172
;; Asm String -> (cons Value String)
6273
;; Like asm-interp, but uses given string for input and returns
6374
;; result with string output
6475
(define (asm-interp/io a input)
76+
77+
(log-a86-info (~v a))
78+
6579
(define t.s (make-temporary-file "nasm~a.s"))
6680
(define t.o (path-replace-extension t.s #".o"))
6781
(define t.so (path-replace-extension t.s #".so"))
@@ -72,7 +86,9 @@
7286
#:exists 'truncate
7387
(λ ()
7488
(parameterize ((current-shared? #t))
75-
(asm-display a))))
89+
(asm-display (if *debug*?
90+
(debug-transform a)
91+
a)))))
7692

7793
(nasm t.s t.o)
7894
(ld t.o t.so)
@@ -95,12 +111,15 @@
95111
(set-ffi-obj! "error_handler" libt.so _pointer
96112
(function-ptr (λ () (raise 'err)) (_fun _-> _void))))
97113

98-
(when (ffi-obj-ref "place" libt.so (thunk #f))
99-
(set-ffi-obj! "place" libt.so _pointer
100-
(function-ptr (λ (n)
101-
(apply show-state
102-
(build-list 16 (lambda (i) (ptr-ref n _int64 (add1 i))))))
103-
(_fun _pointer _-> _void))))
114+
(when *debug*?
115+
(define log (ffi-obj-ref log-label libt.so (thunk #f)))
116+
(when log
117+
(set-ffi-obj! log-label libt.so _pointer
118+
(function-ptr
119+
(λ () (log-a86-info
120+
(apply show-state
121+
(build-list 18 (lambda (i) (ptr-ref log _int64 (add1 i)))))))
122+
(_fun _-> _void)))))
104123

105124
(define has-heap? #f)
106125

@@ -206,3 +225,69 @@
206225
(regexp-match #rx"undefined reference to `(.*)'" err-msg)) ; linux
207226
[(list _ symbol) (ld:undef-symbol symbol)]
208227
[_ (ld:error (format "unknown link error.\n\n~a" err-msg))])))
228+
229+
230+
231+
;; Debugging facilities
232+
233+
(define log-label (symbol->label (gensym 'log)))
234+
235+
(define (Log i)
236+
(seq (save-registers)
237+
(Pushf)
238+
(Mov 'rax i)
239+
(Mov (Offset log-label (* 8 17)) 'rax)
240+
(Mov 'rax (Offset 'rsp 0))
241+
(Mov (Offset log-label (* 8 18)) 'rax)
242+
(Call (Offset log-label 0))
243+
(Popf)
244+
(restore-registers)))
245+
246+
(define (instrument is)
247+
(for/fold ([ls '()]
248+
#:result (reverse ls))
249+
([idx (in-naturals)]
250+
[ins (in-list is)])
251+
(if (serious-instruction? ins)
252+
(seq ins (reverse (Log idx)) ls)
253+
(seq ins ls))))
254+
255+
(define (serious-instruction? ins)
256+
(match ins
257+
[(Label _) #f]
258+
[(Global _) #f]
259+
[(? Comment?) #f]
260+
[_ #t]))
261+
262+
(define (debug-transform is)
263+
(seq (instrument is)
264+
;; End of user program
265+
(Data)
266+
(Global log-label)
267+
(Label log-label)
268+
(Dq 0) ; callback placeholder
269+
(static-alloc-registers)
270+
(Dq 0) ; index of instruction
271+
(Dq 0) ; flags
272+
))
273+
274+
(define registers
275+
'(rax rbx rcx rdx rbp rsp rsi rdi
276+
r8 r9 r10 r11 r12 r13 r14 r15))
277+
278+
(define (static-alloc-registers)
279+
(apply seq
280+
(map (λ (r) (seq (Dq 0) (% (~a r))))
281+
registers)))
282+
283+
(define (save-registers)
284+
(apply seq
285+
(map (λ (r i) (seq (Mov (Offset log-label (* 8 i)) r)))
286+
registers
287+
(build-list (length registers) add1))))
288+
289+
(define (restore-registers)
290+
(apply seq
291+
(map (λ (r i) (seq (Mov r (Offset log-label (* 8 i)))))
292+
registers
293+
(build-list (length registers) add1))))

0 commit comments

Comments
 (0)