Support This Project Get i5/OS Programmer's Toolkit at SourceForge.net. Fast, secure and Free Open Source software downloads

Analyzing the Symbol Table Component

According to IBM's documentation, the symbol table component of an OPM MI program template is composed with the following two parts:

They are defined as SPC objects symtbl-hash-t, and symtbl-base-t in mip-h.emi like the following:

Todo:
link to mip-h.emi
/*
 hashing table of a symbol table component
 */
dcl spc symtbl-hash-t bas(*)    ;
        /* Number of hash buckets */
        dcl dd symtbl-hash?num-buckets bin(4) dir ;
        /*
 Each hash bucket contains an offset to the first symbol
 table base segment entry of the chain. This offset is from
 the beginning of the symbol table. The end of the chain has
 a -1 value.
         */
        dcl dd symtbl-hash?buckets(1000) bin(4) dir ;

/*
 symbol table base segment
 */
dcl spc symtbl-base-t bas(*)    ;
        /* Offset to next entry from beginning of the table. The end of the chain has a -1 value. */
        dcl dd symtbl-base?next-entry-offset bin(4) unsgnd dir ;
        /* ODT or MI number */
        dcl dd symtbl-base?num bin(2) dir ;
        /*
 bit 0. Instruction or ODT number
  0 = MI instruction number. This also means the symbol is the name of a LABEL in the program template.
  1 = ODT number. The symbol is the name of an ODT object.
 bit 1. Symbol origin
  0 = Compiler generated
  1 = Source program
         */ 
        dcl dd symtbl-base?flag char(1) dir ;
        dcl dd symtbl-base?len  char(1) dir ;
        dcl dd symtbl-base?name char(15) dir ;

Here is an sample MI program, tmip02.emi, that parses the symbol table component of OPM RPG program t143rpg.rpg. For the lastest source of tmip02, please refer to the svn repository of the project, https://....

Remarks:
Yet, there is also an ILE RPG sample program (t146.rpgle) that implement the same job as tmip02.emi does.
Todo:
link to tmip02.emi, t146.rpgle, and t143rpg.rpg
/*
 @file tmip02.emi

 Test of SPC objects: symtbl-hash-t, and symtbl-base-t.
 */

entry *(pl-main) ext            ;

dcl spcptr .pgm-name parm          ;
dcl spcptr .pgm-type parm          ;
dcl ol pl-main(
        .pgm-name,
        .pgm-type
) parm ext ;

dcl dd pgm-name char(10) bas(.pgm-name) ;
dcl dd pgm-type char(2) bas(.pgm-type)  ;

dcl dd rt char(34) auto         ;
dcl sysptr pgm auto             ;
        cpybrep rt, x'00'       ;
        cpybla  rt(1:2), pgm-type ;
        cpyblap rt(3:30),
          pgm-name, ' ' ;
        rslvsp  pgm, rt, *, *   ;
brk '1'                         ;

dcl spcptr p auto               ;
dcl dd len bin(4) auto          ;
        modasa p, 8             ;
        cpynv p->matpg?bytes-in, 8 ;
        matpg p, pgm               ;

        cpynv len, p->matpg?bytes-out ;
        modasa p, -8                  ;
        modasa p, len                 ;
        cpynv p->matpg?bytes-in, len  ;
        matpg  p, pgm                 ;
brk '2'                               ;

  calli dsp-header, *, dsp-header-ptr ;

dcl dd inx bin(2) auto          ;
dcl spcptr symtbl-start auto    ;
dcl spcptr hash auto            ;
dcl spcptr sym auto             ;

        addspp symtbl-start, p, p->matpg?symtbl-off ;
        addspp hash, p, p->matpg?symtbl-off         ;
        cpynv inx, 1            ;
loop-sym:
        cmpnv(b) inx, hash->symtbl-hash?num-buckets / hi(end-loop-sym);

        /* skip invalid BUCKET */
        cmpnv(b) hash->symtbl-hash?buckets(inx), -1 / eq(next-bucket) ;

        addspp sym, symtbl-start, hash->symtbl-hash?buckets(inx) ;
        calli dsp-symbol, *, dsp-symbol-ptr ;

        /* has next entry? */
        cmpnv(b) sym->symtbl-base?next-entry-offset, -1 / eq(next-bucket) ;
        addspp sym, symtbl-start, sym->symtbl-base?next-entry-offset ;
        calli dsp-symbol, *, dsp-symbol-ptr ;
next-bucket:       

brk "WHERE"                     ;
        addn(s) inx, 1          ;
        b loop-sym              ;
