blob: ee433b387405d5dbfcfd6bf7ebf839ae721db8b7 [file] [log] [blame]
\ See license at end of file
purpose: Symbolic debugging extensions
\
\ initsyms ( adr len -- )
\ Initializes the symbol table. adr is the address of the header
\ of a memory image of an a.out file, and len is the length of the
\ file.
\
\ <symname> ( -- value )
\ Typing the name of a symbol leaves its value on the stack
\
\ >sym ( value -- offset symnane )
\ symname is a packed string which is the name of the symbol whose
\ value is closest to, but not greater than, "value" . Offset
\ is the positive difference between value and the symbol's value.
\
\ The disassembler is modified so that disassembled addresses are displayed
\ symbolically.
\
\ spread ( -- distance )
\ A value which controls the symbolic display of disassembled
\ addresses. If the distance from the address to the nearest smaller
\ symbol is less then the spread value , the address will be
\ displayed as "symname+offset"; otherwise just the address
\ will be displayed. The initial value of spread is hex 1000 (4K).
\ needs a.out-header ../sun/aout.fth
\ needs /sym ../unix/nlist.fth
headerless
0 value strings
0 value /strings
0 value symbols
0 value /symbols
0 value symbol-offset \ For use when the program is loaded at the wrong place
defer >string
defer >value
defer >sym_type
0 value /symtab-entry
[ifdef] /aout-symbol
0 value fileaddr \ Holds addr where file is copied, starting w/ text seg.
: syms@ ( -- symbol-table-addr ) fileaddr syms0 + ;
: strings@ ( -- strings-addr ) fileaddr string0 + ;
: >a.out-sym_strx ( sym-entry -- cstr ) sym_strx l@ strings + ;
: >a.out-sym_value ( sym-entry -- symbol-address ) sym_value l@ symbol-offset - ;
: >a.out-sym_type ( sym-etry -- valid-sym? ) sym_type c@ 4 9 between ;
' >a.out-sym_strx is >string
' >a.out-sym_value is >value
' >a.out-sym_type is >sym_type
/aout-symbol to /symtab-entry
[then]
: all-syms ( -- end-syms start-syms ) symbols /symbols bounds ;
: $sym>entry ( adr,len -- sym-entry true | adr,len false )
/symbols if ( adr,len )
all-syms do ( adr,len )
2dup i >string cscount $= if ( adr,len )
2drop i true unloop exit ( sym-entry true )
then ( adr,len )
/symtab-entry +loop ( adr,len )
then ( adr,len )
false ( adr,len false )
;
: $sym> ( adr,len -- sym-value true | adr,len false )
$sym>entry if >value true else false then
;
0 value min-sym \ Holds closest ( <= ) symbol to last .adr
0 value max-sym \ Holds closest ( > ) symbol to last .adr
0 value target \ Holds address being symbolized
h# 1000 value spread \ Maximum allowed displacement
: ubetween ( val min max -- ) >r over u<= swap r> u<= and ;
: already-within? ( -- flag ) \ Do previous saved values bracket target?
max-sym if
target min-sym >value max-sym >value 1- ubetween
else false \ Don't try it if uninitialized or at max memory
then
;
: compute-limits ( oldmin oldmax testsym -- min' max' )
dup >value >r -rot ( testsym min max ) ( rs: testval )
2dup r@ -rot ubetween ( testsym min max between? ) ( rs: testval )
if r@ target u> ( testsym min max new-max? ) ( rs: testval )
if drop swap is max-sym r> ( min max' )
else nip swap is min-sym r> swap ( min' max )
then
else rot r> 2drop
then
;
: find-nearest ( -- ) \ Min-sym points to final selection
symbols is min-sym 0 is max-sym
0 -1 \ Starting min, max values
all-syms do ( min max )
\
i >sym_type if i compute-limits then
/symtab-entry +loop ( min max )
2drop
;
headerless
0 value name-to-value ( -- name-to-value-func )
0 value value-to-name ( -- value-to-name-func )
: >sym ( addr -- offset adr len )
symbol-offset + is target ( )
already-within? 0= if find-nearest then
target min-sym >value - ( offset )
dup spread u< if \ Only print if offset isn't too big
min-sym >string cscount ( offset adr len )
else
drop target 0 0
then
;
: .offset ( offset -- )
5 swap ?dup if ( len offset )
." +" base @ >r hex (u.) r> base ! ( len adr,len )
tuck type - 1- ( len' )
then 1 max spaces
;
headers
\ User word to print nearest symbol for 'addr'
: 8u.h ( n -- ) push-hex (.8) type pop-base ;
: .adr ( addr -- )
dup origin u>= if 8u.h exit then
dup /symbols if >sym else 0 0 then ( addr offset adr len )
dup if ( addr offset adr len )
\ Display name[+offset] if name is not null
2swap >r 8u.h space type r> .offset exit
then 3drop
( addr )
dup >r do-value-to-sym if ( offset adr,len ) ( r: addr )
r> 8u.h space type .offset exit
else ( addr ) ( r: addr )
r> drop ( addr )
then ( addr )
value-to-name if ( addr )
value-to-name call32 ( addr retval )
dup l@ l->n -1 <> if ( addr retval )
swap 8u.h space ( retval )
dup l@ swap la1+ cscount ( offset name,len )
type .offset exit ( )
then drop ( addr )
then ( addr )
\ No symbolic info available display as number
8u.h
;
headerless
0 value prev-n2v
0 value prev-v2n
headers
: set-symbol-lookup ( n2v v2n -- old-n2v old-v2n )
name-to-value value-to-name 2swap ( old-n2v old-v2n n2v v2n )
is value-to-name is name-to-value ( old-n2v old-v2n )
0 to prev-n2v 0 to prev-v2n ( old-n2v old-v2n )
;
warning @ warning off
: symbol-lookup-off ( -- )
symbol-lookup-off
name-to-value ?dup if to prev-n2v then
value-to-name ?dup if to prev-v2n then
0 to name-to-value 0 to value-to-name
;
: symbol-lookup-on ( -- )
symbol-lookup-on
prev-n2v ?dup if to name-to-value then
prev-v2n ?dup if to value-to-name then
;
warning !
headerless
: $sym-handle-literal? ( adr,len -- handled? )
2dup 2>r ($handle-literal?) if ( r: adr,len )
2r> 2drop true exit
then 2r> ( adr,len )
$sym> if 1 do-literal true exit then
do-sym-to-value if 1 do-literal true exit then
name-to-value if ( adr,len )
encode-string over here - allot ( encoded$ )
drop name-to-value call32 nip ( retval )
dup l@ l->n if ( retval )
drop false ( false )
else ( pstr retval )
la1+ l@ 1 do-literal true ( true )
then exit ( flag )
then 2drop false ( false )
;
' $sym-handle-literal? is $handle-literal?
[ifdef] allocate-symtab
[ifdef] /aout-symbol
: copysyms ( dst-adr -- )
is symbols
symbols /symbols + is strings
syms@ symbols /symbols move
strings@ strings /strings move
;
\ Another way to calculate "/strings":
\ : /strings ( -- n ) /syms if strings@ @ else 0 then ;
: (initsyms) ( file-adr file-size -- )
swap is fileaddr ( file-size )
/text - /data - /reloc - /syms - is /strings ( )
syms@ is symbols strings@ is strings /syms is /symbols
['] $sym-handle-literal? is $handle-literal?
/symbols /strings + allocate-symtab ( adr ) copysyms
\ XXX What we really need to do:
\ compact the symbol table by removing the boring names (e.g.
\ sccsid) and the boring symbols (e.g. constant names, file names)
\ At the same time, extract the corresponding names into a
\ different area of memory, changing the pointers to 16 bit
\ shifted pointers, and eliminating the type fields.
\ allocate some virtual memory in the monitor's region.
\ allocate physical memory, removing it from the piece list
\ copy the symbol table into that memory
;
headers
: initsyms ( file-adr file-size -- )
over a.out-header /a.out-header move ( file-adr file-size )
['] >a.out-sym_strx is >string
['] >a.out-sym_value is >value
['] >a.out-sym_type is >sym_type
/aout-symbol to /symtab-entry
(initsyms)
;
[then]
[then]
\ Patch symbolic debugger into disassembler
\ also disassembler
' .adr is showaddr \ For disassembler
' .adr is .subname \ For ctrace
\ only forth also definitions
headers
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
\ "Software"), to deal in the Software without restriction, including
\ without limitation the rights to use, copy, modify, merge, publish,
\ distribute, sublicense, and/or sell copies of the Software, and to
\ permit persons to whom the Software is furnished to do so, subject to
\ the following conditions:
\
\ The above copyright notice and this permission notice shall be
\ included in all copies or substantial portions of the Software.
\
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\
\ LICENSE_END