\ 7.6 Client Program Debugging command group
\ Saved program state context
variable __context
0 __context !
: saved-context __context @ @ ;
\ 7.6.1 Registers display
: ctrace ( -- )
;
: .registers ( -- )
;
: .fregisters ( -- )
;
\ to ( param [old-name< >] -- )
\ 7.6.2 Program download and execute
struct ( load-state )
/n field >ls.entry
/n field >ls.file-size
/n field >ls.file-type
/n field >ls.param
constant load-state.size
create load-state load-state.size allot
variable state-valid
0 state-valid !
variable file-size
: !load-size file-size ! ;
: load-size file-size @ ;
\ File types identified by (load-state)
0 constant elf-boot
1 constant elf
2 constant bootinfo
3 constant xcoff
4 constant pe
5 constant aout
10 constant fcode
11 constant forth
12 constant bootcode
13 constant prep
: init-program ( -- )
\ Call down to the lower level for relocation etc.
s" (init-program)" $find if
execute
else
s" Unable to locate (init-program)!" type cr
then
;
: (find-bootdevice) ( param-str param-len -- bootpath-str bootpath-len)
\ Parse the string which is a space-separated list of one or
\ more potential boot devices, and return the first one that can be
\ successfully opened.
\ Space-separated bootpath string
bl left-split \ bootpathstr bootpathstr-len bootdevstr bootdevstr-len
dup 0= if
\ None specified. As per IEEE-1275 specification, search through each value
\ in boot-device and use the first that returns a valid ihandle on open.
2drop \ drop the empty device string as we're going to use our own
s" boot-device" $find drop execute
bl left-split
begin
dup
while
2dup s" Trying " type type s" ..." type cr
2dup open-dev ?dup if
close-dev
2swap drop 0 \ Fake end of string so we exit loop
else
2drop
bl left-split
then
repeat
2drop
then
\ bootargs
2swap dup 0= if
\ None specified, use default from nvram
2drop s" boot-file" $find drop execute
then
\ Set the bootargs property
encode-string
" /chosen" (find-dev) if
" bootargs" rot (property)
then
;
\ Locate the boot-device opened by this ihandle (currently taken as being
\ the first non-interposed package in the instance chain)
: ihandle>boot-device-handle ( ihandle -- 0 | device-ihandle -1 )
>r 0
begin r> dup >in.my-parent @ dup >r while
( result ihandle R: ihandle.parent )
dup >in.interposed @ 0= if
\ Find the first non-interposed package
over 0= if
swap drop
else
drop
then
else
drop
then
repeat
r> drop drop
dup 0<> if
-1
then
;
: $load ( devstr len )
open-dev ( ihandle )
dup 0= if
drop
exit
then
dup >r
" load-base" evaluate swap ( load-base ihandle )
dup ihandle>phandle " load" rot find-method ( xt 0|1 )
if swap call-package !load-size else cr ." Cannot find load for this package" 2drop then
\ If the boot device path doesn't contain an explicit partition id, e.g. cd:,\\:tbxi
\ then the interposed partition package may have auto-probed a suitable partition. If
\ this is the case then it will have set the " selected-partition-args" property in
\ the partition package to contain the new device arguments.
\
\ In order to ensure that bootpath contains the partition argument, we use the contents
\ of this property if it exists to override the boot device arguments when generating
\ the full bootpath using get-instance-path.
my-self
r@ to my-self
" selected-partition-args" get-inherited-property 0= if
decode-string 2swap 2drop
( myself-save partargs-str partargs-len )
r@ ihandle>boot-device-handle if
( myself-save partargs-str partargs-len block-ihandle )
\ Override the arguments before get-instance-path
dup >in.arguments 2@ >r >r dup >r ( R: block-ihandle arg-len arg-str )
>in.arguments 2! ( myself-save )
r@ " get-instance-path" $find if
execute ( myself-save bootpathstr bootpathlen )
then
\ Now write the original arguments back
r> r> r> rot >in.arguments 2! ( myself-save bootpathstr bootpathlen R: )
rot ( bootpathstr bootpathlen myself-save )
then
else
my-self " get-instance-path" $find if
execute ( myself-save bootpathstr pathlen )
rot ( bootpathstr bootpathlen myself-save )
then
then
to my-self
\ Set bootpath property in /chosen
encode-string " /chosen" (find-dev) if
" bootpath" rot (property)
then
r> close-dev
init-program
;
: load ( "{params}" -- )
linefeed parse
(find-bootdevice)
$load
;
: dir ( "{paths}" -- )
linefeed parse
ascii , split-after
2dup open-dev dup 0= if
drop
cr ." Unable to locate device " type
2drop
exit
then
-rot 2drop -rot 2 pick
" dir" rot ['] $call-method catch
if
3drop
cr ." Cannot find dir for this package"
then
close-dev
;
: go ( -- )
state-valid @ 0= if
s" No valid state has been set by load or init-program" type cr
exit
then
\ Call any architecture-specific code
s" (arch-go)" $find if
execute
else
2drop
then
\ go
s" (go)" $find if
execute
then
;
\ 7.6.3 Abort and resume
\ already defined !?
\ : go ( -- )
\ ;
\ 7.6.4 Disassembler
: dis ( addr -- )
;
: +dis ( -- )
;
\ 7.6.5 Breakpoints
: .bp ( -- )
;
: +bp ( addr -- )
;
: -bp ( addr -- )
;
: --bp ( -- )
;
: bpoff ( -- )
;
: step ( -- )
;
: steps ( n -- )
;
: hop ( -- )
;
: hops ( n -- )
;
\ already defined
\ : go ( -- )
\ ;
: gos ( n -- )
;
: till ( addr -- )
;
: return ( -- )
;
: .breakpoint ( -- )
;
: .step ( -- )
;
: .instruction ( -- )
;
\ 7.6.6 Symbolic debugging
: .adr ( addr -- )
;
: sym ( "name< >" -- n )
;
: sym>value ( addr len -- addr len false | n true )
;
: value>sym ( n1 -- n1 false | n2 addr len true )
;