They are defined as SPC objects symtbl-hash-t, and symtbl-base-t in mip-h.emi like the following:
/* 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://....
/* @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