/************************************************** * PL/I symbolic debugger work file definitions * **************************************************/ dcl workfile file sequential env(dev(sy), varying, recsize(1000)); /*recsize must fit current_module record (defined in brksymdef)*/ dcl 1 workdf external, /*put in structure so names not limited to 6 chars*/ /***** * work file record formats. all have a hash record (see workbuf below). some have additional data in a following record. overlay segment: --------------- parent: none value: address in user task of overlay segment descriptor following: */ 2 segment_data, 3 segment_globals_base fixed bin(23), /*fileaddr in map file of beginning of global symbols section*/ /* module: ------ parent: overlay segment value: address in user task of external procedure following: current_module record (defined in brksymdef.pli) block: ----- parent: module value: block code (code appearing in symbol table entries and subscript in current_module.blocks array) following: */ 2 block_data, 3 parent fixed bin(23), /*fileaddr in workfile of parent block hash record*/ 3 address fixed bin(15), /*address in user task of block (procedure prolog)*/ 3 symaddr fixed bin(15), /*virtual address in symfile of symbol table entry, for CALL to get arg list*/ /* symbol: ------ parent: module value: virtual address in symfile of symbol table entry external procedure: ------------------ parent: overlay segment value: address in user task following: filename of symfile (without the .SYM) external data: ------------- parent: overlay segment value: address in user task global_class is a flag for external_address calls - there are no records put in workfile for global symbols debprocedure: ------------ parent: dogroup_subclass or debprocedure_subclass, flagging which type it is value: unused following: one record per line of procedure/do-group, except the first record contains just the DO or PROCEDURE keyword or abbreviation, as typed by user, and the second record contains the rest of user's first line. this allows the user to re-enter the first line if he makes a mistake entering it (see error). the do_fileaddr field in the breakpoint table points directly to the 2nd record, skipping the DO/PROCEDURE. * *****/ ( /* class codes: */ 2 any_class initial(0), 2 overlay_segment_class initial(1), 2 module_class initial(2), 2 block_class initial(3), 2 symbol_class initial(4), 2 external_procedure_class initial(5), 2 external_data_class initial(6), 2 global_class initial(7), 2 debprocedure_class initial(8), 2 replace_class initial(9) ) fixed bin(7), 2 any_parent fixed bin(23) initial(1), /*nonzero (first record has file address of zero)*/ 2 dogroup_subclass fixed bin(23) initial(2), /*debprocedure_class uses parent field as flag*/ 2 debprocedure_subclass fixed bin(23) initial(3), /*debprocedure_class uses parent field as flag*/ 2 any_name char initial(''), 2 last_do_number fixed bin(15) static initial(0), /*sequence number for do group names*/ 2 work_debprocedure_line_pos static fixed bin(23), /*fileaddr of line last written, so we can replace it on error*/ 2 wk_name char(31) varying static, /*for WK poke command*/ 2 wk_class fixed bin(7) static, /*for WK poke command*/ 2 wk_parent fixed bin(23) static, /*for WK poke command*/ 2 work_scan_index fixed bin(15) static, /*for scanning through work file sequentially*/ 2 work_index(97) fixed bin(23) static initial((97)-1/*null_fileaddr*/), /*hashing pointers, hbound should be prime*/ /* pointers to workbuf structures, which are allocated by debinit: */ ( 2 put_workp, /*for all workputs*/ 2 debprocedure_workp, /*for reading commands to execute when indebprocedure*/ 2 path_workp, /*pathfind needs one in addition to scratch, also used by SHOW MODULE*/ 2 scratch_workp, /*for anybody*/ 2 current_workp, /*which of above actual current file position belongs to (pointer only, no separate buffer)*/ 2 external_workp /*which of above contains hash record after successful external_address call (pointer only, no separate buffer)*/ ) pointer static; /* each buffer defines a separate stream with its own current position (curfilepos) to allow executing a do group (reading sequentially in middle of work file) while defining another do group (writing sequentially to the end) or while hashing, doing a show procedure, etc (reading from some other point). shared open through two different file variables doesn't work because the reading file FDB eof location doesnt get updated when the writer appends. */ dcl 1 workbuf based(scratch_workp), 2 curfilepos fixed bin(23), /*saved current file position address*/ 2 fileaddr fixed bin(23), /*file address of workrec*/ 2 parent fixed bin(23), /*file address of parent record, decoded from parentclass by workgrab*/ 2 class fixed bin(7), /*decoded from parentclass by workgrab*/ 2 workrec, /*following is what is read from file for a hash record*/ 3 name char(31) varying, 3 parentclass fixed bin(31), /*parent (high order 24 bits), class (low order 8 bits)*/ 3 next fixed bin(23), /*file addr of next record in hash collision list*/ 3 value fixed bin(15); dcl null_fileaddr fixed bin(23) initial(-1) external; dcl workget entry(char(*) varying/*name*/, fixed bin(7)/*class*/, fixed bin(23)/*parent*/, pointer/*to workbuf*/) returns(fixed bin(1)/*whether found*/), worknext entry(char(*) varying/*name*/, fixed bin(7)/*class*/, fixed bin(23)/*parent*/, pointer/*to workbuf*/) returns(fixed bin(1)/*whether found*/), workgrab entry(fixed bin(23)/*file address*/, pointer/*to workbuf*/), workput entry(char(*) varying/*name*/, fixed bin(7)/*class*/, fixed bin(23)/*parent*/), workread entry(char(*) varying/*string*/, pointer/*to workbuf*/), workwrite entry(char(*) varying/*string*/), workswitch entry(pointer/*to workbuf*/), workpos entry(fixed bin(23)/*file address*/, pointer/*to workbuf*/), workhash entry(char(*) varying/*name*/) returns(fixed bin(15)/*subscript in work_index*/), posfile entry(file, fixed bin(23)/*file address*/), /*note: read_symbol declares independently*/ current_fileaddr entry(file) returns(fixed bin(23)/*file address*/);