;       SCCSID = @(#)debsym.asm 6.1 90/11/17
NAME   DEBSYM
TITLE  Kernel Debugger Symbol Handler
.286p

SCCSID  equ     "@(#)debsym.asm 13.24 90/04/27"

;***    DEBSYM  -  Routines to support symbols in the debugger.
;

DEBUG   equ     1

Extern  CListNear,    FAR
Extern  CListMTEMap, FAR
Extern  CdeActivateMap, FAR
Extern  CActivateMap, FAR
Extern  CListMaps,    FAR
Extern  CListGroups, FAR
Extern  CListSyms, FAR
Extern  CListAbsolutes, FAR
Extern  CmdBreak, NEAR

.xlist
include  debequ.inc
include  debseg.inc
include  debsym.inc
include  debmac.inc
include  debdesc.inc
.list

EACHMAP_ACTIVE          equ     0001h
EACHMAP_START_LAST      equ     0002h

;*      Make sure the public symbol type equates are the same
;       as the internal address type equates.

.errnz  SYM_TYPE_SEG-EXPR_TYPE_SEG
.errnz  SYM_TYPE_SEL-EXPR_TYPE_SEL
.errnz  SYM_TYPE_LIN-EXPR_TYPE_LIN
.errnz  SYM_TYPE_PHY-EXPR_TYPE_PHY

DataSegmentStart

Extern pTXT,            WORD
Extern  AtomBuf,        BYTE            ; String buffer,    in "debeval.asm".
Extern  DisAddr,        WORD            ; Disassembly address
Extern  RegSA,          WORD            ; Register save area
Extern  DefType,        WORD            ; Default address type

;*      These data are statically initialized only; this way if the
;       debugger is reinitialized, the map list will not be lost.

addrsFirstMap   db      (size AddrS) DUP (0)    ; Beginning of Map chain
addrsLastMap    db      (size AddrS) DUP (0)    ; Last map symbol found
cMapCount       dw      0                       ; Number of maps

Static  ListTable, LABEL, BYTE
    CmdTable_s <"A", codeOFFSET ListAbsSyms>    ; List near symbols subcom.
    CmdTable_s <"G", codeOFFSET ListGroups>     ; List groups subcommand.
    CmdTable_s <"M", codeOFFSET ListMaps>       ; List maps subcommand.
    CmdTable_s <"N", codeOFFSET ListNear>       ; List absolute symbols subcom.
    CmdTable_s <"S", codeOFFSET ListSyms>       ; List symbols subcommand.
    CmdTable_s <0,   codeOFFSET perr>           ; Default command.

;Static  LinkTable, LABEL, WORD
;        dw      codeOFFSET LinkMap
;        .errnz  SYM_LINKMAP-0
;        dw      codeOFFSET ReLinkMap
;        .errnz  SYM_RELINKMAP-1
;        dw      codeOFFSET UnLinkMap
;        .errnz  SYM_UNLINKMAP-2
;SYM_TAB_LEN     equ     (($ - LinkTable) SHR 1)

WithMapMsg      label   byte
        db      "Use ""WA mapname | *"" to add a map to the active list"
        db      CR, LF
        db      "Use ""WR mapname | *"" to remove a map from the active list"
        db      CR, LF
        db      "Use ""WL address | *"" to list all mte map list"
        db      CR, LF
        db      0

pMapDefCur      dw      ?       ; pointer into stack for current MapDef

DataSegmentEnd

CodeSegmentStart

Extern perr, NEAR

.286p

;***    WithMap - Activate the specified symbol map.  Add Map
;
;       "WA <mapname> | *" or "WR <mapname> | *" command.
;
;       ENTRY:  NONE
;
;       EXIT:   Flags
;
;       USES:   AX, BX, CX, DX, SI, DI, Flags

DefProc WithMap, NEAR, PUBLIC
LocVar  wa_Addr,     <size AddrS>
LocVar  wa_type,     WORD
BeginProc
        Pcall   PeekChr
        jz      short wmp10
        xor     di,di                   ; (DI) = ActivateMap flag (REMOVE)
        cmp     al,'R'                  ; remove active map
        je      short wmp20
        inc     di                      ; (DI) = ActivateMap flag (ADD)
        cmp     al,'A'                  ; add active map
        je      short wmp20
        inc     di                      ; (DI) = ActivateMap flag (LIST)
        cmp     al,'L'                  ; list MTE map list
        je      short wmp20
wmp10:  mov     dx,dataOFFSET WithMapMsg
        Pcall   rprbuf
        jmp     wmpx

wmp20:  mov     wa_type, di
        Pcall   SkipB
; davidj 09/03/93
        mov     di, wa_type
        mov     si,pTXT                 ; save pTXT incase it is a sel:off
        cmp     di, 1
        je      wm100
        Pcall   GetChr                  ; (AL) = next character after spaces
        mov     di,pTXT                 ; save pTXT incase it is a sel:off
        Pcall   ScanAtom                ; get search map name
        mov     si,dataOFFSET AtomBuf   ; place pointer of AtomBuf in si

; davidj 09/03/93
        mov     di, wa_type
        cmp     di, 0                   ; if it is wr jump to cdeactivate map
        je      wm100
        cmp     di, 1                   ; if it is wa jump to cactivate map
        je      wm100

        cmp     al, '#'                 ; is it a #sel:off
        je      wm95
        cmp     al, '%'                 ; is it a %linear add
        je      wm95
        cmp     al, ':'                 ; is it a sel:off
        je      @F
        mov     ax, [si]                ; now check to see if just ln
        cmp     al,0                    ; si will have AtomBuf[0]=0
        je      wm95
        jne     wm100                   ; it's a symbol jump to _CActivateMap

@@:     dec     di                      ; it's a sel:off and we need to insert #
        mov     ax, [di]
        mov     al, '#'                 ; store # into pTXT
        mov     [di], ax
        mov     pTXT,di                 ; reset pTXT to new position

wm95:   lea     bx,[wa_Addr]            ; it is an address
        mov     ax, [si]
        mov     al, 0
        mov     [si], ax                ; store 0 in AtomBuf[0] to indicate
        inc     si                      ; it is an address
        Pcall   EvalAddr, <di, bx>
        mov     cx, 3                   ; address is 3 words long sel: offset
        mov     di, si                  ; copy data into si
        mov     si, bx
        rep     movsw
        mov     si,dataOFFSET AtomBuf

wm100:  mov     di, wa_type
        push    ds
        push    si
        cmp     di, 0
        jne     @F
        call    far ptr _CdeActivateMap           ; call 'C' code routine
        jmp     wm110
@@:     cmp     di, 1
        jne     @F
        call    far ptr _CActivateMap             ; call 'C' code routine
@@:     cmp     di, 2
        jne     wm110
        call    far ptr _CListMTEMap              ; call 'C' code routine

wm110:  add     sp,4
;        jmp     wmpx
wmpx:
         jmp     CmdBreak
EndProc


;***    Lists - List (maps, groups, symbols, near symbols, absolute symbols.)
;
;       "Lists" will print on the debugger terminal the names of the
;       groups, symbols, maps, or near symbols currently active.
;
;       ENTRY:  No explicit arguments.
;
;       EXIT:   NONE
;
;       USES:   Flags
;
;       CALLS:  Either: ListMaps,ListGroups,ListSyms,ListNear,ListAbsSyms
;

DefProc Lists, NEAR, PUBLIC
        Pcall   GetChrI                 ; (AL) = subcommand character
        jz      short lste
        mov     si,dataOFFSET ListTable ; get ptr to function table
        Pcall   ExecSubr                ; call subroutine from table.
EndProc
lste:   Jump    perr

;***    ListNear - Lists symbols that preceeds and follow input address.
;
;       "LN [<addr>]" command.  The command buffer may contain an address
;       or symbol (if not, use default) which is an anchor.  This routine
;       will find and print on the debugging terminal, the symbol whose
;       address preceeds the anchor, and the first symbol whose address
;       is equal to or greater than the anchor.  In addition the symbols'
;       offsets and relative offsets (to the anchor) are printed.
;
;       ENTRY:  Command buffer contains specified address.
;
;       EXIT:   NONE
;
;       USES:   Flags, AX, BX, CX, DX, SI, DI, Flags

;efProc ListNear, NEAR, PUBLIC
DefProc ListNear, NEAR, LOCAL

LocVar  lns_SymBuff,      <3*MAX_NAME_SIZE>
LocVar  lns_NearAddr,     <size AddrS>
LocVar  lns_FoundSymAddr, <size AddrS>

BeginProc
;       "LN [<addr>| <symbol name>]" command
;       The command buffer may contain an address or symbol
;       (if not, use default) which is an anchor.  This routine
;       will find and print on the debugging terminal, the symbol whose
;       address preceeds the anchor, and the first symbol whose address
;       is equal to or greater than the anchor.  In addition the symbols'
;       offsets and relative offsets (to the anchor) are printed.
;
;       Call ScanAtom,
;         if the address given is an address then ScanAtom will return
;         with character that is at fault which would be either
;         %linear address or : for sel:off or #sel:off
;         if it comes back as any of these then call EvalAddr
;         Normally one would just call EvalAddr, but this function
;         now just jumps to CmdBreak on error, and that we don't want here.
;         If it is not al is not %,#,: then treat it as a symbol.
;         Keep in mind that AtomBuf[0] contains the length of the string
;         and if it is >= 2 then it is a symbol otherwise it is an address
;

        mov     di,pTXT                 ; save pTXT incase it is a sel:off
        Pcall   ScanAtom                ; get search map name
        mov     si,dataOFFSET AtomBuf   ; place pointer of AtomBuf in si
        cmp     al, '#'                 ; is it a #sel:off
        je      lns95
        cmp     al, '%'                 ; is it a %linear add
        je      lns95
        cmp     al, ':'                 ; is it a sel:off
        je      @F
        mov     ax, [si]                ; now check to see if just ln
        cmp     al,0                    ; si will have AtomBuf[0]=0
        je      lns95
        jne     lns100                  ; it's a symbol jump to _CListNear call

@@:     dec     di                      ; it's a sel:off and we need to insert #
        mov     ax, [di]
        mov     al, '#'                 ; store # into pTXT
        mov     [di], ax
        mov     pTXT,di                 ; reset pTXT to new position

lns95:  lea     bx,[lns_NearAddr]       ; it is an address
        mov     ax, [si]
        mov     al, 0
        mov     [si], ax                ; store 0 in AtomBuf[0] to indicate
        inc     si                      ; it is an address
        Pcall   EvalAddr, <dataOFFSET DisAddr, bx>
        mov     cx, 3                   ; address is 3 words long sel: offset
        mov     di, si                  ; copy data into si
        mov     si, bx
        rep     movsw
        mov     si,dataOFFSET AtomBuf

lns100: push    ds
        push    si
        call    far ptr _CListNear              ; call 'C' code routine
        add     sp,4
EndProc


;***    ListMaps - List any symbol maps linked to the debugger.
;
;       "LM" command.  Prints on the debugger terminal the names
;       of the currently linked/active maps.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   AX, BX, CX, DX, SI, DI, Flags
;

;efProc ListMaps, NEAR, PUBLIC
DefProc ListMaps, NEAR, LOCAL
        call    far ptr _CListMaps              ; call 'C' code routine
EndProc


;***    ListGroups - Lists names of groups in currently active map.
;
;       LG [<mapname>].  Prints on the debugger terminal the names
;       of the groups in the currently active symbol maps.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   AX, BX, CX, DX, SI, DI, Flags
;

;efProc ListGroups, NEAR, PUBLIC
DefProc ListGroups, NEAR, LOCAL
        Pcall   ScanAtom                ; get search map name
        mov     si,dataOFFSET AtomBuf
        push    ds
        push    si
        call    far ptr _CListGroups            ; call 'C' code routine
        add     sp,4
EndProc


;***    ListSyms -  List all symbols in the specified group
;
;       "LS [<addr>]" command.  Prints on the debugger terminal the
;       symbols defined in the group whose name is specified in the
;       command line.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   AX, BX, CX, DX, SI, DI, Flags
;

DefProc ListSyms, NEAR, LOCAL

LocVar  lgs_SymBuff,      <3*MAX_NAME_SIZE>
LocVar  lgs_NearAddr,     <size AddrS>
LocVar  lgs_FoundSymAddr, <size AddrS>

BeginProc
;       "LS [<addr>| <group name>]" command
;       The command buffer may contain an address or group
;       (if not, use default) which is an anchor.  This routine
;       will find and print on the debugging terminal, the group whose
;       address preceeds the anchor, and the first group whose address
;       is equal to or greater than the anchor.  In addition the groups'
;       offsets and relative offsets (to the anchor) are printed.
;
;       Call ScanAtom,
;         if the address given is an address then ScanAtom will return
;         with character that is at fault which would be either
;         %linear address or : for sel:off or #sel:off
;         if it comes back as any of these then call EvalAddr
;         Normally one would just call EvalAddr, but this function
;         now just jumps to CmdBreak on error, and that we don't want here.
;         If it is not al is not %,#,: then treat it as a group.
;         Keep in mind that AtomBuf[0] contains the length of the string
;         and if it is >= 2 then it is a group otherwise it is an address
;

        mov     di,pTXT                 ; save pTXT incase it is a sel:off
        Pcall   ScanAtom                ; get search map name
        mov     si,dataOFFSET AtomBuf   ; place pointer of AtomBuf in si
        cmp     al, '#'                 ; is it a #sel:off
        je      lgs95
        cmp     al, '%'                 ; is it a %linear add
        je      lgs95
        cmp     al, ':'                 ; is it a sel:off
        je      @F
        mov     ax, [si]                ; now check to see if just ln
        cmp     al,0                    ; si will have AtomBuf[0]=0
        je      lgs95
        jne     lgs100                  ; it's a group jump to _CListNear call

@@:     dec     di                      ; it's a sel:off and we need to insert #
        mov     ax, [di]
        mov     al, '#'                 ; store # into pTXT
        mov     [di], ax
        mov     pTXT,di                 ; reset pTXT to new position

lgs95:  lea     bx,[lgs_NearAddr]       ; it is an address
        mov     ax, [si]
        mov     al, 0
        mov     [si], ax                ; store 0 in AtomBuf[0] to indicate
        inc     si                      ; it is an address
        Pcall   EvalAddr, <dataOFFSET DisAddr, bx>
        mov     cx, 3                   ; address is 3 words long sel: offset
        mov     di, si                  ; copy data into si
        mov     si, bx
        rep     movsw
        mov     si,dataOFFSET AtomBuf

lgs100: push    ds
        push    si
        call    far ptr _CListSyms              ; call 'C' code routine
        add     sp,4
EndProc


;***    ListAbsSyms -  List all absolute symbols in the active map.
;
;       "LA [<mapname>]" command.  Prints on the debugger terminal the
;       absolute symbols in the map.
;
;       ENTRY:  NONE
;
;       EXIT:   NONE
;
;       USES:   AX, BX, CX, DX, SI, DI, Flags
;

DefProc ListAbsSyms, NEAR, LOCAL
        Pcall   ScanAtom                ; get search map name
        mov     si,dataOFFSET AtomBuf
        push    ds
        push    si
        call    far ptr _CListAbsolutes
        add     sp, 4
EndProc

CodeSegmentEnd

        end