end-loop-sym:   

brk 'END'                       ;
        neg(s) len              ;
        modasa p, len           ;
        rtx *                   ;

/*
 display a symbol table entry

 @pre SPPPTR sym
 */
dcl insptr dsp-symbol-ptr auto  ;
entry dsp-symbol int            ;

dcl dd msg char(64) auto        ;
        dcl dd fld-odt znd(8,0) def(msg) pos(1) ;
        dcl dd fld-inst znd(8,0) def(msg) pos(11) ;
        dcl dd fld-sym-name char(16) def(msg) pos(21) ;
        dcl dd fld-sym-org char(20) def(msg) pos(37)  ;
dcl spcptr fld-sym-name-ptr auto  ;
dcl spcptr symbol-name-ptr auto   ;
dcl dd symbol-len bin(2) auto     ;
        dcl dd symbol-len-lo char(1) def(symbol-len) pos(2) ;

        cpybrep msg, ' '        ;
        /* symbol name */
        cpybrep fld-sym-name, ' ' ;
        setspp fld-sym-name-ptr, fld-sym-name      ;
        setspp symbol-name-ptr, sym->symtbl-base?name ;
        cpybla symbol-len-lo, sym->symtbl-base?len    ;
        %memcpy(fld-sym-name-ptr,
                symbol-name-ptr,
                symbol-len) ;
        /* ODT number or MI instruction number */
        tstbts(b) sym->symtbl-base?flag, 0 / zer(=+3) ;
        cpynv fld-odt, sym->symtbl-base?num           ; /* flag bit 0 = 1, ODT number */
        b =+2                                         ;
:
        cpynv fld-inst, sym->symtbl-base?num ;          /* flag bit 0 = 0, MI instruction */
:
        /* Symbol origin */
        tstbts(b) sym->symtbl-base?flag, 1 / zer(=+3) ;
        cpybla fld-sym-org, "Source program"          ; /* flag bit 1 = 1. source program */
        b =+2                                         ;
:
        cpybla fld-sym-org, "Compiler generated" ; /* flag bit 1 = 0. compiler generated */
:       
        %sendmsg(msg , 64)      ;

        b dsp-symbol-ptr        ;

dcl insptr dsp-header-ptr auto  ;
entry dsp-header int            ;

        cpyblap msg, "HLL Symbol Table", " " ;
        %sendmsg(msg , 64)      ;
        cpyblap msg, pgm-name, " " ;
        cvthc   msg(11:4), pgm-type ;
        %sendmsg(msg , 64)      ;
        cpyblap msg, "ODT Ref   MI Inst   Symbol Name     Symbol Org",
          " "                   ;
        %sendmsg(msg , 64)      ;

        b dsp-header-ptr        ;

/include mip-h.emi              ;
pend                            ;

Call TMIP02 like the following:

CALL TMIP02 ('T143RPG' X'0201)

The output is the following:

HLL Symbol Table                                  
T143RPG   0201                                    
ODT Ref   MI Inst   Symbol Name     Symbol Org    
00000240            ZIGNDECD        Source program
          00000022  *GETIN          Source program
00000023            ARR             Source program
00000076            *MONTH          Source program
00000024            WHR             Source program
00000072            *DATE           Source program
00000017            *INXX           Source program
00000020            *IN             Source program
          00000089  S.ARR           Source program
          00000138  *CANCL          Source program
00000087            M.*YEAR         Source program
00000085            M.*DAY          Source program
          00000084  *DETL           Source program
          00000037  *TOTC           Source program
00000086            M.*MONTH        Source program
00000078            *DAY            Source program
00000013            *ON             Source program
00000083            M.UYEAR         Source program
00000080            M.UDATE         Source program
          00000038  *TOTL           Source program
00000118            ZPGMSTUS        Source program
00000079            UDAY            Source program
00000077            UMONTH          Source program
00000262            C.PGMJTM        Source program
00000082            M.UMONTH        Source program
00000073            UDATE           Source program
00000022            *IN91           Source program
00000019            *INLR           Source program
00000030            WORK.           Source program
00000016            *INIT           Source program
00000263            C*DATE          Source program
00000014            *OFF            Source program
          00000039  *OFL            Source program
00000075            UYEAR           Source program
          00000041  *DETC           Source program
00000074            *YEAR           Source program
00000081            M.UDAY          Source program
          00000146  *TERM           Source program
00000084            M.*DATE         Source program

Support This Project
Generated on Mon Aug 22 08:26:47 2011 for i5/OS Programmer's Toolkit: OPM MI Disassembler by  doxygen 1.5.9