MODULE ALPHA_DSTRECRDS; {---------------------------------------------------------------------- { { ALPHA_DSTRECRDS -- Definition File for the Alpha Debug Symbol Table { { IMPORTANT: YOU MUST UPDATE THE DST VERSION NUMBER ANYTIME YOU CHANGE { SOMETHING IN THIS FILE. SEE THE COMMENTS AROUND THE VERSION NUMBER CODE { FOR MORE INFORMATION. { {---------------------------------------------------------------------- {**************************************************************************** {* * {* COPYRIGHT (c) 1991, 1993, 1994, 1995, 1996, 1997, 1998 BY * {* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. * {* ALL RIGHTS RESERVED. * {* * {* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * {* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * {* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * {* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * {* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * {* TRANSFERRED. * {* * {* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * {* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * {* CORPORATION. * {* * {* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * {* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * {* * {**************************************************************************** { { { WRITTEN BY { Bruce Olsen August, 1980. { Bert Beander August, 1981. { Bert Beander November, 1983. { Edward Freedman April, 1985. { Ken Moreau May, 1985. { Rich Title May, 1986 { Alan H. Martin/AHM { Jeff Diewald January, 1991. (Conversion to SDL) { Jeff E. Nelson/JEN June, 1991. { Mark Arsenault { { MODULE FUNCTION { This REQUIRE file describes the structure of the Debug Symbol Table { generated by the Alpha compilers and interpreted by the VMS Debugger. { It includes definitions for all field names and literals used in { building or interpreting the Debug Symbol Table (DST). { { DISCLAIMER { This interface is not supported by Digital. While the Debug Symbol { Table interface is believed to be correctly described here, Digital { does not guarantee that all descriptions in this definition file are { correct and complete. Also, while this interface is expected to be { reasonably stable across releases, Digital cannot guarantee that it { will not change in future releases of VMS Debug, VMS, the Alpha { compilers, or other software. Upward-compatible additions to this { interface are more likely than incompatible changes, but individuals { and organizations who use this interface stand some risk that their { work will be partially or wholly invalidated by future releases of { VAX DEBUG or other Digital software. Digital reserves the right to { make future incompatible changes to the Debug Symbol Table interface. { { T A B L E O F C O N T E N T S { { { { Purpose of the Debug Symbol Table . . . . . . . . . . . . . . 7 { { General Structure of the DST . . . . . . . . . . . . . . . . 8 { Generation of the DST . . . . . . . . . . . . . . . . . . 8 { Location of the DST within the Image File . . . . . . . . 10 { Overall Structure of the DST . . . . . . . . . . . . . . 12 { Nesting within the DST . . . . . . . . . . . . . . . . . 12 { Data Representation in the DST . . . . . . . . . . . . . 16 { { Field Access Macros . . . . . . . . . . . . . . . . . . . . . 19 { { Debug Module Table (DMT) definition . . . . . . . . . . . . . ?? { { The DST Record Header Format . . . . . . . . . . . . . . . . 20 { { Supported Values for DST$W_TYPE . . . . . . . . . . . . . . . 21 { VAX Standard Type Codes . . . . . . . . . . . . . . . . . 21 { Internal Type Codes for DEBUG . . . . . . . . . . . . . . 22 { Other DST Type Codes . . . . . . . . . . . . . . . . . . 23 { { Module DST Records . . . . . . . . . . . . . . . . . . . . . 26 { The Module Begin DST Record . . . . . . . . . . . . . . . 27 { The Module End DST Record . . . . . . . . . . . . . . . . 30 { { Routine DST Records . . . . . . . . . . . . . . . . . . . . . 31 { The Routine Begin DST Record . . . . . . . . . . . . . . 32 { The Routine End DST Record . . . . . . . . . . . . . . . 33 { { Lexical Block DST Records . . . . . . . . . . . . . . . . . . 40 { The Block Begin DST Record . . . . . . . . . . . . . . . 41 { The Block End DST Record . . . . . . . . . . . . . . . . 42 { { Package DST Records . . . . . . . . . . . . . . . . . . . . . 43 { The Package Spec Begin DST Record . . . . . . . . . . . . 44 { The Package Spec End DST Record . . . . . . . . . . . . . 46 { The Package Body Begin DST Record . . . . . . . . . . . . 47 { The Package Body End DST Record . . . . . . . . . . . . . 49 { { Record Structure DST Records . . . . . . . . . . . . . . . . 50 { The Record Begin DST Record . . . . . . . . . . . . . . . 52 { The Record End DST Record . . . . . . . . . . . . . . . . 53 { The Variant Set Begin DST Record . . . . . . . . . . . . 54 { The Variant Value DST Record . . . . . . . . . . . . . . 55 { Tag Value Range Specifications . . . . . . . . . . . . . 56 { The Variant Set End DST Record . . . . . . . . . . . . . 58 { { { Data Symbol DST Records . . . . . . . . . . . . . . . . . . . 59 { The Standard Data DST Record . . . . . . . . . . . . . . 61 { The Descriptor Format DST Record . . . . . . . . . . . . 65 { The Trailing Value Specification DST Record . . . . . . . 67 { The Separate Type Specification DST Record . . . . . . . 69 { { DST Value Specifications . . . . . . . . . . . . . . . . . . 70 { Standard Value Specifications . . . . . . . . . . . . . . 70 { Descriptor Value Specifications . . . . . . . . . . . . . 74 { Trailing Value Spec Value Specifications . . . . . . . . 75 { VS-Follows Value Specifications . . . . . . . . . . . . . 76 { Split Lifetime Value Specifications . . . . . . . . . . . 77 { DST Binding Specifications . . . . . . . . . . . . . . . . 78 { Calls on Compiler-Generated Thunks . . . . . . . . . . . 79 { Biased Value Specifications . . . . . . . . . . . . . . . ? { Encoded Value Specifications . . . . . . . . . . . . . . . ? { The DST Stack Machine . . . . . . . . . . . . . . . . . . 80 { Extended Value Specifications . . . . . . . . . . . . . . ? { { { Type Specification DST Records . . . . . . . . . . . . . . . 86 { { DST Type Specifications . . . . . . . . . . . . . . . . . . . 87 { Atomic Type Specifications . . . . . . . . . . . . . . . 91 { Descriptor Type Specifications . . . . . . . . . . . . . 91 { ADA Descriptor Type Specifications . . . . . . . . . . . . 92 { Indirect Type Specifications . . . . . . . . . . . . . . 93 { Cross-module Indirect Type Spec . . . . . . . . . . . . . 94 { Typed Pointer Type Specifications . . . . . . . . . . . . 95 { Pointer Type Specifications . . . . . . . . . . . . . . . 95 { Picture Type Specifications . . . . . . . . . . . . . . . 97 { Array Type Specifications . . . . . . . . . . . . . . . . 99 { ADA Array Type Specifications . . . . . . . . . . . . . . 101 { Set Type Specifications . . . . . . . . . . . . . . . . . 103 { Subrange Type Specifications . . . . . . . . . . . . . . 104 { File Type Specifications . . . . . . . . . . . . . . . . 105 { Area Type Specifications . . . . . . . . . . . . . . . . 106 { Offset Type Specifications . . . . . . . . . . . . . . . 107 { Novel Length Type Specifications . . . . . . . . . . . . 108 { Self-Relative Label Type Specifications . . . . . . . . . 110 { Task Type Specifications . . . . . . . . . . . . . . . . 110 { Constrained Record Type Specifications . . . . . . . . . . 111 { Might-Be-Constrained Record Type Specifications . . . . . 113 { Scan Tree Type Specifications . . . . . . . . . . . . . . 114 { Scan Treeptr Type Specifications . . . . . . . . . . . . . 116 { Incomplete Type Specifications . . . . . . . . . . . . . . 117 { BLISS Block Type Specifications . . . . . . . . . . . . . 118 { { Enumeration Type DST Records . . . . . . . . . . . . . . . . 119 { The Enumeration Type Begin DST Record . . . . . . . . . . 120 { The Enumeration Type Element DST Record . . . . . . . . . 121 { The Enumeration Type End DST Record . . . . . . . . . . . 121 { { BLISS Field DST Records { BLISS Field Set Begin DST Record . . . . . . . . . . . . . 122 { BLISS Field Set End DST Record . . . . . . . . . . . . . . 122 { The BLISS Field DST Record . . . . . . . . . . . . . . . 123 { { BLISS Data DST Records . . . . . . . . . . . . . . . . . . . 125 { { { Image DST Records . . . . . . . . . . . . . . . . . . . . . . 130 { { The PSECT DST Record . . . . . . . . . . . . . . . . . . . . 131 { { Label DST Records . . . . . . . . . . . . . . . . . . . . . . 133 { The Label DST Record . . . . . . . . . . . . . . . . . . 133 { The Label-or-Literal DST Record . . . . . . . . . . . . . 134 { { The Entry Point DST Record . . . . . . . . . . . . . . . . . 135 { { Line Number PC-Correlation DST Records . . . . . . . . . . . . 136 { Line Number PC-Correlation Commands . . . . . . . . . . . 137 { PC-Correlation Command Semantics . . . . . . . . . . . . . 139 { { Source File Correlation DST Records . . . . . . . . . . . . . 146 { Declare Source File . . . . . . . . . . . . . . . . . . . 150 { Set Source File . . . . . . . . . . . . . . . . . . . . . 152 { Set Source Record Number Long . . . . . . . . . . . . . . 152 { Set Source Record Number Word . . . . . . . . . . . . . . 153 { Set Line Number Long . . . . . . . . . . . . . . . . . . . 153 { Set Line Number Word . . . . . . . . . . . . . . . . . . . 154 { Increment Line Number Byte . . . . . . . . . . . . . . . 154 { Count Form-Feeds as Source Records . . . . . . . . . . . 155 { Define N Lines Word . . . . . . . . . . . . . . . . . . . 156 { Define N Lines Byte . . . . . . . . . . . . . . . . . . . 156 { { Continuation DST Records . . . . . . . . . . . . . . . . . . . 157 { { Goto and Target DST Records . . . . . . . . . . . . . . . . . 159 { { Fixup DST Records . . . . . . . . . . . . . . . . . . . . . 161 { { { The Overloaded Symbol DST Record . . . . . . . . . . . . . . . 163 { { The Inlined Routine DST Record . . . . . . . . . . . . . . . . 165 { { The ADA Subunit DST Record . . . . . . . . . . . . . . . . . . 167 { { The ADA With Clause DST Record . . . . . . . . . . . . . . . . 170 { { The ADA Use Clause DST Record . . . . . . . . . . . . . . . . 172 { { The ADA Package Real Name DST Record . . . . . . . . . . . . . 174 { { The ADA Package-Body Spec DST Record . . . . . . . . . . . . . 175 { { The Alias DST Record . . . . . . . . . . . . . . . . . . . . . 177 { { Fulfills Type DST Record . . . . . . . . . . . . . . . . . . . 178 { { The Definition Line Number DST Record . . . . . . . . . . . . 180 { { The Static Link DST Record . . . . . . . . . . . . . . . . . . 181 { { The Prolog DST Record . . . . . . . . . . . . . . . . . . . . 182 { { The Epilog DST Record . . . . . . . . . . . . . . . . . . . . ??? { { The Return DST Record . . . . . . . . . . . . . . . . . . . . ??? { { The Version Number DST Record . . . . . . . . . . . . . . . . 183 { { The COBOL Global Attribute DST Record . . . . . . . . . . . . 184 { { Register DST Records . . . . . . . . . . . . . . . . . . . . . ??? { The Register Save Begin DST Record . . . . . . . . . . . . ??? { The Register Save DST Record . . . . . . . . . . . . . . . ??? { The Register Save End DST Record . . . . . . . . . . . . . ??? { { The Exception DST Record . . . . . . . . . . . . . . . . . . . ??? { { C++ Support { Base Classs { Virtual Functions { Type Signatures { C++ Attributes { Template Declarations { Namespace Support -- Using DSTs { { Obsolete DST Records . . . . . . . . . . . . . . . . . . . . . 185 { The Global-Is-Next DST Record . . . . . . . . . . . . . . { The External-Is-Next DST Record . . . . . . . . . . . . . { The Threaded-Code PC-Correlation DST Record . . . . . . . { The COBOL Hack DST Record . . . . . . . . . . . . . . . . { The Value Specification DST Record . . . . . . . . . . . . { { DST Record Declaration Macro . . . . . . . . . . . . . . . . 189 { { P U R P O S E O F T H E D E B U G S Y M B O L T A B L E { { { { The Debug Symbol Table (DST) is the symbol table that the VAX compilers { produce to pass symbol table information to the VAX Debugger and to the { VAX Traceback facility. The DST is a language-independent symbol table { in the sense that all VAX compilers output symbol information in the { same format, regardless of source language. This symbol information is { emitted into the object modules produced by the compiler. It is then { passed through the linker into the executable image file that the linker { generates. DEBUG or TRACEBACK can then retrieve the symbol information { from the image file. { { The purpose of the Debug Symbol Table is thus to permit the Traceback { facility to give a symbolic stack dump on abnormal program termination { and to permit DEBUG to support fully symbolic debugging. Other Digital { software may also use the DST information for various purposes. { { To support these purposes, the Debug Symbol Table represents all major { aspects of program structure and data representation. It can represent { modules, routines, lexical blocks, labels, and data symbols and it can { represent all nesting relationships between such symbols. It can also { describe line number and source line information. It can describe all { data types supported by DEBUG, including complex types such as record { structures and enumeration types. In addition, it can describe arbi- { trarily complex value and address computations. { { The Debug Symbol Table is solely intended to support compiled languages, { not interpreted languages. The DST representation assumes that source { lines have been compiled into VAX instructions and that those instruc- { tions are actually executed, not interpreted. Such DEBUG facilities as { breakpoints and single-stepping will not work if this assumption is { violated. Similarly, it is assumed that data objects have addresses { that can be accessed directly when these objects are examined or depo- { sited into. DST information is thus generated by all compilers that { VAX DEBUG supports, but not by the interpreters for languages such as { APL or MUMPS. { { G E N E R A L S T R U C T U R E O F T H E D S T { { { { This section describes the general structure of the Debug Symbol Table. { It explains how the DST is generated by the various VAX compilers, how { it is passed along to the executable image file by the linker, and how { it is accessed in the image file by DEBUG or TRACEBACK. This section { also describes in general terms how the DST is structured internally: { how it is subdivided into modules, routines, lexical blocks, and indi- { vidual symbols, how nesting relationships are represented, and how data { symbols, including their values and data types, are represented. The { exact formats of the various Debug Symbol Table records and other fine- { grained detail are described later in this definition file, not here, { but the coarse structure of the DST and how that structure is accessed { are outlined in this section. { { { { GENERATION OF THE DST { { { The Debug Symbol Table (DST) is generated by the compilers for all VAX { languages supported by DEBUG. During compilation, the compiler outputs { the DST for the module being compiled into the corresponding object { file. When the linker is invoked, it does relocation and global-symbol { resolution on the DST text and then outputs it into the executable image { file. Beyond knowing what must be relocated, the linker has no special { knowledge of the format or contents of the DST. Finally, the Debugger { reads the DST information from the executable image file during a debug- { ging session, or Traceback reads it when giving a traceback in response { to an unhandled severe exception during image execution. { { A compiler outputs DST information in the form of two kinds of object { records, TBT records and DBT records. (See the linker manual for a { full description of the VAX object language accepted by the linker.) { All "traceback" information goes into the TBT records and all "symbol" { information goes into the DBT records. When the user later links using { the plain LINK command, only the DST information in the TBT records are { copied to the executable image file. These records contain enough in- { formation for Traceback to give a call-stack traceback. If the user { links with the LINK/DEBUG command, all information in both the TBT and { the DBT records are copied to the executable image file. These records { together give all DST information needed for full symbolic debugging. { The user can also link with LINK/NOTRACEBACK, in which case no DST in- { formation at all is copied to the executable image file. { { It is not possible to have the linker copy the DBT records without also { copying the TBT records; the information in the TBT records is required { for the information in the DBT records to make sense. { { The "traceback" information in the TBT records includes all Module Begin { and End DST records, all Routine Begin and End DST records, all Lexical { Block Begin and End DST records, and all Line Number PC-Correlation DST { records. It may also include Version Number DST records. All other DST { records should be included in DBT records. { { Most VAX compilers have a /DEBUG qualifier which in its most general { form has two subqualifiers: /DEBUG=([NO]TRACEBACK,[NO]SYMBOLS). The { unadorned /DEBUG qualifier is equivalent to /DEBUG=(TRACEBACK,SYMBOLS); { it causes all DST information to be output. /DEBUG=TRACEBACK causes { only the traceback information (the TBT records) to be output by the { compiler. /DEBUG=(NOTRACE,NOSYMBOL) causes no DST information to be { output at all. Finally, /DEBUG=(NOTRACE,SYMBOLS) causes all DST infor- { mation except Line Number PC-Correlation DST records to be output (this { combination is largely pointless although it saves some DST space). { Note that the module, routine, and lexical block information, which { counts as traceback information, must be output if any symbol informa- { tion is output since it defines the scopes within which other symbols { are defined. { { When the linker outputs the Debug Symbol Table to the executable image { file, it may also output two more image sections: the Global Symbol { Table (GST) and the Debug Module Table (DMT). These two tables are { generated if the LINK/DEBUG command is used, not otherwise. The Global { Symbol Table contains records for all global symbols known to the linker { in the current user program. DEBUG uses the GST as a symbol table of { last resort when DST information is not available, either because the { module containing some global symbol was compiled without DST informa- { tion being output or because the module is not set (with SET MODULE) in { the current debugging session. The GST information is not as complete { as the DST information for the same symbols because the GST has no type { description (the linker does not need to know about data types). { { The Debug Module Table (DMT) is an indexing structure for the DST. It { contains one record for each module in the DST. This record contains { a pointer to the start of the DST for the corresponding module, the size { of the DST for that module, the number of PSECTs in that module, and the { address ranges of all those PSECTs. The DMT allows DEBUG to initialize { its Module Table and its Static Address Table without actually having to { read through the entire DST; because the DMT is very small compared to { the DST, it can be scanned much more efficiently. { { The details of how the DST, the GST, and the DMT are accessed in the { executable image file are explained in the next section. { { LOCATION OF THE DST WITHIN THE IMAGE FILE { { { The Debug Symbol Table is accessed through pointer information found in { the executable image file header block. This header block contains a { pointer in a fixed location (IHD$W_SYMDBGOFF) which points to a small { block later in the header which gives the size and location of the { Debug Symbol Table (DST), the Global Symbol Table (GST), and the Debug { Module Table (DMT). The first part of the executable image file header { looks as follows: { { { +---------------------------------------------------------------+ { long | | { +-------------------------------+-------------------------------+ { long | | IHD$W_SYMDBGOFF | { +-------------------------------+-------------------------------+ { long | | { | | { .. | | { +---------------------------------------------------------------+ { { { { Here IHD$W_SYMDBGOFF contains the byte offset relative to the start of { the header of an Image Header Symbol Table Descriptor. The Image Header { Symbol Table Descriptor (IHS) in turn has the following format: { { { +---------------------------------------------------------------+ { long | IHS$L_DSTVBN | { +---------------------------------------------------------------+ { long | IHS$L_GSTVBN | { +-------------------------------+-------------------------------+ { long | IHS$W_GSTRECS | IHS$W_DSTBLKS | { +-------------------------------+-------------------------------+ { long | IHS$L_DMTVBN | { +---------------------------------------------------------------+ { long | IHS$L_DMTBYTES | { +---------------------------------------------------------------+ { long | IHS$L_DSTBLKS | { +---------------------------------------------------------------+ { long | IHS$L_GSTRECS | { +---------------------------------------------------------------+ { { { { Here IHS$W_DSTBLKS and IHS$L_DSTVBN give the size (in blocks) and loca- { tion (Virtual Block Number) of the Debug Symbol Table (DST) within the { executable image file. The fields IHS$W_GSTRECS and IHS$L_GSTVBN give { the size (in GST records) and start location (Virtual Block Number) of { the Global Symbol Table (GST). Finally, the fields IHS$L_DMTBYTES and { IHS$L_DMTVBN give the size (in bytes) and start location (Virtual Block { Number) of the Debug Module Table (DMT). The DMT is described below. { These field names are declared by macros in SYS$LIBRARY:LIB.L32. The { symbol IHD$W_SYMDBGOFF is also defined in SYS$LIBRARY:LIB.L32. { { IHS$L_DSTBLKS gives the (longword) size (in blocks) of the Debug Symbol { Table (DST). This field must be used, rather than IHS$W_DSTBLKS, when { the IHD$V_IHSLONG (located in SYS$LIBRARY:LIB.L32) flag is set. Note { that if IHD$V_IHSLONG is set, IHS$W_DSTBLKS will still contain a value { for the purposes of backwards compatibility. However, this value is { corrupt -- it is the truncated value contained in IHS$L_DSTBLKS. { { IHS$L_GSTRECS gives the (longword) size (in GST records ) of the Debug { Symbol Table (DST). This field must be used, rather than IHS$W_GSTRECS, { when the IHD$V_IHSLONG (located in SYS$LIBRARY:LIB.L32) flag is set. { Note that if IHD$V_IHSLONG is set, IHS$W_GSTRECS will still contain a { value for the purposes of backwards compatibility. However, this value { is corrupt -- it is the truncated value contained in IHS$L_GSTRECS. { { Pointers to the Image Header and the Image Header Symbol Table Descrip- { tor are declared as follows: { { IHDPTR: REF BLOCK[,BYTE] { IHSPTR: REF BLOCK[IHS$K_LENGTH,BYTE] { { The Image File Header in an executable image file points to the Image { Header Symbol Table descriptor as described above. If bit 5 of field { IHD$L_LNKFLAGS in the image header is set, this is a "new" image, i.e. { one produced by the VMS V4.0 or later linker, and the IHS$L_DMTVBN and { IHS$L_DMTBYTES fields exist in the Image Header Symbol Table descriptor. { (If bit 5 is not set, this is an "old" image and those fields do not { exist.) If non-zero, IHS$L_DMTVBN gives the Virtual Block Number in { the image file of the Debug Module Table (the DMT). IHS$L_DMTBYTES { then gives the size of the DMT in bytes. The DMT is only built if the { user did a LINK/DEBUG; if he did not, IHS$L_DMTVBN and IHS$L_DMTBYTES { are zero. { { The Debug Module Table contains one entry per module in the Debug { Symbol Table (the DST). This is the format of each such DMT entry: { { { +---------------------------------------------------------------+ { long | DST address of Module Begin DST Record | { +---------------------------------------------------------------+ { long | Size in bytes of module's DST | { +-------------------------------+-------------------------------+ { long | Unused--Must Be Zero | Number of PSECTs for module | { +-------------------------------+-------------------------------+ { long | Start address of first PSECT in module | { +---------------------------------------------------------------+ { long | Length of first PSECT in module in bytes | { +---------------------------------------------------------------+ { .. | | { | | { .. | (Two longwords per PSECT) | { | | { .. | | { +---------------------------------------------------------------+ { long | Start address of last PSECT in module | { +---------------------------------------------------------------+ { long | Length of last PSECT in module in bytes | { +---------------------------------------------------------------+ { { { { Longword 0 gives the address relative to the start of the DST of the { Module Begin DST Record for this module. Longword 1 gives the size { of the DST in bytes for the same module. Longword 2 gives the number { of PSECTs in the module (i.e., the number of statically allocated { program sections), and this is followed by that number of two-longword { pairs which give the start address and length (in bytes) of each such { PSECT. Since the number of PSECTs cannot exceed 65K, the upper two { bytes of longword 2 are available for future expansion. { { The DMT is used during DEBUG initialization to initialize DEBUG's Run- { Time Symbol Table (RST) and Program Static Address Table (Program SAT). { Using the DMT is much faster than the alternative procedure, namely { reading through the entire DST to pick up the needed information. The { information in the DMT entry is enough to build a Module RST Entry for { each module in the DST and the PSECT information is used to build the { Program SAT. The amount of RST symbol table space needed per module is { not computable from the DMT information, but is estimated by multiplying { the DST size of each module by an appropriate scale factor. { { { OVERALL STRUCTURE OF THE DST { { { The Debug Symbol Table consists of a contiguous sequence of DST records. { Each DST record contains a two-byte header which gives the length of the { record in bytes and the type of the record. The structure of the rest { of the record (if any) is determined by the record type. The length of { the DST in 512-byte blocks is given in the image file header; if the DST { does not fill the last block, that block is zero-padded to the end. { { The largest structural unit within the DST is the module. Each module { represents the symbol table information of a separately compiled object { module. The DST for a module always begins with a Module Begin DST rec- { ord and ends with a Module End DST record. The Module Begin DST record { gives the name of the module and the source language in which it was { written. The Module End DST record simply marks the end of the module { and contains no other information. As noted above, if present, the { Debug Module Table (DMT) points to the Module Begin DST record of each { module represented in the DST. DEBUG uses the DMT (if present) to lo- { cate all modules in the DST. { { The DST as a whole thus always begins with the Module Begin DST record { for the first module in the DST. It is followed by the symbol informa- { tion for that module. Then comes the Module End DST record for that { module. Immediately after that Module End DST record comes the Module { Begin DST record for the next module, and so on to the end of the whole { DST, where the Module End DST record for the last module is found. The { final thing in the DST (after the final Module End) is a sequence of { Fixup DST Records which are used to fix up addresses in the DST that { are relative to the base of some shareable image. After any Fixup DSTs, { the rest of the last image file block is zero-filled to the next block { boundary. Note that there is no break between modules in the DST. { { { { NESTING WITHIN THE DST { { { For most languages, the symbol table must represent a variety of nesting { relationships. Routines are nested within modules, data symbols are { declared within routines, and even routines are nested within routines. { Certain data constructs, in particular record structures, contain addi- { tional nesting relationships. In the Debug Symbol Table, such nesting { relationships are represented by Begin-End pairs of DST records. We { have already seen above that the largest subunit of the DST, namely the { module, is represented by a Module Begin DST record and a Module End DST { record bracketting the DST information for the module. { { This principle extends to other nesting relationships. The DST informa- { tion for a routine is thus represented by a Routine Begin DST record and { a Routine End DST record enclosing the DST information for all symbols { local to or nested within that routine. Similarly, lexical blocks (such { as BEGIN-END blocks or their equivalents in various languages) are re- { presented by Block Begin and Block End DST records enclosing the symbol { DST records local to that lexical block. The nesting of routines and { blocks within one another to any depth (within reason) is represented by { the proper nesting of the corresponding Begin and End DST records. { { An example may help clarify this notion. The following example shows a { program in a fictitious language along the corresponding sequence of DST { records: { { { Program Structure DST Record Sequence { ----------------- ------------------- { { MODULE M = Module Begin M { BEGIN { VAR SYM_M1: INTEGER; Data SYM_M1 (DTYPE_L) { VAR SYM_M2: REAL; Data SYM_M2 (DTYPE_F) { { ROUTINE R1 = Routine Begin R1 { BEGIN { VAR SYM_R11: BOOLEAN; Data SYM_R11 (BOOLEAN) { VAR SYM_R12: INTEGER; Data SYM_R12 (DTYPE_L) { END; Routine End (for R1) { { ROUTINE R2 = Routine Begin R2 { BEGIN { VAR SYM_R21: DOUBLE; Data SYM_R21 (DTYPE_D) { VAR SYM_R22: INTEGER; Data SYM_R22 (DTYPE_L) { ROUTINE R2A = Routine Begin R2A { BEGIN { VAR SYM_R2A: BYTE; Data SYM_R2A (DTYPE_B) { BEGIN Block Begin (no name) { VAR BLK_V1: WORD; Data BLK_V1 (DTYPE_W) { ROUTINE R2BLKR = Routine Begin R2BLKR { BEGIN { FOO:BEGIN Block Begin FOO { VAR FOO_V:REAL; Data FOO_V (DTYPE_F) { END; Block End (for FOO) { { VAR R2BLK_V2:REAL; Data R2BLK_V2 (DTYPE_F) { END; Routine End (for R2BLKR) { { VAR BLK_V2: DOUBLE; Data BLK_V2 (DTYPE_D) { END; Block End (for no name) { { END; Routine End (for R2A) { { VAR SYM_R23: REAL; Data SYM_R23 (DTYPE_F) { END; Routine End (for R2) { { END; Module End { { { Here module (compilation unit) M contains two module-level data items, { SYM_M1 and SYM_M2, and two routines, R1 and R2. Routine R2 in turn con- { tains several local data symbols (SYM_R21, SYM_R22, and SYM_R23) and a { nested routine R2A. R2A in turn contains an anonymous BEGIN-END block, { that blocks contains two local data symbols BLK_V1 and BLK_V2 and a { local routine R2BLKR, local routine R2BLKR contains a data symbol and a { labelled BEGIN-END block FOO, and block FOO contains one local symbol, { FOO_V. All this nesting is represented by Begin and End DST records in { the Debug Symbol Table as illustrated on the right. { { Additional nesting must be represented for data. A record (called a { structure in some languages) is a composite data object containing some { number of record components of various data types. A record component { may itself be a record. In addition, some languages allow records to { have "variants" (as in PASCAL), which imposes additional structure that { must be represented in the DST. { { A record type is represented by a Record Begin and Record End DST record { pair bracketting the DST records for the record components. This notion { is illustrated by this program segment and the corresponding DST: { { { Program Structure DST Record Sequence { ----------------- ------------------- { { TYPE RECTYP = Record Begin (RECTYP) { RECORD OF { COMP1: INTEGER; Data COMP1 (DTYPE_L) { COMP2: REAL; Data COMP2 (DTYPE_F) { COMP3: DOUBLE; Data COMP3 (DTYPE_D) { END; Record End (for RECTYP) { { { Here RECTYP is a record type. Each object of this type is a record con- { taining three components, COMP1, COMP2, and COMP3. This structure is { represented in the DST by a Record Begin DST record followed by Data DST { records for the components followed by a Record End DST record. The { addresses specified in the component DST records are bit or byte offsets { from the start of the RECTYP record as a whole. { { In this example, the Record Begin DST record for RECTYP may in fact re- { present either a record type or a record object. A field in the Record { Begin DST record indicates which. However, let us assume that RECTYP { defines a record type. How do we then declare objects of that type? { The following example illustrates how: { { { Program Structure DST Record Sequence { ----------------- ------------------- { { Data REC1 (SepTypSpec) { TYPE RECTYP = Record Begin (RECTYP) { RECORD OF { COMP1: INTEGER; Data COMP1 (DTYPE_L) { COMP2: REAL; Data COMP2 (DTYPE_F) { COMP3: DOUBLE; Data COMP3 (DTYPE_D) { END; Record End (for RECTYP) { { VAR REC1: RECTYP; { VAR REC2: RECTYP; Data REC2 (SepTypSpec) { Type Spec DST record { (Indirect Type Spec { pointing to RECTYP) { { { Here the same record type RECTYP is defined. Two objects of that type { are also defined, REC1 and REC2. Both data objects are represented by { Separate Type Specification DST records. Such a DST record must be im- { mediately followed by a DST record that defines the symbol's data type. { The REC1 Separate Type Specification DST record is immediately followed { by the RECTYP Record Begin DST record; hence REC1 is of the RECTYP data { type. The REC2 Separate Type Specification DST record is immediately { followed by a Type Specification DST record. This record contains an { Indirect Type Specification that points back to the Record Begin DST { record for RECTYP. Hence REC2 is also of that record type. { { Records may be nested in the sense that a record component may itself be { an object of some record type. A record component of a record type is { represented the same way as any other object of a record type, namely by { a Separate Type Specification DST record. This record must be followed { by a Record Begin DST record or by a Type Specification DST record that { points to a Record Begin DST record. The record component can also be { represented by a Record Begin DST record directly if this record is { marked as defining an object rather than a type. { { Record variants, as found in PASCAL, introduce additional structure. A { detailed description of how variants are represented in the DST is found { in the section on "Record Structure DST Records" later in this defini- { tion file. Here we will only give an example that illustrates the gene- { ral scheme that is used: { { { Program Structure DST Record Sequence { ----------------- ------------------- { { Data REC1 (SepTypSpec) { TYPE RECTYP = Record Begin (RECTYP) { RECORD OF { COMP1: INTEGER; Data COMP1 (DTYPE_L) { CASE TAG: BOOLEAN OF Data TAG (BOOLEAN) { Variant Set Begin { (tag variable = TAG) { FALSE: ( Variant Value for FALSE { COMP2: REAL; Data COMP2 (DTYPE_F) { COMP3: DOUBLE); Data COMP3 (DTYPE_D) { { TRUE: ( Variant Value for TRUE { COMP4: INTEGER); Data COMP4 (DTYPE_L) { { END CASE; Variant Set End { { END; Record End (for RECTYP) { { VAR REC1: RECTYP; { { { Nesting is also used to describe enumeration types as found in PASCAL { and some other languages. An enumeration type is described by an Enum- { eration Type Begin DST record followed by Enumeration Type Element DST { records for all the enumeration literals of the type followed by an { Enumeration Type End DST record. Any actual object of the enumeration { type must be described by a Separate Type Specification DST record. { This example illustrates what the DST for an enumeration type looks { like: { { { Program Structure DST Record Sequence { ----------------- ------------------- { { Data HUE (SepTypSpec) { TYPE COLOR = ( Enum Type Begin COLOR { RED, Enum Type Element RED { GREEN, Enum Type Element GREEN { BLUE Enum Type Element BLUE { ); Enum Type End (COLOR) { { VAR HUE: COLOR; { VAR PAINT: COLOR; Data PAINT (SepTypSpec) { Type Spec DST record { (Indirect Type Spec { pointing to COLOR) { { { A more detailed description is found in the section entitled "Enumera- { tion Type DST Records" later in this definition file. { { The ADA language contains a construct called a "package". ADA packages { are another construct that give rise to nesting in the DST. For example, { { ADA program fragment DST { -------------------- --- { { PACKAGE P IS Package Spec Begin "P" { X: INTEGER; Data X { Y: INTEGER; Data Y { END P; Package Spec End { { For more details on DST for ADA packages, see the section entitled { "Package DST Records". { { For some DST record types, DEBUG ignores all nesting relationships below { the module level. Line Number PC-Correlation DST records, for example, { may be scattered throughout the DST for a module. DEBUG treats all such { DST records as defining the line number information for the module as a { whole, regardless of how they may be scattered within or outside the { routines and blocks of the module. Similarly, Source File Correlation { DST records may be scattered throughout the DST for a module. Records { such as these can be generated wherever the compiler finds it most con- { venient to generate them. { { { { DATA REPRESENTATION IN THE DST { { { Data Symbols are described in the DST by a variety of representations. { Fundamentally, all such representations give three pieces of information { about each data symbol: its name, its address or value, and its data { type. DEBUG needs additional information about a data symbol, in parti- { cular its scope of declaration, but that information is implicit in the { nesting structure of the DST as described above. { { The name is given by a Counted ASCII string in the data symbol's DST { record. The value or address can be given by a five-byte encoding con- { taining one byte of control information and a longword address, offset, { or value. However, if this five-byte encoding is not adequate to de- { scribe the address or value, escapes to a more complex value specifica- { tion later in the DST record are available. The data type may be repre- { sented by a one-byte type code, but if that is not adequate there are { several escapes to a more complex type description elsewhere in the DST. { { The standard five-byte value specification can specify any VAX 32-bit { or smaller literal value, any VAX static byte address, any VAX { register address, and any VAX address that is formed by one indexing { operation off a register or one indirection or both. On Alpha, the { standard five-byte value specification can do all of the above with the { exception that register indexing and indirection is limited to { registers R16 through R31. { { If a VAX Standard Descriptor exists for the symbol in user memory, the { five-byte encoding can describe the descriptor address by any of the { above means; the actual data address is then retrieved from the { descriptor. { { The standard five-byte value specification is adequate for the bulk of { all data symbols. However, there are cases when it is inadequate. It { cannot describe literal values longer than 32 bits, it cannot describe { very complex address computations, and it cannot describe bit addresses { unless an appropriate descriptor is available in user memory. For these { cases, the first byte of the five-byte encoding must have one of several { special escape values. The remaining longword then contains (in most { cases) a pointer to a more complex value specification later in the same { DST record. That more complex value specification may consist of a VAX { Standard Descriptor or a "VS-Follows" Value Specification. A VS-Follows { Value Specification can, in the most complex case, contain a routine to { be executed by DEBUG to compute the desired value or address. This rou- { tine may even call compiler-generated thunks when the complexity of the { address computation so requires. { { The details of these more complex value specifications are given in the { section entitled "DST Value Specifications" later in this definition { file. The point being made here is simply that the DST provides a { simple and compact value specification mechanism that is adequate for { all simple cases, but it also provides several escapes to arbitrarily { complex DST Value Specifications. These complex value specifications { are capable of describing all known address and value computations { required by the languages supported by DEBUG. { { Data type specifications are done in a similar way. For all simple, { atomic data types, a single type byte describes the data type of a data { symbol. However, there are several escape mechanisms for more complex { data types. One mechanism is to take the type information from a VAX { Standard Descriptor found either in user memory or in the DST. Another { is to use a Separate Type Specification DST record for the data symbol. { The data type is then described by a second DST record which immediately { follows the Separate Type Specification DST record. This second record { must be a Record Begin DST record (describing a record type), an Enume- { ration Type Begin DST record (describing an enumeration type), or a Type { Specification DST record. A Type Specification DST record can describe { any data type supported by DEBUG. It contains a DST Type Specification { for the data type in question. This Type Specification may be an Indi- { rect Type Specification, pointing to a DST record elsewhere in the DST { that defines the data type. Alternatively, it may describe the desired { data type directly and may be as complex as the data type requires. { { DST Type Specifications are described in a separation section elsewhere { in this definition file. The point being made here is simply that the { simple one-byte type specification is available for simple data types, { but several escapes to arbitrarily complex DST type specifications are { available when the simple type specification is inadequate. { { { { For C, bracket the results in an #ifndef - #endif bracket. { This way, we only define these definitions once, even if the { include file gets included a number of times. { IFLANGUAGE CC; LITERAL; #ifndef DSTRECRDS_H #define DSTRECRDS_H 1 END_LITERAL; END_IFLANGUAGE CC; { { { Debug Module Table (DMT) definition { { { Define the pairs of per-psect info which follow the header of a DMT { entry. { AGGREGATE DBG$DMT_PSECT STRUCTURE TYPEDEF; dbg$l_dmt_psect_start ADDRESS; { Start address of psect within module dbg$l_dmt_psect_length LONGWORD UNSIGNED; { Length of PSECT within module #dbg$dmt_psect_size = :; END; { DBG$DMT_PSECT definition CONSTANT DBG$K_DMT_PSECT_SIZE EQUALS #dbg$dmt_psect_size; { { Define the fixed-size header of a DMT entry { AGGREGATE DBG$DMT_HEADER STRUCTURE TYPEDEF; dbg$l_dmt_modbeg ADDRESS; { Module begin DST { Address of Module Begin DST record, { relative to the start of the DST dbg$l_dmt_dst_size LONGWORD UNSIGNED; { Size in bytes of module's DST dbg$w_dmt_psect_count WORD UNSIGNED; { Number of PSECTs for module dbg$w_dmt_mbz WORD UNSIGNED; { Unused--must be zero #dbg$dmt_header_size = :; END; { DBG$DMT_HEADER definition CONSTANT DBG$K_DMT_HEADER_SIZE EQUALS #dbg$dmt_header_size; { { Define the PSECT base address { IFLANGUAGE BLISSF; LITERAL; MACRO dbg$a_dmt_psect_base = DBG$K_DMT_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { S U P P O R T E D V A L U E S F O R D S T $ B _ T Y P E { { { { All supported values of the DST record type field (DST$W_TYPE) are { listed here. If the value is in the range of 1 To { DBG$K_MAXIMUM_DTYPE, it is a VAX Standard Type Code and gives the { data type of the object being defined. In this case, the record is { a Standard Data DST Record or one of its variants. Otherwise, the { type value must be in the range DST$K_LOWEST to DST$K_HIGHEST or it { may be DST$K_BLI. In these cases, the type code denotes the type of { the DST record and the format of the record is determined by type { value. All other type codes are unsupported by DEBUG. The type codes { between DBG$K_MAXIMUM_DTYPE and DST$K_LOWEST are reserved for future { use by Digital. The type codes in the range 192 - 255 are potentially { reserved for use by customers, although DEBUG does not support any { such type codes. DEBUG ignores all records with unsupported type { codes. { { Define a typedef for the type field. { ITEM DST$DTYPE WORD UNSIGNED TYPEDEF; { { VAX STANDARD TYPE CODES { { { As mentioned above, VAX Standard Type Codes can be used as DST record { type codes for data symbols. The type code then gives the data type { of the symbol in addition to indicating that the DST record has the { Standard Data DST record format or a variant thereof. { { { { All VAX Standard Type Codes are listed here for convenience. They are { commented out since they are actually declared in STARLET.REQ. { {LITERAL { DSC$K_DTYPE_Z = 0, { Unspecified (May not appear in DST). { DSC$K_DTYPE_V = 1, { Bit. { DSC$K_DTYPE_BU = 2, { Byte logical. { DSC$K_DTYPE_WU = 3, { Word logical. { DSC$K_DTYPE_LU = 4, { Longword logical. { DSC$K_DTYPE_QU = 5, { Quadword logical. { DSC$K_DTYPE_B = 6, { Byte integer. { DSC$K_DTYPE_W = 7, { Word integer. { DSC$K_DTYPE_L = 8, { Longword integer. { DSC$K_DTYPE_Q = 9, { Quadword integer. { DSC$K_DTYPE_F = 10, { Single-precision floating. { DSC$K_DTYPE_D = 11, { Double-precision floating. { DSC$K_DTYPE_FC = 12, { Complex. { DSC$K_DTYPE_DC = 13, { Double-precision Complex. { DSC$K_DTYPE_T = 14, { ASCII text string. { DSC$K_DTYPE_NU = 15, { Numeric string, unsigned. { DSC$K_DTYPE_NL = 16, { Numeric string, left separate sign. { DSC$K_DTYPE_NLO = 17, { Numeric string, left overpunched sign. { DSC$K_DTYPE_NR = 18, { Numeric string, right separate sign. { DSC$K_DTYPE_NRO = 19, { Numeric string, right overpunched sign { DSC$K_DTYPE_NZ = 20, { Numeric string, zoned sign. { DSC$K_DTYPE_P = 21, { Packed decimal string. { DSC$K_DTYPE_ZI = 22, { Sequence of instructions. { DSC$K_DTYPE_ZEM = 23, { Procedure entry mask. { DSC$K_DTYPE_DSC = 24, { Descriptor, used for arrays of { { dynamic strings { DSC$K_DTYPE_OU = 25, { Octaword logical { DSC$K_DTYPE_O = 26, { Octaword integer { DSC$K_DTYPE_G = 27, { Double precision G floating, 64 bit { DSC$K_DTYPE_H = 28, { Quadruple precision floating, 128 bit { DSC$K_DTYPE_GC = 29, { Double precision complex, G floating { DSC$K_DTYPE_HC = 30, { Quadruple precision complex, H floating { DSC$K_DTYPE_CIT = 31, { COBOL intermediate temporary { DSC$K_DTYPE_BPV = 32, { Bound Procedure Value { DSC$K_DTYPE_BLV = 33, { Bound Label Value { DSC$K_DTYPE_VU = 34, { Bit Unaligned { DSC$K_DTYPE_ADT = 35, { Absolute Date-Time { = 36, { Unused (not supported by DEBUG) { DSC$K_DTYPE_VT = 37, { Varying Text { DSC$K_DTYPE_T2 = 38, { 16-bit char { DSC$K_DTYPE_VT2 = 39, { 16-bit varying char { { { The next two values are used for range checking of the type values { in DST entries. They are used mainly in CASE statements. { CONSTANT DSC$K_DTYPE_LOWEST EQUALS 1; { Lowest DTYPE data type we support CONSTANT DSC$K_DTYPE_HIGHEST EQUALS 39; { Highest DTYPE data type we support { EXTENDED TYPE CODES FOR DEBUG { { { The following definitions are our own extensions to the VAX standard { type codes. These may also be generated in the DST and are treated { by DEBUG the same as if they were VAX-standard codes in the above { list. However, these codes are not actually VAX-standard types { and are therefore not defined in STARLET.REQ. Therefore, { although these codes may be used in the DST, they should not { be used in run-time descriptors that get passed RTL routines { or other DEC software. { { These definitions have been approved by the VAX Calling Standard { Committee (Ron TLE:: Brender, Chair), now called the VMS Calling { Standard Committee. { { NOTE WELL: any futher extensions to this list *must* be pre-approved { by the Calling Standard Committee! NO EXCEPTIONS! PRE-APPROVED! { { Define DEBUG-internal type codes. { CONSTANT ( DSC$K_DTYPE_TF, { 40 { Boolean True/False (length in bits) DSC$K_DTYPE_SV, { 41 { Signed bit-field (aligned) DSC$K_DTYPE_SVU, { 42 { Signed bit-field (unaligned) DSC$K_DTYPE_FIXED, { 43 { Fixed binary, used for FIXED in ADA { and FIXED BINARY in PL/I. This { code is used the type conversion { tables in DBGEVALOP. DSC$K_DTYPE_TASK, { 44 { Task type in ADA. This actually { has its own fcode, but we need { a dtype code as well in order { to implement EXAMINE/TASK DSC$K_DTYPE_AC, { 45 { ASCIC Text DSC$K_DTYPE_AZ, { 46 { ASCIZ Text DSC$K_DTYPE_M68_S, { 47 { Motorola 68881 Single Precision { (32 bit) DSC$K_DTYPE_M68_D, { 48 { Motorola 68881 Double Precision { (64 bit) DSC$K_DTYPE_M68_X, { 49 { Motorola 68881 Extended Precision { (96 bit) DSC$K_DTYPE_1750_S, { 50 { 1750 Single Precision (32 bit) DSC$K_DTYPE_1750_X, { 51 { 1750 Extended Precision (48 bit) { The following 4 values are no longer DEBUG-internal but defined in { STARLET.REQ (starting with the BLADE (aka VMS V6.0) and ALPHA V1.0 { releases). They are temporarily in TEMPREQ.REQ (so that we can { continue to build here on the debug cluster). Thus, these four { definitions are commented out (otherwise we'd have compile-time { errors). They are listed here for completeness. { { DSC$K_DTYPE_FS, { 52 { IEEE single { DSC$K_DTYPE_FT, { 53 { IEEE double { DSC$K_DTYPE_FSC, { 54 { IEEE single complex { DSC$K_DTYPE_FTC { 55 { IEEE double complex { { The calling standard documents this next value as "Reserved to { DEBUG (setlocale dependent C string)". DEBUG uses this type as { for implementing JDEBUG "wide character" support. { {!+ JDEBUG BLADE-001 NH WCHAR { DSC$K_DTYPE_WC { 56 { wchar_t {!- JDEBUG BLADE-001 NH WCHAR { { These next two values are defined by the calling standard committee { and live in STARLET. They are placed here for documentation purposes. { { DSC$K_DTYPE_FX, { 57 { IEEE eXtended (128 bit) floating { DSC$K_DTYPE_FXC, { 58 { IEEE eXtended complex { { ******************************************************************** { * * { * If a new dtype is needed, you must FIRST GET PRE-APPROVAL FROM * { * THE CALLING STANDARD COMMITTEE. SEE ABOVE. * { * * { ******************************************************************** { { Once approved, the following places in the DEBUG sources must be { changed (this is NOT an exhaustive list): { RSTCNTRL\DBG$STATIC_CHECK - contains a table of dtype-lengths, { which must be extended. { DBGCVTDX - search for DTYPE_TABLE, which consists of zero-based tables { in which the dtype value is used to index into the tables. { These tables must be extended if new dtypes are added. { ) equals DSC$K_DTYPE_HIGHEST + 1 increment 1 counter #debug_dtype_counter; { Advance the counter past the datatypes which are commented out above: four { IEEE, one JDEBUG, and two FX. { #debug_dtype_counter = #debug_dtype_counter + 4 + 1 + 2; { { The following literals are used as CASE statement bounds internally { in DEBUG for the range of DTYPE codes used. { CONSTANT DBG$K_MINIMUM_DTYPE EQUALS 0; { Lowest internal DEBUG dtype value CONSTANT DBG$K_MAXIMUM_DTYPE EQUALS #debug_dtype_counter; { Highest internal DEBUG dtype value { { The following definition is only used internally in DEBUG. It is { a DTYPE code that is temporarily put into a Value Descriptor to { tell the address expression interpreter that the Value Descriptor { came from a literal constant. It does not have to be in the above { range because it is only used during the parsing of address expres- { sions. After the address expression has been parsed, if the DTYPE { is LITERAL, it is then changed to DSC$K_DTYPE_L. { CONSTANT DSC$K_DTYPE_LITERAL EQUALS 191; { Value is from a literal constant { The next type code is also only used internally in DEBUG. It is a DTYPE { code that represents an ASCID Text type. It is never passed to software. { CONSTANT DBG$K_DTYPE_AD EQUALS 192; { OTHER DST TYPE CODES { { { The following literals are the DST type codes other than VAX Standard { Type Codes which can appear in DST$W_TYPE. Each indicates the format { of the record which contains it and most indicate the kind of object { being described by that record. When new DST records are defined, the { type code is assigned by making DST$K_LOWEST one smaller and using that { value. The type codes above DST$K_HIGHEST (191) are reserved, the idea { being that the DTYPEs 192 - 255 are architecturally reserved to users. { DEBUG ignores all DST records whose type codes are not DST$K_BLI, in { the range from DSC$K_DTYPE_LOWEST to DSC$K_DTYPE_HIGHEST, or in the { range DST$K_LOWEST TO DST$K_HIGHEST. { { { { Define all Additional Debug Symbol Table record type codes. Note that the { BLISS Special Cases record has code zero (for historical reasons). All { other type codes are in the range DST$K_LOWEST to DST$K_HIGHEST. { CONSTANT DST$K_BLI EQUALS 0; { BLISS Special Cases Record {-------------------------------{---------------------------- #minimum_nonstandard_dtype = 116; CONSTANT DST$K_LOWEST EQUALS #minimum_nonstandard_dtype; { Lowest numbered DST record in this { range--used for range checking CONSTANT ( DST$K_SYMBOL_FIXUP_64, { 116, { Symbol DST fixup info (quadword) DST$K_FIXUP_64, { 117, { DST fixup information (quadword) DST$K_DIS_RANGE, { 118, { Discontiguous Range Record DST$K_PROLOG_LIST, { 119, { Prolog List Record DST$K_RTN_UNALLOC, { 120, { Unallocated Routine Record DST$K_SYMBOL_FIXUP, { 121, { Symbol DST fixup info (longword) DST$K_BASE_CLASS, { 122, { Refers to a C++ class's base class DST$K_TEMP_DECL, { 123, { C++ Template Declaration DST$K_VIRT_FUNC, { 124, { C++ Virtual function's vtbl index DST$K_EXCEPTION, { 125, { Describes the mapping from an XD Ada { exception number to an exception name DST$K_RETURN, { 126, { Locations of return instructions, for { execution profiling DST$K_EPILOG, { 127, { Locations of routine epilogs, for { STEP/RETURN, etc. DST$K_REG_SAVE_END, { 128, { End of Register Save DSTs DST$K_REG_SAVE, { 129, { Description of where a register is { saved in a particular routine DST$K_REG_SAVE_BEGIN, { 130, { Beginning of Register Save DSTs DST$K_BLIFLDBEG, { 131, { Bliss Field Set Begin DST$K_BLIFLDEND, { 132, { Bliss Field Set End DST$K_FULFILLS_TYPE, { 133, { Fulfills type DST DST$K_FIXUP, { 134, { DST fixup information (longword) DST$K_IMAGE, { 135, { DST entry to describe Image in a { running program. This is not { generated by any compilers, but { such DSTs are constructed by DEBUG { to describe the images in the { program being debugged. DST$K_INLINE, { 136, { Routine inlined instance DST$K_EPILOGS, { 137, { Routine and inline epilogs DST$K_TYPE_SIG, { 138, { C++ Type Signature DST DST$K_EDIT_SOURCE, { 139, { Source correlation records for { use by the EDIT command. DST$K_ALIAS, { 140, { Alias DST DST$K_CXX_ATTRIBUTES, { 141, { C++ Attributes DST$K_GOTO, { 142, { GOTO dst record DST$K_TARGET, { 143, { TARGET dst record DST$K_REAL_NAME, { 144, { Gives real name of package DST$K_BODY_SPEC, { 145, { Relates package body to package spec DST$K_PACK_SPEC_BEG, { 146, { Package Specification Begin (ADA) DST$K_PACK_SPEC_END, { 147, { Package Specification End (ADA) DST$K_PACK_BODY_BEG, { 148, { Package Body Begin (ADA) DST$K_PACK_BODY_END, { 149, { Package Body End (ADA) DST$K_SUBUNIT, { 150, { Subunit Specification (ADA) DST$K_SET_MODULE, { 151, { "WITH" Clause Specification (ADA) DST$K_USE_CLAUSE, { 152, { "USE" Clause Specification (ADA) DST$K_VERSION, { 153, { Version Number Record DST$K_COBOLGBL, { 154, { COBOL Global Attribute Record DST$K_SOURCE, { 155, { Source File Correlation Record DST$K_STATLINK, { 156, { Static Link Record DST$K_VARVAL, { 157, { Variant Value Record DST$K_BOOL, { 158, { Atomic object of type BOOLEAN, { Allocated one byte. { low order bit = 1 if TRUE, { low order bit = 0 if FALSE. DST$K_EXTRNXT, { 159, { External-Is-Next Record (Obsolete) DST$K_GLOBNXT, { 160, { Global-Is-Next record (Obsolete) DSC$K_DTYPE_UBS, { 161, { DEBUG internal use only (unaligned { bit string) (Obsolete) DST$K_PROLOG, { 162, { Prolog Record DST$K_SEPTYP, { 163, { Separate Type Specification Record DST$K_ENUMELT, { 164, { Enumerated Type Element Record DST$K_ENUMBEG, { 165, { Enumerated Type Begin Record DST$K_ENUMEND, { 166, { Enumerated Type End Record DST$K_VARBEG, { 167, { Variant Set Begin Record DST$K_VAREND, { 168, { Variant Set End Record DST$K_OVERLOAD, { 169, { Overloaded Symbol record DST$K_DEF_LNUM, { 170, { Definition Line Number Record DST$K_RECBEG, { 171, { Record Begin Record DST$K_RECEND, { 172, { Record End Record DST$K_CONTIN, { 173, { Continuation Record DST$K_VALSPEC, { 174, { Value Specification Record DST$K_TYPSPEC, { 175, { Type Specification Record DST$K_BLKBEG, { 176, { Block Begin Record DST$K_BLKEND, { 177, { Block End Record DST$K_COB_HACK, { 178, { COBOL Hack Record (Obsolete) DST$K_DTYPE_RESERVED_1, { 179, { Reserved to DEBUG DST$K_USING, { 180, { C++ Using Decls and Directives DST$K_ENTRY, { 181, { Entry Point Record DST$K_LINE_NUM_REL_R11, { 182, { Threaded Code PC-Correlation { Record (Obsolete) DST$K_BLIFLD, { 183, { BLISS Field Record DST$K_PSECT, { 184, { PSECT Record DST$K_LINE_NUM, { 185, { Line Number PC-Correlation Record DST$K_LBLORLIT, { 186, { Label-or-Literal Record DST$K_LABEL, { 187, { Label Record DST$K_MODBEG, { 188, { Module Begin Record DST$K_MODEND, { 189, { Module End Record DST$K_RTNBEG, { 190, { Routine Begin Record DST$K_RTNEND, { 191, { Routine End Record DST$K_PCLOC { 192, { PC-GEM Locator Correlation Record ) equals #minimum_nonstandard_dtype increment 1 counter #nonstandard_dtype_counter; CONSTANT DST$K_HIGHEST EQUALS #nonstandard_dtype_counter; { Highest numbered DST record in this { range--used for range checking { NOTE TO DEVELOPERS: { { New DST Records should not be added at this end of the DST record number { range. VAX Standard Type Codes 192 - 255 are reserved to users. Hence { DEBUG does not use type codes in that range, even though DEBUG does not { support user-defined type codes. New DST record numbers should be allocated { by decrementing DST$K_LOWEST and using that number for the new DST record. { { T H E D S T R E C O R D H E A D E R F O R M A T { { { { All DST records have the same general format, consisting of a fixed { two-byte header followed by zero or more fields whose format is { determined by the DST record's type. This is the format of all DST { records: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE | { +---------------------------------------------------------------+ { var | DST$A_NEXT | { | | { | Zero or more additional fields depending on | { | | { | the value of the DST$W_TYPE field | { | | { | | { | | { +---------------------------------------------------------------+ { { { { These fields appear in all DST records. { { WARNING: SEE THE COMMENTS BELOW BEFORE CHANGING ANYTHING IN THIS STRUCTURE { DEFINITION. { AGGREGATE DST$HEADER STRUCTURE TYPEDEF; dst$$header_length UNION; { Declare two names for length dst$w_length WORD UNSIGNED; { The length of this DST { record, minus 1 dst$x_length WORD UNSIGNED; { An alias for dst$w_length END dst$$header_length; { end of UNION #dst$length_length = :; { size in bytes of length field #dst$base_for_next = :; dst$$header_type UNION; { Declare two names for type dst$w_type DST$DTYPE; { The type of this DST record dst$x_type DST$DTYPE; { An alias for dst$w_type END dst$$header_type; { end of UNION { { Compute the size in bytes of the type field, by taking the { current byte offset and subtracting the size of the fields { which preceed it. Fortunately, there's just one field before { this one. { #dst$length_type = : - #dst$length_length; #dst$header_size = :; END; { DST$HEADER definition CONSTANT DST$K_DST_BASE_FOR_NEXT EQUALS #dst$base_for_next; CONSTANT DST$K_DST_HEADER_SIZE EQUALS #dst$header_size; { { Define constants to tell us how big the length and type fields are. { CONSTANT DST$K_LENGTH_LENGTH EQUALS #dst$length_length; CONSTANT DST$K_LENGTH_TYPE EQUALS #dst$length_type; { { Define the address to help find the next DST record. { The next DST record starts at this location plus DST$W_LENGTH. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_next = DST$K_DST_BASE_FOR_NEXT, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { WARNING: A long explanation on why we are forced to do things the way we do. { { Note: when reading the following, assume that DST$W_LENGTH refers to both { DST$W_LENGTH and DST$X_LENGTH. The same goes for DST$W_TYPE. { { When SDL processses this file for language BLISSF, the result is that a { FIELDSET gets defined with the fields that were declared in the SDL { aggregate. { { For example, the FIELDSET that SDL creates for the DST$MODULE_BEGIN { aggregate defines the field names DST$B_MODBEG_FLAGS, DST$L_MODBEG_LANGUAGE, { etc. SDL makes the use of this FIELDSET easier by providing a MACRO, { DST$MODULE_BEGIN, which defines a block of the appropriate size and { associates the FIELDSET with that block. { { This is all fine and dandy, except for one small problem: the DST header { fields (DST$W_LENGTH and DST$W_TYPE) are *not* included in either the { FIELDSET definition or the MACRO definition. This makes it virtually { impossible to use the DST$MODULE_BEGIN macro. The same is true for all { of the other MACROs. { { Unfortunately, SDL is uncapable of providing any way to resolve this problem { within the constraints of the SDL. However, there is one solution that does { work: a BLISSF-specific literal which *undeclares* DST$W_LENGTH and { DST$W_TYPE and then redefines them as MACROs. Thus, the symbols are not { bound to any one FIELDSET, and can be used everywhere. { { That is what we now do. { { This is how we do it: first, the individual components of the field value are { captured into compile-time constants. Second, the field name is undeclared. { Third, the field name is redefined as a macro. Notice the use of %quote, { %expand and %number in the macro definition. The %number turns the compile- { time symbol into its compile-time value. the %expand forces the %number to { evaluate when the inner macro is defined. The %quote prevents the %expand { from trying to evaluate when the outer macro is parsed. Finally, the compile- { time constants are undeclared. { { The whole thing is inside a macro definition so we can redefine several { field names at once. Once this is done, we undeclare the macro so it { will never conflict with anything that's already defined. { { We go to a lot of work to do this. We do it this way so that if the field { definition ever changes, the macro will automatically track the new field { value. { IFLANGUAGE BLISSF; LITERAL; MACRO $DBG$FIELD_TO_MACRO(fieldname)[] = COMPILETIME dbg$$n = %FIELDEXPAND(fieldname,0), dbg$$p = %FIELDEXPAND(fieldname,1), dbg$$s = %FIELDEXPAND(fieldname,2), dbg$$e = %FIELDEXPAND(fieldname,3); UNDECLARE fieldname; MACRO fieldname = %quote %expand %number(dbg$$n), %quote %expand %number(dbg$$p), %quote %expand %number(dbg$$s), %quote %expand %number(dbg$$e) %QUOTE % ; UNDECLARE dbg$$n, dbg$$p, dbg$$s, dbg$$e; $DBG$FIELD_TO_MACRO(%REMAINING) %; $DBG$FIELD_TO_MACRO(DST$W_LENGTH, DST$X_LENGTH, DST$W_TYPE, DST$X_TYPE); UNDECLARE %QUOTE $DBG$FIELD_TO_MACRO ; END_LITERAL; END_IFLANGUAGE BLISSF; { { Language codes { { Define a typedef for the language field. { ITEM DST$LANGUAGE LONGWORD UNSIGNED TYPEDEF; ITEM DBG$DST_LANGUAGE BYTE UNSIGNED TYPEDEF; { We can't use DBG$LANGUAGE { because there is a Debug { routine by that name... { Define all the language codes that may appear in the DST$L_MODBEG_LANGUAGE { field of the Module Begin DST record. (Note that DEBUG may not actually { support all languages that have language codes.) { #minimum_language_code = 0; CONSTANT DST$K_MIN_LANGUAGE EQUALS #minimum_language_code; { Smallest language code CONSTANT ( DST$K_MACRO, { 0 { Macro DST$K_FORTRAN, { 1 { Fortran DST$K_BLISS, { 2 { Bliss DST$K_COBOL, { 3 { Cobol DST$K_BASIC, { 4 { Basic DST$K_PLI, { 5 { PL/I DST$K_PASCAL, { 6 { Pascal DST$K_C, { 7 { C DST$K_RPG, { 8 { RPG DST$K_ADA, { 9 { Ada DST$K_UNKNOWN, { 10 { Language Unknown DST$K_SCAN, { 11 { Scan DST$K_DIBOL, { 12 { Dibol DST$K_MODULA, { 13 { Modula DST$K_PILLAR, { 14 { Pillar DST$K_CXX, { 15 { C++ DST$K_AMACRO, { 16 { Amacro DST$K_MACRO64 { 17 { Macro64 ) equals #minimum_language_code increment 1 counter #language_code_counter; CONSTANT DST$K_MAX_LANGUAGE EQUALS #language_code_counter; { Largest language code { Here also we define all the same language codes using names with the DBG$ { prefix. This prefix is used in DEBUG for historical reasons. These names { may eventually be discarded. { CONSTANT DBG$K_MIN_LANGUAGE EQUALS DST$K_MIN_LANGUAGE; { Smallest language code CONSTANT DBG$K_MACRO EQUALS DST$K_MACRO; { Macro CONSTANT DBG$K_FORTRAN EQUALS DST$K_FORTRAN; { Fortran CONSTANT DBG$K_BLISS EQUALS DST$K_BLISS; { Bliss-32 CONSTANT DBG$K_COBOL EQUALS DST$K_COBOL; { Cobol CONSTANT DBG$K_BASIC EQUALS DST$K_BASIC; { Basic CONSTANT DBG$K_PLI EQUALS DST$K_PLI; { PL/I CONSTANT DBG$K_PASCAL EQUALS DST$K_PASCAL; { Pascal CONSTANT DBG$K_C EQUALS DST$K_C; { C CONSTANT DBG$K_RPG EQUALS DST$K_RPG; { RPG CONSTANT DBG$K_ADA EQUALS DST$K_ADA; { Ada CONSTANT DBG$K_UNKNOWN EQUALS DST$K_UNKNOWN; { Language Unknown CONSTANT DBG$K_SCAN EQUALS DST$K_SCAN; { Scan CONSTANT DBG$K_DIBOL EQUALS DST$K_DIBOL; { Dibol CONSTANT DBG$K_MODULA EQUALS DST$K_MODULA; { Modula CONSTANT DBG$K_PILLAR EQUALS DST$K_PILLAR; { Pillar CONSTANT DBG$K_CXX EQUALS DST$K_CXX; { C++ CONSTANT DBG$K_AMACRO EQUALS DST$K_AMACRO; { Amacro CONSTANT DBG$K_MACRO64 EQUALS DST$K_MACRO64; { Macro64 CONSTANT DBG$K_MAX_LANGUAGE EQUALS DST$K_MAX_LANGUAGE; { Largest language code { { Language UNKNOWN requires some special explanation. DEBUG supports "unknown" { languages with a standard set of DEBUG functionality. This standard set in- { cludes all language-independent functionality plus "vanilla-flavored" language { expressions. Identifiers are assumed to allow A - Z, 0 - 9, $, and _. Symbol { references may include subscripting (using round () or square [] parentheses) { and record component selection (using dot-notation as in A.B.C). Most simple { operators are allowed in language expressions. { { While not officially supported, language UNKNOWN is intended as an escape for { compilers which do not yet have true DEBUG support. By specifying language { code DST$K_UNKNOWN in the DST$L_MODBEG_LANGUAGE field, such languages can { take advantage of whatever support DEBUG provides for unknown languages. If { and when true DEBUG support is provided, a new language code for the new { language can be allocated by incrementing DST$K_MAX_LANGUAGE by one and { assigning that language code to the new language. { { DEBUG treats any out-of-range language code in the Module Begin DST record as { being equivalent to language UNKNOWN. Use of the DST$K_UNKNOWN language code { or any out-of-range language code is intended for internal use by Digital { only. DEBUG's unknown-language support is not officially supported and is { subject to possibly incompatible changes in future releases of DEBUG. { { Internally, DEBUG treats the language code as a byte value. Hence any { language code above 255 is truncated to its low-order eight bits. { { M O D U L E D S T R E C O R D S { { { { The Debug Symbol Table for each separately compiled module must be { enclosed within a Module-Begin/Module-End pair of DST records. The { Module Begin DST record must thus be the very first DST record for { any separately compiled module (i.e., any object file) and the Module { End DST record must be the very last DST record for the module. Only { one Module-Begin/Module-End pair is allowed in what the linker sees { as a single object module. (If multiple Module-Begin/Module-End pairs { are included in one object module, DEBUG will only see the first such { pair and ignore the rest because the linker will only tell DEBUG about { the location of the first Module Begin record.) { { The Module-Begin/Module-End pair defines a symbolic scope which con- { tains all symbols defined by DST records within that pair. The module { has the name given in the Module Begin DST record. The language of the { object module is also encoded in the Module Begin record. { THE MODULE BEGIN DST RECORD { { { The Module Begin DST Record marks the beginning of the DST for a module. { This DST record also gives the name of the module and the source lan- { guage in which the module was written. The Module Begin DST Record { must be the the first DST record of every compilation unit ("module") { and it must be matched by a Module End DST Record that ends the DST for { that module. Only one Module Begin DST Record is allowed to appear in { the DST for a separately compiled object module. { { This is the format of the Module Begin DST Record: { { { +---------------------------------------------------------------+ { byte | DST$X_LENGTH | { +---------------------------------------------------------------+ { byte | DST$X_TYPE (= DST$K_MODBEG) | { +---------------------------------------------------------------+ { byte | DST$B_MODBEG_FLAGS | { +---------------------------------------------------------------+ { byte | unused | { +---------------------------------------------------------------+ { long | DST$L_MODBEG_LANGUAGE | { +-------------------------------+-------------------------------+ { long | DST$W_VERSION_MINOR | DST$W_VERSION_MAJOR | { +-------------------------------+-------------------------------+ { byte | DST$B_MODBEG_NAME | { +---------------------------------------------------------------+ { var | | { | The Module Name in ASCII | { | | { | (The name's length is given by DST$B_MODBEG_NAME) | { | | { | | { +---------------------------------------------------------------+ { byte | DST$B_COMPILER | { +---------------------------------------------------------------+ { var | The name of the compiler used to compile | { | the module (in ASCII) | { | | { | (The name's length is given by DST$B_COMPILER) | { +---------------------------------------------------------------+ { { { { Define the fields and size of the Module Begin DST Record. { AGGREGATE DST$MODULE_BEGIN STRUCTURE TYPEDEF; dst$a_modbeg_header DST$HEADER; { Header dst$b_modbeg_flags STRUCTURE; { Flags byte dst$v_modbeg_hide BITFIELD LENGTH 1; { Hide this module from the SHOW { MODULE command dst$v_modbeg_version BITFIELD LENGTH 1; { This DST record contains the { DST$L_VERSION field dst$v_modbeg_unused BITFIELD LENGTH 6; { Unused, must be zero END dst$b_modbeg_flags; dst$b_modbeg_unused BYTE UNSIGNED; { Alignment byte; must be zero dst$l_modbeg_language DST$LANGUAGE; { Language code of language { module was written in dst$w_version_major WORD UNSIGNED; { DST major version number dst$w_version_minor WORD UNSIGNED; { DST minor version number dst$b_modbeg_name BYTE UNSIGNED; { Count byte in name counted { ASCII string #dst$module_begin_size = :; END; { DST$MODULE_BEGIN definition CONSTANT DST$K_MODBEG_SIZE EQUALS #dst$module_begin_size; { Size in bytes of the fixed part of { the Module Begin DST record { { Definition of the offset to the trailer fields in the Module Begin DST { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_modbeg_trlr = DST$K_MODBEG_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the Module Begin DST trailer fields structure { AGGREGATE DST$MB_TRLR STRUCTURE TYPEDEF; dst$b_compiler BYTE UNSIGNED; { Count byte in compiler name counted { ASCII string #dst$modbeg_trailer_size = :; END; { DST$MB_TRLR definition CONSTANT DST$K_MB_TRLR_SIZE EQUALS #dst$modbeg_trailer_size; { Byte size of the fixed part of the { Module Begin DST trailer record { Define constants for the version number fields of the Module Begin DST. { { The DST version number is a pair of numbers. The first number is the { major version number, or major id; the second is called the minor version { number, or minor id. { { The major id is incremented whenever an "incompatible" change is made to the { DST. "Incompatible" refers to how the primary DST consumer, DEBUG, handles { the change. So, an incompatible change means that a debugger that understands { Vn.m of DSTs cannot understand Vn+1.0. A "compatible" change means that DEBUG { can cope with the DST change. { { Incompatible changes are: DST layout changes (DST record structure change) { or semantic changes which don't change the size of the structure but do { change the meaning. For example, if the DST$L_RTN_ADDRESS field of the { ROUTINE BEGIN DST record is changed to mean the address of the procedure { descriptor, then that is an incompatible change. Note that the size of the { field didn't change, but that the semantics (interpretation) of the field { *did* change. { { The test for deciding whether or not a change requires a major id bump { is always, "how will an existing debugger--already out in the field--cope { with this change?" If the answer is "it can't," then the change is { "incompatible" and requires a major id increment. Given this definition, one { discovers another example of an incompatible change: the introduction { of, say, a new VS_FOLLOWS value spec type. Though one might think that this { is a compatible change, it really isn't, because nothing like it has existed { before, so older debuggers don't know how to handle it. { { Lots of care and thought needs to be given before making an incompatible { DST change, because the debugger can (currently) only cope with one major { DST version at any given time. { { Whenever a new major DST version is introduced, the minor id always { resets to zero. E.g., { { V1.0 - initial { V1.1 - compatible change { V1.2 - another compatible change { V2.0 - incompatible change. Minor id reset back to zero. Contains { all of V1.2. { { The minor id is changed whenever the change is "compatible" with the { existing major DST version. Examples of compatible changes are rare. { { { Major version number zero is special: it indicates a field test release { of the DSTs. Customers should never see this DST version. The first { supported release version of the DSTs is V1.0. { { The debugger's algorithm for detecting DST version mismatches is as { follows. If the major id in the DSTs is zero (indicating a field test { release) then both the major and minor ids in the DST must match exactly { with the major and minor IDs against which the debugger was built. { { If the major id in the DSTs is non-zero, then the major id in the DST must { match the major id against which the debugger was built (or it must be a { major id of which the debugger is aware), and the minor id is not checked { (because it's supposed to be a compatible change, right?!). { DST MAJOR VERSIONS (MAJOR IDs) { CONSTANT ( DST$K_MAJOR_ID_0, { FT release. Customers never see this. DST$K_MAJOR_ID_1 { First official release. ) equals 0 increment 1 counter #debug_major_id_counter; { Define constants to describe the range of major version numbers. { CONSTANT DST$K_MIN_MAJOR_ID EQUALS DST$K_MAJOR_ID_0; CONSTANT DST$K_MAX_MAJOR_ID EQUALS #debug_major_id_counter; {************************ { FIELD TEST DST VERSIONS {************************ { Define constants which define the progression of changes to Major ID 0 { of the DSTs. These are the Minor IDs for Major Version 0. { { Every time a new field test DST is introduced, you must update this list { to record it, even if there is no change between it and the previous { version. { CONSTANT ( DST$K_MAJOR_ID_0_MINOR_ID_0, { 100% compatible with DSTs on VAX/VMS DST$K_MAJOR_ID_0_MINOR_ID_1, { Two extensions: (1) module begin with { version/producer info and (2) procedure { descriptors in rtnbeg, entry, and { packages DST$K_MAJOR_ID_0_MINOR_ID_2, { Size of dst$x_length and dst$x_type each { increase from byte to word DST$K_MAJOR_ID_0_MINOR_ID_3 { Alpha registers are renumbered. Extended { value spec's VALUE field is back to { a quadword. Special register number { constants are permitted for the { DST$V_VS_REGNUM field. { { Renumbered Stack machine operations which { push Alpha registers; this is a compatible { change because (a) the current design is { broken and (b) no released compiler { generates these yet. { ************************************************************************ { DST Version 1.0 is introduced at this point. It is identical to V0.3. { ************************************************************************ ) equals 0 increment 1 counter #debug_major_id_0_counter; { Define constants to describe the range of minor version numbers within { Major version zero. { CONSTANT DST$K_MAJOR_ID_0_MIN_MINOR_ID EQUALS DST$K_MAJOR_ID_0_MINOR_ID_0; CONSTANT DST$K_MAJOR_ID_0_MAX_MINOR_ID EQUALS #debug_major_id_0_counter; {******************* {DST VERSION 1 {******************* { Define constants which define the progression of changes to Version 1 { of the DSTs. These are the minor version numbers for version 1. Note that { NO RANGE of minor IDs is defined. That's because we don't care about a range { because the changes are supposed to be compatible. The minor id is more { for documentation purposes than anything else. { CONSTANT ( DST$K_MAJOR_ID_1_MINOR_ID_0, { First release. Identical to V0.3. DST$K_MAJOR_ID_1_MINOR_ID_1, { V1.1. Defines bit in RTNBEG DST { for unallocated routines. Upward { compatible because no debugger checks { the bit, which was previously MBZ. DST$K_MAJOR_ID_1_MINOR_ID_2, { V1.2. Adds in support for AMACRO { and MACRO64. DST$K_MAJOR_ID_1_MINOR_ID_3, { V1.3. Adds three new datatypes: { DSC$K_DTYPE_WC (JDEBUG wide-char) { DSC$K_DTYPE_FX (IEEE 128-bit float) { DSC$K_DTYPE_FXC (two FXs => complex FX) DST$K_MAJOR_ID_1_MINOR_ID_4, { V1.4. Adds new DST record type: { DBG$K_SYMBOl_FIXUP DST$K_MAJOR_ID_1_MINOR_ID_5, { V1.5. Adds new DST record type: { DST$K_PC_LOC (for PC correlation against { GEM-style locators) DST$K_MAJOR_ID_1_MINOR_ID_6, { V1.6. Adds vector of PC definitions { to split-lifetime DST. Also moves and { extends number of bindings from byte to { word. Upward compatible because no AXP { compiler generates this yet and this { change is NOT being done on VAX. DST$K_MAJOR_ID_1_MINOR_ID_7, { V1.7. Redefines and extends locator { correlation tables. Removed underscore { between "PC_LOC" in all symbols with this { string in their name. DST$K_MAJOR_ID_1_MINOR_ID_8, { V1.8. Added DST$K_VFLAGS_NOTACTIVE. DST$K_MAJOR_ID_1_MINOR_ID_9, { V1.9. Renumbered, renamed and added { PCLOC event commands. DATA is now { READ and WRITE (with arguments), CONTROL { is now CONTROL and CALL. DST$K_MAJOR_ID_1_MINOR_ID_10, { V1.10. Introduced PWRIT (partial write) { PCLOC event command, redefined WRITE { to be a "complete" write. Added LINS { (LINE SHORT) PCLOC commands. DST$K_MAJOR_ID_1_MINOR_ID_11, { V1.11. Added the 64-bit pointer type { specs: DST$K_TS_TPTR_64, DST$K_TS_PTR_64 DST$K_MAJOR_ID_1_MINOR_ID_12, { V1.12. Added LABEL PCLOC subcommand DST$K_MAJOR_ID_1_MINOR_ID_13, { V1.13. C++ support. Also, start using { the DST$V_RTNBEG_UNALLOC field. DST$K_MAJOR_ID_1_MINOR_ID_14, { V1.14. C++ DST size reduction. DST$K_MAJOR_ID_1_MINOR_ID_15, { V1.15. C++ namespace support. DST$K_MAJOR_ID_1_MINOR_ID_16, { V1.16. inline, prolog list, { discontinguous ranges DST$K_MAJOR_ID_1_MINOR_ID_17, { V1.17. 64-bit Static Data: add { DBG$K_FIXUP_64 and DBG$K_SYMBOl_FIXUP_64 DST$K_MAJOR_ID_1_MINOR_ID_18, { V1.18. C++ Reference Type: add { DST$K_TS_REF and DST$K_TS_REF_64 ) equals 0 increment 1 counter #debug_major_id_1_counter; { For our DST producers, define the latest and greatest minor id within { major id 1. DEBUG does not consume this value, but provides it for the { benefit of DST producers who want to generate the latest minor version { of major version 1. { CONSTANT DST$K_MAJOR_ID_1_MAX_MINOR_ID EQUALS #debug_major_id_1_counter; {************** { Constants which define the current version of DSTs {************** { Most recent field test version { CONSTANT DST$K_MAJOR_FIELD_TEST EQUALS DST$K_MAJOR_ID_0; CONSTANT DST$K_MINOR_FIELD_TEST EQUALS DST$K_MAJOR_ID_0_MAX_MINOR_ID; { Latest-and-greatest DST version { { DEBUG always understands the latest and greatest DST version. DST producers { should always try to generate whichever DST version is defined below. { { If this is a field test DST version, uncomment the two lines below. { {CONSTANT DST$K_VERSION_MAJOR EQUALS DST$K_MAJOR_FIELD_TEST; {CONSTANT DST$K_VERSION_MINOR EQUALS DST$K_MINOR_FIELD_TEST; { If this is a non-field test version, uncomment the two lines below. { CONSTANT DST$K_VERSION_MAJOR EQUALS DST$K_MAJOR_ID_1; CONSTANT DST$K_VERSION_MINOR EQUALS DST$K_MAJOR_ID_1_MAX_MINOR_ID; { THE MODULE END DST RECORD { { { The Module End DST Record must be the last DST record in the DST for a { compilation unit. Its sole purpose is to mark the end of the DST for { a separately compiled object module. There can be only one Module End { DST record per module, matching the previous Module Begin DST record. { This is its format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_MODEND) | { +---------------------------------------------------------------+ { { { { Define the size in bytes of the Module End DST Record. { AGGREGATE DST$MODULE_END STRUCTURE TYPEDEF; dst$a_modend_header DST$HEADER; { Header #dst$module_end_size = :; END; { DST$MODULE_END definition CONSTANT DST$K_MODEND_SIZE EQUALS #dst$module_end_size; { Size of Module End record in bytes { R O U T I N E D S T R E C O R D S { { { A routine is represented in the Debug Symbol Table by a pair of DST { records, namely a Routine Begin DST record which is matched with a { later Routine End DST record. All DST records between the Routine { Begin and the Routine End DST records represent the symbols that are { declared in that routine or in nested routines or blocks. Nested rou- { tines are represented in the DST by nested Routine-Begin/Routine-End { pairs. Lexical blocks (BEGIN-END blocks or the like, depending on { the language) may also be nested freely outside or inside routines, { provided all blocks and routines are properly nested. { { Consider the following example of nested blocks and routines. If { routine R1 contains a nested routine R2 and a lexical block B1 and { if block B1 contains routine R3 and Block B2, the DST would have the { following sequence of DST records: { { Module Begin for whole module { ...module-level data DST records... { Routine Begin for R1 { ...local data DST records for R1... { Routine Begin for R2 { ...local data DST records for R2... { Routine End for R2 { Block Begin for B1 { ...local data DST records for B1... { Routine Begin for R3 { ...local data DST records for R3... { Routine End for R3 { Block Begin for B2 { ...local data DST records for B2... { Block End for B2 { Block End for B1 { Routine End for R1 { Module End for whole module { { In addition to defining a symbol scope, the Routine-Begin/Routine-End { pair defines the name and address range of the corresponding routine. { The name and start address is found in the Routine Begin DST record { and the byte length of the routine is found in the Routine End DST { record. It is assumed that the start address is also the entry point { to the routine. The Routine Begin record also indicates whether the { routine uses a CALLS/CALLG linkage or a JSB/BSB linkage. { THE ROUTINE BEGIN DST RECORD { { { The Routine Begin DST record marks the beginning of a routine and the { associated scope. This record contains the routine's name and start { address and indicates whether the routine is a CALLS/CALLG routine { or a JSB/BSB routine. It must be matched by a Routine End DST record { later in the DST, except if the language of the current module is { MACRO. (Since MACRO routines have entry points but no well defined { end points, the Routine End record can and must be omitted for this { language. This exception applies to no other language.) { { This is the format of the Routine Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_RTNBEG) | { +-------+------+-----+-------+----------------------------------+ { byte |NO_CALL|noused|PROTO|UNALLOC| DST$V_RTNBEG_UNUSED | { +-------+------+-----+-------+----------------------------------+ { long | DST$L_RTNBEG_ADDRESS | { +---------------------------------------------------------------+ { long | DST$L_RTNBEG_PD_ADDRESS | { +---------------------------------------------------------------+ { byte | DST$B_RTNBEG_NAME | { +---------------------------------------------------------------+ { var | | { | The Routine Name in ASCII | { | | { | (The name's length is given by DST$B_RTNBEG_NAME) | { | | { +---------------------------------------------------------------+ { { { { Define the fields and size of the Routine Begin DST record. { AGGREGATE DST$ROUTINE_BEGIN STRUCTURE TYPEDEF; dst$a_rtnbeg_header DST$HEADER; { Header dst$b_rtnbeg_flags STRUCTURE; { Flags dst$v_rtnbeg_unused BITFIELD LENGTH 4; { Unused--Must Be Zero dst$v_rtnbeg_unalloc BITFIELD LENGTH 1; { This bit is set if this { routine has been "optimized { away". Address and PD Address { should both be zero; in any { case, they're ignored. A { routine end DST must still be { supplied. dst$v_rtnbeg_prototype BITFIELD LENGTH 1; { This bit is set if this is a { routine prototype, and { dst$l_rtnbeg_address and { dst$l_rtnend_size should be { ignored dst$v_rtnbeg_notused BITFIELD LENGTH 1; { This bit is not used. It can { be redefined. dst$v_rtnbeg_no_call BITFIELD LENGTH 1; { This bit is set if this rou- { tine is invoked with a { JSB or BSB rather a CALLS { or CALLG instruction END dst$b_rtnbeg_flags; dst$l_rtnbeg_address ADDRESS; { The routine's start address { (and entry point address { if no procedure { descriptor address) dst$l_rtnbeg_pd_address ADDRESS; { The routine's procedure { descriptor address dst$b_rtnbeg_name BYTE UNSIGNED; { The count byte of the rou- { tine's Counted ASCII name #dst$routine_begin_size = :; END; { DST$ROUTINE_BEGIN definition CONSTANT DST$K_RTNBEG_SIZE EQUALS #dst$routine_begin_size; { Byte size of the fixed part of the { Routine Begin DST record { THE ROUTINE END DST RECORD { { { The Routine End DST Record marks the end of a routine's scope in the { DST. It also contains the byte length of the routine's code. (Note { that Routine End DST records must be omitted for language MACRO but { are mandatory for all other languages.) This is the format of the { Routine End DST record. { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_RTNEND) | { +---------------------------------------------------------------+ { byte | Unused (Must Be Zero) | { +---------------------------------------------------------------+ { long | DST$L_RTNEND_SIZE | { +---------------------------------------------------------------+ { { { Define the fields of the Routine End DST record. { AGGREGATE DST$ROUTINE_END STRUCTURE TYPEDEF; dst$a_rtnend_header DST$HEADER; { Header dst$b_rtnend_unused BYTE; dst$l_rtnend_size LONGWORD UNSIGNED; #dst$routine_end_size = :; END; { DST$ROUTINE_END definition CONSTANT DST$K_RTNEND_SIZE EQUALS #dst$routine_end_size; { Size of Routine End record in bytes { U N A L L O C A T E D R O U T I N E D S T R E C O R D S { { { The Unallocated Routine DST Record exists in order to mimimize the use { of DST space while describing routines that have not been allocated (no { code has been produced) by the compiler. For such routines, only the { routine name and (for C++ only as of 3-Dec-96) its type signature is { described in this DST. This is the format of the Routine Begin DST { record: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_RTN_UNALLOC) | { +---------------------------------------------------------------+ { byte | DST$B_RTNUNALLOC_NAME | { +---------------------------------------------------------------+ { var | | { | The Routine Name in ASCII | { | | { | (The name's length is given by DST$B_RTNUNALLOC_NAME) | { | | { +---------------------------------------------------------------+ { byte | DST$B_RTNUNALLOC_TYPE_SIG | { +---------------------------------------------------------------+ { var | | { | The Type Signature in ASCII | { | | { | (The name's length is given by DST$B_RTNUNALLOCTYPE_SIG) | { | | { +---------------------------------------------------------------+ { { { Define the fields and size of the Unallocated Routine DST record. { AGGREGATE DST$ROUTINE_UNALLOC STRUCTURE TYPEDEF; dst$a_rtnunalloc_header DST$HEADER; { Header dst$b_rtnunalloc_name BYTE UNSIGNED; { The count byte of the rou- { tine's Counted ASCII name #dst$routine_unalloc_size = :; END; { DST$ROUTINE_UNALLOC definition CONSTANT DST$K_RTNUNALLOC_SIZE EQUALS #dst$routine_unalloc_size; { Byte size of the fixed part of the { Unallocated Routine DST record { THE INLINE INSTANCE DST RECORD { { { The Inline Instance DST record indicates that a particular scope is the { result of an inline expansion (instantiation) of a routine. A single { inline instance DST can appear within a given block begin-end pair. { That block begin-end pair is the scope of the inline instance. { { The DST$L_INLINE_RTN_DST field contains the offset of the routine begin { DST of the routine being inlined. The DST$L_INLINE_CALLER_LINE field { contains the line number of the 'call' of the routine. { { Nested inline instances are described using nested block begin-end { pairs, each block having its own Inline Instance DST. { { The entry/prolog and epilog/exit address ranges of an inlined instance { are described using prolog and epilog DSTs, just as if it were a normal { routine. { { This is the format of the Inline Instance Begin DST record: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_INLINE) | { +---------------------------------------------------------------+ { long | DST$L_INLINE_RTN_DST | { +---------------------------------------------------------------+ { long | DST$L_INLINE_CALLER_LINE | { +---------------------------------------------------------------+ { { { Define the fields and size of the Routine Begin DST record. { AGGREGATE DST$INLINE STRUCTURE TYPEDEF; dst$a_inline_header DST$HEADER; { Header dst$l_inline_rtn_dst LONGWORD UNSIGNED; { offset of the { instance's routine DST dst$l_inline_caller_line LONGWORD UNSIGNED; { line number of the { instance 'call' #dst$inline_size = :; END; CONSTANT DST$K_INLINE_SIZE EQUALS #dst$inline_size; { L E X I C A L B L O C K D S T R E C O R D S { { { A "Lexical Block" is any programming language construct other than a { routine that defines a scope within which symbols can be declared. { What distinguishes a "block" from a "routine", from DEBUG's point of { view, is that a block is always entered by jumping to it or simply { falling into it while a routine is always entered by a call instruc- { tion of some sort. A routine has a entry point that can be called; { a block does not. Hence BEGIN-END blocks in BLISS and PL/I are blocks { and so are Paragraphs and Sections in COBOL. Subroutines, functions, { and procedures, on the other hand, are "routines". { { Blocks and routines do have one thing in common, however. Both define { syntactic units within which other symbols can be defined. The pur- { pose of representing blocks in the DST is to define the scopes they { enclose and to give the address ranges of the corresponding bodies { of code. { { A lexical block is represented in the Debug Symbol Table by a pair { of DST records, namely a Block Begin DST record which is matched with { a later Block End DST record. All DST records between the Block Begin { and the Block End DST record represent the symbols that are declared { in that lexical block or in nested routines or blocks. Nested blocks { are represented in the DST by properly nested Block-Begin/Block-End { pairs. Routines and blocks may freely be nested within one another, { using the appropriate proper nesting of the corresponding Begin and { End DST records. { { The start address of a block's code is given in the Block Begin DST { record and the byte length of that code is given in the Block End { DST record. The name of the block is given in the Block-Begin record. { If a block has no name (which is common for BEGIN-END blocks), the { null name is given (the name of length zero). Blocks with null names { cannot be explicitly referenced in DEBUG, but line numbers within such { blocks can be used to specify breakpoint locations or symbol scopes. { THE BLOCK BEGIN DST RECORD { { { The Block Begin DST Record marks the beginning of a lexical block and { the associated scope. This record contains the block's name and start { address. It must be matched by a Block End DST record later in the { DST. This is the format of the Block Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLKBEG) | { +---------------------------------------------------------------+ { byte | DST$B_BLKBEG_UNUSED | { +---------------------------------------------------------------+ { long | DST$L_BLKBEG_ADDRESS | { +---------------------------------------------------------------+ { byte | DST$B_BLKBEG_NAME | { +---------------------------------------------------------------+ { var | | { | The Block's Name in ASCII | { | | { | (The name's length is given by DST$B_BLKBEG_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { Define the fields of the Block Begin DST record. { AGGREGATE DST$BLOCK_BEGIN STRUCTURE TYPEDEF; dst$a_blkbeg_header DST$HEADER; { Header dst$b_blkbeg_unused BYTE UNSIGNED; { Unused--Must Be Zero dst$l_blkbeg_address ADDRESS; { The block's start address dst$b_blkbeg_name BYTE UNSIGNED; { The count byte of the block's { Counted ASCII name #dst$block_begin_size = :; END; { DST$BLOCK_BEGIN definition CONSTANT DST$K_BLKBEG_SIZE EQUALS #dst$block_begin_size; { Size of Block Begin record in bytes { THE BLOCK END DST RECORD { { { The Block End DST Record marks the end of a lexical block's scope in { the DST. It also contains the byte length of the block's code. This { is the format of the Block End DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLKEND) | { +---------------------------------------------------------------+ { byte | Unused (Must Be Zero) | { +---------------------------------------------------------------+ { long | DST$L_BLKEND_SIZE | { +---------------------------------------------------------------+ { { { { Define the fields of the Block End DST record. { AGGREGATE DST$BLOCK_END STRUCTURE TYPEDEF; dst$a_blkend_header DST$HEADER; { Header dst$b_blkend_unused BYTE UNSIGNED; { MBZ dst$l_blkend_size LONGWORD UNSIGNED; { The byte length of the lexical block #dst$block_end_size = :; END; { DST$BLOCK_END definition CONSTANT DST$K_BLKEND_SIZE EQUALS #dst$block_end_size; { Size of Block End record in bytes { P A C K A G E D S T R E C O R D S { { { { ADA package specs are represented in the DEBUG symbol table by a pair { of DST records, namely a Package Spec Begin DST record which is matched { with a later Package Spec End DST record. All DST records between the { Package Spec Begin DST record and the Package Spec End DST record { represent the items that are declared in the Package Spec. { { Similarly, package bodies are represented in the DEBUG symbol { table by a pair of DST records, namely the Package Body Begin DST record { which is matched with a later Package Body End DST record. All DST { records between the Package Body Begin DST record and the Package { Body End DST record represent the items that are declared in the { Package Body. { THE PACKAGE SPEC BEGIN DST RECORD { { { The Package Spec Begin DST record marks the beginning of an ADA { package spec. { { This record contains a code describing whether or not there is { elaboration code for the package. If there is elaboration code, { then the Package Spec Begin DST record contains the address { of the start of this elaboration code. Breakpoints can be { set on the elaboration code using the syntax "SET BREAK P", { where "P" is the package name. { { The other information in the Package Spec Begin record is { the name of the package. This name appears exactly as it { did in the ADA program, i.e., if the package name is "P" then { the name "P" should appear here. Elements of the package { are referred to with the usual ADA syntax, e.g., "EXAMINE P.X". { { Note - the format of the Package Spec Begin record must continue { to conform to the format of the Routine Begin record (i.e., { the address and name fields are in the same place). There { is code in TRACEBACK and PCA that depends on this. { { This is the format of the Package Spec Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PACK_SPEC_BEG) | { +---------------------------------------------------------------+ { byte | unused (MBZ) | (2) | (1) | { +---------------------------------------------------------------+ { long | DST$L_PACKSPEC_ADDRESS | { +---------------------------------------------------------------+ { long | DST$L_PACKSPEC_PD_ADDRESS | { +---------------------------------------------------------------+ { byte | DST$B_PACKSPEC_NAME | { +---------------------------------------------------------------+ { var | | { | The package name in ASCII | { | | { | (The name's length is given by DST$B_PACKSPEC_NAME | { | | { +---------------------------------------------------------------+ { { (1) = DST$V_PACKSPEC_ELAB, a 2-bit field specifying whether there { is elaboration code and whether it has an entry mask { (2) = DBG$V_PACKSPEC_DUPL, a flag saying this DST is a duplicated { definition. { { { These are the possible values for the DST$B_PACKSPEC_ELAB field. { CONSTANT DST$K_NOELAB EQUALS 0; { Indicates that there is no { elaboration code for the package. CONSTANT DST$K_ELAB_NOCALL EQUALS 1; { Indicates that there is elaboration code { for the package and that there is no { entry mask at the start of this code { (the address in the ADDRESS field { refers to the first instruction { in this code). CONSTANT DST$K_ELAB_CALL EQUALS 2; { Indicates that there is elaboration code { for the package and that there is { an entry mask at the start of this code { (the address in the ADDRESS field { refers to the entry mask). { { Define the fields and size of the Package Spec Begin DST record. { AGGREGATE DST$PACKAGE_SPEC_BEGIN STRUCTURE TYPEDEF; dst$a_packspec_beg_header DST$HEADER; { Header dst$b_packspec_flags STRUCTURE; { Flags dst$v_packspec_elab BITFIELD LENGTH 2; { A 2-bit code saying describing { the elaboration code dst$v_packspec_dupl BITFIELD LENGTH 1; { A flag for duplicated DST dst$v_packspec_beg_unused BITFIELD LENGTH 5; END dst$b_packspec_flags; dst$l_packspec_address ADDRESS; { Address of the elaboration code dst$l_packspec_pd_address ADDRESS; { Address of the procedure descriptor { that describes the elaboration code dst$b_packspec_name BYTE UNSIGNED; { The count byte of the package's { counted ASCII name #dst$packspec_begin_size = :; END; { DST$PACKAGE_SPEC_BEGIN definition CONSTANT DST$K_PACKSPEC_BEG_SIZE EQUALS #dst$packspec_begin_size; { Byte size of the fixed part { of the Package Spec Begin DST { THE PACKAGE SPEC END DST RECORD { { { The Package Spec End DST record marks the end of a package's { scope in the DST. This DST record contains a SIZE field which { represents the size of the elaboration code in bytes. { { The format of this record is the same as that of the Routine End { DST record, and must remain that way. { { This is the format of the Package Spec End DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PACK_SPEC_END) | { +---------------------------------------------------------------+ { byte | unused (must be zero) | { +---------------------------------------------------------------+ { long | DST$L_PACKSPEC_END_SIZE | { +---------------------------------------------------------------+ { { { Define the fields and size of the Package Spec End DST record. { AGGREGATE DST$PACKAGE_SPEC_END STRUCTURE TYPEDEF; dst$a_packspec_end_header DST$HEADER; { Header dst$b_packspec_end_unused BYTE UNSIGNED; { MBZ dst$l_packspec_end_size LONGWORD UNSIGNED; { The size of the elaboration code { in bytes. Zero if no elab code. #dst$packspec_end_size = :; END; { DST$PACKAGE_SPEC_END definition CONSTANT DST$K_PACKSPEC_END_SIZE EQUALS #dst$packspec_end_size; { Size of Package Spec End DST { in bytes { THE PACKAGE BODY BEGIN DST RECORD { { { The Package Body Begin DST record marks the beginning of an ADA { package body. { { This record contains a code describing whether or not there is { elaboration code for the package body. If there is elaboration code, { then the Package Body Begin DST record contains the address { of the start of this elaboration code. Breakpoints can be { set on the elaboration code using the syntax "SET BREAK P$BODY", { where "P" is the package name, and "P$BODY" is a name invented { by the ADA compiler. { { The other information in the Package Body Begin record is { the invented name for the package body. This name is constructed { by the ADA compiler according to some simple naming rule (e.g., { if the package name is "P" then the invented name might be "P$BODY"). { { Note - the format of the Package Body Begin record must continue { to conform to the format of the Routine Begin record (i.e., { the address and name fields are in the same place). There { is code in TRACEBACK and PCA that depends on this. { { This is the format of the Package Body Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PACK_BODY_BEG) | { +---------------------------------------------------------------+ { byte | unused (MBZ) | (1) | { +---------------------------------------------------------------+ { long | DST$L_PACKBODY_ADDRESS | { +---------------------------------------------------------------+ { long | DST$L_PACKBODY_PD_ADDRESS | { +---------------------------------------------------------------+ { byte | DST$B_PACKBODY_NAME | { +---------------------------------------------------------------+ { var | | { | The invented name in ASCII | { | | { | (The name's length is given by DST$B_PACKBODY_NAME | { | | { +---------------------------------------------------------------+ { { (1) = DST$V_PACKBODY_ELAB, a 2-bit field specifying whether there { is elaboration code and whether it has an entry mask { { The possible values of the DST$V_PACKBODY_ELAB field are the same { as the possible values of the DST$V_PACKSPEC_ELAB field. These are { described above in the section on Package Spec Begin DST records. { { Define the fields and size of the Package Body Begin DST record. { AGGREGATE DST$PACKAGE_BODY_BEGIN STRUCTURE TYPEDEF; dst$a_packbody_beg_header DST$HEADER; { Header dst$b_packbody_flags STRUCTURE; { Flags dst$v_packbody_elab BITFIELD LENGTH 2; { Code describing the package body { elaboration code. dst$v_packbody_mbz BITFIELD LENGTH 6; END dst$b_packbody_flags; dst$l_packbody_address ADDRESS; { Address of elaboration code. dst$l_packbody_pd_address ADDRESS; { Address of procedure descriptor that { describes elaboration code dst$b_packbody_name BYTE UNSIGNED; { The count byte of the package's { counted ASCII name #dst$package_body_begin_size = :; END; { DST$PACKAGE_BODY_BEGIN definition CONSTANT DST$K_PACKBODY_BEG_SIZE EQUALS #dst$package_body_begin_size; { Byte size of the fixed part { of the Package Body Begin DST { THE PACKAGE BODY END DST RECORD { { { The Package Body End DST record marks the end of a package body's { scope in the DST. This DST record contains a SIZE field which { represents the size of the elaboration code in bytes. { { The format of this record must remain the same as the format of { the Routine End DST record. { { This is the format of the Package Body End DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PACK_BODY_END) | { +---------------------------------------------------------------+ { byte | unused (must be zero) | { +---------------------------------------------------------------+ { long | DST$L_PACKBODY_END_SIZE | { +---------------------------------------------------------------+ { { { Define the fields and size of the Package Spec End DST record. { AGGREGATE DST$PACKAGE_BODY_END STRUCTURE TYPEDEF; dst$a_packbody_end_header DST$HEADER; { Header dst$b_packbody_end_unused BYTE UNSIGNED; { MBZ dst$l_packbody_end_size LONGWORD UNSIGNED; { The size of the elaboration code { in bytes. Zero if no elab code. #dst$package_body_end_size = :; END; { DST$PACKAGE_BODY_END definition CONSTANT DST$K_PACKBODY_END_SIZE EQUALS #dst$package_body_end_size; { Byte size of the { Package Body End DST { THE DISCONTIGUOUS RANGE LIST DST RECORD { { The Discontinuous Range List DST Record can be used in any lexical { scope, i.e. routine, block, package, or inline instance. A single { Discontinuous Range List DST Record can appear within the lexical { entity it describes. When a Discontinuous Range List DST Record { does appear, it supercedes that range specified in the immediately { containing scope. { { Routine Begin for R1 { ...local data DST records for R1... { Block Begin for B1 { ...local data DST records for B1... { Discontiguous Range List for B1 { range 1 { range 2 { range 3 { Block End for B1 { Discontiguous Range List for B2 { range 1 { range 2 { Routine End for R1 { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_DIS_RANGE) | { +---------------------------------------------------------------+ { long | DST$LU_DISRNG_COUNT | { +---------------------------------------------------------------+ { quad | first range | { +---------------------------------------------------------------+ { quad | second range | { +---------------------------------------------------------------+ { | ... | { +---------------------------------------------------------------+ { quad | Nth range | { +---------------------------------------------------------------+ { { Each of the ranges described by a discontiguous record list must be { distinct -- they cannot overlap. Also, the ranges in the list must be { sorted so that the lowest address range is described first. { { Define the fields of the Routine Discontiguous Range List DST record. { AGGREGATE DST$DIS_RANGES STRUCTURE TYPEDEF; dst$a_disrng_header DST$HEADER; { Header dst$lu_disrng_count LONGWORD UNSIGNED; { Count of address ranges { which follow #dst$dis_ranges_end_size = :; END; CONSTANT DST$K_DISRNGS_SIZE EQUALS #dst$dis_ranges_end_size; { in bytes { { Define an offset for the additional address range information. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_dis_ranges = DST$K_DISRNG_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the information for one range. { AGGREGATE DST$DIS_RANGE STRUCTURE TYPEDEF; dst$lu_disrng_address LONGWORD UNSIGNED; { starting address of range dst$lu_disrng_size LONGWORD UNSIGNED; { number of bytes in range #dst$dis_range_size = :; END; CONSTANT DST$K_DISRNG_SIZE EQUALS #dst$dis_range_size; { Byte size of one address range { portion of an Dis-Range DST record { { For Bliss, define a macro for defining an array of these structures { IFLANGUAGE BLISSF; LITERAL; KEYWORDMACRO DST$DIS_RANGE_VECTOR(N = 1) = BLOCKVECTOR[(N), DST$K_DISRNG_SIZE,BYTE] FIELD(DST$DIS_RANGE_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { R E C O R D S T R U C T U R E D S T R E C O R D S { { { Record structures, or simply records, refer to the aggregates of non- { homogeneous components found in many languages. In some languages, { such constructs are called "records" (in PASCAL and COBOL, for example) { and in others they are called "structures" (in PL/I, for example). { Here we will call them "records". What all records have in common is { that they consist of a set of named components, each corresponding to { some field in the record structure. The components can in general be { of any data types supported by the language. { { In the Debug Symbol Table, a record is represented by a Record Begin { DST record followed by some number of data object DST records, one for { each record component, followed by a Record End DST record. Any data { object DST record within a Record-Begin/Record-End pair is taken to { denote a component of that enclosing record specification. Other DST { records may also appear between the Record-Begin/Record-End pair, such { as Type Specification and other DST records that specify the data types { of the components. However, only data DST records denote record com- { ponents. { { Nested records are defined by record components which are themselves { records. The type of a record component which is itself a record is { defined by another Record-Begin/Record-End pair of DST records. This { additional record definition may appear inside the original record { definition, but does not have to do so--an Indirect Type Specification { pointing to a record definition outside the original record definition { is also legal. Conversely, a record definition inside another record { definition does not define a nested record unless some component of { the outer record actually references the inner record definition. In { short, the DST can only describe one level of record components at a { time, but any component can be of any arbitrary data type including { another record type. { { The Record Begin DST record is unusual in that it can define both a { data type and a data object. If the DST$B_VFLAGS field has the special { value DST$K_VFLAGS_NOVAL, then the Record Begin DST record defines an { abstract data type. Any object of this data type must be represented { by a Separate Type Specification DST record which immediately precedes { either the Record Begin DST record or a Type Specification DST record { that contains an Indirect Type Specification that points to the Record { Begin DST record. In this case, the name in the Record Begin record is { taken to be the name of the data type, not of any object of that type. { { However, if the DST$B_VFLAGS field does not contain DST$K_VFLAGS_NOVAL, { then the Record Begin DST record defines both a data type and a data { object of that type. This form can be used for languages such as COBOL { which do not have named data types. In this case, the DST$B_VFLAGS and { DST$L_VALUE fields specify the address of the record object in the same { way as in the Standard Data DST record. It is still legal to have { Indirect Type Specifications pointing to this Record Begin DST record, { using it strictly as a type definition. { { Some languages, such as PASCAL, allow record variants. (In ADA, the { same concept is called "discriminated" records.) An object of a record { type with variants contains some set of components found in all objects { of that type plus some set of components that vary from one record { variant to the next. Which of the varying components are actually { present in a given record may be determined by the value of a "tag { variable" which is a fixed component of the record. Variants may also { be nested so that variants have variants. { { In the DST, record variants are described by Variant Set Begin DST { records, Variant Value DST records, and Variant Set End DST records. { The Variant Set Begin DST record marks the beginning of a set of record { variants, where each variant consists of some set of record components. { The Variant Set Begin DST record indicates which record component con- { stitutes the tag variable that discriminates between the variants in { the set. This tag variable must be a component of the same record and { must precede the Variant Begin DST record in the DST. The Variant { Begin DST record also gives the bit size of the variant, if known at { compile-time. { { The Variant Value DST record marks the beginning of a single record { variant. It also specifies all tag variable values or value ranges { that indicate the presence of this variant in a given record object. { All record components (indicated by data DST records) after this Vari- { ant Value DST record and before the next Variant Value or Variant Set { End DST record are taken to be components in this variant. { { The Variant Set End DST record marks the end of some set of variants { within a record specification. It also terminates the last variant { within the set. { { A record type with variants is thus specified as follows. First a { Record Begin DST record marks the beginning of the record specifica- { tion. After that come data DST records that denote all fixed compo- { nents of the record type. Then comes a Variant Set Begin DST record { that marks the beginning of a set of variant definitions and identi- { fies the tag variable (if any) for that variant set. Immediately { thereafter comes the first Variant Value DST record. It marks the { start of the first variant and identifies the values or value ranges { of the tag variable that correspond to this specific variant. { { After the first Variant Value DST record come the data DST records { for the record components in this particular variant. Next comes the { Variant Value DST record for the next variant, along with its component { DST records, and so on for each variant in the variant set. After the { last component DST record for the last variant in the set comes a { Variant Set End DST record. It is followed by the DST records for any { additional record components, possibly including additional variant { set definitions. Then comes the the Record End DST record. { { Variant sets may be nested inside variant sets. Such nesting is indi- { cated in the DST by the corresponding proper nesting of Variant Set { Begin and Variant Set End DST records. { THE RECORD BEGIN DST RECORD { { { The Record Begin DST record marks the beginning of a record type { definition in the DST. It must be followed by the DST records for { the components of that record and by a matching Record End DST record. { The Record Begin DST record has essentially the same format as the { Standard Data DST record, but with two exceptions. First, an extra { longword gives the bit length of the record type and second, the { DBG$B_VFLAGS field may have the special value DST$K_VFLAGS_NOVAL to { indicate that this is strictly a type definition, not also the defini- { tion of a record object. If a normal value specification is used, a { record object is being declared as well as a record type. In this { case, a Trailing Value Specification may be included at the end of the { DST record if necessary to describe the record's address. { { The bit size of objects of this record type is also given in the DST { record. This size should be included if the size is known at compile- { time. If it is not known at compile-time, it should be specified as { zero. { { This is the format of the Record Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (=DST$K_REGBEG) | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the Record or Record Type in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { long | DST$L_RECBEG_SIZE | { +---------------------------------------------------------------+ { { { Define the fields of the Record Begin DST record. Also declare the macro { that defines the trailer part of the DST record. { AGGREGATE DST$RECBEG_TRLR STRUCTURE TYPEDEF; dst$l_recbeg_size LONGWORD UNSIGNED; { The bit size of data objects of this { record type (or 0 if unknown) #dst$recbeg_trailer_size = :; END; { DST$RECBEG_TRLR definition CONSTANT DST$K_RECBEG_TRAILER_SIZE EQUALS #dst$recbeg_trailer_size; { Size of Module End record in bytes { { THE RECORD END DST RECORD { { { The Record End DST record marks the end of a record type definition in { the DST. In effect, it terminates the scope set up by the matching { Record Begin DST record. This is the record's format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_RECEND) | { +---------------------------------------------------------------+ { { Define the size in bytes of the Record End DST Record. { AGGREGATE DST$RECORD_END STRUCTURE TYPEDEF; dst$a_recend_header DST$HEADER; { Header #dst$record_end_size = :; END; { DST$RECORD_END definition CONSTANT DST$K_RECEND_SIZE EQUALS #dst$record_end_size; { Size of Record End record in bytes { THE VARIANT SET BEGIN DST RECORD { { { The Variant Set Begin DST record marks the beginning of the DST { description of a set of record variants. This DST record also { identifies the tag variable that discriminates between the variants { in the variant set. The tag variable is identified by a pointer { to the DST record for the tag variable. This DST pointer consists { of a byte address relative to the start of the DST. The size in { bits of this variant set, meaning the size of the largest variant { in the set, is also included. If this size is not known at compile- { time, it should be set to zero. { { This is the format of the Variant Set Begin DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_VARBEG) | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the Variant Set in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | (This name is normally null) | { | | { | | { +---------------------------------------------------------------+ { long | DST$L_VARBEG_SIZE | { +---------------------------------------------------------------+ { long | DST$L_VARBEG_TAG_PTR | { +---------------------------------------------------------------+ { { { { Define the fields of the Variant Set Begin DST record. Also define the { declaration macro for the trailer part of the record. { AGGREGATE DST$VARBEG_TRAILER STRUCTURE TYPEDEF; dst$l_varbeg_size LONGWORD UNSIGNED; { Size in bits of variant part { of record (or zero) dst$l_varbeg_tag_ptr ADDRESS; { Pointer to TAG field DST { record relative to the { start of the DST #dst$varbeg_trailer_size = :; END; { DST$VARBEG_TRAILER definition CONSTANT DST$K_VARBEG_TRAILER_SIZE EQUALS #dst$varbeg_trailer_size; { Size of Module End record in bytes { THE VARIANT VALUE DST RECORD { { { The Variant Value DST record marks the beginning of a new record { variant within a variant set. It also marks the end of the previous { variant (if any). It is always found between a Variant Set Begin { and a Variant Set End DST record. Since the Variant Set Begin DST { record has already specified the tag variable, the Variant Value { DST record only specifies the tag value or values that correspond { to the present variant. It also specifies the size in bits of this { variant if known at compile-time (otherwise zero is specified). The { Variant Value DST record is followed by the data DST records (includ- { ing nested variants if appropriate) which constitute the components { of this specific variant. { { A variant may have many tag values or tag value ranges. This DST { record thus specifies a set of tag value ranges. The way these { ranges are specified is described in detail on the following page. { { This is the format of the Variant Value DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_VARVAL) | { +---------------------------------------------------------------+ { long | DST$L_VARVAL_SIZE | { +---------------------------------------------------------------+ { word | DST$W_VARVAL_COUNT | { +---------------------------------------------------------------+ { var | DST$A_VARVAL_RNGSPEC | { | | { | Zero or More Tag Value Range Specifications | { | | { | (The number of Range Specs is given by DST$W_VARVAL_COUNT) | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Variant Value DST record. { AGGREGATE DST$VARIANT_VALUE STRUCTURE TYPEDEF; dst$a_varval_header DST$HEADER; { Header dst$l_varval_size LONGWORD UNSIGNED; { Bit size of this variant part dst$w_varval_count WORD UNSIGNED; { The number of tag value ranges { which follow #dst$variant_value_size = :; END; { DST$VARIANT_VALUE definition CONSTANT DST$K_VARIANT_VALUE_SIZE EQUALS #dst$variant_value_size; { Size of Variant value record in bytes { { Define an address for where the tag value range specs start { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_varval_rngspec = DST$K_VARIANT_VALUE_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { TAG VALUE RANGE SPECIFICATIONS { { { Each Tag Value Range Specification in a Variant Value DST record { consists of a byte specifying the kind of the range specification { followed by one or two Value Specifications. If one Value Speci- { fication is given, that gives the tag value--the range consists of { that one value. If two Value Specifications are given, they speci- { fy the lowest and highest values in the tag value range. The illu- { strations below show the two possible formats of Tag Value Range { Specifications: { { { +---------------------------------------------------------------+ { byte | DST$B_VARVAL_RNGKIND (= DST$K_VARVAL_SINGLE) | { +---------------------------------------------------------------+ { var | DST$A_VARVAL_RNGADDR | { | | { | A DST Value Specification Giving a Variant Tag Value | { | | { | | { +---------------------------------------------------------------+ { { { { +---------------------------------------------------------------+ { byte | DST$B_VARVAL_RNGKIND (= DST$K_VARVAL_RANGE) | { +---------------------------------------------------------------+ { var | DST$A_VARVAL_RNGADDR | { | | { | A DST Value Specification Giving the Lower Bound | { | | { | for a Range of Variant Tag Values | { | | { | | { +---------------------------------------------------------------+ { var | | { | A DST Value Specification Giving the Upper Bound | { | | { | for a Range of Variant Tag Values | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Tag Value Range Specification. { AGGREGATE DST$VARVAL_RANGE STRUCTURE TYPEDEF; dst$b_varval_rngkind BYTE UNSIGNED; { Tag Value Range Spec kind #dst$varval_range_size = :; END; { DST$VARVAL_RANGE definition CONSTANT DST$K_VARVAL_RANGE_SIZE EQUALS #dst$varval_range_size; { Size of fixed part of Tag Value { Range specification { { Define an address for the location of first Value Specification { in the range. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_varval_rngaddr = DST$K_VARVAL_RANGE_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the possible values of the DST$B_VARVAL_RNGKIND field. { CONSTANT DST$K_VARVAL_SINGLE EQUALS 1; { The range consists of a single value CONSTANT DST$K_VARVAL_RANGE EQUALS 2; { The range is given by a lower and an { upper bound (two value specs). { THE VARIANT SET END DST RECORD { { { The Variant Set End DST record marks the end of record variant set; { it terminates a set of variants which have the same tag variable. { This is the format of the Variant Set End DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_VAREND) | { +---------------------------------------------------------------+ { AGGREGATE DST$VARIANT_SET_END STRUCTURE TYPEDEF; dst$a_varset_end_header DST$HEADER; { Header #dst$variant_set_end_size = :; END; { DST$VARIANT_SET_END definition CONSTANT DST$K_VARSET_END_SIZE EQUALS #dst$variant_set_end_size; { Size of Variant Set End record in bytes { D A T A S Y M B O L D S T R E C O R D S { { { { Data symbols are represented in the Debug Symbol Table by data DST { records which come in several varieties. All such DST records give { three pieces of information about each symbol: the data type of the { symbol, the value or address or the symbol, and the name of the { symbol. { { The Standard Data DST record is the simplest form of data DST symbol { record and is used for most ordinary atomic data objects. It repre- { sents the data type by a one-byte VAX Standard Type Code. It repre- { sents the value or address of the symbol by a simple five-byte encoding { capable of specifying 32-bit literal values, absolute addresses, reg- { ister locations, and addresses computed as offsets from a register, { possibly including indirection. It is also possible to specify that { the computed address is the address of a VAX Standard Descriptor for { the data symbol. Finally, the name is represented as a Counted ASCII { character string. { { There are several reasons why a Standard Data DST record may not be { adequate to represent a data symbol. First, the symbol's data type { may be too complicated to represent by a one-byte type code. In this { case, one of several available escape mechanisms must be used so that { expanded type information can be included in the symbol's DST informa- { tion. Second, if the symbol is a literal (a named constant), its { value may be too large to fit in one longword. In this case, an ex- { panded value specification must be used. And third, if the symbol is { a variable, its address may be specified by a more complicated compu- { tation than can be represented in the Standard Data DST record. In { this case, an escape to a more complicated value specification must { be used. { { Expanded type specifications come in three main forms: Descriptor { Format DST records, Separate Type Specification DST records, and { various specialized DST records that handle various special kinds { of data types such as record structures, enumeration types, and { BLISS structures. { { Descriptor Format DST records are used when the data object must be { described by a VAX Standard Descriptor and has a static address. A { packed decimal data object, for example, must be described by a { descriptor that specifies the object's length and scale factor. If { a descriptor exists in user memory at run-time, the Standard Data { DST record can be used, but otherwise it is necessary to include the { descriptor directly in the DST within a Descriptor Format DST record. { These DST records are used for all static arrays and other data objects { that can be described by VAX Standard Descriptors. { { For data types that can be described by neither one-byte type codes { nor VAX Standard Descriptors, a Separate Type Specification DST record { must be used. In this case the DST record's type field indicates that { the type specification is found is a separate DST record which imme- { diately follows the present DST record. The DST record that follows { must be a Type Specification, Record Begin, or Enumeration Type Begin { DST record. These records can describe all data types supported by { DEBUG in full detail. { { As mentioned above, the third data type "escape" mechanism is to use { one of a number of specialized DST records that describe data symbols { of special kinds. BLISS structures and fields, for example, are de- { scribed by special DST records, as are enumeration type elements. { These DST records will not be further described in this section; they { are described elsewhere in this definition file. { { Expanded "Value Specifications" must be used for data symbols whose { values or addresses are too long or too complicated to be described { by the Standard Data DST record. Indirection or displacement off of { Alpha registers R0 through R15, for example, cannot be described in { the Standard Data DST record. A D-Floating constant, for example, { has too large a value (8 bytes) to fit in a Standard Data DST record. { A "based variable" in PL/I may require a complicated computation or { even a call on a compiler-generated thunk to compute the variable's { address. For these and other cases, a Trailing Value Specification { DST record must be used. Such a record includes a Value Specifica- { tion which may be arbitrarily complex. { { Trailing Value Specification DST records are sometimes used to speci- { fy both type and address information. An array with dynamic array { bounds, for instance, must be described in the DST if no descriptor { exists in user memory at run-time. A Trailing Value Specification { can be used to compute the entire descriptor for such an array at { DEBUG-time. The descriptor then gives both the array address and { type information such as the element type and the array bounds. { THE STANDARD DATA DST RECORD { { { The Standard Data DST record is used to describe most simple scalar { data objects such as integers, floating-point numbers, and complex { numbers. The data type is represented by the one-byte VAX Standard { Type Code in the DST$W_TYPE field. The value DST$K_BOOL is also { accepted; it denotes that the data symbol is a Boolean variable or { value which is TRUE if the low-order bit is set and FALSE otherwise. { { The value specification in the Standard Data DST record indicates { the symbol's value or address or how to compute the symbol's address. { The details are found below. { { This is the format of the Standard Data DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE | { +-------------------------------+-------+-------+---------------+ { byte | DST$V_REGNUM | DISP | INDIR | DST$V_VALKIND | { +-------------------------------+-------+-------+---------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Symbol Name in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { Define the Standard Data DST header, which is shared by many of the { definitions that follow { AGGREGATE DST$DATA_HEADER STRUCTURE TYPEDEF; dst$a_data_header DST$HEADER; { Header dst$b_vflags STRUCTURE; { Value-Flags (access information) dst$v_valkind BITFIELD LENGTH 2; { How to interpret the specified value dst$v_indirect BITFIELD LENGTH 1; { Set if address of address is produced { by indicated computation (do an { indirection to compute address) dst$v_disp BITFIELD LENGTH 1; { Set if content of DST$L_VALUE is used { as a displacement off a register { specified in DST$V_REGNUM dst$v_regnum BITFIELD LENGTH 4; { Number of register used in displace- { ment mode addressing END dst$b_vflags; #dst$standard_data_header_size = :; END; { DST$DATA_HEADER definition CONSTANT DST$K_DATA_HEADER_SIZE EQUALS #dst$standard_data_header_size; { Size of Standard Data DST header { portion of record in bytes { { Define the fields of the Standard Data DST record. These fields are also { used in many other DST records of similar formats. { AGGREGATE DST$DATA_DST STRUCTURE TYPEDEF; dst$a_data_dst_header DST$DATA_HEADER; { Header dst$l_value LONGWORD UNSIGNED; { Value, address, or bit offset dst$b_name BYTE UNSIGNED; { Count byte of the symbol name field, { a counted ASCII string #dst$standard_data_size = :; END; { DST$DATA_DST definition CONSTANT DST$K_DATA_SIZE EQUALS #dst$standard_data_size; { Size of Standard Data DST record in bytes { WARNING: Special BLISS workaround follows. { { The MACRO that SDL generates for the above aggregate definition is not { very useful, because the FIELDSET does not include the DATA DST header { fields. This works around the problem by undeclaring the MACRO and then { redefining it such that the FIELDSET is included. { IFLANGUAGE BLISSF; LITERAL; UNDECLARE %QUOTE DST$DATA_DST; MACRO DST$DATA_DST = BLOCK[S_DST$DATA_DST,BYTE] FIELD(DST$DATA_HEADER_FIELDSET, DST$DATA_DST_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define all special values that may appear in the DST$B_VFLAGS field. If one { of these values appears in that field, the DST$L_VALUE field has some special { meaning indicated by the special value. In such cases, the DST$B_VFLAGS sub- { fields have no meaning. Not all of these special values may appear in a { Standard Data DST record (see the comments below), but they are all listed { here for completeness. Note that these values (with one exception) all have { the top four bits set--hence they cannot be normal VFLAGS values since the { REGNUM field cannot contain 15 (indicating the PC) in a normal VFLAGS value. { CONSTANT DST$K_VFLAGS_NOVAL EQUALS 128; { A flag which indicates that no value { is specified, i.e. the object { being described is a type. This { value may only appear in a Record { Begin DST record. CONSTANT DST$K_VFLAGS_NOTACTIVE EQUALS 248; { This value in DST$B_VFLAGS signals a { data item that has an address, but { not one which is active at the { current pc. Thus, this is most { likely to occur within a split { lifetime DST. Possible uses of { this encoding are for Ada scoping { rules, where a symbol isn't active { until it's been elaborated. { Contrast this meaning with the one { for UNALLOC (below), which means { that the item is NEVER in memory. { CONSTANT DST$K_VFLAGS_UNALLOC EQUALS 249; { This value in DST$B_VFLAGS signals a { data item that was never { allocated (and hence has no { address). For example, PASCAL { does not allocate variables { that are not referenced. { { Note: This code is not supported { inside of a Type Specification { DST record. That is, many { Type Specs have embedded Value { Specs, but we do not support { the "unalloc" DST in these { embedded Value Specs. We also do { not support this { record as the value of an { enumeration literal. { It is only supported in the VFLAGS { field of a data DST record. { { The above restrictions are only { natural: data can be "unallocated", { it does not make sense for type { specifications to be "unallocated" { or enumeration literals to be { unallocated. { CONSTANT DST$K_VFLAGS_DSC EQUALS 250; { This value in DST$B_VFLAGS signals a { Descriptor Format DST record { or Descriptor Value Specification CONSTANT DST$K_VFLAGS_TVS EQUALS 251; { This value in DST$B_VFLAGS signals a { Trailing Value Spec DST record CONSTANT DST$K_VS_FOLLOWS EQUALS 253; { Value Specification Follows (allowed { only in a Trailing Value Spec) CONSTANT DST$K_VFLAGS_BITOFFS EQUALS 255; { A flag indicating that DST$L_VALUE { contains a bit offset (used { only for record components) { { Provided the DBG$B_VFLAGS field does not have one of the above special values, { the DBG$V_VALKIND field indicates what kind of value or address is computed { by the value computation. The possible values of this field are defined here. { CONSTANT DST$K_VALKIND_LITERAL EQUALS 0; { DST$L_VALUE contains a literal value CONSTANT DST$K_VALKIND_ADDR EQUALS 1; { Computation produces the address of { the data object CONSTANT DST$K_VALKIND_DESC EQUALS 2; { Computation produces the address of a { VAX Standard Descriptor for the { data object CONSTANT DST$K_VALKIND_REG EQUALS 3; { Value is contained in the register { whose number is in DST$L_VALUE { Define some range numbers for the VALKIND literals { CONSTANT DST$K_VALKIND_MIN EQUALS 0; CONSTANT DST$K_VALKIND_MAX EQUALS 3; { If the DST$K_VFLAGS field does not contain one of the special values listed { above, then the computation that produces the value or address of the data { object proceeds as follows: { { 1. If the VALKIND field contains DST$K_VALKIND_LITERAL, the symbol is a { constant whose value is given by the DST$L_VALUE field. Such constants { can be up to 32 bits long. { { 2. If the VALKIND field contains DST$K_VALKIND_REG, then the value { in DST$L_VALUE is picked up and interpreted as a register number. { If the DST$V_INDIRECT bit is not set, then the value spec describes { a variable bound to that register. If the DST$V_INDIRECT bit is { set then the value spec describes a variable whose address is { the contents of that register. { { 3. Otherwise, the symbol is a variable with a non-register address. To { compute that address, the DST$L_VALUE field is picked up. { { 4. If the DST$V_DISP bit is set, the contents of the register whose reg- { ister number is given by the DST$V_REGNUM field is added to the value { picked up from the DST$L_VALUE field. { { 5. If the DST$V_INDIRECT bit is set, the address computed so far is treated { as the address of a pointer that points to the actual data object. In { other words, an indirection is done. { { 6. If the value of the VALKIND field is DST$K_VALKIND_ADDR, the address { computed so far is treated as the address of the data object. { { 7. If the value of the VALKIND field is DST$K_VALKIND_DESC, the address { computed so far is treated as the address of a VAX Standard Descriptor { for the data object. The actual address of the object, along with its { other attributes such as type and size, must therefore be retrieved { from that descriptor. { { As this description indicates, moderately complicated address computations { can be specified in the Standard Data DST record. For example, the address { of the second formal parameter to a routine, passed by reference, can be { described by making DST$V_REGNUM = 12 (for register AP), DST$L_VALUE = 8 { (to indicate an offset of 8 bytes from AP to get at the second longword in { the argument vector), DST$V_DISP = 1 (to indicate that DST$L_VALUE is to be { treated as a displacement off AP), and DST$V_INDIRECT = 1 (to indicate an { indirection since the argument is passed by reference). DST$V_VALKIND = { DST$K_VALKIND_ADDR in this case. If the parameter were passed by descrip- { tor, however, DST$V_VALKIND should be DST$K_VALKINKD_DESC, with all other { fields having the same values as in the passed-by-reference case. { { The following defines the literal values for registers. All of the following { values can be placed in the DST$L_VALUE field when the DST$V_VALKIND field { contains DST$K_VALKIND_REG. Due to size restrictions, only some of these { values can be placed into the DST$V_REGNUM field (ie, only those with values { between 0 and 15). For these cases, use a trailing value specification { (DST$K_VS_FOLLOWS) to an Extended Value Specification. { { Literals will be defined here for the register sets for all of the supported { architectures. A compiler will only use the relevant architecture's literal { values, but they are all defined here for simplicity. { CONSTANT DST$K_NO_SUCH_REG EQUALS -1; { { Register numbers for VAX { #minimum_vax_reg_number = 0; CONSTANT ( DST$K_REG_VAX_R0, { 0 DST$K_REG_VAX_R1, { 1 DST$K_REG_VAX_R2, { 2 DST$K_REG_VAX_R3, { 3 DST$K_REG_VAX_R4, { 4 DST$K_REG_VAX_R5, { 5 DST$K_REG_VAX_R6, { 6 DST$K_REG_VAX_R7, { 7 DST$K_REG_VAX_R8, { 8 DST$K_REG_VAX_R9, { 9 DST$K_REG_VAX_R10, { 10 DST$K_REG_VAX_R11, { 11 DST$K_REG_VAX_R12, { 12 DST$K_REG_VAX_R13, { 13 DST$K_REG_VAX_R14, { 14 DST$K_REG_VAX_R15, { 15 DST$K_REG_VAX_PSL, { 16 DST$K_REG_VAX_V0, { 17 DST$K_REG_VAX_V1, { 18 DST$K_REG_VAX_V2, { 19 DST$K_REG_VAX_V3, { 20 DST$K_REG_VAX_V4, { 21 DST$K_REG_VAX_V5, { 22 DST$K_REG_VAX_V6, { 23 DST$K_REG_VAX_V7, { 24 DST$K_REG_VAX_V8, { 25 DST$K_REG_VAX_V9, { 26 DST$K_REG_VAX_V10, { 27 DST$K_REG_VAX_V11, { 28 DST$K_REG_VAX_V12, { 29 DST$K_REG_VAX_V13, { 30 DST$K_REG_VAX_V14, { 31 DST$K_REG_VAX_V15, { 32 DST$K_REG_VAX_VCR, { 33 DST$K_REG_VAX_VLR, { 34 DST$K_REG_VAX_VMR { 35 { ??? Should we define VMRHI and VMRLO ??? ) equals #minimum_vax_reg_number increment 1 counter #vax_reg_counter; CONSTANT DST$K_REG_VAX_MIN EQUALS #minimum_vax_reg_number; CONSTANT DST$K_REG_VAX_MAX EQUALS #vax_reg_counter; { { Define a few register aliases { CONSTANT DST$K_REG_VAX_AP EQUALS DST$K_REG_VAX_R12; CONSTANT DST$K_REG_VAX_FP EQUALS DST$K_REG_VAX_R13; CONSTANT DST$K_REG_VAX_SP EQUALS DST$K_REG_VAX_R14; CONSTANT DST$K_REG_VAX_PC EQUALS DST$K_REG_VAX_R15; CONSTANT DST$K_REG_VAX_PS EQUALS DST$K_REG_VAX_PSL; { { Some range definitions... { CONSTANT DST$K_REG_VAX_MIN_SCALAR EQUALS DST$K_REG_VAX_R0; CONSTANT DST$K_REG_VAX_MAX_SCALAR EQUALS DST$K_REG_VAX_R15; CONSTANT DST$K_REG_VAX_MIN_FLOAT EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_VAX_MAX_FLOAT EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_VAX_MIN_REAL_VECTOR EQUALS DST$K_REG_VAX_V0; CONSTANT DST$K_REG_VAX_MAX_REAL_VECTOR EQUALS DST$K_REG_VAX_V15; CONSTANT DST$K_REG_VAX_MIN_VECTOR EQUALS DST$K_REG_VAX_V0; CONSTANT DST$K_REG_VAX_MAX_VECTOR EQUALS DST$K_REG_VAX_VMR; { { Register numbers for Alpha VAX { #minimum_alpha_reg_number = 36; CONSTANT ( DST$K_REG_ALPHA_R0, { 36 DST$K_REG_ALPHA_R1, { 37 DST$K_REG_ALPHA_R2, { 38 DST$K_REG_ALPHA_R3, { 39 DST$K_REG_ALPHA_R4, { 40 DST$K_REG_ALPHA_R5, { 41 DST$K_REG_ALPHA_R6, { 42 DST$K_REG_ALPHA_R7, { 43 DST$K_REG_ALPHA_R8, { 44 DST$K_REG_ALPHA_R9, { 45 DST$K_REG_ALPHA_R10, { 46 DST$K_REG_ALPHA_R11, { 47 DST$K_REG_ALPHA_R12, { 48 DST$K_REG_ALPHA_R13, { 49 DST$K_REG_ALPHA_R14, { 50 DST$K_REG_ALPHA_R15, { 51 DST$K_REG_ALPHA_R16, { 52 DST$K_REG_ALPHA_R17, { 53 DST$K_REG_ALPHA_R18, { 54 DST$K_REG_ALPHA_R19, { 55 DST$K_REG_ALPHA_R20, { 56 DST$K_REG_ALPHA_R21, { 57 DST$K_REG_ALPHA_R22, { 58 DST$K_REG_ALPHA_R23, { 59 DST$K_REG_ALPHA_R24, { 60 DST$K_REG_ALPHA_R25, { 61 DST$K_REG_ALPHA_R26, { 62 DST$K_REG_ALPHA_R27, { 63 DST$K_REG_ALPHA_R28, { 64 DST$K_REG_ALPHA_R29, { 65 DST$K_REG_ALPHA_R30, { 66 DST$K_REG_ALPHA_R31, { 67 { { Alpha floating point registers. { DST$K_REG_ALPHA_F0, { 68 DST$K_REG_ALPHA_F1, { 69 DST$K_REG_ALPHA_F2, { 70 DST$K_REG_ALPHA_F3, { 71 DST$K_REG_ALPHA_F4, { 72 DST$K_REG_ALPHA_F5, { 73 DST$K_REG_ALPHA_F6, { 74 DST$K_REG_ALPHA_F7, { 75 DST$K_REG_ALPHA_F8, { 76 DST$K_REG_ALPHA_F9, { 77 DST$K_REG_ALPHA_F10, { 78 DST$K_REG_ALPHA_F11, { 79 DST$K_REG_ALPHA_F12, { 80 DST$K_REG_ALPHA_F13, { 81 DST$K_REG_ALPHA_F14, { 82 DST$K_REG_ALPHA_F15, { 83 DST$K_REG_ALPHA_F16, { 84 DST$K_REG_ALPHA_F17, { 85 DST$K_REG_ALPHA_F18, { 86 DST$K_REG_ALPHA_F19, { 87 DST$K_REG_ALPHA_F20, { 88 DST$K_REG_ALPHA_F21, { 89 DST$K_REG_ALPHA_F22, { 90 DST$K_REG_ALPHA_F23, { 91 DST$K_REG_ALPHA_F24, { 92 DST$K_REG_ALPHA_F25, { 93 DST$K_REG_ALPHA_F26, { 94 DST$K_REG_ALPHA_F27, { 95 DST$K_REG_ALPHA_F28, { 96 DST$K_REG_ALPHA_F29, { 97 DST$K_REG_ALPHA_F30, { 98 DST$K_REG_ALPHA_F31, { 99 { { Some special alpha registers. { DST$K_REG_ALPHA_PC, { 100 Program counter DST$K_REG_ALPHA_PS, { 101 Program status DST$K_REG_ALPHA_FPCR, { 102 Floating point control register DST$K_REG_ALPHA_SFPCR { 103 Software floating point control register ) equals #minimum_alpha_reg_number increment 1 counter #alpha_reg_counter; CONSTANT DST$K_REG_ALPHA_MIN EQUALS #minimum_alpha_reg_number; CONSTANT DST$K_REG_ALPHA_MAX EQUALS #alpha_reg_counter; { { Define a few register aliases { CONSTANT DST$K_REG_ALPHA_AI EQUALS DST$K_REG_ALPHA_R25; { R25 is the Argument Information register CONSTANT DST$K_REG_ALPHA_RA EQUALS DST$K_REG_ALPHA_R26; { R26 is the Return Address register CONSTANT DST$K_REG_ALPHA_PV EQUALS DST$K_REG_ALPHA_R27; { R27 is the Procedure Value register CONSTANT DST$K_REG_ALPHA_FP EQUALS DST$K_REG_ALPHA_R29; { R29 is the frame pointer CONSTANT DST$K_REG_ALPHA_SP EQUALS DST$K_REG_ALPHA_R30; { R30 is the stack pointer { { Special definitions for FP and SP so that they can be used in the REGNUM { field of a value spec. { CONSTANT DST$K_REG_ALPHA_REGNUM_FP EQUALS DST$K_REG_VAX_FP; CONSTANT DST$K_REG_ALPHA_REGNUM_SP EQUALS DST$K_REG_VAX_SP; { { For Alpha, the DST$V_VS_REGNUM field of a standard value specification is { not large enough to hold the Alpha register numbers. So, a special { exception is made: if the constants DST$K_REG_ALPHA_REGNUM_FP or { DST$K_REG_ALPHA_REGNUM_SP are stored in this field, then those values { are converted to mean DST$K_REG_ALPHA_FP and DST$K_REGT_ALPHA_SP, { respectively. This special BLISS macro performs that conversion. { IFLANGUAGE BLISSF; LITERAL; MACRO $DBG_VS_REGNUM(NUM) = ( %IF DBG$K_TARGET_IS_ALPHA %THEN IF ((NUM) EQLU DST$K_REG_ALPHA_REGNUM_FP) THEN (DST$K_REG_ALPHA_FP) ELSE IF ((NUM) EQLU DST$K_REG_ALPHA_REGNUM_SP) THEN (DST$K_REG_ALPHA_SP) ELSE (NUM) %ELSE (NUM) %FI ) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { Some range definitions... { CONSTANT DST$K_REG_ALPHA_MIN_SCALAR EQUALS DST$K_REG_ALPHA_R0; CONSTANT DST$K_REG_ALPHA_MAX_SCALAR EQUALS DST$K_REG_ALPHA_R31; CONSTANT DST$K_REG_ALPHA_MIN_FLOAT EQUALS DST$K_REG_ALPHA_F0; CONSTANT DST$K_REG_ALPHA_MAX_FLOAT EQUALS DST$K_REG_ALPHA_F31; CONSTANT DST$K_REG_ALPHA_MIN_VECTOR EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_ALPHA_MAX_VECTOR EQUALS DST$K_NO_SUCH_REG; { { Register numbers for 68xxx/68881 { #minimum_m68_reg_number = 0; CONSTANT ( DST$K_REG_M68_A0, { 0 DST$K_REG_M68_A1, { 1 DST$K_REG_M68_A2, { 2 DST$K_REG_M68_A3, { 3 DST$K_REG_M68_A4, { 4 DST$K_REG_M68_A5, { 5 DST$K_REG_M68_A6, { 6 DST$K_REG_M68_A7, { 7 DST$K_REG_M68_D0, { 8 DST$K_REG_M68_D1, { 9 DST$K_REG_M68_D2, { 10 DST$K_REG_M68_D3, { 11 DST$K_REG_M68_D4, { 12 DST$K_REG_M68_D5, { 13 DST$K_REG_M68_D6, { 14 DST$K_REG_M68_D7, { 15 DST$K_REG_M68_FP0, { 16 DST$K_REG_M68_FP1, { 17 DST$K_REG_M68_FP2, { 18 DST$K_REG_M68_FP3, { 19 DST$K_REG_M68_FP4, { 20 DST$K_REG_M68_FP5, { 21 DST$K_REG_M68_FP6, { 22 DST$K_REG_M68_FP7, { 23 {************************************************************************** { { Compilers must not generate any DSTs with the following register numbers. { {************************************************************************** DST$K_REG_M68_PC, { 24 DST$K_REG_M68_SR, { 25 DST$K_REG_M68_FPCR, { 26 DST$K_REG_M68_FPSR, { 27 DST$K_REG_M68_FPIAR, { 28 DST$K_REG_M68_USP, { 29 DST$K_REG_M68_MSP, { 30 DST$K_REG_M68_CAAR, { 31 DST$K_REG_M68_CACR, { 32 DST$K_REG_M68_VBR, { 33 DST$K_REG_M68_SFC, { 34 DST$K_REG_M68_DFC { 35 ) equals #minimum_m68_reg_number increment 1 counter #m68_reg_counter; CONSTANT DST$K_REG_M68_MIN EQUALS #minimum_m68_reg_number; CONSTANT DST$K_REG_M68_MAX EQUALS #m68_reg_counter; { { Some range definitions... { CONSTANT DST$K_REG_M68_MIN_SCALAR EQUALS DST$K_REG_M68_A0; CONSTANT DST$K_REG_M68_MAX_SCALAR EQUALS DST$K_REG_M68_D7; CONSTANT DST$K_REG_M68_MIN_FLOAT EQUALS DST$K_REG_M68_FP0; CONSTANT DST$K_REG_M68_MAX_FLOAT EQUALS DST$K_REG_M68_FP7; CONSTANT DST$K_REG_M68_MIN_VECTOR EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_M68_MAX_VECTOR EQUALS DST$K_NO_SUCH_REG; { { Register numbers for MIL STD 1750 { #minimum_1750_reg_number = 0; CONSTANT ( { { These numbers are mapped backwards... { DST$K_REG_1750_R15, { 0 DST$K_REG_1750_R14, { 1 DST$K_REG_1750_R13, { 2 DST$K_REG_1750_R12, { 3 DST$K_REG_1750_R11, { 4 DST$K_REG_1750_R10, { 5 DST$K_REG_1750_R9, { 6 DST$K_REG_1750_R8, { 7 DST$K_REG_1750_R7, { 8 DST$K_REG_1750_R6, { 9 DST$K_REG_1750_R5, { 10 DST$K_REG_1750_R4, { 11 DST$K_REG_1750_R3, { 12 DST$K_REG_1750_R2, { 13 DST$K_REG_1750_R1, { 14 DST$K_REG_1750_R0, { 15 {************************************************************************** { { Compilers must not generate any DSTs with the following register numbers. { {************************************************************************** DST$K_REG_1750_PC, { 16 DST$K_REG_1750_SW, { 17 DST$K_REG_1750_FT, { 18 DST$K_REG_1750_MK, { 19 DST$K_REG_1750_PI, { 20 DST$K_REG_1750_IOIC, { 21 DST$K_REG_1750_MFSR, { 22 DST$K_REG_1750_PAGE, { 23 ) equals #minimum_1750_reg_number increment 1 counter #1750_reg_counter; CONSTANT DST$K_REG_1750_MIN EQUALS #minimum_1750_reg_number; CONSTANT DST$K_REG_1750_MAX EQUALS #1750_reg_counter; { { Some alias definitions { CONSTANT DST$K_REG_1750_SP EQUALS DST$K_REG_1750_R11; CONSTANT DST$K_REG_1750_FP EQUALS DST$K_REG_1750_R15; CONSTANT DST$K_REG_1750_IC EQUALS DST$K_REG_1750_PC; { { Some range definitions... { CONSTANT DST$K_REG_1750_MIN_SCALAR EQUALS DST$K_REG_1750_R15; CONSTANT DST$K_REG_1750_MAX_SCALAR EQUALS DST$K_REG_1750_R0; CONSTANT DST$K_REG_1750_MIN_INDEX EQUALS DST$K_REG_1750_R15; CONSTANT DST$K_REG_1750_MAX_INDEX EQUALS DST$K_REG_1750_R1; CONSTANT DST$K_REG_1750_MIN_BASE EQUALS DST$K_REG_1750_R15; CONSTANT DST$K_REG_1750_MAX_BASE EQUALS DST$K_REG_1750_R12; CONSTANT DST$K_REG_1750_MIN_FLOAT EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_1750_MAX_FLOAT EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_1750_MIN_VECTOR EQUALS DST$K_NO_SUCH_REG; CONSTANT DST$K_REG_1750_MAX_VECTOR EQUALS DST$K_NO_SUCH_REG; { THE DESCRIPTOR FORMAT DST RECORD { { { The Descriptor Format DST record is used when a VAX Standard { Descriptor must be included in the DST for a static symbol. It { includes the descriptor directly in the DST record right after { the name field. This record is essentially identical to the { Standard Data DST record except that the DST$B_VFLAGS field has { the special value DST$K_VFLAGS_DSC and the DST$L_VALUE field is { a relative byte offset to the VAX descriptor later in the record. { This is the format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS (= DST$K_VFLAGS_DSC) | { +---------------------------------------------------------------+ { long | DST$L_DSC_OFFS |---+ { +---------------------------------------------------------------+ | { byte | DST$B_NAME (also DST$A_DSC_BASE) | | { +---------------------------------------------------------------+ | { var | | | { | The Symbol Name in ASCII | | { | | | { | (The name's length is given by DST$B_NAME) | | { | | | { | | | { +---------------+---------------+-------------------------------+ | { long | DSC$B_CLASS | DSC$B_DTYPE | DSC$W_LENGTH |<--+ { +---------------+---------------+-------------------------------+ { long | DSC$A_POINTER | { +---------------------------------------------------------------+ { var | | { | Other VAX Standard Descriptor Fields | { | | { | depending on the descriptor class | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Descriptor Format DST record. { AGGREGATE DST$DESCRIPTOR_FORMAT STRUCTURE TYPEDEF; dst$a_dsc_format_header DST$DATA_HEADER; { Header. Flags have { special value of { DST$K_VFLAGS_DSC dst$l_dsc_offs LONGWORD UNSIGNED; { Offset in bytes to descriptor { from DST$A_DSC_BASE #dst$descriptor_format_size = :; END; { DST$DESCRIPTOR_FORMAT definition CONSTANT DST$K_DESCRIPTOR_FORMAT_SIZE EQUALS #dst$descriptor_format_size; { Size of Descriptor Format { DST record in bytes { { Define the base to use when computing where the descriptor starts { The address of the descriptor is computed as follows: { { DST_RECORD[DST$A_DSC_BASE] + .DST_RECORD[DST$L_DSC_OFFS] { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_dsc_base = DST$K_DESCRIPTOR_FORMAT_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { WARNING: Special BLISS workaround follows. { { The MACRO that SDL generates for the above aggregate definition is not { very useful, because the FIELDSET does not include either the DATA DST header { fields nor the DATA DST structure fields. This works around the problem by { undeclaring the MACRO and then redefining it such that the missing FIELDSETs { are included. { IFLANGUAGE BLISSF; LITERAL; UNDECLARE %QUOTE DST$DESCRIPTOR_FORMAT; MACRO DST$DESCRIPTOR_FORMAT = BLOCK[S_DST$DESCRIPTOR_FORMAT,BYTE] FIELD( DST$DATA_HEADER_FIELDSET, DST$DATA_DST_FIELDSET, DST$DESCRIPTOR_FORMAT_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { THE TRAILING VALUE SPECIFICATION DST RECORD { { { The Trailing Value Specification DST record is used when an expanded { value specification is needed to compute a data symbol's value or { address. It includes a Value Specification directly in the DST rec- { ord right after the name field. This record is essentially identical { to the Standard Data DST record except that the DST$B_VFLAGS field has { the special value DST$K_VFLAGS_TVS and the DST$L_VALUE field is a { relative byte offset to the Value Specification later in the record. { This is the format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS (= DST$K_VFLAGS_TVS) | { +---------------------------------------------------------------+ { long | DST$L_TVS_OFFSET |---+ { +---------------------------------------------------------------+ | { byte | DST$B_NAME (also DST$A_TVS_BASE) | | { +---------------------------------------------------------------+ | { var | | | { | The Symbol Name in ASCII | | { | | | { | (The name's length is given by DST$B_NAME) | | { | | | { | | | { +---------------------------------------------------------------+ | { var | |<--+ { | DST Value Specification | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Trailing Value Specification DST record. { AGGREGATE DST$TRAILING_VALSPEC STRUCTURE TYPEDEF; dst$a_tvs_header DST$DATA_HEADER; { Header. Flags have { special value of { DST$K_VFLAGS_TVS dst$l_tvs_offset LONGWORD UNSIGNED; { Offset in bytes to trailing Value Spec { from DST$A_TVS_BASE #dst$trailing_value_spec_size = :; END; { DST$TRAILING_VALSPEC definition CONSTANT DST$K_TRAILING_VALSPEC_SIZE EQUALS #dst$trailing_value_spec_size; { Size of Trailing Value Spec { DST record in bytes { { Define the base to use when computing where the value descriptor { starts. The address of the trailing Value Specification is { computed as follows: { { DST_RECORD[DST$A_TVS_BASE] + .DST_RECORD[DST$L_TVS_OFFSET] { { { Also note that Value Specifications are described in a separate section { later in this definition file. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_tvs_base = DST$K_TRAILING_VALSPEC_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { THE SEPARATE TYPE SPECIFICATION DST RECORD { { { The Separate Type Specification DST record is used when the data type { of the symbol being described is too complex to be described by a { a one-byte type code or a VAX Standard Descriptor. This DST record { must be immediately followed by a Type Specification, Record Begin, { or Enumeration Type Begin DST record which describes the data type { of the data symbol. (Only Continuation DST records may intervene.) { The format of the Separate Type Specification DST record is essential- { ly identical to that of the Standard Data DST record. It may contain { a Trailing Value Specification if necessary to describe the symbol's { value or address. This is the format of the record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_SEPTYP) | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Symbol Name in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { var | | { | A Trailing Value Specification or nothing, | { | | { | depending on the value of DST$B_VFLAGS field | { | | { | | { +---------------------------------------------------------------+ { { { Define a constant for the size of the fixed portion of the Separate Type { DST Record. Because this shares the same fields as the Data DST record, { it also shares the same size. { CONSTANT DST$K_SEPTYP_SIZE EQUALS DST$K_DATA_SIZE; { D S T V A L U E S P E C I F I C A T I O N S { { { { A DST Value Specification specifies the value or address of some symbol. { Value Specification can occur in a number of places in the Debug Symbol { Table. The simplest forms of Value Specifications occur in the Standard { Data DST record. A somewhat more complicated form occurs in Descriptor { Format DST records where a VAX Standard Descriptor is included in the { DST record to give more complete address information (and type informa- { tion). The Trailing Value Specification DST record has a simple five- { byte Value Specification at the beginning of the record which points to { a more complex Value Specification at the end of the record. That more { complex Value Specification can be any kind of Value Specification, in- { cluding the most general forms. An extended value specification is for { defining addresses that are indexed or displaced off a register and { the register number is larger than will fit in the DST$V_REGNUM field { of a standard value specification. { { In addition, Value Specifications may occur in a number of Type Speci- { fications. In these cases, they typically generate values (as opposed { to addresses), such as subrange bounds for a subrange data type, or they { generate full VAX Standard Descriptors in order to specify some sort of { data type, such as a dynamic array. { { All Value Specifications start with one byte, the DST$B_VS_VFLAGS field. { In Standard Data DST records, this field and the DST$B_VFLAGS field are { synonymous. If this field has one of the special values DST$K_VFLAGS_xx { described in the Standard Data DST Record section above, the format of { the Value Specification depends on that value. Otherwise the VFLAGS { field is interpreted as a set of subfields, namely DST$V_VS_REGNUM, { DST$V_VS_DISP, DST$V_VS_INDIRECT, and DST$K_VS_VALKIND. This is also { described in detail in the Standard Data DST Record section above. { { { { STANDARD VALUE SPECIFICATIONS { { { As indicated above, if the DST$B_VS_VFLAGS field does not have a special { value, the Value Specification is a Standard Value Specification and has { the following structure: { { { +-------------------------------+-------+-------+---------------+ { byte | DST$V_VS_REGNUM | DISP | INDIR | $V_VS_VALKIND | { +-------------------------------+-------+-------+---------------+ { long | DST$L_VS_VALUE | { +---------------------------------------------------------------+ { { { DESCRIPTOR VALUE SPECIFICATIONS { { { If the DST$B_VS_VFLAGS field has the special value DST$K_VFLAGS_DSC, { this is a Descriptor Value Specification. Such a Value Specification { contains an offset relative to the end of the Value Specification that { points to a VAX Standard Descriptor later in the same DST record. That { descriptor then contains the actual address that the Value Specifica- { tion seeks to specify. This is thus the format: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (= DST$K_VFLAGS_DSC) | { +---------------------------------------------------------------+ { long | DST$L_VS_DSC_OFFS |---+ { +---------------------------------------------------------------+ | { var | DST$A_VS_DSC_BASE | | { | | | { | Other Fields in DST Record | | { | | | { | | | { +---------------------------------------------------------------+ | { var | |<--+ { | | { | VAX Standard Descriptor Giving Symbol Address | { | | { | | { +---------------------------------------------------------------+ { { { { The address of the VAX Standard Descriptor is computed as follows: { { DSC_PTR = VS_PTR[DST$A_VS_DSC_BASE] + .VS_PTR[DST$L_VS_DSC_OFFS]; { TRAILING VALUE SPEC VALUE SPECIFICATIONS { { { If the DST$B_VS_VFLAGS field has the special value DST$K_VFLAGS_TVS, { this is a Trailing Value Spec Value Specification. Such a Value { Specification contains a pointer relative to DST$A_VS_TVS_BASE that { points to another Value Specification later in the same DST record. { This second Value Specification is normally of the most general and { powerful form of Value Specification, namely the VS-Follows Value Spec- { ification. In effect, the Trailing Value Spec format is a five-byte { Value Specification (small enough to fit in a Data DST Record) which { points to a larger Value Specification elsewhere in the same DST record. { This larger Value Specification can be arbitrarily large and complex { in order to do whatever computation is necessary to obtain the desired { value, address, or descriptor. { { This is the format of the Trailing Value Spec Value Specification: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (= DST$K_VFLAGS_TVS) | { +---------------------------------------------------------------+ { long | DST$L_VS_TVS_OFFSET |---+ { +---------------------------------------------------------------+ | { var | DST$A_VS_TVS_BASE | | { | | | { | Other Fields in DST Record | | { | | | { | | | { +---------------------------------------------------------------+ | { var | |<--+ { | | { | The Trailing Value Specification | { | | { | (Normally a DST$K_VS_FOLLOWS Value Specification) | { | | { | | { +---------------------------------------------------------------+ { { { { The address of the Trailing Value Specification is computed as follows: { { TVS_PTR = VS_PTR[DST$A_VS_TVS_BASE] + .VS_PTR[DST$L_VS_TVS_OFFSET]; { VS-FOLLOWS VALUE SPECIFICATIONS { { { If the DST$B_VS_VFLAGS field has the special value DST$K_VS_FOLLOWS, { this is a VS-Follows Value Specification. This is the most general { and powerful form of Value Specification. The specification itself { can be arbitrarily long, but it can also do an arbitrarily complex { computation in order to compute the desired value, address, or de- { scriptor. This is the format of the VS-Follows Value Specification: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (=DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC | { +---------------------------------------------------------------+ { var | DST$A_VS_MATSPEC | { | | { | A Materialization Specification | { | | { | | { +---------------------------------------------------------------+ { { { { A VS-Follows Value Specification contains a Materialization Specifica- { tion which indicates how the value is materialized. This specifica- { tion indicates what kind of value is being produced, by what mechanism { it is produced, and in detail how it is produced. It also contains { some flag bits. { { The kind of value being produced can be a 32-bit byte address, a 64-bit { bit address (a byte address followed by a 32-bit bit offset), a bit { offset (relative to the start of a record--used only for record compon- { ents), a literal value (a constant or "R-value"), a register address, { or an actual VAX Standard Descriptor. VAX Standard Descriptors are { mainly produced by Value Specification within Type Specifications where { a descriptor must be built to describe a data type such as an array { type with run-time subscript bounds. { { Values can be produced by two mechanisms. One is a routine call on a { compiler-generated thunk. In this case, the compiler generates a rou- { tine in the object code which when called produces the desired value. { The address of the routine is specified in the Mechanism Specification. { The other mechanism is a DST Stack Machine routine. The DST Stack { Machine is a virtual machine which DEBUG emulates. To use it, the com- { piler generates code for this virtual machine which, when executed at { DEBUG-time, produces the desired value. The DST Stack Machine form of { Mechanism Specification constitutes the most general and powerful form { of value specification supported by DEBUG. { SPLIT LIFETIME VALUE SPECS { { This value spec has a VFLAGS field of DST$K_VS_FOLLOWS and an { ALLOC field of DST$K_VS_ALLOC_SPLIT. This value spec is used { when a variable is located at different addresses depending on { the value of PC (i.e., has a split lifetime). { { By "split lifetime", we mean that, within a routine, the address { computation varies according to PC. For example, your routine may { extend from address 1000 to 1100. The variable X may be "unallocated" { between 1000 and 1010, may be in register R1 from 1010 to 1050, { and then be in stack location 20(FP) from 1050 to 1100. The { Split Lifetime Value Spec must be used to describe this. { { You do NOT need to use the Split Lifetime Value Spec to describe { the situation where the lifetime of a stack-allocated or register- { allocated variable is the entire routine it was declared in. { This is assumed to be the case when you use any of the other { kinds of Value Specs. { { The Split Lifetime Value Spec has a series of PC ranges, with { a nested Value Spec associated with each PC range. The nested { Value Spec may be any of the other kinds of value spec { (e.g., Standard Value Spec, Thunk, Stack Machine , "Unallocated", { and so on). Thus the Split Lifetime Value Spec is completely general. { { This is the format of the Split Lifetime Value Specification: { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (=DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC (= DST$K_VS_ALLOC_SPLIT) | { +---------------------------------------------------------------+ { byte | MBZ | { +---------------------------------------------------------------+ { word | DST$W_VS_NUM_BINDINGS | { +---------------------------------------------------------------+ { long | Low PC | { +---------------------------------------------------------------+ { long | High PC | { +---------------------------------------------------------------+ { word | DST$W_BS_NUM_PC_BINDINGS | { +---------------------------------------------------------------+ { var | Vector of PCs, counted by DST$W_BS_NUM_PC_BINDINGS | { +---------------------------------------------------------------+ { var | Nested Value Spec | { +---------------------------------------------------------------+ { ... { +---------------------------------------------------------------+ { long | Low PC | { +---------------------------------------------------------------+ { long | High PC | { +---------------------------------------------------------------+ { word | DST$W_BS_NUM_PC_BINDINGS | { +---------------------------------------------------------------+ { var | Vector of PCs, counted by DST$W_BS_NUM_PC_BINDINGS | { +---------------------------------------------------------------+ { var | Nested Value Spec | { +---------------------------------------------------------------+ { { The PC ranges are searched first to last, so if they overlap, { the first one covering the current PC will be chosen. { { Continuation DSTs may be used if the total length of the DST record { exceeds 255 bytes. { { Define the type and possible values for the value allocation { kind information (for the DST$B_VS_ALLOC field.) { ITEM DST$VS_ALLOC_KIND BYTE UNSIGNED TYPEDEF; { { DST$K_VS_ALLOC_STAT and DST$K_VS_ALLOC_DYN may be used interchangeably - the { information about whether the value is static or dynamic is redundant; it can { be determined from the rest of the Value Spec. { { DST$K_VS_ALLOC_SPLIT should be used to describe the address of a variable { with a split lifetime. { { DST$K_VS_ALLOC_BIASED is used for variables whose operating value (the value { seen by the user) is not the same as the value that is allocated in memory { (the internal representation of the value). { { DST$K_VS_ALLOC_XVS is used to escape to an extended value specification { (one that can handle a larger range of registers and options). { #minimum_vs_alloc_value = 1; CONSTANT ( DST$K_VS_ALLOC_STAT, { 1, Value is static DST$K_VS_ALLOC_DYN, { 2, Value is dynamic DST$K_VS_ALLOC_SPLIT, { 3, Value varies according to PC. { This code is used to describe { variables with split lifetimes. DST$K_VS_ALLOC_BIASED, { 4, The value as allocated is not the { actual value but a biased { representation DST$K_VS_ALLOC_XVS { 5, The value is described using an { extended value specification ) equals #minimum_vs_alloc_value increment 1 counter #vs_alloc_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_VS_ALLOC_MIN EQUALS #minimum_vs_alloc_value; CONSTANT DST$K_VS_ALLOC_MAX EQUALS #vs_alloc_counter; { { Define the fields of the various kinds of Value Specifications. { AGGREGATE DST$VAL_SPEC STRUCTURE TYPEDEF; dst$b_vs_vflags STRUCTURE; { Value-flags (access info) dst$v_vs_valkind BITFIELD LENGTH 2; { How to interpret the value dst$v_vs_indirect BITFIELD LENGTH 1; { Set to get indirection dst$v_vs_disp BITFIELD LENGTH 1; { Set for register displacement dst$v_vs_regnum BITFIELD LENGTH 4; { Register number for indexing END dst$b_vs_vflags; { { The Value Specification is a union of many different { possibilities: { dst$value_spec_variants UNION; { { It can be a simple value: { dst$l_vs_value LONGWORD UNSIGNED; { Value, address, or bit offset { { It can reference a descriptor { dst$l_vs_dsc_offs LONGWORD UNSIGNED; { Offset in bytes to descriptor { from DST$A_VS_DSC_BASE #dst$a_vs_dsc_base_addr = :; { { It can reference a trailing value specification { dst$l_vs_tvs_offset LONGWORD UNSIGNED; { Offset in bytes to Value Spec { from DST$A_VS_TVS_BASE #dst$a_vs_tvs_base_addr = :; { { It can reference a materialization specification { dst$a_vs_materialization_spec STRUCTURE; dst$w_vs_length WORD UNSIGNED; { Length of Value Spec in bytes { not counting the VFLAGS { and VS_LENGTH fields dst$b_vs_alloc DST$VS_ALLOC_KIND; { Allocation indicator #dst$a_vs_matspec_addr = :; #dst$a_vs_xvs_base_addr= :; { { There are additional materialization specification { fields, dependent on the value of DST$B_VS_ALLOC. { dst$a_mat_spec_info UNION; { { When the DST$B_VS_ALLOC contains DST$K_VS_ALLOC_SPLIT: { dst$b_vs_mbz BYTE UNSIGNED; { On VAX for split lifetime variables, { this field gives the number of { bindings. On AXP, this field is not { used; the number of bindings follows { in a separate structure. #dst$a_vs_bindspec_addr = :; { { When the DST$B_VS_ALLOC contains DST$K_VS_ALLOC_BIASED: { dst$b_vs_reserved BYTE UNSIGNED; { Field specifying biasing algorithm #dst$a_vs_biasing_valspec_addr = :; END dst$a_mat_spec_info; END dst$a_vs_materialization_spec; END dst$value_spec_variants; #dst$value_spec_size = :; END; { DST$VAL_SPEC definition CONSTANT DST$K_VALUE_SPEC_SIZE EQUALS #dst$value_spec_size; { Size of Value Specification { DST record in bytes { { Define a number of constants representing byte offsets of various { variant possibilities. { CONSTANT DST$K_VS_DSC_BASE EQUALS #dst$a_vs_dsc_base_addr; CONSTANT DST$K_VS_TVS_BASE EQUALS #dst$a_vs_tvs_base_addr; CONSTANT DST$K_VS_MATSPEC_BASE EQUALS #dst$a_vs_matspec_addr; CONSTANT DST$K_VS_BINDSPEC_BASE EQUALS #dst$a_vs_bindspec_addr; CONSTANT DST$K_VS_BIASING_VS_BASE EQUALS #dst$a_vs_biasing_valspec_addr; CONSTANT DST$K_VS_BIASED_VS_BASE EQUALS #dst$a_vs_biasing_valspec_addr + #dst$value_spec_size; CONSTANT DST$K_VS_XVS_BASE EQUALS #dst$a_vs_xvs_base_addr; { { Define a number of base field references for Bliss. { IFLANGUAGE BLISSF; LITERAL; MACRO DST$A_VS_DSC_BASE = DST$K_VS_DSC_BASE, 0, 0, 0%; ! Descriptor starts at this loca- ! tion + DST$L_VS_DSC_OFFS MACRO DST$A_VS_TVS_BASE = DST$K_VS_TVS_BASE, 0, 0, 0%; ! Value Spec starts at this loca- ! tion + DST$A_VS_TVS_OFFSET MACRO DST$A_VS_MATSPEC = DST$K_VS_MATSPEC_BASE, 0, 0, 0%; ! Location of Materialization ! Specification MACRO DST$A_VS_BINDSPEC = DST$K_VS_BINDSPEC_BASE, 0, 0, 0%; ! Base address of first binding ! specification within split ! lifetime value specification MACRO DST$A_VS_BIASING_VALSPEC = DST$K_VS_BIASING_VS_BASE, 0, 0, 0%; ! Value Spec of Bias to add/subtract to ! value (Note use of "biasING" to ! avoid errors) MACRO DST$A_VS_BIASED_VALSPEC = DST$K_VS_BIASED_VS_BASE, 0, 0, 0%; MACRO DST$A_VS_XVS_BASE = DST$K_VS_XVS_BASE, 0, 0, 0%; ! Base address of the Extended Value ! Spec within a standard Value ! Spec. END_LITERAL; END_IFLANGUAGE BLISSF; { { D S T B I N D I N G S P E C I F I C A T I O N { { A "Binding specification" is a sub-record within the Split Lifetime { Value Specification that indicates a value specification for a { given PC range. { { The start address of the bind spec is referenced by { [DST$A_VS_BINDSPEC], a symbolic offset from a value specification. { { +---------------------------------------+ { word | DST$W_BS_NUM_BINDINGS | { +---------------------------------------+ { long | DST$L_BS_LO_PC | { +---------------------------------------+ { long | DST$L_BS_HI_PC | { +---------------------------------------+ { word | DST$W_BS_NUM_PC_BINDINGS | { +---------------------------------------+ { var | DST$A_BS_PC_BINDINGS | { +---------------------------------------+ { var | DST$A_BS_VALSPEC | { +---------------------------------------+ { { Define the fields of the binding specification. { AGGREGATE DST$BIND_SPEC_STRUCT STRUCTURE TYPEDEF; dst$w_bs_num_bindings WORD UNSIGNED; #dst$bind_spec_struct_size = :; END; { DST$BIND_SPEC_STRUCT definition CONSTANT DST$K_BIND_SPEC_STRUCT_SIZE EQUALS #dst$bind_spec_struct_size; { { Define a base field references for Bliss. { IFLANGUAGE BLISSF; LITERAL; MACRO DST$A_BS_BINDSPEC = DST$K_BIND_SPEC_STRUCT_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; AGGREGATE DST$BIND_SPEC STRUCTURE TYPEDEF; dst$l_bs_lo_pc LONGWORD UNSIGNED; { Bind spec's low pc range dst$l_bs_hi_pc LONGWORD UNSIGNED; { Bind spec's high pc range dst$w_bs_num_pc_bindings WORD UNSIGNED; #dst$bind_spec_size = :; END; { DST$BIND_SPEC definition CONSTANT DST$K_BIND_SPEC_SIZE EQUALS #dst$bind_spec_size; { Size of Binding Specification { DST record in bytes { { Define the offset for the location of the Nested Value Spec { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_bs_pc_bindings = DST$K_BIND_SPEC_SIZE, 0, 0, 0%; MACRO dst$a_bs_valspec = DST$K_BIND_SPEC_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { CALLS ON COMPILER-GENERATED THUNKS { { { The Routine Call Mechanism Specification specifies the address of a { compiler-generated routine (a thunk) which DEBUG can call to perform { the desired value computation. This form of Mechanism Specification { must be used for PL/I "BASED" variables since the address of such a { variable can depend on the value returned by a user-defined function. { In this case, the Mechanism Specification consists of a single longword { giving the address of the compiler-generated thunk to call. { { This is the format of the whole Value Specification when the Routine { Call Mechanism Specification is used: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (=DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH (= 8) | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC (= DST$K_VS_ALLOC_DYN) | { +---------------------------------------------------------------+ { byte | DST$B_MS_KIND | { +---------------------------------------------------------------+ { byte | DST$B_MS_MECH (= DST$K_MS_MECH_RTNCALL) | { +---------------------------------------------------------------+ { byte | DST$B_MS_FLAGBITS | { +---------------------------------------------------------------+ { long | DST$L_MS_MECH_RTNADDR | { +---------------------------------------------------------------+ { { { { The called routine is passed the address of a vector of register values { as its one argument. This vector contains all register value for the { scope (call frame) in which the symbol having this Value Specification { is declared. The vector contains the values of registers R0 - R11, AP, { FP, SP, PC, and PSL in that order. The routine is allowed to use all { such values in its computations, but is not allowed to change the con- { tents of the register vector. In addition, the routine is passed the { value of FP (the Frame Pointer) in register R1. { { The value of the routine should be returned to DEBUG in register R0. { { The DST$V_MS_DUMARG bit should be set in the DST$B_MS_FLAGBITS field if { the called routine expects to return a value longer than one longword. { If DST$V_MS_DUMARG is set, the address of an octaword (four-longword) { buffer is passed as the first argument to the called routine with the { expectation that the routine's value will be returned to this buffer. { The address of the register vector is then the second argument. { { Materialization Specification definitions { { Define the type and possible values for the Materialization { Specification kind information (for the DST$B_MS_KIND field.) { ITEM DST$MS_KIND BYTE UNSIGNED TYPEDEF; #minimum_ms_kind = 1; CONSTANT ( DST$K_MS_BYTADDR, { 1, the value is a byte address DST$K_MS_BITADDR, { 2, the value is a bit address (a longword { byte address plus a longword bit { offset from the byte address) DST$K_MS_BITOFFS, { 3, the value is a bit offset (normally a { bit offset from the start of a { record--used for record components) DST$K_MS_RVAL, { 4, the value is a literal value (constant) DST$K_MS_REG, { 5, the value is a register number (the { address is a register address) DST$K_MS_DSC, { 6, the value is a VAX standard descriptor DST$K_MS_ADDR_DSC { 7, the value is the address of a { VAX standard descriptor ) equals #minimum_ms_kind increment 1 counter #ms_kind_counter; CONSTANT DST$K_MS_LOWEST EQUALS #minimum_ms_kind; CONSTANT DST$K_MS_HIGHEST EQUALS #ms_kind_counter; { { Define the type and possible values for the Materialization { Specification mechanism information (for the DST$B_MS_MECH field.) { ITEM DST$MS_MECH BYTE UNSIGNED TYPEDEF; #minimum_ms_kind = 1; CONSTANT ( DST$K_MS_MECH_RTNCALL, { 1, Routine call on a compiler- { generated thunk DST$K_MS_MECH_STK, { 2, DST Stack Machine routine DST$K_MS_MECH_RTN_NOFP, { 3, Same as "1" but no FP passed in ) equals #minimum_ms_kind increment 1 counter #ms_kind_counter; CONSTANT DST$K_MS_MECH_MIN EQUALS #minimum_ms_kind; CONSTANT DST$K_MS_MECH_MAX EQUALS #ms_kind_counter; { { Define the fields of the Materialization Specification. { AGGREGATE DST$MATER_SPEC STRUCTURE TYPEDEF; dst$b_ms_kind DST$MS_KIND; { The kind of value produced dst$b_ms_mech DST$MS_MECH; { The mechanism whereby produced dst$b_ms_flagbits STRUCTURE; { Flag bits dst$v_ms_noeval BITFIELD LENGTH 1; { Purpose of this bit not clear dst$v_ms_dumarg BITFIELD LENGTH 1; { Include dummy argument on call dst$v_ms_wrongbounds BITFIELD LENGTH 1; { This flag indicates potentially { incorrect array bounds in { the descriptor that is { produced by this value { spec. (see below for { more details). dst$v_ms_mbz BITFIELD LENGTH 5; { Must be zero END dst$b_ms_flagbits; #dst$a_ms_header_size = :; dst$l_ms_mech_rtnaddr ADDRESS; { Routine address for call on { compiler-generated thunk #dst$materialization_spec_size = :; END; { DST$MATER_SPEC definition CONSTANT DST$K_MATER_SPEC_HEADER_SIZE EQUALS #dst$a_ms_header_size; CONSTANT DST$K_MATER_SPEC_SIZE EQUALS #dst$materialization_spec_size; { Size of Materialization Specification { DST record in bytes { { Define the constant for the offset of the Mechanism Spec { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ms_mech_spec = DST$K_MATER_SPEC_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { The following is more information on the WRONGBOUNDS flag: { This flag may be set by the ADA compiler when it is generating an { array descriptor within an array type spec. The flag indicates that { the ADA compiler was not able to describe the bounds of the array { correctly in the type spec (because the array is dynamic and the { bounds must be determined by looking at a run-time descriptor). { { When DEBUG encounters a WRONGBOUNDS flag, it must find the access object { that is being examined (which should have been described by a { TPTR_D type spec), and obtain the array bounds from the runtime { descriptor instead of from the array type spec. { { Example of an ADA program that may generate this: { { procedure ADADYN2 is { { type UNCONSTR is array (integer range <>) of integer; { type ACC is access UNCONSTR ; { type ARR is array( integer range <> ) of ACC; { type ACC2 is access ARR; { OBJ : ACC2 := { new ARR'( { new UNCONSTR'(1,1,1) , { new UNCONSTR'(1,2,3) ); { begin { { OBJ := { new ARR'( { new UNCONSTR'(2,4), { new UNCONSTR'(2,2,2,3,4) , { new UNCONSTR'(1,2) ); { { end; { { BIASED VALUE SPECIFICATIONS { { { This value spec has a VFLAGS field of DST$K_VS_FOLLOWS and an ALLOC { field of DST$K_VS_ALLOC_BIASED. This value spec is used to represent { Biased Values. Biased Values occur in ADA code when the number of bits { for the storage specified in the representation clause is inadequate { to store an unbiased value. In the fragment of ADA code which follows, { the values 100 through 103 are represented internally by two bits { having biased values 0 through 3. The bias is 100. { { subtype S is INTEGER range 100 .. 103; { type R is record C : S; end record; { for R use record C at 0 range 0..1; end record; { { A Biased Value Spec will be pointed to by a Trailing Value { Specification, as are other VS_FOLLOWS specs. { { This is the format of a Biased Value Specifications: { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (= DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC (= DST$K_VS_ALLOC_BIASED) | { +---------------------------------------------------------------+ { byte | reserved for future use (MBZ) | { +---------------------------------------------------------------+ { byte, | DST$A_VS_BIASING_VALSPEC | { long | (Nested 5 byte Value Spec for bias computation) | { +---------------------------------------------------------------+ { var | DST$A_VS_BIASED_VALSPEC | { | Nested Value Spec for address computation | { +---------------------------------------------------------------+ { { { Calculation of Value Addresses: { { The field DST$A_VS_BIASED_VALSPEC (or DST$A_VS_ENCODED_VALSPEC) { contains a nested value specification which provides the information to { calculate the location of the internal representation of the value in { the user's program. In the above example, that would be the location { of record component C. Once that location is calculated and the { internal representation fetched by DEBUG, the actual value can be { materialized. { { Calculation of Biased Values: { { The field DST$A_VS_BIASING_VALSPEC contains a simple five byte value { specification. When evaluated, this will yield a 32 bit value, the { BIAS, which will be treated as a signed integer. It will be added to { the internal representation of the value to produce the operating value { as seen by the user (and displayed by DEBUG). When DEBUG needs to { convert from the operating value to its internal representation, as for { a DEPOSIT command, the BIAS will be subtracted. In most cases, the { five byte value spec will simply contain a longword literal, however { it does allow for a bias which is not fixed at compile time. { { The "reserved for future use" field allows for future expansion of the { biasing algorithm. For example, instead of signed addition, flags { or literal values could indicate unsigned arithmetic, multiplication, { logical shift, etc. Currently these are not specified and the field { must be zero. { { ENCODED VALUE SPECIFICATIONS { { { Encoded Value Specifications can be considered a generalization of { Biased Value Specifications. Since these are not currently supported { in DEBUG, their definition is not given here. See the memo { "Representation of ADA Biased and Encoded Values in the DEBUG Symbol { Table" (by Edward Freedman, 22-NOV-1986) for a description and { definition of their fields. { { { THE DST STACK MACHINE { { { The DST Stack Machine is a virtual machine emulated by DEBUG. This { machine can push and pop values on a stack and can perform a variety { of arithmetic and logical operations. It can also call compiler- { generated thunks. The DST Stack Machine is used when a value must be { computed at DEBUG-time and the Standard Format Value Specification is { not adequate and a compiler-generated thunk to do the whole computation { seems undesirable. In such cases, the compiler can generate a Mecha- { nism Specification which consists of code for the Stack Machine. At { DEBUG-time, when the value in question is needed, DEBUG will interpret { this code until the STOP instruction is encountered. The value that { remains on the top of the Stack Machine stack is then taken to be the { desired value. { { The format of the whole Value Specification when a DST Stack Machine { Mechanism Specification is used is as follows: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_VFLAGS (=DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC | { +---------------------------------------------------------------+ { byte | DST$B_MS_KIND | { +---------------------------------------------------------------+ { byte | DST$B_MS_MECH (= DST$K_MS_MECH_STK) | { +---------------------------------------------------------------+ { byte | DST$B_MS_FLAGBITS | { +---------------------------------------------------------------+ { var | DST$A_MS_MECH_SPEC | { | | { | DST Stack Machine Routine | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$B_VS_ALLOC field should have the value DST$K_VS_ALLOC_DYN { if any kind of address is computed and DST$K_VS_ALLOC_STAT if a literal { value (a constant) is computed. The need for this field is not clear { since DEBUG ignores it at present. { { The stack upon which the DST Stack Machine operates consists of 256 { locations where each location is a longword. The stack grows toward { smaller addresses and shrinks toward larger addresses; in this regard { it is like the VAX call stack. A DST Stack Machine Routine consists { of a sequence of Stack Machine instructions ending in a STOP instruc- { tion (DST$K_STK_STOP). When the machine stops, the top location or { locations on the stack constitute the value of the routine. The length { of the value is determined by the DST$B_MS_KIND field. { { The DST Stack Machine supports the instructions tabulated in the re- { mainder of this section. Each instruction consists of a one-byte op- { code followed by zero or more operand bytes, depending on the op-code. { In this description, the "top" stack cell refers to the most recently { pushed cell still on the stack and the "second" cell refers to the next { most recently pushed cell still on the stack. Each cell contains a { longword value. { { { { Define the Push Register instructions. These instructions push the indicated { register value on the Stack Machine stack. The register values are taken from { the scope (call frame) of the symbol for which the value is being computed. { CONSTANT DST$K_STK_LOW EQUALS 0; { Lower bound for range checking CONSTANT DST$K_STK_PUSHR0 EQUALS 0; { Push the value of register R0 CONSTANT DST$K_STK_PUSHR1 EQUALS 1; { Push the value of register R1 CONSTANT DST$K_STK_PUSHR2 EQUALS 2; { Push the value of register R2 CONSTANT DST$K_STK_PUSHR3 EQUALS 3; { Push the value of register R3 CONSTANT DST$K_STK_PUSHR4 EQUALS 4; { Push the value of register R4 CONSTANT DST$K_STK_PUSHR5 EQUALS 5; { Push the value of register R5 CONSTANT DST$K_STK_PUSHR6 EQUALS 6; { Push the value of register R6 CONSTANT DST$K_STK_PUSHR7 EQUALS 7; { Push the value of register R7 CONSTANT DST$K_STK_PUSHR8 EQUALS 8; { Push the value of register R8 CONSTANT DST$K_STK_PUSHR9 EQUALS 9; { Push the value of register R9 CONSTANT DST$K_STK_PUSHR10 EQUALS 10; { Push the value of register R10 CONSTANT DST$K_STK_PUSHR11 EQUALS 11; { Push the value of register R11 CONSTANT DST$K_STK_PUSHRAP EQUALS 12; { Push the value of the AP CONSTANT DST$K_STK_PUSHRFP EQUALS 13; { Push the value of the FP CONSTANT DST$K_STK_PUSHRSP EQUALS 14; { Push the value of the SP CONSTANT DST$K_STK_PUSHRPC EQUALS 15; { Push the value of the PC { { Synonyms for the above symbols for use in stack machines for ALPHA { CONSTANT DST$K_STK_PUSH_ALPHA_R0 EQUALS 55; { Push the value of register R0 CONSTANT DST$K_STK_PUSH_ALPHA_R1 EQUALS 56; { Push the value of register R1 CONSTANT DST$K_STK_PUSH_ALPHA_R2 EQUALS 57; { Push the value of register R2 CONSTANT DST$K_STK_PUSH_ALPHA_R3 EQUALS 58; { Push the value of register R3 CONSTANT DST$K_STK_PUSH_ALPHA_R4 EQUALS 59; { Push the value of register R4 CONSTANT DST$K_STK_PUSH_ALPHA_R5 EQUALS 60; { Push the value of register R5 CONSTANT DST$K_STK_PUSH_ALPHA_R6 EQUALS 61; { Push the value of register R6 CONSTANT DST$K_STK_PUSH_ALPHA_R7 EQUALS 62; { Push the value of register R7 CONSTANT DST$K_STK_PUSH_ALPHA_R8 EQUALS 63; { Push the value of register R8 CONSTANT DST$K_STK_PUSH_ALPHA_R9 EQUALS 64; { Push the value of register R9 CONSTANT DST$K_STK_PUSH_ALPHA_R10 EQUALS 65; { Push the value of register R10 CONSTANT DST$K_STK_PUSH_ALPHA_R11 EQUALS 66; { Push the value of register R11 CONSTANT DST$K_STK_PUSH_ALPHA_R12 EQUALS 67; { Push the value of register R12 CONSTANT DST$K_STK_PUSH_ALPHA_R13 EQUALS 68; { Push the value of register R13 CONSTANT DST$K_STK_PUSH_ALPHA_R14 EQUALS 69; { Push the value of register R14 CONSTANT DST$K_STK_PUSH_ALPHA_R15 EQUALS 70; { Push the value of register R15 CONSTANT DST$K_STK_PUSH_ALPHA_R16 EQUALS 71; { Push the value of register R16 CONSTANT DST$K_STK_PUSH_ALPHA_R17 EQUALS 72; { Push the value of register R17 CONSTANT DST$K_STK_PUSH_ALPHA_R18 EQUALS 73; { Push the value of register R18 CONSTANT DST$K_STK_PUSH_ALPHA_R19 EQUALS 74; { Push the value of register R19 CONSTANT DST$K_STK_PUSH_ALPHA_R20 EQUALS 75; { Push the value of register R20 CONSTANT DST$K_STK_PUSH_ALPHA_R21 EQUALS 76; { Push the value of register R21 CONSTANT DST$K_STK_PUSH_ALPHA_R22 EQUALS 77; { Push the value of register R22 CONSTANT DST$K_STK_PUSH_ALPHA_R23 EQUALS 78; { Push the value of register R23 CONSTANT DST$K_STK_PUSH_ALPHA_R24 EQUALS 79; { Push the value of register R24 CONSTANT DST$K_STK_PUSH_ALPHA_R25 EQUALS 80; { Push the value of register R25 CONSTANT DST$K_STK_PUSH_ALPHA_R26 EQUALS 81; { Push the value of register R26 CONSTANT DST$K_STK_PUSH_ALPHA_R27 EQUALS 82; { Push the value of register R27 CONSTANT DST$K_STK_PUSH_ALPHA_R28 EQUALS 83; { Push the value of register R28 CONSTANT DST$K_STK_PUSH_ALPHA_R29 EQUALS 84; { Push the value of register R29 CONSTANT DST$K_STK_PUSH_ALPHA_R30 EQUALS 85; { Push the value of register R30 CONSTANT DST$K_STK_PUSH_ALPHA_R31 EQUALS 86; { Push the value of register R31 CONSTANT DST$K_STK_PUSH_ALPHA_AI EQUALS DST$K_STK_PUSH_ALPHA_R25; CONSTANT DST$K_STK_PUSH_ALPHA_RA EQUALS DST$K_STK_PUSH_ALPHA_R26; CONSTANT DST$K_STK_PUSH_ALPHA_PV EQUALS DST$K_STK_PUSH_ALPHA_R27; CONSTANT DST$K_STK_PUSH_ALPHA_FP EQUALS DST$K_STK_PUSH_ALPHA_R29; CONSTANT DST$K_STK_PUSH_ALPHA_SP EQUALS DST$K_STK_PUSH_ALPHA_R30; { { Synonyms for the above symbols for use in stack machines for the 68K { CONSTANT DST$K_STK_PUSH_M68_A0 EQUALS 0; { Push the value of register A0 CONSTANT DST$K_STK_PUSH_M68_A1 EQUALS 1; { Push the value of register A1 CONSTANT DST$K_STK_PUSH_M68_A2 EQUALS 2; { Push the value of register A2 CONSTANT DST$K_STK_PUSH_M68_A3 EQUALS 3; { Push the value of register A3 CONSTANT DST$K_STK_PUSH_M68_A4 EQUALS 4; { Push the value of register A4 CONSTANT DST$K_STK_PUSH_M68_A5 EQUALS 5; { Push the value of register A5 CONSTANT DST$K_STK_PUSH_M68_A6 EQUALS 6; { Push the value of register A6 CONSTANT DST$K_STK_PUSH_M68_A7 EQUALS 7; { Push the value of register A7 CONSTANT DST$K_STK_PUSH_M68_D0 EQUALS 8; { Push the value of register D0 CONSTANT DST$K_STK_PUSH_M68_D1 EQUALS 9; { Push the value of register D1 CONSTANT DST$K_STK_PUSH_M68_D2 EQUALS 10; { Push the value of register D2 CONSTANT DST$K_STK_PUSH_M68_D3 EQUALS 11; { Push the value of register D3 CONSTANT DST$K_STK_PUSH_M68_D4 EQUALS 12; { Push the value of register D4 CONSTANT DST$K_STK_PUSH_M68_D5 EQUALS 13; { Push the value of register D5 CONSTANT DST$K_STK_PUSH_M68_D6 EQUALS 14; { Push the value of register D6 CONSTANT DST$K_STK_PUSH_M68_D7 EQUALS 15; { Push the value of register D7 { { Synonyms for the above symbols for use in stack machines for the MIL STD 1750 { CONSTANT DST$K_STK_PUSH_1750_R0 EQUALS 15; CONSTANT DST$K_STK_PUSH_1750_R1 EQUALS 14; CONSTANT DST$K_STK_PUSH_1750_R2 EQUALS 13; CONSTANT DST$K_STK_PUSH_1750_R3 EQUALS 12; CONSTANT DST$K_STK_PUSH_1750_R4 EQUALS 11; CONSTANT DST$K_STK_PUSH_1750_R5 EQUALS 10; CONSTANT DST$K_STK_PUSH_1750_R6 EQUALS 9; CONSTANT DST$K_STK_PUSH_1750_R7 EQUALS 8; CONSTANT DST$K_STK_PUSH_1750_R8 EQUALS 7; CONSTANT DST$K_STK_PUSH_1750_R9 EQUALS 6; CONSTANT DST$K_STK_PUSH_1750_R10 EQUALS 5; CONSTANT DST$K_STK_PUSH_1750_R11 EQUALS 4; CONSTANT DST$K_STK_PUSH_1750_R12 EQUALS 3; CONSTANT DST$K_STK_PUSH_1750_R13 EQUALS 2; CONSTANT DST$K_STK_PUSH_1750_R14 EQUALS 1; CONSTANT DST$K_STK_PUSH_1750_R15 EQUALS 0; { { Define the Push Immediate instructions. These instructions are used to push { constant values on the Stack Machine stack. The constant value to push comes { immediately after the instruction op-code. For the signed and unsigned in- { structions, the value to push is zero-extended or sign-extended to 32 bits { as appropriate. In the case of the Push Immediate Variable instruction, the { byte after the op-code gives the byte length of the constant value to push. { The constant value to push then follows immediately after that length byte. { The constant value is zero-extended to the nearest longword boundary on the { high-address end and the resulting block is pushed onto the stack. { CONSTANT DST$K_STK_PUSHIMB EQUALS 16; { Push Immediate Byte (signed) CONSTANT DST$K_STK_PUSHIMW EQUALS 17; { Push Immediate Word (signed) CONSTANT DST$K_STK_PUSHIML EQUALS 18; { Push Immediate Longword (signed) CONSTANT DST$K_STK_PUSHIM_VAR EQUALS 24; { Push Immediate Variable CONSTANT DST$K_STK_PUSHIMBU EQUALS 25; { Push Immediate Byte Unsigned CONSTANT DST$K_STK_PUSHIMWU EQUALS 26; { Puch Immediate Word Unsigned { { Define the Push Indirect instructions. For these instructions, the top stack { cell is popped and the one, two, or four bytes at the address given by the { popped cell are sign extended to 32 bits and pushed on the stack. For the { unsigned instructions, the value is instead zero-extended to 32 bits and { pushed on the stack. { CONSTANT DST$K_STK_PUSHINB EQUALS 20; { Push Indirect Byte (signed) CONSTANT DST$K_STK_PUSHINW EQUALS 21; { Push Indirect Word (signed) CONSTANT DST$K_STK_PUSHINL EQUALS 22; { Push Indirect Longword (signed) CONSTANT DST$K_STK_PUSHINBU EQUALS 27; { Push Indirect Byte Unsigned CONSTANT DST$K_STK_PUSHINWU EQUALS 28; { Push Indirect Word Unsigned { { Define the arithmetic and logical instructions. These instruction pop the { top two cells on the stack, perform the indicated operation on these operands, { and push the result back onto the stack. { CONSTANT DST$K_STK_ADD EQUALS 19; { Add--The top two cells on the stack { are popped from the stack and { added together. The resulting { sum is pushed onto the stack. CONSTANT DST$K_STK_SUB EQUALS 29; { Subtract--The second cell on the stack { is subtracted from the top cell. { Both are popped from the stack. { The resulting difference is then { pushed onto the stack. CONSTANT DST$K_STK_MULT EQUALS 30; { Multiply--The top two stack cells are { popped from the stack and multi- { plied. The resulting product is { then pushed onto the stack. CONSTANT DST$K_STK_DIV EQUALS 31; { Divide--The top stack cell is divided { by the second stack cell. Both { are popped from the stack. Their { quotient is then pushed onto the { stack. CONSTANT DST$K_STK_LSH EQUALS 32; { Logical Shift--Shift the second stack { cell by the number of bits given { by the top stack cell; pop both { operands and push the shifted { second cell on the stack CONSTANT DST$K_STK_ROT EQUALS 33; { Rotate--Rotate the second stack cell { by the number of bits given by { the top stack cell; pop both { operands and push the rotated { second cell on the stack { { Define the extract field instructions. These instruction pop the top three { cells on the stack, perform the indicated operation on these operands, and { push the result back onto the stack. { CONSTANT DST$K_STK_EXTV_IMED EQUALS 45; { Move Bit Field and Sign Extend--A bit { field in the operand (the third { stack cell), starting at a given { bit position (the first stack { cell), and of the given size (the { second stack cell), is sign { sign extended and put on the { top of the stack. CONSTANT DST$K_STK_EXTZV_IMED EQUALS 46; { Move Bit Field and Zero Extend--Works { just like the above instruction { except the result is zero { extended instead. CONSTANT DST$K_STK_EXTV_IND EQUALS 47; { Move Bit Field (indirect) and Sign { Extend--Same as above except the { operand is not in the third stack { cell, rather, the third stack { cell contains the address of the { operand. CONSTANT DST$K_STK_EXTZV_IND EQUALS 48; { Move Bit Field (indirect) and Zero { Extend--Same as above. The address of { the operand is in the third stack { cell. { { Define the Copy and Exchange instructions. These instructions make a copy { of the top stack cell or exchange the top two cells on the stack. { CONSTANT DST$K_STK_COP EQUALS 34; { Copy--A copy of the top stack cell { is pushed onto the stack CONSTANT DST$K_STK_EXCH EQUALS 35; { Exchange--The top two stack cells are { interchanged { { Define the Store instructions. Following the op-code, these instructions { contain a byte which is interpreted as an unsigned offset into the stack. The { low-order byte, word, or longword of the top stack cell is stored into the { byte, word, or longword given by the current stack pointer plus four plus { the signed offset into the stack. (In short, the offset is an offset from { the second stack cell.) After that, the top stack cell is popped. These { instructions permit values to be stored into stack locations other than the { top or second stack cell. { CONSTANT DST$K_STK_STO_B EQUALS 36; { Store Byte into Stack CONSTANT DST$K_STK_STO_W EQUALS 37; { Store Word into Stack CONSTANT DST$K_STK_STO_L EQUALS 38; { Store Longword into Stack { { Define the Fetch instructions. Following the op-code, these instructions { contain a byte which is interpreted as an unsigned offset into the stack. The { low-order byte, word, or longword of the referenced cell is stored into { a new longword that is pushed onto the stack. The unused bits of the the { pushed longword are undefined. Note that the offset into the stack { is relative to the top cell BEFORE the push. This makes these { instructions exact inverses of the above store instructions. These { instructions permit values to be retrieved from deep in the stack. { CONSTANT DST$K_STK_FET_B EQUALS 49; { Fetch Byte into Stack CONSTANT DST$K_STK_FET_W EQUALS 50; { Fetch Word into Stack CONSTANT DST$K_STK_FET_L EQUALS 51; { Fetch Longword into Stack { { Define the Pop instruction. This instruction simply pops the top stack cell, { meaning that the top stack cell is removed from the stack and discarded. { CONSTANT DST$K_STK_POP EQUALS 39; { Pop Top Stack Cell { { Define the Stop instruction. This instruction stops the DST Stack Machine and { is required at the end of every DST Stack Machine routine. Whatever value is { left at the top of the stack when the Stop instruction is executed is taken to { be the value of the Stack Machine routine. This value may be a longword (a { byte address, for example), two longwords (byte address and bit offset), any { size literal value (an H-Floating literal, for instance), or a full VAX Stan- { dard Descriptor, depending on the value of the DST$B_MS_KIND field. { CONSTANT DST$K_STK_STOP EQUALS 23; { Stop the Stack Machine { { Define the Routine Call instructions. These instructions call a compiler- { generated routine (a thunk) whose address is given by the top stack cell. { Before the call actually occurs, the top stack cell is popped. The value { that is returned by the thunk is then pushed onto the stack. { { The Routine Call instruction works as follows. The address of the thunk to { to be called is taken from the top stack cell. The top cell is then popped. { The thunk, which is called with a CALL instruction, gets two arguments. The { first argument is the address of a vector of register values for the scope { (call frame) of the symbol to which this Value Specification belongs. This { vector contains the values of registers R0 - R11, AP, FP, SP, PC, and PSL in { that order; the called thunk is free to read any value it wants from this { vector but may not store into it. The second parameter is a pointer to the { top of the DST Stack Machine stack after the thunk address has been popped. { A Stack Machine routine can thus compute arguments to the thunk and push them { on the stack before pushing the thunk address and calling the thunk. In { addition, the value of FP in the symbol's scope is passed to the thunk in { register R1. The routine's value is expected to be returned in register R0. { This value is pushed onto the stack. { { The Routine Call With Alternate Return instruction works this same way except { that the address of an octaword buffer (4 longwords) is passed to the thunk { as the first argument, with the register vector being the second argument and { the stack address being the third argument. In this case, the routine value { is expected to be returned to the octaword buffer, not in register R0. The { whole octaword buffer is then pushed onto the stack. { { The routine call with no FP is the same as the normal routine call descibed { above, except that DEBUG does not check whether the FP is zero or not. DEBUG { actually passes the FP (zero or not) along just like above. Just be careful { if you make use of this, because you may be getting a zero FP. { CONSTANT DST$K_STK_RTNCALL EQUALS 40; { Routine Call (value returned in R0) CONSTANT DST$K_STK_RTNCALL_ALT EQUALS 41; { Routine Call With Alternate Return CONSTANT DST$K_STK_RTN_NOFP EQUALS 44; { Routine Call - no FP passed in { { Define the Push Record Address instructions. These instructions push the { address of the outer-most or inner-most record structure for which the cur- { rent symbol is a record component. They are used for constructing VAX Stan- { dard Descriptors on the Stack Machine stack when some part of the descriptor { depends on some other component of the same record. In PL/I, for instance, { the subscript bounds of an array component of a record may depend on another { component of that record. In such cases, the only way to get the address of { that other component in the current record is to use one of the Push Record { Address instructions. The Push Outer Record Address instruction pushes the { address of the outer-most record of which the current symbol is a component { while the Push Inner Record Address instruction pushes the address of the { inner-most record of which the current symbol is a component. { CONSTANT DST$K_STK_PUSH_OUTER_REC EQUALS 42; { Push Outer Record Address CONSTANT DST$K_STK_PUSH_INNER_REC EQUALS 43; { Push Inner Record Address { { Define the enumeration value-to-position number operator. This operator is { followed by a longword value which is the offset from the start of the whole { DEBUG Symbol Table to a DST which denotes an enumeration type. The referenced { DST may be an Enumerated Type Begin DST (DST$K_ENUMBEG) or a Type { Specification DST (DST$K_TYPSPEC). The operator replaces the value in the { top longword on the stack with the position number of that value in the { designated enumeration type. The position number of the first enumeration { value is 0. { { ***** RESTRICTION ***** { The referenced Enumerated Type Element (DST$K_ENUMELT) DSTs must have { value specifications with a literal valkind (DST$K_VALKIND_LITERAL). CONSTANT DST$K_STK_POS EQUALS 52; { Convert enumeration value to { position number { { Define a placeholder for the proposed indirect valspec operator. This { operator's exact syntax is undecided, but probably ought to consist of { a trailing longword value which is the offset from the start of the whole { DEBUG Symbol Table to a valspec whose value should be computed and pushed { on the stack. { { ***** NOT YET IMPLEMENTED ***** CONSTANT DST$K_STK_PUSH_VALSPEC EQUALS 53; { Push valspec value { { Define a placeholder for the proposed push inner array operator. Like { DST$K_STK_PUSH_OUTER_REC and DST$K_STK_PUSH_INNER_REC, this operator takes { no operands on the stack or in the stack machine instruction stream. { { ***** NOT YET IMPLEMENTED ***** CONSTANT DST$K_STK_PUSH_INNER_ARRAY EQUALS 54; { Push valspec value { { Define the highest op-code value accepted by the DST Stack Machine. This { value is used for op-code range checking. { CONSTANT DST$K_STK_HIGH EQUALS 86; { Upper bound for range checking { EXTENDED VALUE SPECIFICATIONS { { { Extended Value Specifications are designed to operate the same as { a standard value specification. The difference between this and { the standard value specification is the increase in size of some { fields. These increases make it possible to describe address { calculations (including register displacement and indexing) using { the entire Alpha register set. { { Other than the field size difference, the only other difference { between this and the standard value specification is that the XVS_FLAGS { field is not interpreted as a whole. Only the bits within the XVS_FLAGS { field is interpreted. { { The Extended Value Specification is always defined within a { VS-FOLLOWS value specification. { { This is the format of the Extended Value Specification DST record: { { { +---------------------------------------------------------------+ { byte | DST$B_VS_FLAGS (=DST$K_VS_FOLLOWS) | { +---------------------------------------------------------------+ { word | DST$W_VS_LENGTH (=13) | { +---------------------------------------------------------------+ { byte | DST$B_VS_ALLOC (=DST$K_VS_ALLOC_XVS) | { +---------------------------------------------------------------+ { word | DST$W_XVS_FLAGS | { +---------------------------------------------------------------+ { word | DST$W_XVS_REGNUM | { +---------------------------------------------------------------+ { quad | DST$Q_XVS_VALUE | { +---------------------------------------------------------------+ { { AGGREGATE DST$XVS_SPEC STRUCTURE TYPEDEF; dst$w_xvs_flags STRUCTURE; dst$v_xvs_indirect BITFIELD LENGTH 1; dst$v_xvs_disp BITFIELD LENGTH 1; dst$v_xvs_valkind BITFIELD LENGTH 2; dst$v_xvs_fill0 BITFIELD LENGTH 16-4; END dst$w_xvs_flags; dst$w_xvs_regnum WORD UNSIGNED; dst$q_xvs_value STRUCTURE; dst$l_xvs_low_value LONGWORD; dst$l_xvs_hi_value LONGWORD; END dst$q_xvs_value; #dst$xvs_spec_size = :; END; CONSTANT DST$K_XVS_SPEC_SIZE EQUALS #dst$xvs_spec_size; { Size of XVS record { END OF VALUE SPECIFICATION DESCRIPTION. { { { T H E T Y P E S P E C I F I C A T I O N D S T R E C O R D { { { { The Type Specification DST record gives the most general data type { description available in the Debug Symbol Table. It contains the { name of the data type being described and a DST Type Specification { that describes the type. The type name is used in languages where { data types can be named, such as PASCAL. If no type name exists, { the null name (the name of zero length) is specified in this record. { DST Type Specifications are described in detail in the next section { of this definition file. { { Type Specification DST records either immediately follow Separate { Type Specification DST records or are pointed to by Indirect Type { Specifications or Novel Length Type Specifications elsewhere in { the DST for the current module. { { This is the format of the Type Specification DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_TYPSPEC) | { +---------------------------------------------------------------+ { byte | DST$B_TYPSPEC_NAME | { +---------------------------------------------------------------+ { var | | { | The Type Name in ASCII | { | | { | (The name's length is given by DST$B_TYPSPEC_NAME) | { | | { | | { +---------------------------------------------------------------+ { var | DST$A_TYPSPEC_TS_ADDR | { | | { | The DST Type Specification for the | { | | { | Data Type being defined | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Type Specification DST record. { AGGREGATE DST$TYPSPEC STRUCTURE TYPEDEF; dst$a_typspec_header DST$HEADER; { Header dst$b_typspec_name BYTE UNSIGNED; { The count byte for the Counted { ASCII Type Name #dst$typspec_size = :; END; { DST$TYPSPEC definition CONSTANT DST$K_TYPSPEC_SIZE EQUALS #dst$typspec_size; { Size of Type Specification { DST record in bytes { { Define the location of the DST Type Specification { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_typspec_ts_addr = DST$K_TYPSPEC_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { D S T T Y P E S P E C I F I C A T I O N S { { { { A DST Type Specification specifies the data type of some data symbol. { DST Type Specifications constitute the most general form of data type { description available in the Debug Symbol Table. They are found in { only one kind of DST record, namely the Type Specification DST record. { However, some Type Specifications contain nested Type Specifications, { which permits quite complex type descriptions. For example, the parent { type for a Subrange data type is given by a nested Type Specification { within the Subrange Type Specification. { { This is the general format of all DST Type Specifications: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND | { +---------------------------------------------------------------+ { var | | { | | { | Zero or More Other Fields Depending on DST$B_TS_KIND | { | | { | | { +---------------------------------------------------------------+ { { { { A data symbol whose data type must be described by a DST Type Specifi- { cation is described by a Separate Type Specification DST record. This { DST record is immediately followed by a Type Specification DST record { which contains the DST Type Specification for the symbol's data type. { { To conserve DST space when several symbols have the same data type, the { Type Specification that follows the Separate Type Specification DST { record may be an Indirect Type Specification. The Indirect Type Speci- { fication then contains a DST pointer to the actual Type Specification { DST record for the symbol's type. Only a single copy of this actual { Type Specification is then needed. Multiple symbols of the same Record { or Enumeration type must also use Separate Type Specification DST { records followed by Type Specification DST records containing Indirect { Type Specifications. In this case, the Indirect Type Specifications { point to the Record Begin or Enumeration Type Begin DST record for the { record or enumeration type being specified. { { In fact, the only Type Specification that can refer to a record or enum- { eration type is the Indirect Type Specification. (The Novel Length Type { Specification can too but is not normally used this way.) This Type { Specification is thus used within other Type Specifications when record { or enumeration types must be specified. For example, when the element { type of an array is a record or enumeration type, it is specified by an { Indirect Type Specification within the Array Type Specification. Simi- { larly, if the target of a typed pointer is a record or enumeration type { object, the target type is specified by an Indirect Type Specification { within the Typed Pointer Type Specification. { { { The following are the values that may appear in the DST$B_TS_KIND field. { ITEM DST$TS_DTYPE BYTE UNSIGNED TYPEDEF; #minimum_ts_dtype = 1; CONSTANT ( DST$K_TS_ATOM, { 1, Atomic Type Spec DST$K_TS_DSC, { 2, VAX Standard Desciptor Type Spec DST$K_TS_IND, { 3, Indirect Type Spec DST$K_TS_TPTR, { 4, Typed Pointer Type Spec DST$K_TS_PTR, { 5, Pointer Type Spec DST$K_TS_PIC, { 6, Pictured Type Spec DST$K_TS_ARRAY, { 7, Array Type Spec DST$K_TS_SET, { 8, Set Type Spec DST$K_TS_SUBRANGE, { 9, Subrange Type Spec DST$K_TS_ADA_DSC, { 10, ADA Descriptor Type Spec DST$K_TS_FILE, { 11, File Type Spec DST$K_TS_AREA, { 12, Area Type Spec (PL/I) DST$K_TS_OFFSET, { 13, Offset Type Spec (PL/I) DST$K_TS_NOV_LENG, { 14, Novel Length Type Spec DST$K_TS_IND_TSPEC, { 15, DEBUG internally generated pointer to { Type Spec (cannot appear in DST) DST$K_TS_SELF_REL_LABEL, { 16, Self-Relative Label Type Spec (PL/I) DST$K_TS_RFA, { 17, Record File Address Type Spec (BASIC) DST$K_TS_TASK, { 18, Task Type Spec (ADA) DST$K_TS_ADA_ARRAY, { 19, ADA Array Type Spec DST$K_TS_XMOD_IND, { 20, Cross-Module Indirect Type Spec DST$K_TS_CONSTRAINED, { 21, Constrained Type Spec (ADA) DST$K_TS_MAYBE_CONSTR, { 22, Might-be-constrained Type Spec (ADA) DST$K_TS_DYN_NOV_LENG, { 23, Dynamic Novel Length Type Spec DST$K_TS_TPTR_D, { 24, Typed Pointer to descriptor DST$K_TS_SCAN_TREE, { 25, SCAN Tree Type Spec DST$K_TS_SCAN_TREEPTR, { 26, SCAN Treeptr Type Spec DST$K_TS_INCOMPLETE, { 27, Incomplete Type Spec DST$K_TS_BLISS_BLOCK, { 28, Bliss Block DST DST$K_TS_TPTR_64, { 29, Typed 64-bit Pointer Type Spec DST$K_TS_PTR_64, { 30, 64-bit Pointer Type Spec DST$K_TS_REF, { 31, C++ Reference Type DST$K_TS_REF_64 { 32, C++ Reference Type, 64-bit pointer ) equals #minimum_ts_dtype increment 1 counter #ts_dtype_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_TS_DTYPE_LOWEST EQUALS #minimum_ts_dtype; CONSTANT DST$K_TS_DTYPE_HIGHEST EQUALS #ts_dtype_counter; { { Define all the fields that can appear in the various Type Specifications. { AGGREGATE DST$TYPE_SPEC STRUCTURE TYPEDEF; dst$w_ts_length WORD UNSIGNED; { The byte length of the Type { Specification not includ- { ing this length field #dst$a_ts_base_addr = :; dst$b_ts_kind DST$TS_DTYPE; { The Type Specification kind { { Many types "end" here. They consist of the fields above, or are { followed by some based set of additional fields. In order to get { the sizes and/or offsets correct, we define a number of sizes { and/or bases here. { { { Type spec for a descriptor type specification { has based additional fields... { #dst$descriptor_type_base = :; { { Type spec for an area type specification { has based additional fields... { #dst$area_type_base = :; { { Type spec for an offset type specification { has based additional fields... { #dst$offset_type_base = :; { { Type spec for a typed pointer type specification has { based additional fields... { #dst$typed_pointer_type_base = :; { { Type spec for a pointer type specification has no additional { fields... { #dst$pointer_type_size = :; { { Type spec for a SCAN Treeptr type specification has { based additional fields... { #dst$scan_treeptr_type_base = :; dst$type_spec_variants UNION; { { Type spec for an atomic type { dst$atomic_type STRUCTURE; dst$b_ts_atom_typ BYTE UNSIGNED; { The Atomic data type code #dst$atomic_type_size = :; END dst$atomic_type; { { Type spec for an Ada descriptor type specification { dst$ada_descriptor_type STRUCTURE; dst$b_ts_ada_dsc_class BYTE UNSIGNED; { Class code dst$b_ts_ada_dsc_dtype BYTE UNSIGNED; { Dtype code #dst$ada_descriptor_type_base = :; END dst$ada_descriptor_type; { { Type spec for an indirect type specification { dst$indirect_type STRUCTURE; dst$l_ts_ind_ptr LONGWORD UNSIGNED; { Indirect Type Spec DST pointer #dst$indirect_type_size = :; END dst$indirect_type; { { Type spec for a cross-module indirect type specification { dst$xmod_indirect_type STRUCTURE; dst$l_ts_xmod_offset LONGWORD UNSIGNED; { Cross-module Indirect Type Spec- { Offset within module dst$b_ts_xmod_modname BYTE UNSIGNED; { Cross-module Indirect Type Spec- { Name of module #dst$xmod_indirect_type_size = :; END dst$xmod_indirect_type; { { Type spec for a picture type specification { dst$picture_type STRUCTURE; dst$b_ts_pic_dleng BYTE UNSIGNED; { The byte length of data objects { of this picture type dst$b_ts_pic_lang DBG$DST_LANGUAGE; { Note BYTE size... { The DST language code for this { picture data type dst$b_ts_pic_pleng BYTE UNSIGNED; { The length of the picture { string in this Type Spec #dst$picture_type_base = :; END dst$picture_type; { { Type spec for an array type specification { dst$array_type STRUCTURE; dst$b_ts_array_dim BYTE UNSIGNED; { The number of array dimensions #dst$array_type_base = :; END dst$array_type; { { Type spec for an Ada array type specification { dst$ada_array_type STRUCTURE; dst$b_ts_ada_array_dim BYTE UNSIGNED; { The number of array dimensions { NOTE: This name was added to { avoid name conflicts with the { simple array type spec fields dst$b_ts_ada_array_class BYTE UNSIGNED; { Class code dst$b_ts_ada_array_dtype BYTE UNSIGNED; { Dtype code #dst$ada_array_type_base = :; END dst$ada_array_type; { { Type spec for a set type specification { dst$set_type STRUCTURE; dst$l_ts_set_leng LONGWORD UNSIGNED; { The length in bits of data { objects of this Set type #dst$set_type_base = :; END dst$set_type; { { Type spec for a subrange type specification { dst$subrange_type STRUCTURE; dst$l_ts_subr_leng LONGWORD UNSIGNED; { The length in bits of objects { of this subrange type #dst$subrange_type_base = :; END dst$subrange_type; { { Type spec for a file type specification { dst$file_type STRUCTURE; dst$b_ts_file_lang DBG$DST_LANGUAGE; { Note BYTE size { Language code for file type #dst$file_type_size = :; END dst$file_type; { { Type spec for a novel length type specification { dst$novel_length_type STRUCTURE; dst$l_ts_nov_leng LONGWORD UNSIGNED; { The "novel" length in bits of { objects of this data type dst$l_ts_nov_leng_par_tspec LONGWORD UNSIGNED; { DST pointer to parent type for { this "novel length" type #dst$novel_length_size = :; END dst$novel_length_type; { { Type spec for a dynamic novel length type specification { dst$dynamic_novel_length_type STRUCTURE; #dst$dyn_nov_len_val_spec = :; dst$a_dyn_nov_val_spec DST$VAL_SPEC; { Embedded value spec in dynamic { novel length type spec #dst$dyn_nov_len_type_base = :; END dst$dynamic_novel_length_type; { { Type spec for a self-relative label type specification { dst$self_relative_type STRUCTURE; dst$l_ts_self_leng LONGWORD UNSIGNED; { Table length for this array of { PL/I Self-Relative Labels #dst$self_relative_base = :; END dst$self_relative_type; { { Type spec for a task type specification { dst$task_type STRUCTURE; #dst$task_type_size = :; dst$wu_ts_task_entry_count WORD UNSIGNED; { Optional number of entry names { which follow #dst$task_entry_base = :; END dst$task_type; { { Type spec for a constrained type specification { dst$constrained_type STRUCTURE; dst$l_ts_constr_record LONGWORD UNSIGNED; { Pointer to a Record DST for { Constrained records. dst$l_ts_constr_count LONGWORD UNSIGNED; { Number of constrained components { for this record. #dst$constrained_type_base = :; END dst$constrained_type; { { Type spec for a might-be-constrained type specification { dst$might_be_constrained_type STRUCTURE; dst$l_ts_mightbe_record LONGWORD UNSIGNED; { Pointer to a Record DST for { Might-Be-Constrained { records. #dst$might_be_constrained_base = :; END dst$might_be_constrained_type; { { Type spec for a SCAN tree type specification { dst$scan_tree_type STRUCTURE; dst$b_ts_scan_tree_depth BYTE UNSIGNED; { Number of SCAN Tree Subscripts #dst$scan_tree_base = :; END dst$scan_tree_type; { { Type spec for an incomplete type specification { dst$incomplete_type STRUCTURE; dst$l_ts_incomplete_ptr LONGWORD UNSIGNED; { Pointer to a Type Spec DST that { follows a Fulfills DST. #dst$incomplete_type_size = :; END dst$incomplete_type; { { Type spec for a BLISS block type specification { dst$bliss_block_type STRUCTURE; dst$l_ts_number_units LONGWORD UNSIGNED; { Number of units in the BLISS { BLOCK (i.e., the "N" in { BLOCK[N, xxxx]). dst$b_ts_unit_size BYTE UNSIGNED; { Unit size in the BLISS block { (i.e., 1 = BLOCK[,BYTE], { 2 = BLOCK[,WORD], { 4 = BLOCK[,LONG]) dst$b_ts_field_set_count BYTE UNSIGNED; { Number of field sets associated { with this BLISS Block #dst$bliss_block_base = :; END dst$bliss_block_type; END dst$type_spec_variants; #dst$type_spec_size = :; END; { DST$TYPE_SPEC definition CONSTANT DST$K_TYPE_SPEC_SIZE EQUALS #dst$type_spec_size; { Size of Type Specification { DST record in bytes { { The following set of literals give the lengths in bytes of those Type { Specifications which have a fixed length. { { Atomic Type Spec length { CONSTANT DST$K_TS_ATOM_LENG EQUALS #dst$atomic_type_size; { { Indirect Type Spec length { CONSTANT DST$K_TS_IND_LENG EQUALS #dst$indirect_type_size; { { Pointer Type Spec length { CONSTANT DST$K_TS_PTR_LENG EQUALS #dst$pointer_type_size; { { 64-bit Pointer Type Spec length { CONSTANT DST$K_TS_PTR_64_LENG EQUALS #dst$pointer_type_size; { { File Type Spec length { CONSTANT DST$K_TS_FILE_LENG EQUALS #dst$file_type_size; { { Area Type Spec length { CONSTANT DST$K_TS_AREA_LENG EQUALS #dst$area_type_base; { { Offset Type Spec length { CONSTANT DST$K_TS_OFFSET_LENG EQUALS #dst$offset_type_base; { { Novel Length Type Spec length { CONSTANT DST$K_TS_NOV_LENG_LENG EQUALS #dst$novel_length_size; { { Task Type Spec length { CONSTANT DST$K_TS_TASK_LENG EQUALS #dst$task_type_size; { { Incomplete Type Spec length { CONSTANT DST$K_TS_INCOMPLETE_LENG EQUALS #dst$incomplete_type_size; { { Define a number of field offsets for variable sized objects that { follow the fixed sized parts of type specifications. { CONSTANT DST$K_TS_BASE EQUALS #dst$a_ts_base_addr; { If FOO is a REF DST$TYPE_SPEC { then the data which follows a { typespec is at { FOO[DST$A_TS_BASE] + { .FOO[DST$W_TS_LENGTH] CONSTANT DST$K_TS_DSC_VSPEC EQUALS #dst$descriptor_type_base; { The VAX descriptor Value Spec CONSTANT DST$K_TS_ADA_DSC_VSPEC EQUALS #dst$ada_descriptor_type_base; { The ADA descriptor Value Spec CONSTANT DST$K_TS_TPTR_TSPEC EQUALS #dst$typed_pointer_type_base; { Typed Pointer parent type Type CONSTANT DST$K_TS_TPTR_64_TSPEC EQUALS #dst$typed_pointer_type_base; { Typed 64-bit Pointer parent type Type CONSTANT DST$K_TS_REF_TSPEC EQUALS #dst$typed_pointer_type_base; { C++ Reference Type parent type Type CONSTANT DST$K_TS_REF_64_TSPEC EQUALS #dst$typed_pointer_type_base; { C++ 64-bit Reference Type parent type Type CONSTANT DST$K_TS_PIC_ADDR EQUALS #dst$picture_type_base; { The location where the picture { is encoded in Type Spec { Specification location CONSTANT DST$K_TS_ARRAY_FLAGS EQUALS #dst$array_type_base; { The location of the array flags { that indicate Type Specs { for the subscript types CONSTANT DST$K_TS_ADA_ARRAY_FLAGS EQUALS #dst$ada_array_type_base; { The location of the array flags CONSTANT DST$K_TS_SET_PAR_TSPEC EQUALS #dst$set_type_base; { The location of the Set's { parent type Type Spec CONSTANT DST$K_TS_SUBR_PAR_TSPEC EQUALS #dst$subrange_type_base; { Location of the parent type { Type Specification within { the Subrange Type Spec CONSTANT DST$K_TS_FILE_RCRD_TYP EQUALS #dst$file_type_size; { Location of Type Spec giving { element type for file CONSTANT DST$K_TS_AREA_BYTE_LEN EQUALS #dst$area_type_base; { Length in bytes of PL/I "area" CONSTANT DST$K_TS_OFFSET_VALSPEC EQUALS #dst$offset_type_base; { Location of Value Spec giving { base address of PL/I area CONSTANT DST$K_TS_NOV_LENG_VSPEC EQUALS #dst$dyn_nov_len_val_spec; { Embedded value spec in dynamic { novel length type spec CONSTANT DST$K_TS_NOV_LENG_TSPEC EQUALS #dst$dyn_nov_len_type_base; { Embedded type spec in dynamic { novel length type spec CONSTANT DST$K_TS_TASK_ENTRY EQUALS #dst$task_entry_base; { Base address of { entry descriptions CONSTANT DST$K_TS_CONSTR_LIST EQUALS #dst$constrained_type_base; { Address of constrained { component list. CONSTANT DST$K_TS_MIGHTBE_VALSPEC EQUALS #dst$might_be_constrained_base; { Address of Might-be-constrained { Value Specification. CONSTANT DST$K_TS_SCAN_TREE_FLAGS EQUALS #dst$scan_tree_base; { Bitvector for SCAN Tree Subscripts CONSTANT DST$K_TS_SCAN_TREEPTR_TREE EQUALS #dst$scan_treeptr_type_base; { SCAN Treeptr Tree Type Spec CONSTANT DST$K_TS_FIELD_SET_LIST EQUALS #dst$bliss_block_base; { The start of a vector of { pointers to BLISS Field DSTs. { { Using those offsets, generate a number of Bliss macros { IFLANGUAGE BLISSF; LITERAL; MACRO DST$A_TS_BASE = DST$K_TS_BASE, 0, 0, 0%; MACRO DST$A_TS_DSC_VSPEC_ADDR = DST$K_TS_DSC_VSPEC, 0, 0, 0%; MACRO DST$A_TS_ADA_DSC_VSPEC = DST$K_TS_ADA_DSC_VSPEC, 0, 0, 0%; MACRO DST$A_TS_TPTR_TSPEC_ADDR = DST$K_TS_TPTR_TSPEC, 0, 0, 0%; MACRO DST$A_TS_PIC_ADDR = DST$K_TS_PIC_ADDR, 0, 0, 0%; MACRO DST$A_TS_ARRAY_FLAGS_ADDR = DST$K_TS_ARRAY_FLAGS, 0, 0, 0%; MACRO DST$A_TS_ADA_ARRAY_FLAGS = DST$K_TS_ADA_ARRAY_FLAGS, 0, 0, 0%; MACRO DST$A_TS_SET_PAR_TSPEC_ADDR = DST$K_TS_SET_PAR_TSPEC, 0, 0, 0%; MACRO DST$A_TS_SUBR_PAR_TSPEC_ADDR = DST$K_TS_SUBR_PAR_TSPEC, 0, 0, 0%; MACRO DST$A_TS_FILE_RCRD_TYP = DST$K_TS_FILE_RCRD_TYP, 0, 0, 0%; MACRO DST$A_TS_AREA_BYTE_LEN = DST$K_TS_AREA_BYTE_LEN, 0, 0, 0%; MACRO DST$A_TS_OFFSET_VALSPEC = DST$K_TS_OFFSET_VALSPEC, 0, 0, 0%; MACRO DST$A_TS_NOV_LENG_VSPEC = DST$K_TS_NOV_LENG_VSPEC, 0, 0, 0%; MACRO DST$A_TS_NOV_LENG_TSPEC = DST$K_TS_NOV_LENG_TSPEC, 0, 0, 0%; MACRO DST$A_TS_TASK_ENTRY_BASE = DST$K_TS_TASK_ENTRY, 0, 0, 0%; MACRO DST$A_TS_CONSTR_LIST = DST$K_TS_CONSTR_LIST, 0, 0, 0%; MACRO DST$A_TS_MIGHTBE_VALSPEC = DST$K_TS_MIGHTBE_VALSPEC, 0, 0, 0%; MACRO DST$A_TS_SCAN_TREE_FLAGS = DST$K_TS_SCAN_TREE_FLAGS, 0, 0, 0%; MACRO DST$A_TS_SCAN_TREEPTR_TREE = DST$K_TS_SCAN_TREEPTR_TREE, 0, 0, 0%; MACRO DST$A_TS_FIELD_SET_LIST = DST$K_TS_FIELD_SET_LIST, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { ATOMIC TYPE SPECIFICATIONS { { { { The Atomic Type Specification is used to describe an atomic VAX standard { data type. This Type Specification consists of the standard Type Speci- { fication header followed by a single byte containing the VAX standard { data type code (one of the DSC$K_DTYPE_x codes). The Atomic Type Speci- { fication has the following format: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 2) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_ATOM) | { +---------------------------------------------------------------+ { byte | DST$B_TS_ATOM_TYP | { +---------------------------------------------------------------+ { { { { DESCRIPTOR TYPE SPECIFICATIONS { { { { The Descriptor Type Specification is used for VAX Standard Data Types { that can be described by VAX Standard Descriptors but cannot be de- { scribed by an atomic type code. Packed decimal, which requires a { digit length and a scale factor, and ASCII text, which requires a { string length, are examples of such data types. The Descriptor Type { Specification contains a Value Specification which must produce a { VAX Standard Descriptor. This is the format: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_DSC) | { +---------------------------------------------------------------+ { var | DST$A_TS_DSC_VSPEC_ADDR | { | | { | Value Specification Yielding a VAX Standard Descriptor | { | | { | | { +---------------------------------------------------------------+ { { { { ADA DESCRIPTOR TYPE SPECIFICATIONS { { { { The ADA Descriptor Type Specification is put out by the ADA compiler { for objects that can be described by an ADA "extended descriptor". { This is a VAX standard descriptor except that the DSC$W_LENGTH { field occupies a full longword and thus overlays the Class { and Dtype fields. For this reason, the Class and Dtype codes { are included in this type spec. These are followed by the { Value Spec which produces one of these "extended descriptors". { This is the format: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_ADA_DSC) | { +---------------------------------------------------------------+ { byte | DST$B_TS_ADA_DSC_CLASS | { +---------------------------------------------------------------+ { byte | DST$B_TS_ADA_DSC_DTYPE | { +---------------------------------------------------------------+ { var | DST$A_TS_ADA_DSC_VSPEC | { | | { | Value Specification Yielding a VAX Standard Descriptor | { | | { | | { +---------------------------------------------------------------+ { INDIRECT TYPE SPECIFICATIONS { { { { The Indirect Type Specification is used when the actual Type Specifica- { tion desired is found in another DST record. This Type Specification { contains a DST pointer which points to that other DST record. The DST { pointer contains the byte offset relative to the start of the whole DST { of the DST record that gives the actual type information. The pointed- { to DST record must be one of three kinds of DST records: a Type Speci- { fication DST record, a Record Begin DST record, or an Enumeration Type { Begin DST record. The Indirect Type Specification is the only Type { Specification that can refer to a record or enumeration type; those { types are too complex (potentially) to be referred to any other way. { This is the format of the Indirect Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 5) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_IND) | { +---------------------------------------------------------------+ { long | DST$L_TS_IND_PTR | { +---------------------------------------------------------------+ { CROSS-MODULE INDIRECT TYPE SPECIFICATIONS { { { { The Cross-Module Indirect Type Specification is like an indirect type { spec, except that the offset is relative to the start of another { module's DST. This type spec is generated by ADA in order to { refer to a type spec that is defined in a library package. { { This DST record contains the name of the other module as a counted { ascii string, and the "OFFSET" field is a byte offset relative to { the start of the DST for that module. { { The pointed-to DST record must be one of three kinds of DST records: { a Type Specification DST record, a Record Begin DST record, or { an Enumeration Type Begin DST record. { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_XMOD_IND) | { +---------------------------------------------------------------+ { long | DST$L_TS_XMOD_OFFSET | { +---------------------------------------------------------------+ { | DST$B_TS_XMOD_MODNAME | { var | | { | ( the length of the name is given in DST$B_TS_XMOD_MODNAME, ) | { | ( and the ascii name follows ) | { +---------------------------------------------------------------+ { TYPED POINTER TYPE SPECIFICATIONS { { { The Typed Pointer Type Specification describes a typed pointer data { type, meaning a pointer to a specific other data type. Pointer-to- { integer, as found in PASCAL and other languages, is an example of a { typed pointer type. In this example, integer is the "parent type". { This Type Specification contains an embedded Type Specification which { specifies the parent type for the typed pointer type. { { The Typed 64-bit Pointer Type Specification has the same format and { meaning as the Typed Pointer Type Specification, except that the size { of the pointer field is 64 rather 32 bits long. { { C++ Reference Type Specification has the same format and meaning as { the Typed Pointer Type Specification, except that it describes a C++ { reference type. { { There is also a code DST$K_TS_TPTR_D which has the same format { as the DST$K_TS_TPTR type spec. However, if the type code is { DST$K_TS_TPTR_D, this indicates that the item points to a { VAX standard descriptor, rather than to the object itself. { { E.g., if you have a pointer to an array, { use the standard DST$K_TS_TPTR code for this case: { { +-----------+ { P -> | the array | { | itself | { +-----------+ { { If you have a 64-bit pointer to an array, { use the DST$K_TS_TPTR_64 code for this case: { { +-----------+ { 64-bit-P -> | the array | { | itself | { +-----------+ { { But use the DST$K_TS_TPTR_D code for this case: { { +---+---+-------+ { P -> | C | D | L | { +---+---+-------+ +------------+ { | DSC$A_POINTER | -> | the array | { +---------------+ | itself | { +------------+ { { This second case arises in pointers to unconstrained arrays in ADA. { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND(DST$K_TS_TPTR,DST$K_TS_TPTR_64,DST$K_TS_TPTR_D, | { | DST$K_TS_REF,DST$K_TS_REF_64) | { +---------------------------------------------------------------+ { var | DST$A_TS_TPTR_TSPEC_ADDR | { | | { | Type Specification for Parent Type that | { | | { | Objects of Typed Pointer Type Point to | { | | { | | { +---------------------------------------------------------------+ { { POINTER TYPE SPECIFICATIONS { { { The Pointer Type Specification is used for pointer types which are not { typed, meaning that the type of object that the pointer points to is { not known at compile-time. PL/I pointers are examples of this kind of { pointer type. Since there is no known parent type, none is specified { in this Type Specification. The Pointer Type Specification thus has { the simplest possible format: { { The 64-bit Pointer Type Specification has the same format and { meaning as the Pointer Type Specification, except that the size { of the pointer field is 64 rather 32 bits long. { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 1) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_PTR) | { +---------------------------------------------------------------+ { PICTURE TYPE SPECIFICATIONS { { { The Picture Type Specification is used for picture data types as found { in COBOL and PL/I. Because the exact semantics of picture data types { vary between languages, this Type Specification contains the language { code associated with this specific picture type. It also contains the { byte length of objects of the picture type, an encoding of the picture, { and a language-specific picture encoding (usually the EDITPC pattern { string). The actual data objects of the picture data type are assumed { to be represented as ASCII character strings. { { This is the format of the Picture Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | -\ { +---------------------------------------------------------------+ | { byte | DST$B_TS_KIND (= DST$K_TS_PIC) | | { +---------------------------------------------------------------+ | { byte | DST$B_TS_PIC_DLENG | | { +---------------------------------------------------------------+ | { byte | DST$B_TS_PIC_LANG | | { +---------------------------------------------------------------+ | { byte | DST$B_TS_PIC_PLENG | | { +---------------------------------------------------------------+ | { var | DST$A_TS_PIC_ADDR | | { | | | { | Picture String Encoding | | { | | | { | | | { +---------------------------------------------------------------+ | { var | | | { | Value Specification Yielding a | | { | | | { | Language-Specific Encoding of Picture Semantics | | { | | | { | | | { +---------------------------------------------------------------+ | { byte | DST$B_TS_PIC_SCALE |<-/ { +---------------------------------------------------------------+ { byte | DST$B_TS_PIC_DIGITS | { +---------------------------------------------------------------+ { { { { The DST$B_TS_PIC_DLENG field contains the length in bytes of each data { object of this picture type. DEBUG assumes that picture objects are { represented internally as ASCII character strings. { { The language code in the DST$B_TS_PIC_LANG field is the same as that { used in the Module Begin DST record. { { The DST$B_TS_PIC_PLENG field gives the byte length of the picture { encoding in the DST$A_TS_PIC_ADDR field. The picture encoding in the { DST$A_TS_PIC_ADDR field consists of a sequence of words. The high- { order byte of each word contains an unsigned repetition factor and { the low-order byte contains the ASCII representation of the repeated { picture character. Hence the picture S999.99 is represented by this { sequence of byte values: "S", 1, "9", 3, ".", 1, "9", 2. (The same { picture can be written as "S(3)9.(2)9".) { { The optional Value Specification at the end of the Picture Type Speci- { fication yields the address of the EDITPC pattern string that performs { the encoding associated with this picture type. DEBUG uses this pattern { string with the EDITPC instruction when doing DEPOSITS into objects of { this picture type. If the Value Specification is omitted, DEBUG can { only deposit character strings into such objects since it does not know { how to encode numeric values. { { The DST$W_TS_LENGTH field is an offset (using the location of { DST$W_TS_LENGTH as the base) to the location of the DST$B_TS_PIC_SCALE { field. The DST$B_TS_PIC_SCALE field records the scale factor of { the picture type. The field following, DST$B_TS_PIC_DIGITS, contains { the number of digits of the picture type. Note that these last two { fields do not have real symbolic names defined in SDL, but are named { in the description only. { { ARRAY TYPE SPECIFICATIONS { { { { The Array Type Specification specifies an Array data type. This speci- { fication can be quite complex because it not only specifies the shape of { each array of this type, but also specifies the corresponding element { data type and all subscript data types. The element type and the types { of the subscripts are given by additional Type Specifications nested { within the Array Type Specification. { { This is the format of the Array Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_ARRAY) | { +---------------------------------------------------------------+ { byte | DST$B_TS_ARRAY_DIM | { +---------------------------------------------------------------+ { var | DST$A_TS_ARRAY_FLAGS_ADDR | { | | { | Bit Vector of Flags Indicating What Type | { | | { | Specifications are Given Below | { | | { | (The vector's bit length is given by DST$B_TS_ARRAY_DIM + 1) | { | | { | | { +---------------------------------------------------------------+ { var | | { | Value Specification Producing an Array Descriptor | { | | { +---------------------------------------------------------------+ { var | | { | Optional Type Specification for Array Element Data Type | { | | { | | { +---------------------------------------------------------------+ { var | | { | Optional Type Specification for First Subscript Data Type | { | | { | | { +---------------------------------------------------------------+ { var | | { | | { | More Optional Type Specifications for Subscript Data Types | { | | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$B_TS_ARRAY_DIM field gives the number of dimensions of this { array type. Next, DST$A_TS_ARRAY_FLAGS_ADDR gives the location of a { bit-vector which indicates what nested Type Specifications are found { later in this Array Type Specification. If bit 0 is set, a nested Type { Specification is included for the array element type (the cell type). { After that, if bit n is set, a nested Type Specification for the n-th { subscript type is included in this Array Type Specification. If a bit { in the bit-vector is zero (not set), the corresponding Type Specifica- { tion is omitted from the Array Type Specification. If the element type { specification is omitted, the element type is assumed to be given by the { array descriptor's DTYPE field. If a subscript type specification is { omitted, the subscript type is assumed to be longword integer (DTYPE_L). { (Subscript Type Specifications are mainly needed for enumeration type { subscripts as allowed in PASCAL.) { { The number of bits in the bit-vector is DST$B_TS_ARRAY_DIM plus one more { for the element type. The whole DST$A_TS_ARRAY_FLAGS_ADDR field is of { course rounded up to the nearest byte boundary. { { The array descriptor Value Specification that follows the bit-vector { field produces a VAX Standard Descriptor for the array. (The descriptor { class must be DSC$K_CLASS_A, DSC$K_CLASS_NCA, or DSC$K_CLASS_UBA.) This { array descriptor gives the strides (or multipliers) and the lower and { upper bounds for all of the array dimensions. It also gives the element { data type, including its scale factor, digit count, or other type infor- { mation as appropriate. However, the descriptor's element type can be { overridden by an element Type Specification as noted above; in this case { the DSC$B_DTYPE field of the descriptor should be zero. { { The Array Type Specification is normally only used in two situations. { First, it is used if the array type does not have a compile-time-con- { stant descriptor (for example, if it has variable array bounds) and no { run-time descriptor exists in the user's address space. Second, it is { used if the array type cannot be described a VAX Standard Descriptor, { either because the element type cannot be described by a VAX Standard { Descriptor or because the subscript types are not integers. (Element { types such as records, enumeration types, and typed pointers cannot be { described by VAX Standard Descriptors.) If neither of these situations { pertains, there are simpler ways of describing array types in the DST { using Standard Data or Descriptor Format DST records. { ADA ARRAY TYPE SPECIFICATIONS { { { The ADA Array Type Specification is similar to the Array Type { Specification. The difference is that the Array Descriptor { within this type spec is one of ADA's "extended descriptors", { in which the DSC$W_LENGTH field occupies the entire first { longword and thus overlays the class and dtype. For this { reason, the ADA Array Type Specification contains a Class { field and a Dtype field in order that the compiler can give { us this information. { { This is the format of the ADA Array Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_ADA_ARRAY) | { +---------------------------------------------------------------+ { byte | DST$B_TS_ARRAY_DIM | { +---------------------------------------------------------------+ { byte | DST$B_TS_ADA_ARRAY_CLASS | { +---------------------------------------------------------------+ { byte | DST$B_TS_ADA_ARRAY_DTYPE | { +---------------------------------------------------------------+ { var | DST$A_TS_ADA_ARRAY_FLAGS | { | | { | Bit Vector of Flags Indicating What Type | { | | { | Specifications are Given Below | { | | { | (The vector's bit length is given by DST$B_TS_ARRAY_DIM) | { | | { | | { +---------------------------------------------------------------+ { | | { var | Value Specification Producing an | { | "extended" Array Descriptor | { | | { +---------------------------------------------------------------+ { | | { var | Optional Type Specification for Array Element Data Type | { | | { | | { +---------------------------------------------------------------+ { | | { var | Optional Type Specification for First Subscript Data Type | { | | { | | { +---------------------------------------------------------------+ { | | { | | { var | More Optional Type Specifications for Subscript Data Types | { | | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$B_TS_ARRAY_DIM field gives the number of dimensions of this { array type. Next, DST$A_TS_ADA_ARRAY_FLAGS gives the location of a { bit-vector which indicates what nested Type Specifications are found { later in this ADA Array Type Specification. If bit 0 is set, a nested Type { Specification is included for the array element type (the cell type). { After that, if bit n is set, a nested Type Specification for the n-th { subscript type is included in this ADA Array Type Specification. If a bit { in the bit-vector is zero (not set), the corresponding Type Specifica- { tion is omitted from the Array Type Specification. If the element type { specification is omitted, the element type is assumed to be given by { type spec's DTYPE field. If a subscript type specification is { omitted, the subscript type is assumed to be longword integer (DTYPE_L). { (Subscript Type Specifications are mainly needed for enumeration type { subscripts.) { { The number of bits in the bit-vector is DST$B_TS_ARRAY_DIM plus one more { for the element type. The whole DST$A_TS_ADA_ARRAY_FLAGS field is of { course rounded up to the nearest byte boundary. { { The DST$B_TS_ADA_ARRAY_CLASS field must be one of DSC$K_CLASS_A, { DSC$K_CLASS_NCA, or DSC$K_CLASS_UBA. The DST$B_TS_ADA_ARRAY_DTYPE { field describes the element type of the array. However, this element { type can be overridden by the optional Type Specification for { the array element type. If this optional type spec is present, { then the DST$B_TS_ADA_ARRAY_DTYPE field should be zero. { { The array descriptor Value Specification that follows the bit-vector { field produces an "extended" descriptor for the array. This is the { same as a VAX standard descriptor except that the DSC$W_LENGTH field { occupies the entire first longword. This { array descriptor gives the strides (or multipliers) and the lower and { upper bounds for all of the array dimensions. { { The ADA Array Type Specification is normally only used in two situations. { First, it is used if the array type does not have a compile-time-con- { stant descriptor (for example, if it has variable array bounds) and no { run-time descriptor exists in the user's address space. Second, it is { used if the array type cannot be described a VAX Standard Descriptor, { either because the element type cannot be described by a VAX Standard { Descriptor or because the subscript types are not integers. (Element { types such as records, enumeration types, and typed pointers cannot be { described by VAX Standard Descriptors.) If neither of these situations { pertains, there are simpler ways of describing array types in the DST { using Standard Data or Descriptor Format DST records. { SET TYPE SPECIFICATIONS { { { { The Set Type Specification specifies a Set data type as in PASCAL. A { Set type always has a parent data type. For the set-of-integers type, { for example, integer is the parent type. The parent type must be either { integer, some enumeration type, or a subrange of those types. DEBUG { assumes that the Set type is represented internally as a bit-string { where a given bit is set if and only if the corresponding integer or { enumeration type element is a member of the set. The n-th bit of the { bit-string (starting at bit 0) is assumed to correspond to the n-th { element of the parent type. The length of the bit-string is part of { the Set type and is specified in the Set Type Specification. { { This is the format of the Set Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_SET) | { +---------------------------------------------------------------+ { long | DST$L_TS_SET_LENG | { +---------------------------------------------------------------+ { var | DST$A_TS_SET_PAR_TSPEC_ADDR | { | | { | Type Specification Specifying the Set's Parent Type | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$L_TS_SET_LENG field gives the bit length of an object of { the Set data type. DST$A_TS_SET_PAR_TSPEC_ADDR marks the location of { an embedded DST Type Specification for the parent type of the Set type. { Typically this is an Atomic Type Specification for type integer, an { Indirect Type Specification that points to an Enumeration Type Begin { DST record, or a Subrange Type Specification. { { { Define a constant for the maximum size of a set (in bytes). For a set { of a integers, that maximum size of a set is 256 elements. So it { takes 32 bytes to hold that many bits. For sets of user-defined { enumerations, since the DST's length field for the number of elements { of a set is a word, the maximum number of elements in a set is 65536 { (or 2^16). So it takes 8192 bytes to hold that many bits, so that's { the maximum size of a set, as far as the debugger is concerned. { CONSTANT DBG$K_SET_SIZE_MAX EQUALS 8192; { In bytes CONSTANT DBG$K_PREDEF_SET_SIZE_MAX EQUALS 32; { In bytes { SUBRANGE TYPE SPECIFICATIONS { { { { The Subrange Type Specification describes a Subrange data type, meaning { a subrange of some ordinal type such as integer or an enumeration type. { This Type Specification specifies the parent type (the original ordinal { type) and the lower and upper bounds of the subrange. It also gives the { bit length of objects of the Subrange type. This is the format of the { Subrange Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_SUBRANGE) | { +---------------------------------------------------------------+ { long | DST$L_TS_SUBR_LENG | { +---------------------------------------------------------------+ { var | DST$A_TS_SUBR_PAR_TSPEC_ADDR | { | | { | Type Specification Specifying the Subrange's Parent Type | { | | { | | { +---------------------------------------------------------------+ { var | | { | Value Specification Giving the Lower Bound of the Subrange | { | | { | | { +---------------------------------------------------------------+ { var | | { | Value Specification Giving the Upper Bound of the Subrange | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$L_TS_SUBR_LENG field gives the length in bits of objects { of the Subrange data type. DST$A_TS_SUBR_PAR_TSPEC_ADDR marks the { location of a DST Type Specification for the parent type of the sub- { range. Typically this is an Atomic Type Specification for type integer { or an Indirect Type Specification pointing to an Enumeration Type Begin { DST record. { { The two Value Specifications in this Type Specification specify the { lower and upper bounds of the subrange. These bounds values must be { values of the parent type. { FILE TYPE SPECIFICATIONS { { { { The File Type Specification specifies a File data type as found in { PASCAL or PL/I, for example. Since the interpretation of File types { varies from language to language, the language code for this File { type is included in the Type Specification. Optionally, a file record { Type Specification can be included specifying the type of a record in { this file type. A PASCAL File-of-Reals, for instance, would have Real { (F-Floating) as its file record type. { { This is the format of the File Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_FILE) | { +---------------------------------------------------------------+ { byte | DST$B_TS_FILE_LANG | { +---------------------------------------------------------------+ { var | DST$A_TS_FILE_RCRD_TYP | { | | { | Type Specification Giving the File Record Type | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$B_TS_FILE_LANG field contains the language code for this { file. The same language codes are used as in the Module Begin DST { record. DST$A_TS_FILE_RCRD_TYP is the location of a DST Type Specifi- { cation for the record type, if applicable. This Type Specification is { optional; if omitted, file-of-characters is assumed. { AREA TYPE SPECIFICATIONS { { { { NOTE: THIS TYPE SPECIFICATION IS NOT SUPPORTED BY DEBUG V4.0. { { The Area Type Specification describes a PL/I "area" type. PL/I areas { are regions of memory whose base addresses are determined at run-time. { Areas are always used in conjunction with PL/I Offsets (see below). { This is the format of the Area Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_AREA) | { +---------------------------------------------------------------+ { var | DST$A_TS_AREA_BYTE_LEN | { | | { | Value Specification Giving the Area Byte Length | { | | { | | { +---------------------------------------------------------------+ { { { Here the DST$A_TS_AREA_BYTE_LEN Value Specification specifies the byte { length of the PL/I Area. { OFFSET TYPE SPECIFICATIONS { { { { NOTE: THIS TYPE SPECIFICATION IS NOT SUPPORTED BY DEBUG V4.0. { { The Offset Type Specification describes a PL/I "offset" type. PL/I { offsets are offsets relative to the start of a PL/I "area" (see above), { a dynamically allocated region of memory. The Offset Type Specifica- { tion specifies the base address of the associated area and the byte { offset value of this offset type. This is the format: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_OFFSET) | { +---------------------------------------------------------------+ { var | DST$A_TS_OFFSET_VALSPEC | { | | { | Value Specification Giving the Base Address | { | | { | of the Area Associated with this Offset | { | | { | | { +---------------------------------------------------------------+ { var | | { | Value Specification Giving the Byte Offset Value | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$A_TS_OFFSET_VALSPEC Value Specification produces the base { address of the associated area and the second Value Specification gives { the byte offset value into the area. { NOVEL LENGTH TYPE SPECIFICATIONS { { { { The Novel Length Type Specification is used to specify any data type { that is identical to a parent data type except that the objects of this { new type have a different length (a "novel" or atypical length). This { Type Specification is used for the components of PACKED records in { PASCAL, for example. A boolean component of a packed record consists { of a single bit (the novel length) while all other booleans consist of { a byte (the normal length). To describe the packed boolean type, a { Novel Length Type Specification is used which specifies the novel length { and points to the DST description of the parent type, namely the normal { boolean type. DEBUG accessed objects of a Novel-Length type by expand- { ing them to the normal length for that type. { { This is the format of the Novel Length Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 9) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_NOV_LENG) | { +---------------------------------------------------------------+ { long | DST$L_TS_NOV_LENG | { +---------------------------------------------------------------+ { long | DST$L_TS_NOV_LENG_PAR_TSPEC | { +---------------------------------------------------------------+ { { { { Here the DST$L_TS_NOV_LENG field contains the "novel" length of this { data type. The DST$L_TS_NOV_LENG_PAR_TSPEC field is a DST pointer which { contains the byte offset relative to the start of the whole DST of the { DST record that specifies the parent type. The pointed-to DST record { must be a Type Specification DST record, a Record Begin DST record, or { an Enumeration Type Begin DST record. (Typically it is a Type Specifi- { cation DST record containing an Atomic Type Specification for type inte- { ger or boolean or an Enumeration Type Begin DST record.) { { { DYNAMIC NOVEL LENGTH TYPE SPECIFICATIONS { { { The "dynamic" novel length type spec fulfills the same function { as the novel length type spec. The difference is that the { "novel length" is specified as a value spec rather than as { an immediate value. Thus the dynamic novel length type spec { can be used to specify a length that is not known at compile time. { { This is the format of the Dynamic Novel Length Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_DYN_NOV_LENG) | { +---------------------------------------------------------------+ { byte | DST$A_TS_NOV_LENG_VSPEC | { long | | { +---------------------------------------------------------------+ { var | DST$A_TS_NOV_LENG_TSPEC | { | | { +---------------------------------------------------------------+ { { Here the DST$A_TS_NOV_LENG_VSPEC field is an embedded value spec { that specifies the new length. The DST$A_TS_NOV_LENG_TSPEC is { an embedded type spec which specifies the parent type. This may { be an indirect type spec. { { SELF-RELATIVE LABEL TYPE SPECIFICATIONS { { { { The Self-Relative Label Type Specification specifies the type of a PL/I { "self-relative" label. Such a label is actually a label array, meaning { that it must be indexed by an integer value to yield a specific label { value. The internal representation consists of an array of longwords { where each array element contains a label value relative to the start of { the array. Making the element values relative to the start of the array { ensures that the label array is Position-Independent (PIC). { { This is the format of the Self-Relative Label Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 1) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_SELF_REL_LABEL) | { +---------------------------------------------------------------+ { { TASK TYPE SPECIFICATIONS { { { { The Task Type Specification specifies the data type of task objects { as found in ADA. Objects of the Task data type are assumed to have { longword values understood by the ADA multi-tasking kernel. Some { additional information about entry names may be associated with the { Task data type, depending on the value of DST$W_TS_LENGTH: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 1) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_TASK) | { +---------------------------------------------------------------+ { | ... | { +---------------------------------------------------------------+ AGGREGATE DST$TASK_TS_ENTRY STRUCTURE TYPEDEF; dst$bu_ts_task_entry_flags STRUCTURE; dst$v_ts_task_entry_family BITFIELD LENGTH 1; { This entry represents a family dst$v_ts_task_entry_mbz BITFIELD LENGTH 7; { Must Be Zero END dst$bu_ts_task_entry_flags; dst$bu_ts_task_fields UNION; dst$bu_ts_task_entry_name BYTE UNSIGNED; { Count byte of the entry name field, { a counted ASCII string dst$bu_ts_task_entry_trlr_offs BYTE UNSIGNED; { Byte offset to the task entry { optional trailer fields END dst$bu_ts_task_fields; #dst$task_ts_entry_size = :; END; { DST$TASK_TS_ENTRY definition CONSTANT DST$K_TASK_TS_ENTRY_SIZE EQUALS #dst$task_ts_entry_size; { Size of Value Specification { DST record in bytes { { Define the base address for offset to optional task entry trailer fields { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ts_task_entry_trlr_base = DST$K_TASK_TS_ENTRY_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; AGGREGATE DST$TASK_TS_FAMILY STRUCTURE TYPEDEF; dst$a_ts_entry_family_lb DST$VAL_SPEC; { Valspec for the lower bound of a { task entry family dst$a_ts_entry_family_ub DST$VAL_SPEC; { Valspec for the upper bound of a { task entry family #dst$task_ts_entry_family_size = :; END; { DST$TASK_TS_FAMILY definition CONSTANT DST$K_TASK_TS_ENTRY_FAMILY_SIZE EQUALS #dst$task_ts_entry_family_size; { Size of Value Specification { DST record in bytes { { Force the datatype name to be consistent with the old DSTRECRDS.REQ. { The problem is that SDL generates a fieldset name longer than 32 { characters if we don't do this... { IFLANGUAGE BLISSF; LITERAL; MACRO DST$TASK_TS_ENTRY_FAMILY = DST$TASK_TS_FAMILY%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the offset for the Typespec for the index of a task entry family { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ts_entry_family_type = DST$K_TASK_TS_ENTRY_FAMILY_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { CONSTRAINED RECORD TYPE SPECIFICATION { { { { The Constrained Record Type Specification is used to indicate that { a particular record is constrained in the Ada sense. A constrained { record is a record structure with variants where one or more of the { tag variables (discriminants in Ada terminology) are required to { have certain fixed values. These fixed tag values constitute the { constraints on the record type. { { The Constrained Record Type Specification has a pointer to the { original Record Type Begin DST and a list of Value Specifications { for each of the constrained record components. { Constraint checks are then done when this record is referenced by { looking at these Value Specs. The Constrained Record Type Specifi- { cation has the following format: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_CONSTRAINED) | { +---------------------------------------------------------------+ { long | DST$L_TS_CONSTR_RECORD | { +---------------------------------------------------------------+ { long | DST$L_TS_CONSTR_COUNT | { +---------------------------------------------------------------+ { var | DST$A_TS_CONSTR_LIST | { | | { | List of Value Specifications that describe those | { | components that are constrained. | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$L_TS_CONSTR_RECORD field is the address of either a { Record Begin DST, a Typed Pointer Type Spec DST, or a Cross-Module { Indirect Type Spec DST. This is a byte offset relative to the { start all the DSTs. The DST$L_TS_CONSTR_LENG field has the number { of constrained components that this DST describes. The { DST$A_TS_CONSTR_LIST is the address of a list of value specs that { describe the constrained components of this Record. This list has { two items per component. The first is the number of the component { that is constrained, where the first component is 0, the next is 1, { and so forth. The second item is the value spec to be evaluated { for this component. The structure of the list will look like this: { { { +---------------------------------------------------------------+ { long | Number of the first constrained record component | { +---------------------------------------------------------------+ { var | | { | Value Specification for the first constrained component | { | | { +---------------------------------------------------------------+ { long | Number of the second constrained record component | { +---------------------------------------------------------------+ { var | | { | Value Specification for the second constrained component | { | | { +---------------------------------------------------------------+ { long | Number of the third constrained record component | { +---------------------------------------------------------------+ { var | | { | Value Specification for the third constrained component | { | | { +---------------------------------------------------------------+ { : { : { MIGHT-BE-CONSTRAINED RECORD TYPE SPECIFICATION { { { { The Might-Be-Constrained Record Type Specification is used to des- { cribe a record which is a formal procedure parameter where the { formal parameter is not constrained but where the corresponding { actual parameter might be constrained. { { The Might-Be-Constrained Record Type Specification has a pointer { to the original Record Type Begin DST and has a Value Specification { to indicate whether this record is constrained or not. { Might-Be-Constrained records are treated exactly like ordinary { records except that its Value Specification will be evaluated for { TRUE or FALSE when the 'CONSTRAINED attribute is requested by the { user. The format of the Might-Be-Constrained Record Type Specifi- { cation is as follows: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_MAYBE_CONSTR) | { +---------------------------------------------------------------+ { long | DST$L_TS_MIGHTBE_RECORD | { +---------------------------------------------------------------+ { var | DST$A_TS_MIGHTBE_VALSPEC | { | | { | Value Spec indicating whether this Record is | { | constrained or not. The Value Spec yields a | { | result of TRUE or FALSE (LSB). | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$L_TS_RECORD field is the address of a Record Begin { DST record as a byte offset relative to the start all the DST { records. The DST$A_CONTR_VALSPEC field contains the Value { Specification to evaluate to determine whether this record is { constrained or not. The Value Specification will yield either { TRUE if the actual parameter is constrained and FALSE if the actual { parameter is not constrained. { { { SCAN TREE TYPE SPECIFICATIONS { { { { The SCAN Tree Type Specification specifies a Tree data type in the { SCAN language. This specification is similar to the Array Type { Specification but not as complex. It specifies the number of { subscripts or "depth" of the Tree, but does not give any information { about their bounds, since they are not bounded in the conventional { sense, only by the SCAN language implementation. It specifies the { leaf data type by an additional Type Specification embedded within the { Tree Type Specification. Subscript data types are also given by { additional Type Specifications embedded within the Tree Type { Specification. { { { This is the format of the SCAN Tree Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_SCAN_TREE) | { +---------------------------------------------------------------+ { byte | DST$B_TS_SCAN_TREE_DEPTH | { +---------------------------------------------------------------+ { var | DST$A_TS_SCAN_TREE_FLAGS | { | | { | Bit Vector of Flags Indicating which Embedded Type | { | | { | Specifications are Given Below | { | | { | (The vector's bit length is given by DST$B_TS_TREE_DEPTH + 1) | { | | { | | { +---------------------------------------------------------------+ { var | | { | Optional Type Specification for SCAN Tree Leaf Data Type | { | | { +---------------------------------------------------------------+ { var | | { | Optional Type Specification for First Subscript Data Type | { | | { +---------------------------------------------------------------+ { var | | { | Optional Type Specifications for N-th Subscript Data Types | { | | { | | { +---------------------------------------------------------------+ { { { { Here the DST$B_TS_SCAN_TREE_DEPTH field gives the number of subcripts { or "depth" of this tree type. Next, DST$A_TS_SCAN_TREE_FLAGS gives { the location of a bit-vector which indicates which embedded Type { Specifications are found later in this SCAN Tree Type Specification. { If bit 0 is set, an embedded Type Specification is included for the tree { leaf type After that, if bit n is set, then an embedded Type { Specification for the n-th subscript type is included in this SCAN { Tree Type Specification. If a bit in the bit-vector is zero (not set), { the corresponding embedded Type Specification is omitted from the SCAN { Tree Type Specification. { { If a subscript type specification is omitted, the subscript type is { assumed to be signed longword integer (DTYPE_L). If the leaf type { specification is omitted, the leaf type is assumed to be signed { longword integer (DTYPE_L). Currently, SCAN restricts tree subscripts { to be either of type STRING or of type INTEGER. However, this general { mechanism allows subscripts to be extended to other datatypes (for { example enumeration type subscripts such as exist in PASCAL), should { the SCAN language evolve this way. { { The number of bits in the bit-vector is DST$B_TS_SCAN_TREE_DEPTH plus { one more for the leaf type. The whole DST$A_TS_SCAN_TREE_FLAGS field { is of course rounded up to the nearest byte boundary. { { Since the nodes and leaves of a SCAN Tree are allocated in heap { storage and can move arbitrarily at run time, no mechanism is provided { in the DST for DEBUG to calculate their location. { { SCAN TREEPTR TYPE SPECIFICATIONS { { { { The SCAN Treeptr Type Specification describes a special kind of typed { pointer data type. A Treeptr always points to a node at a fixed level { in a SCAN Tree. It's Type Specification contains an embedded Type { Specification for a Tree that describes the level where the Treeptr { points. { { There are two distinguishing features of a given TREEPTR: the data type { of the subscript at the level of the node that the Treeptr points to, { and the data type of the structure below that node (either a subtree or { a leaf). To simplify DEBUG processing, these two features are combined { and represented by a single embedded Type Specification for a Tree data { type. { { To illustrate: { { Suppose we have the following declarations, { { DECLARE city_ptr: TREEPTR (STRING) TO TREE (INTEGER) OF INTEGER; { DECLARE ward_ptr: TREEPTR (INTEGER) OF INTEGER; { { Then the Type Specification for city_ptr would have an embedded Type { Specification for a Tree declared as { TREE (STRING, INTEGER) OF INTEGER, { and the Type Specifiaction for ward_ptr would have an embedded Type { Specification for a Tree declared as { TREE (INTEGER) OF INTEGER. { { { The DST$A_TS_SCAN_TREEPTR_TREE field provides a Type Specification for { a subtree at the level of the node that the Treeptr points to. { { { This is the format of the SCAN Treeptr Type Specification: { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_SCAN_TREEPTR) | { +---------------------------------------------------------------+ { var | DST$A_TS_SCAN_TREEPTR_TREE | { | | { | Type Specification for SCAN Tree Type | { | | { | that SCAN Treeptr Type Points to | { | | { | | { +---------------------------------------------------------------+ { INCOMPLETE TYPE SPECIFICATIONS { { { { The Incomplete Type Specification is used when the actual Type { Specification for the object is in an Ada package body. Just the { stub of the type declaration is in the package spec. Note the { following example: { { pacakge P is -- module P_ { package Q is { type A is private; { private { type CELL; { type A is access CELL; { end; { end; { { package body P is -- module P { package body Q is { type CELL is array(1..10) of integer; { end; { end; { { It is possible to have only package spec P SET (P_) and not package { body P. When Ada compiles P_ it doesn't know anything about type { CELL to put out a DST to describe it. The Incomplete Type Spec DST { is to be generated in this case. The DST$L_TS_INCOMPLETE_PTR is to { be zero when generated. DEBUG will fill it in later when it see's the { DST$K_FULFILLS_TYPE DST. See that DST description for more information. { { After the DST$L_TS_INCOMPLETE_PTR field get's filled in we will handle { this DST just like the DST$K_TS_IND DST. (Indeed, the processing of the { Fulfills Type DST turns this type spec into an indirect type spec. So { these formats must remain the same{) When this field is not filled { in we'll issue a message saying that we don't have any type information { until the package body gets set. { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH (= 5) | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_INCOMPLETE) | { +---------------------------------------------------------------+ { long | DST$L_TS_INCOMPLETE_PTR | { +---------------------------------------------------------------+ { { { { { BLISS BLOCK TYPE SPECIFICATIONS { { The Bliss Block Type Specification describes the BLOCK data structure { in language BLISS. The BLISS Block Type Specification replaces the older { DST$K_BLI DST record (the intent being to make BLISS DSTs be more { consistent in format with the other languages). { { Note: REF BLOCKs in BLISS should be described as pointers to Blocks, { using the "Typed Pointer" Type Specification. BLOCKVECTORs in BLISS { should be described as arrays of Blocks, using the Array Type { Specification. { { The general form of a Block declaration is { BLOCK [number-units, unit-size] FIELD (field-set, ...) { Therefore, the Bliss Block DST allows the compiler to describe { the number of units, the unit size, and if field sets were { specified, the compiler can optionally point to one or more { Bliss Field DSTs to specify that those field sets go with this block. { The pointers to the Bliss Field DSTs are byte offsets relative { to the start of the entire DST. { { { +---------------------------------------------------------------+ { word | DST$W_TS_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_TS_KIND (= DST$K_TS_BLISS_BLOCK) | { +---------------------------------------------------------------+ { long | DST$L_TS_NUMBER_UNITS | { +---------------------------------------------------------------+ { byte | DST$B_TS_UNIT_SIZE | { +---------------------------------------------------------------+ { byte | DST$B_TS_FIELD_SET_COUNT | { +---------------------------------------------------------------+ { var | DST$A_TS_FIELD_SET_LIST | { | A list of N pointers to Bliss Field DST Records, where | { | N is given in the above FIELD_SET_COUNT record. | { +---------------------------------------------------------------+ { { { { { END OF TYPE SPECIFICATION DESCRIPTION. { E N U M E R A T I O N T Y P E D S T R E C O R D S { { { { Enumeration types, as found in PASCAL and C, are represented in the { DST by three kinds of DST records. The Enumeration Type Begin DST { record describes the type itself, giving the bit length of objects { of that type and the name of the type (e.g., COLOR). This record { is followed by some number of Enumeration Type Element DST records, { one for each element, or literal, in the type (e.g., RED, BLUE, and { GREEN). Each Enumeration Type Element DST record gives the name and { numeric value of one literal of the enumeration type. The whole type { description is then terminated by an Enumeration Type End DST record. { { The Enumeration Type Begin and Enumeration Type End DST records thus { bracket the list of elements of the type, much like other Begin-End { pairs in the DST. The Enumeration Type Element DST records within { those brackets do not have to be in numeric order of their values, { although it is desirable if they are. For languages like ADA, where { the numeric values of the elements need not go up sequentially with { the logical element positions, the Enumeration Type DST Elements do { have to be order of their logical positions, however. No other kinds { of DST records (except Continuation DST records) may appear between { the Enumeration Type Begin and the Enumeration Type End DST records. { THE ENUMERATION TYPE BEGIN DST RECORD { { { The Enumeration Type Begin DST record specifies the name of an { enumeration type and the bit length of objects of that type. { It also serves as the opening bracket for a list of Enumeration { Type Element DST records, and must be matched by a closing { Enumeration Type End DST record. This is record's format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_ENUMBEG) | { +---------------------------------------------------------------+ { byte | DST$B_ENUMBEG_LENG | { +---------------------------------------------------------------+ { byte | DST$B_ENUMBEG_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the Enumeration Type in ASCII | { | | { | (The name's length is given by DST$B_ENUMBEG_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Enumeration Type Begin DST record. { AGGREGATE DST$ENUM_BEGIN STRUCTURE TYPEDEF; dst$a_enumbeg_header DST$HEADER; dst$b_enumbeg_leng BYTE UNSIGNED; { Bit length of data objects of { this enumeration type dst$b_enumbeg_name BYTE UNSIGNED; { Count byte for the Counted { ASCII Type Name #dst$enum_begin_size = :; END; { DST$ENUM_BEGIN definition CONSTANT DST$K_ENUM_BEGIN_SIZE EQUALS #dst$enum_begin_size; { Size of Enumeration Type Begin { DST header record in bytes { THE ENUMERATION TYPE ELEMENT DST RECORD { { { The Enumeration Type Element DST record specifies the name and value { of one element (one literal) of an enumeration type. It may only { appear between an Enumeration Type Begin and an Enumeration Type End { DST record. The underlying representation of enumeration types is { assumed to be unsigned integer. The DST$B_VFLAGS field in this record { has its normal interpretation (see the Standard Data DST record for { the details). Hence the DST$V_VALKIND field will have the value { DST$K_VALKIND_LITERAL and the DST$L_VALUE field will have the appro- { priate integer value in this case. { { This is the format of the Enumeration Type Element DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_ENUMELT) | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the Enumeration Literal in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { { THE ENUMERATION TYPE END DST RECORD { { { The Enumeration Type End DST record terminates the description of an { enumeration type. This is the record's format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_ENUMEND) | { +---------------------------------------------------------------+ { AGGREGATE DST$ENUM_END STRUCTURE TYPEDEF; dst$a_enum_end_header DST$HEADER; #dst$enum_end_size = :; END; { DST$ENUM_END definition CONSTANT DST$K_ENUM_END_SIZE EQUALS #dst$enum_end_size; { Size of Enumeration End { DST record in bytes { B L I S S F I E L D D S T R E C O R D S { { BLISS Field Sets are data structures in BLISS that are somewhat analogous { to records in PASCAL, but are different enough so that they need their { own DST records. { { BLISS Field Sets are represented in the Debug Symbol Table by a { Bliss Field Set Begin DST record, followed by some { number of BLISS Field DST records, followed by a BLISS Field Set End { DST record. { { { THE BLISS FIELD SET BEGIN DST RECORD { { The Bliss Field Set Begin DST Record marks the beginning of a BLISS { Field Set. The Bliss Field Set Begin DST Record contains the name { of the field set. It is followed by some number of Bliss Field DST { Records defining the fields in the field set. The field set is { closed by a Bliss Field Set End DST Record. { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLIFLDBEG) | { +---------------------------------------------------------------+ { byte | DST$B_BLIFLDBEG_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the BLISS Field Set in ASCII | { | | { | (The name's length is given by DST$B_BLIFLDBEG_NAME) | { | | { | | { +---------------------------------------------------------------+ { { Define the fields of the Bliss Field Set Begin DST record { AGGREGATE DST$BLISS_FIELD_BEGIN STRUCTURE TYPEDEF; dst$a_blifldbeg_header DST$HEADER; dst$b_blifldbeg_name BYTE UNSIGNED; { Length of the name of the { Bliss Field Set #dst$blifld_begin_size = :; END; { DST$BLISS_FIELD_BEGIN definition CONSTANT DST$K_BLISS_FIELD_BEGIN_SIZE EQUALS #dst$blifld_begin_size; { Size of Bliss Field Set Begin { DST header record in bytes { { THE BLISS FIELD SET END DST RECORD { { The Bliss Field Set End DST Record marks the end of a BLISS { Field Set. { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLIFLDEND) | { +---------------------------------------------------------------+ { AGGREGATE DST$BLISS_FIELD_END STRUCTURE TYPEDEF; dst$a_blifld_end_header DST$HEADER; #dst$blifld_end_size = :; END; { DST$BLISS_FIELD_END definition CONSTANT DST$K_BLISS_FIELD_END_SIZE EQUALS #dst$blifld_end_size; { Size of Bliss Field Set End { DST record in bytes { THE BLISS FIELD DST RECORD { { { The BLISS Field DST record describes a BLISS field name. BLISS field { names are declared in FIELD declarations in BLISS. Each BLISS field { name is bound to an n-tuple of numbers. Usually the n-tuple is a four- { tuple and the numbers represent a byte or longword offset, the bit { offset within that byte or longword, the bit length of the field being { described, and a sign-extension flag. However, a BLISS field { can be any n-tuple. DEBUG supports references to BLISS field names { when picking up subscripts in BLOCKs or BLOCKVECTORs. DEBUG also { allows you to EVALUATE a Bliss Field and see what n-tuple it is { bound to. { { The BLISS Field DST record should be nested within a BLISS Field Set { Begin DST Record and a BLISS Field Set End DST record. However, for { compatibility with older versions (which didn't have the begin-end { records), the BLISS Field DST record can stand by itself, in which { case it defines a BLISS field globally known in the module, and { not (as far as DEBUG is concerned) associated with any particular { field set. { { { The BLISS Field DST record should not be generated for any language { other than BLISS. This is the format of the record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLIFLD) | { +---------------------------------------------------------------+ { byte | DST$B_BLIFLD_UNUSED | { +---------------------------------------------------------------+ { long | DST$L_BLIFLD_COMPS | { +---------------------------------------------------------------+ { byte | DST$B_BLIFLD_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the BLISS Field in ASCII | { | | { | (The name's length is given by DST$B_BLIFLD_NAME) | { | | { | | { +---------------------------------------------------------------+ { var | | { | A Vector of Longwords Containing the Integer | { | | { | Values of the Components of the BLISS Field Definition | { | | { | (The number of values is given by DST$B_BLIFLD_COMPS) | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the BLISS Field DST record. { AGGREGATE DST$BLISS_FIELD STRUCTURE TYPEDEF; dst$a_blifld_header DST$HEADER; dst$b_blifld_unused BYTE UNSIGNED; { Unused--Must Be Zero dst$l_blifld_comps LONGWORD UNSIGNED; { The number of components dst$b_blifld_name BYTE UNSIGNED; { The count byte of the field { name Counted ASCII string #dst$bliss_field_size = :; END; { DST$BLISS_FIELD definition CONSTANT DST$K_BLISS_FIELD_SIZE EQUALS #dst$bliss_field_size; { Size of Value Specification { DST record in bytes { B L I S S D A T A D S T R E C O R D S { { Note - this DST record, while still supported, should be viewed { as obsolete. This DST record is the "old" way of describing { BLISS Vectors, Bitvectors, Blocks, Blockvectors, and REFs of { the preceding. This DST record has a non-standard format and hence { is being phased out. The new way of describing these constructs is: { { VECTOR, BITVECTOR, BLOCKVECTOR - { use Septyp record followed by Array Type Spec { BLOCK - use Septyp record followed by Bliss Block Type Spec { REF - use Septyp record followed by Typed Pointer Type Spec { { THE BLISS DATA DST RECORD { { The BLISS Data DST record is used to describe a number of { data objects whose data types are specific to the BLISS language only. { This includes such objects as BLISS Vectors, Bitvectors, Blocks, and { Blockvectors and pointers to these objects (REF VECTOR, REF BLOCK, { and so on). This DST record should not be generated for any language { other than BLISS. { { This DST records consists of four parts: The DST header fields, the { fields in the set DST$BLI_FIELD, a variable-length set of fields, and { the fields in the set DST$BLI_TRAIL_FIELDS. The variable-length set { of fields can be empty, consist of the fields in DST$BLI_VEC_FIELDS, { the fields in DST$BLI_BITVEC_FIELDS, the fields in DST$BLI_BLOCK_FIELDS, { or the fields in DST$BLI_BLKVEC_FIELDS. Which set of fields appears { in the variable-length part depends on the value of BLI$V_BLI_STRUC, { which indicates which type of symbol is being defined. { { This is thus the format of the BLISS Data DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BLI) | { +---------------------------------------------------------------+ { byte | DST$B_BLI_LNG | { +---------------------------------------------------------------+ { byte | DST$B_BLI_FORMAL | { +---------------------------------------------------------------+ { byte | DST$B_BLI_VFLAGS | { +-------+-------------------------------+-----------------------+ { byte |BLI_REF| Unused--Must Be Zero | DST$V_BLI_STRUC | { +-------+-------------------------------+-----------------------+ { var | DST$A_BLI_SYM_ATTR | { | | { | Variable-Length Portion of DST Record | { | | { | | { +---------------------------------------------------------------+ { long | DST$L_BLI_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_BLI_NAME | { +---------------------------------------------------------------+ { var | | { | The BLISS Symbol Name in ASCII | { | | { | (The name's length is given by DST$B_BLI_NAME) | { | | { | | { +---------------------------------------------------------------+ { long | DST$L_BLI_SIZE | { +---------------------------------------------------------------+ { { { { The variable-length portion of the DST record can have several forms { as discussed above. One possibility is that it is absent altogether. { This occurs if the DST$V_BLI_STRUC field contains DST$K_BLI_NOSTRUC. { { However, if DST$V_BLI_STRUC has the value DST$K_BLI_VEC, the variable- { length portion of the DST record has the following format: { { { +---------------------------------------------------------------+ { long | DST$L_BLI_VEC_UNITS | { +-------------------------------+-------------------------------+ { byte | DST$V_BLI_VEC_SIGN_EXT | DST$V_BLI_VEC_UNIT_SIZE | { +-------------------------------+-------------------------------+ { { { { If DST$V_BLI_STRUC has the value DST$K_BLI_BITVEC, the variable-length { portion of the DST record has the following format: { { { +---------------------------------------------------------------+ { long | DST$L_BLI_BITVEC_SIZE | { +---------------------------------------------------------------+ { { { { If DST$V_BLI_STRUC has the value DST$K_BLI_BLOCK, the variable-length { portion of the DST record has the following format: { { { +---------------------------------------------------------------+ { long | DST$L_BLI_BLOCK_UNITS | { +-------------------------------+-------------------------------+ { byte | Unused | DST$V_BLI_BLOCK_UNIT_SIZE | { +-------------------------------+-------------------------------+ { { { { If DST$V_BLI_STRUC has the value DST$K_BLI_BLKVEC, the variable-length { portion of the DST record has the following format: { { { +---------------------------------------------------------------+ { long | DST$L_BLI_BLKVEC_BLOCKS | { +---------------------------------------------------------------+ { long | DST$L_BLI_BLKVEC_UNITS | { +---------------------------------------------------------------+ { byte | DST$B_BLI_BLKVEC_UNIT_SIZE | { +---------------------------------------------------------------+ { { { { These are the possible values of the DST$B_BLI_STRUC field. { #minimum_bliss_struc_kind = 0; CONSTANT ( DST$K_BLI_NOSTRUC, { 0, Not a BLISS structure DST$K_BLI_VEC, { 1, BLISS Vector DST$K_BLI_BITVEC, { 2, BLISS Bitvector DST$K_BLI_BLOCK, { 3, BLISS Block DST$K_BLI_BLKVEC { 4, BLISS Blockvector ) equals #minimum_bliss_struc_kind increment 1 counter #bliss_struc_kind_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_BLI_STRUC_MIN EQUALS #minimum_bliss_struc_kind; CONSTANT DST$K_BLI_STRUC_MAX EQUALS #bliss_struc_kind_counter; { { Define the fields in the BLISS Data DST Record. { AGGREGATE DST$BLI_FIELDS STRUCTURE TYPEDEF; dst$a_bli_fields_header DST$HEADER; dst$b_bli_lng BYTE UNSIGNED; { Length in bytes of the set of { fields between this one { and TRAIL_FIELDS { between 3 and 12 #dst$a_bli_trlr1 = :; dst$b_bli_formal BYTE UNSIGNED; { Flag set if this symbol is a { routine formal parameter dst$b_bli_vflags BYTE UNSIGNED; { Value access information dst$b_bli_sym_type STRUCTURE; { The type of the BLISS symbol { as described by the fol- { lowing sub-fields: dst$v_bli_struc BITFIELD LENGTH 3; { The structure of this symbol dst$v_bli_mbz BITFIELD LENGTH 4; { This field Must Be Zero dst$v_bli_ref BITFIELD LENGTH 1; { Flag set if this is a REF { (1 = REF, 0 = no REF) END dst$b_bli_sym_type; #dst$a_bli_sym_attr = :; dst$bli_struc_variants UNION; { { If this is not a structure definition, then there is nothing { else that is necessary to define. { { { Define the fields in the variable-length part of the BLISS Data { DST record when the value of the BLI$V_BLI_STRUC field is DST$K_BLI_VEC. { This field describes a BLISS Vector. { dst$bli_struc_vector STRUCTURE; dst$l_bli_vec_units LONGWORD UNSIGNED; { Number of elements allocated { in the vector dst$v_bli_vec_flags STRUCTURE; dst$v_bli_vec_unit_size BITFIELD LENGTH 4; { The vector element unit { size: 1 = byte, 2 = { word, and 4 = longword dst$v_bli_vec_sign_ext BITFIELD LENGTH 4; { Sign extension flag: { 1 = sign extension { 0 = no sign extension END dst$v_bli_vec_flags; END dst$bli_struc_vector; { { Define the fields in the variable-length part of the BLISS Data { DST record when the value of the BLI$V_BLI_STRUC field is DST$K_BLI_BITVEC. { This field describes a BLISS Bitvector. { dst$bli_struc_bitvector STRUCTURE; dst$l_bli_bitvec_size LONGWORD UNSIGNED; { The number of bits in the bitvector END dst$bli_struc_bitvector; { { Define the fields in the variable-length part of the BLISS Data { DST record when the value of the BLI$V_BLI_STRUC field is DST$K_BLI_BLOCK. { These fields describe a BLISS Block. { dst$bli_struc_block STRUCTURE; dst$l_bli_block_units LONGWORD UNSIGNED; { The number of units allocated { in the block dst$v_bli_block_flags STRUCTURE; dst$v_bli_block_unit_size BITFIELD LENGTH 4; { The unit size of the { block: 1 = byte, 2 = { word, and 4 = longword dst$v_bli_block_mbz BITFIELD LENGTH 4; { Must Be Zero END dst$v_bli_block_flags; END dst$bli_struc_block; { { Define the fields in the variable-length part of the BLISS Data { DST record when the value of the BLI$V_BLI_STRUC field is DST$K_BLI_BLKVEC. { These fields describe a BLISS Blockvector. { dst$bli_struc_blockvector STRUCTURE; dst$l_bli_blkvec_blocks LONGWORD UNSIGNED; { The number of blocks in the { blockvector dst$l_bli_blkvec_units LONGWORD UNSIGNED; { The number of units per block dst$b_bli_blkvec_unit_size BYTE UNSIGNED; { The block unit size: 1 = byte, { 2 = word, 4 = longword END dst$bli_struc_blockvector; END dst$bli_struc_variants; #dst$bli_fields_size = :; END; { DST$BLI_FIELDS definition CONSTANT DST$K_BLI_FIELDS_SIZE EQUALS #dst$bli_fields_size; { Size of Bliss Data { DST record in bytes { { Define a few interesting offsets for Bliss { CONSTANT DST$K_BLI_TRLR1 EQUALS #dst$a_bli_trlr1; { The first trailer is at this { location + DST$B_BLI_LNG CONSTANT DST$K_BLI_SYM_ATTR EQUALS #dst$a_bli_sym_attr; { Address of variable length { attribute segment in { this DST record IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_bli_trlr1 = DST$K_BLI_TRLR1, 0, 0, 0%; MACRO dst$a_bli_sym_attr = DST$K_BLI_SYM_ATTR, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the fields in the first trailer portion of the BLISS Data { DST record. { AGGREGATE DST$BLI_TRAILER1 STRUCTURE TYPEDEF; dst$l_bli_value LONGWORD UNSIGNED; { Value longword, interpreted { according to contents of { DST$B_BLI_VFLAGS dst$b_bli_name BYTE UNSIGNED; { Count byte of the symbol name { Counted ASCII string #dst$bli_trailer1_size = :; END; { DST$BLI_TRAILER1 definition CONSTANT DST$K_BLI_TRAILER1_SIZE EQUALS #dst$bli_trailer1_size; { Size of 1st trailer portion of { Bliss Data DST record in bytes { { Define the start of the second trailer. It starts at { this location + DST$B_BLI_NAME { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_bli_trlr2 = DST$K_BLI_TRAILER1_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the fields in the second trailer portion of the BLISS Data { DST record. { AGGREGATE DST$BLI_TRAILER2 STRUCTURE TYPEDEF; dst$l_bli_size LONGWORD UNSIGNED; { Size of the Bliss data item in bytes #dst$bli_trailer2_size = :; END; { DST$BLI_TRAILER2 definition CONSTANT DST$K_BLI_TRAILER2_SIZE EQUALS #dst$bli_trailer2_size; { Size of Enumeration End { DST record in bytes { { I M A G E D S T R E C O R D S { { { { Image DST records are not generated by compilers, so compiler writers { can skip this description. { { Since DEBUG stores information about shareable images in its { symbol table, it needs to construct dummy DST records to describe { shareable images. The following describes the structure of such { DST records. { { { This is the format of the Image DST Record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_IMAGE) | { +---------------------------------------------------------------+ { byte | unused | { +---------------------------------------------------------------+ { long | unused | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Image Name in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { { Define size of the Image DST Record. { AGGREGATE DST$IMAGE STRUCTURE TYPEDEF; dst$a_image_header DST$DATA_DST; #dst$image_size = :; END; { DST$IMAGE definition CONSTANT DST$K_IMAGE_SIZE EQUALS #dst$image_size; { Size in bytes of the fixed part of { the Image DST record { T H E P S E C T D S T R E C O R D { { { { The PSECT DST record specifies the name, address, and length of { a PSECT, where a PSECT is a Program Section in the linker sense. { PSECT DST records are only used for language MACRO where it is { possible to generate code or data at the beginning of a PSECT { without having any other label on that code. DEBUG ignores PSECT { DST records for all other languages since high-level languages { have other code and data labels that are more appropriate. { { This is the format of the PSECT DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PSECT) | { +---------------------------------------------------------------+ { byte | DST$K_PSECT_UNUSED | { +---------------------------------------------------------------+ { long | DST$L_PSECT_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_PSECT_NAME (also DSK$B_PSECT_TRLR_OFFS) | { +---------------------------------------------------------------+ { var | DST$A_PSECT_TRLR_BASE | { | | { | The Name of the PSECT in ASCII | { | | { | (The name's length is given by DST$B_PSECT_NAME) | { | | { | | { +---------------------------------------------------------------+ { long | DST$L_PSECT_SIZE | { +---------------------------------------------------------------+ { { { { Define the fields of the PSECT DST record. { AGGREGATE DST$PSECT STRUCTURE TYPEDEF; dst$a_psect_header DST$HEADER; dst$b_psect_unused BYTE UNSIGNED; { Unused--Must Be Zero dst$l_psect_value LONGWORD UNSIGNED; { Start address of the PSECT dst$a_psect_info UNION; dst$b_psect_name BYTE UNSIGNED; { The count byte in the PSECT { name Counted ASCII string dst$b_psect_trlr_offs BYTE UNSIGNED; { Byte offset to the PSECT DST { record trailer fields END dst$a_psect_info; #dst$psect_header_size = :; END; { DBG$PSECT definition CONSTANT DST$K_PSECT_HEADER_SIZE EQUALS #dst$psect_header_size; { { Define the base address for offset to DST record trailer fields. { Note that the address of the PSECT DST record trailer is computed as follows: { { DST_RECORD[DST$A_PSECT_TRLR_BASE] + .DST_RECORD[DST$B_PSECT_TRLR_OFFS] { { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_psect_trlr_base = DST$K_PSECT_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the PSECT DST record trailer fields. Also define the declaration { macro. { AGGREGATE DST$PSECT_TRAILER STRUCTURE TYPEDEF; dst$l_psect_size LONGWORD UNSIGNED; { Number of bytes in the PSECT #dst$psect_trailer_size = :; END; { DST$PSECT_TRAILER definition CONSTANT DST$K_PSECT_TRAILER_SIZE EQUALS #dst$psect_trailer_size; { L A B E L D S T R E C O R D S { { { { Labels are represented by two different DST records. A label, in the { sense used here, is a symbol bound to an instruction address. Labels { do not include routine, lexical block, and entry point symbols, however. { A label can be represented by either a Label DST record or a Label-or- { Literal DST record. The Label-or-Literal DST record is intended only { for language MACRO, it appears. (The history on the origin and intent { of this record is unclear, however.) All other languages should use { the Label DST record for labels. { { { { THE LABEL DST RECORD { { { The Label DST record specifies the name and address of a label in the { the current module. A label in this sense is always bound to an in- { struction address, not a data address. This is the DST record normally { used for labels in high-level languages. The DST$L_VALUE field of this { record contains the code address to which the label is bound. { { This is the format of the Label DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_LABEL) | { +---------------------------------------------------------------+ { byte | Unused--Must Be Zero | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Label Name in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { { Define a constant for the size of the Label DST Record { CONSTANT DST$K_LABEL_SIZE EQUALS DST$K_DATA_SIZE; { THE LABEL-OR-LITERAL DST RECORD { { { The Label-or-Literal DST record specifies the name and address of a { label (meaning a code location) or the name and value of an integer { literal (a named constant). It is not entirely clear why this DST { record exists since labels can be described by Label DST records and { integer literals can be described with Standard Data DST records. { Most likely this DST record was intended for language MACRO where { there is little distinction between labels and literals; one is relo- { catable and the other is not, but that is about all. If DST$V_VALKIND { has the value DST$K_VALKIND_ADDR, the symbol is a label and if it has { the value DST$K_VALKIND_LITERAL, the symbol is a literal. The address { of the label or the value of the literal is found in the DST$L_VALUE { field. It is recommended that high-level languages avoid this DST { record and use the Label DST record or the Standard Data DST record { instead. { { This is the format of the Label-or-Literal DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_LBLORLIT) | { +-----------------------------------------------+---------------+ { byte | Unused--Must Be Zero | DST$V_VALKIND | { +-----------------------------------------------+---------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Label or Literal Name in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { { Define a constant for the size of the Label-or-Literal DST Record { CONSTANT DST$K_LBL_OR_LIT_SIZE EQUALS DST$K_DATA_SIZE; { T H E E N T R Y P O I N T D S T R E C O R D { { { { The Entry Point DST record describes an ENTRY name in the FORTRAN or { PL/I sense. In other words, it describes a secondary entry point to { the routine within which this DST record is nested. This record should { never be generated for the main entry point to a routine since that { entry point is already described by the Routine Begin DST record. An { entry point described by the Entry Point DST record is always assumed { to be called through the CALLS/CALLG instructions (not JSB/BSB). The { DST$L_ENTRY_ADDRESS field contains the address of the entry point. { DST$L_ENTRY_PD_ADDRESS contains the address of the procedure { descriptor. DST$B_ENTRY_FLAGS contains special flags. No special { flags are defined, so this field MBZ. { { This is the format of the Entry Point DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_ENTRY) | { +---------------------------------------------------------------+ { byte | DST$B_ENTRY_FLAGS | { +---------------------------------------------------------------+ { long | DST$L_ENTRY_ADDRESS | { +---------------------------------------------------------------+ { long | DST$L_ENTRY_PD_ADDRESS | { +---------------------------------------------------------------+ { byte | DST$B_ENTRY_NAME | { +---------------------------------------------------------------+ { var | | { | The Entry Point Name in ASCII | { | | { | (The name's length is given by DST$B_ENTRY_NAME) | { | | { | | { +---------------------------------------------------------------+ { { { Define the fields of the Entrypoint DST record. These fields used to { be shared with the Standard Data DST record, but cannot anymore, because { of the addition of the procedure descriptor address. Thus, the fields of { the entrypoint DST are now patterned after the other DSTs that incorporate { procedure descriptor addresses: namely, package spec, package body, and { routine begin. { AGGREGATE DST$ENTRY STRUCTURE TYPEDEF; dst$a_entry_dst_header DST$HEADER; { Header dst$b_entry_flags STRUCTURE; { Flags dst$v_entry_mbz BITFIELD LENGTH 8; { No flags are used END dst$b_entry_flags; dst$l_entry_address ADDRESS; { Address of entrypoint dst$l_entry_pd_address ADDRESS; { Address of procedure { descriptor dst$b_entry_name BYTE UNSIGNED; { Count byte of entry's counted { ASCII name { #dst$entry_size = :; END; { DST$ENTRY definition CONSTANT DST$K_ENTRY_SIZE EQUALS #dst$entry_size; { Byte size of the fixed part of the { Entrypoint DST { L I N E N U M B E R P C - C O R R E L A T I O N { { D S T R E C O R D S { { { { The Line Number PC-Correlation DST record specifies the correlation { between listing line numbers, as assigned by the compiler, and PC { addresses. It thus the means whereby the compiler tells DEBUG where { the generated object code for each source line starts and how long { it is in bytes. This is the format of the Line Number PC-Correlation { DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_LINE_NUM) | { +---------------------------------------------------------------+ { var | | { | One or More Line Number PC-Correlation Commands | { | | { | | { +---------------------------------------------------------------+ { { { { After the two-byte header, each Line Number PC-Correlation DST record { contains a sequence of Line Number PC-Correlation commands. Each such { command sets or manipulates one or more state variables used by DEBUG { in the interpretation of these commands. The main state variables are { the current line number and the current PC address, but there are seve- { ral others as well. The exact semantics of the various commands are { described in the sections that follow. { { Line Number PC-Correlation DST records are associated with the module { within which they appear. The must thus appear between the Module { Begin and the Module End DST records for the current module. There are { no further restrictions on where they may appear, however. In particu- { lar, they need not be nested within the routines or lexical blocks that { they describe. It is thus legal to generate all Line Number PC-Corre- { lation DST records for a module after the last Routine End DST record, { for instance. These records can also be interspersed between Routine { and Block Begin and End records in any way convenient for the compiler { implementer. However it is done, DEBUG treats them as belonging to the { module as a whole. { { The Line Number PC-Correlation information may be spread over as many { DST records as necessary. No Line Number PC-Correlation command may be { broken across record boundaries, but otherwise the Line Number PC-Corre- { lation DST records within a module are considered to constitute a single { command stream. The Continuation DST record may not be used to continue { Line Number PC-Correlation DST records. { { { { Define the fields of the Line Number PC-Correlation DST record. { AGGREGATE DST$LINE_NUM_HEADER STRUCTURE TYPEDEF; dst$a_line_num_header DST$HEADER; #dst$line_num_header_size = :; END; { DST$LINE_NUM_HEADER definition CONSTANT DST$K_LINE_NUM_HEADER_SIZE EQUALS #dst$line_num_header_size; { { Define the start address of PC-correlation data { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_line_num_data = DST$K_LINE_NUM_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the fields of the PC Line Number Correlation commands. { AGGREGATE DST$PCLINE_COMMANDS STRUCTURE TYPEDEF; { { Field common to all PC Line Correlation commands. { dst$b_pcline_command BYTE; { Command code (signed, since { it could be a Delta PC) { { Fields used to access information in all other commands. { dst$a_pcline_access_fields UNION; dst$l_pcline_unslong LONGWORD UNSIGNED; { Unsigned longword parameter dst$w_pcline_unsword WORD UNSIGNED; { Unsigned word parameter dst$b_pcline_unsbyte BYTE UNSIGNED; { Unsigned byte parameter #dst$pcline_commands_size_min = :; END dst$a_pcline_access_fields; #dst$pcline_commands_size_max = :; END; { DST$PCLINE_COMMANDS definition { Define three constants: the "default" PC-Line DST size, the smallest { PC-Line DST size, and the largest PC-Line DST size. { CONSTANT DST$K_PCLINE_COMMANDS_SIZE EQUALS #dst$pcline_commands_size_max; CONSTANT DST$K_PCLINE_COMMANDS_SIZE_MIN EQUALS #dst$pcline_commands_size_min; CONSTANT DST$K_PCLINE_COMMANDS_SIZE_MAX EQUALS #dst$pcline_commands_size_max; { { LINE NUMBER PC-CORRELATION COMMANDS { { { Each PC-Correlation command consists of a command byte possibly fol- { lowed by a parameter byte, word, or longword. The presence, size, and { meaning of the parameter field is determined by the command byte. This { illustration summarizes the structure of one command: { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { var | | { | Zero or One Parameter Field | { | | { | (Byte, Word, or Longword) | { | | { | | { +---------------------------------------------------------------+ { { { The command byte contains a command code. If this command code is { negative, this is a Delta-PC command. A Delta-PC command specifies { by how many bytes to increment the PC to get to the start of the { next line (see detailed description below). This byte count is en- { coded directly in the command byte: If the command code is negative, { its negative is the PC increment. The Delta-PC command has no param- { eter field. If the command code is positive, it specifies some other { command as described below. In this case, there may be a parameter { field, depending on the command code. { { { Define the command codes allowed in Line Number PC-Correlation commands. { If the command code is zero or negative, the command is a one-byte Delta-PC { command. Here we define the command-code range for the Delta-PC command. { CONSTANT DST$K_DELTA_PC_LOW EQUALS -128; { The lower bound on Delta-PC commands CONSTANT DST$K_DELTA_PC_HIGH EQUALS 0; { The upper bound on Delta-PC commands { { Define the PC-correlation command codes other than the Delta-PC command. { These command codes are always positive. { #dst$k_pc_corr_cmd_min = DST$K_DELTA_PC_HIGH + 1; CONSTANT ( DST$K_DELTA_PC_W, { 1, Delta-PC Word command DST$K_INCR_LINUM, { 2, Increment Line Number Byte command DST$K_INCR_LINUM_W, { 3, Increment Line Number Word command DST$K_SET_LINUM_INCR, { 4, Set Line Number Increment Byte command DST$K_SET_LINUM_INCR_W, { 5, Set Line Number Increment Word command DST$K_RESET_LINUM_INCR, { 6, Reset Line Number Increment command DST$K_BEG_STMT_MODE, { 7, Begin Statement Mode command DST$K_END_STMT_MODE, { 8, End Statement Mode command DST$K_SET_LINUM, { 9, Set Line Number Word command DST$K_SET_PC, { 10, Set Relative PC Byte command DST$K_SET_PC_W, { 11, Set Relative PC Word command DST$K_SET_PC_L, { 12, Set Relative PC Longword command DST$K_SET_STMTNUM, { 13, Set Statement Number Byte command DST$K_TERM, { 14, Terminate Line Byte command DST$K_TERM_W, { 15, Terminate Line Word command DST$K_SET_ABS_PC, { 16, Set Absolute PC Longword command DST$K_DELTA_PC_L, { 17, Delta-PC Longword command DST$K_INCR_LINUM_L, { 18, Increment Line Number Longword command DST$K_SET_LINUM_B, { 19, Set Line Number Byte command DST$K_SET_LINUM_L, { 20, Set Line Number Longword command DST$K_TERM_L { 21, Terminate Line Longword command ) equals #dst$k_pc_corr_cmd_min increment 1 counter #pc_corr_cmd_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_PCCOR_LOW EQUALS DST$K_DELTA_PC_LOW; { Smallest value allowed in the first { byte of a PC-correlation command CONSTANT DST$K_PCCOR_HIGH EQUALS #pc_corr_cmd_counter; { Largest value allowed in the first { byte of a PC-correlation command { { The parameter field, if present, contains an unsigned byte, unsigned { word, or longword value. The possible PC-Correlation command formats { thus look as follows: { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { byte | NEXT_UNS_BYTE (Unsigned Byte Value) | { +---------------------------------------------------------------+ { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { word | NEXT_UNS_WORD (Unsigned Word Value) | { +---------------------------------------------------------------+ { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { long | NEXT_UNS_LONG (Longword Value) | { +---------------------------------------------------------------+ { { { { PC-CORRELATION COMMAND SEMANTICS { { { The individual commands are described separately below. To clarify what { these commands actually do, each is followed by a formal semantic de- { scription using BLISS-like pseudo-code. This description show what the { command does to a number of state variables used by DEBUG when inter- { preting these commands. The state variables are the following: { { CURRENT_LINE -- The current line number. { CURRENT_STMT -- The current statement number. { CURRENT_INCR -- The current line number increment. { CURRENT_STMT_MODE -- The statement mode flag; set to TRUE when { statement mode is set, set to FALSE otherwise; { START_PC -- The start address of the lowest-address routine { in the current module; { CURRENT_PC -- The current PC value (code address). { CURRENT_MARK -- The line-open/line-closed flag; set to LINE_OPEN { when line numbers are being defined and set to { LINE_CLOSED when a routine has been terminated { and new lines are not being defined. { { The initial values of these state variables when the PC-Correlation { commands for a given module are interpreted are as follows: { { CURRENT_LINE = 0; { CURRENT_STMT = 1; { CURRENT_INCR = 1; { CURRENT_STMT_MODE = FALSE; { START_PC = Start address of the lowest-address { routine in the current module; { CURRENT_PC = START_PC; { CURRENT_MARK = LINE_CLOSED; { { The sections below describe the format and semantics of each of the { individual PC-Correlation commands. { { { { THE DELTA-PC COMMAND { { This command defines a correlation between a line number and a PC value. { The current line number is incremented by the current increment value { (normally 1) and the current PC value is incremented by the negative of { the command byte. The resulting line number then has the resulting PC { value. In other words, both the line number and the PC value are incre- { mented before the correlation is established. The PC increment value { (the negative of the command code) thus specifies how many bytes to go { forward to get to the start of the line being defined. These are the { formal semantics of the command: { { { IF CURRENT_STMT_MODE { THEN { CURRENT_STMT = CURRENT_STMT + 1 { ELSE { CURRENT_LINE = CURRENT_LINE + CURRENT_INCR; { { CURRENT_PC = CURRENT_PC - PC_COMMAND[COMMAND_BYTE]; { CURRENT_MARK = LINE_OPEN; { { { The value of CURRENT_PC now contains the start address of the listing { line specified by the values of CURRENT_LINE and CURRENT_STMT. Note { that line-open mode is now set. { { { { THE DST$K_DELTA_PC_W COMMAND { { This command is like the normal Delta-PC command except that the PC { increment value is given in an unsigned word following the command { code. These are the semantics: { { { IF CURRENT_STMT_MODE { THEN { CURRENT_STMT = CURRENT_STMT + 1 { ELSE { CURRENT_LINE = CURRENT_LINE + CURRENT_INCR; { { CURRENT_MARK = LINE_OPEN; { CURRENT_PC = CURRENT_PC + PC_COMMAND[NEXT_UNS_WORD]; { { { The value of CURRENT_PC now contains the start address of the listing { line specified by the values of CURRENT_LINE and CURRENT_STMT. Note { that line-open mode is now set. { { { { THE DST$K_DELTA_PC_L COMMAND { { This command is like the normal Delta-PC command except that the PC { increment value is given in an unsigned longword following the command { code. These are the semantics: { { { IF CURRENT_STMT_MODE { THEN { CURRENT_STMT = CURRENT_STMT + 1 { ELSE { CURRENT_LINE = CURRENT_LINE + CURRENT_INCR; { { CURRENT_MARK = LINE_OPEN; { CURRENT_PC = CURRENT_PC + PC_COMMAND[NEXT_UNS_LONG]; { { { The value of CURRENT_PC now contains the start address of the listing { line specified by the values of CURRENT_LINE and CURRENT_STMT. Note { that line-open mode is now set. { { { { THE DST$K_INCR_LINUM COMMAND { { This command increments the current line number by the value given in { the unsigned byte following the command code. If statement mode is set, { the current statement is reset to 1 as well. These are the formal { semantics of the command: { { { CURRENT_LINE = CURRENT_LINE + PC_COMMAND[NEXT_UNS_BYTE]; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_INCR_LINUM_W COMMAND { { This command increments the current line number by the value given in { the unsigned word following the command code. If statement mode is set, { the current statement is reset to 1 as well. These are the formal { semantics of the command: { { { CURRENT_LINE = CURRENT_LINE + PC_COMMAND[NEXT_UNS_WORD]; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_INCR_LINUM_L COMMAND { { This command increments the current line number by the value given in { the unsigned longword following the command code. If statement mode is set, { the current statement is reset to 1 as well. These are the formal { semantics of the command: { { { CURRENT_LINE = CURRENT_LINE + PC_COMMAND[NEXT_UNS_LONG]; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_SET_LINUM_INCR COMMAND { { This command set the current line number increment value to the value { specified in the unsigned byte following the command code. If state- { ment mode is set, the current statement number is set to 1. These are { the formal semantics of the command: { { { CURRENT_INCR = PC_COMMAND[NEXT_UNS_BYTE]; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_SET_LINUM_INCR_W COMMAND { { This command set the current line number increment value to the value { specified in the unsigned word following the command code. If state- { ment mode is set, the current statement number is set to 1. These are { the formal semantics of the command: { { { CURRENT_INCR = PC_COMMAND[NEXT_UNS_WORD]; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_RESET_LINUM_INCR COMMAND { { This command resets the current line number increment value to 1. If { statement mode is set, the current statement number is set to 1 as well. { These are the semantics: { { { CURRENT_INCR = 1; { IF CURRENT_STMT_MODE THEN CURRENT_STMT = 1; { { { { THE DST$K_BEG_STMT_MODE COMMAND { { This command sets statement mode, meaning that subsequent Delta-PC com- { mands will increment the current statement number within the current { line and not the current line itself. This command is only allowed in { the line-open state. Statement mode can optionally be used by languages { that have multiple statements per line. This command also set the cur- { rent statement number to 1. These are the semantics: { { { IF CURRENT_MARK NEQ LINE_OPEN THEN SIGNAL(Invalid DST Record); { CURRENT_STMT_MODE = TRUE; { CURRENT_STMT = 1; { { { { THE DST$K_END_STMT_MODE COMMAND { { This command clears statement mode so that that subsequent Delta-PC com- { mands will again increment the current line number, not the statement { number. The command also set the current statement number to 1. These { are the semantics: { { { CURRENT_STMT_MODE = FALSE; { CURRENT_STMT = 1; { { { { THE DST$K_SET_LINUM_B COMMAND { { This command sets the current line number to the value specified in the { unsigned byte that follows the command code. These are the semantics: { { { CURRENT_LINE = PC_COMMAND[NEXT_UNS_BYTE]; { { { { THE DST$K_SET_LINUM COMMAND { { This command sets the current line number to the value specified in the { unsigned word that follows the command code. These are the semantics: { { { CURRENT_LINE = PC_COMMAND[NEXT_UNS_WORD]; { { { { THE DST$K_SET_LINUM_L COMMAND { { This command sets the current line number to the value specified in the { longword that follows the command code. These are the semantics: { { { CURRENT_LINE = PC_COMMAND[NEXT_UNS_LONG]; { { { { THE DST$K_SET_STMTNUM COMMAND { { This command sets the current statement number to the value specified { in the unsigned word that follows the command code. The command should { only be used when statement mode is set. These are the semantics: { { { CURRENT_STMT = PC_COMMAND[NEXT_UNS_WORD]; { { { { THE DST$K_SET_PC COMMAND { { This command sets the current PC value to be the value specified in the { unsigned byte following the command code added to the start address of { the lowest-address routine in the current module. This command is only { allowed in the line-closed state. These are the formal semantics: { { { IF CURRENT_MARK NEQ LINE_CLOSED THEN SIGNAL(Invalid DST Record); { CURRENT_PC = START_PC + PC_COMMAND[NEXT_UNS_BYTE]; { { { { THE DST$K_SET_PC_W COMMAND { { This command sets the current PC value to be the value specified in the { unsigned word following the command code added to the start address of { the lowest-address routine in the current module. This command is only { allowed in the line-closed state. These are the formal semantics: { { { IF CURRENT_MARK NEQ LINE_CLOSED THEN SIGNAL(Invalid DST Record); { CURRENT_PC = START_PC + PC_COMMAND[NEXT_UNS_WORD]; { { { { THE DST$K_SET_PC_L COMMAND { { This command sets the current PC value to be the value specified in the { longword following the command code added to the start address of the { lowest-address routine in the current module. This command is only { allowed in the line-closed state. These are the formal semantics: { { { IF CURRENT_MARK NEQ LINE_CLOSED THEN SIGNAL(Invalid DST Record); { CURRENT_PC = START_PC + PC_COMMAND[NEXT_UNS_LONG]; { { { { THE DST$K_SET_ABS_PC COMMAND { { This command sets the current PC value to be the absolute address speci- { fied in the longword following the command code. This command is only { allowed in the line-closed state. These are the formal semantics: { { { IF CURRENT_MARK NEQ LINE_CLOSED THEN SIGNAL(Invalid DST Record); { CURRENT_PC = PC_COMMAND[NEXT_UNS_LONG]; { { { { THE DST$K_TERM COMMAND { { This command terminates the PC-Correlation command sequence for the { current routine or other program unit and specifies the number of bytes { in the last line specified by a Delta-PC command. Since the Delta-PC { command specifies how many bytes precede the line being defined, the { Terminate command is needed to say how many bytes are in that line { (i.e., how many bytes will increment the PC to the first byte past the { current program unit). { { There should not be any other DSTs between the last Delta-PC DST and { the Term DST. Other DSTs between a Delta-PC DST and the Term DST will { prevent the Debugger from correctly interpreting the addresses in the { final range. { { The number of bytes in the last line is specified by the unsigned byte { following the command code. This command also sets the line-closed { state. These are the semantics of the command: { { { CURRENT_PC = CURRENT_PC + PC_COMMAND[NEXT_UNS_BYTE]; { CURRENT_MARK = LINE_CLOSED; { { { { THE DST$K_TERM_W COMMAND { { This command terminates the PC-Correlation command sequence for the cur- { rent routine or other program unit and specifies the number of bytes in { the last line of that program unit. It is a variant of the DST$K_TERM { command described above. { { There should not be any other DSTs between the last Delta-PC DST and { the Term DST. Other DSTs between a Delta-PC DST and the Term DST will { prevent the Debugger from correctly interpreting the addresses in the { final range. { { The number of bytes in the last line is specified by the unsigned word { following the command code. This command also sets the line-closed { state. These are the semantics of the command: { { { CURRENT_PC = CURRENT_PC + PC_COMMAND[NEXT_UNS_WORD]; { CURRENT_MARK = LINE_CLOSED; { { { { THE DST$K_TERM_L COMMAND { { This command terminates the PC-Correlation command sequence for the cur- { rent routine or other program unit and specifies the number of bytes in { the last line of that program unit. It is a variant of the DST$K_TERM { command described above. { { There should not be any other DSTs between the last Delta-PC DST and { the Term DST. Other DSTs between a Delta-PC DST and the Term DST will { prevent the Debugger from correctly interpreting the addresses in the { final range. { { The number of bytes in the last line is specified by the longword { following the command code. This command also sets the line-closed { state. These are the semantics of the command: { { { CURRENT_PC = CURRENT_PC + PC_COMMAND[NEXT_UNS_LONG]; { CURRENT_MARK = LINE_CLOSED; { { { END OF LINE NUMBER PC-CORRELATION DST RECORD DESCRIPTION. { S O U R C E F I L E C O R R E L A T I O N { { D S T R E C O R D S { { { { The Source File Correlation DST record is used to specify the correla- { tion between listing line numbers on the one hand and source files and { source file record numbers on the other. These records enable DEBUG { to display source lines during the debugging session. { { There may optionally be a separate set of source correlation DST { records for the EDIT command. Normally, this second set of source { correlation records are not present and the same set is used for { source display and for EDIT. However, in ADA there was a need { to point to a different file for editing (the .ADA instead of { the .ADC), because of the way ACS works. { { This EDIT source correlation records have the { value DST$K_EDIT_SOURCE in the type field. Otherwise, they have { an identical format as the Source File Correlation record. { Please note that if the EDIT source correlation record is used, { the COMPLETE description of source correlation must be duplicated. { You cannot generate just some of the records and assume the { remaining information will be obtained from the normal Source { Correlation records. { { The Source File Correlation DST record has the following format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_SOURCE) | { +---------------------------------------------------------------+ { var | | { | | { | A variable number of | { | | { | Source File Correlation commands | { | | { | | { +---------------------------------------------------------------+ { { { The Source File Correlation DST record for the EDIT command { has the following format: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_EDIT_SOURCE) | { +---------------------------------------------------------------+ { var | | { | | { | A variable number of | { | | { | Source File Correlation commands | { | | { | | { +---------------------------------------------------------------+ { { { After the length and DST type bytes, the record consists of a sequence { of Source File Correlation commands. These commands specify what source { files contributed source lines to this module and how the module's list- { ing line numbers are lined up with the source files and record numbers { within those source files. The available commands are described indi- { vidually below. { { If the Source File Correlation commands needed to fully describe the { current module will not fit in a single Source Line Correlation DST { record, they can be spread over any number of such DST records. These { records will be processed sequentially, in the order that they appear, { until there are no more such records for the current module. { { The purpose of the Source File Correlation commands is to allow DEBUG { to construct a table of correlations between line numbers and source { records. A "line number" in this context means the listing line num- { ber. This is the line number which is printed in the program listing { and is output to the PC-Correlation DST records by the compiler. (PC- { Correlation DST records correlate listing line numbers with Program { Counter values.) A corresponding source line is identified by two { things: a source file and a record number within that source file. { { The semantics of the Source File Correlation commands can be understood { in terms of manipulating three state variables and issuing one command. { The three state variables are: { { LINE_NUM -- The current listing line number. { SRC_FILE -- The File ID of the current source file, { i.e. a small integer uniquely defining { the source file. { SRC_REC -- The record number (in the RMS sense) in { the current source file of the current { source line. { { LINE_NUM is assumed to have an initial value of 1 while SRC_FILE and { SRC_REC are initially undefined. The one command is: { { DEFINE(LINE_NUM, SRC_FILE, SRC_REC) { { This command declares that line number LINE_NUM is associated with the { source line at record number SRC_REC in the file specified by SRC_FILE. { { Given this, the compiler must output a sequence of Source File Correla- { tion commands which cause LINE_NUM, SRC_FILE, and SRC_REC to be set up { appropriately and which cause the proper DEFINE operations to be issued { to allow DEBUG to generate the correct line number to source record { correlation table. (DEBUG may not actually generate the full table, { but it must be able to generate any part of such a table it needs.) { The semantics of each Source File Correlation command is described { below in terms of these state variables and commands. { { Line numbers must be DEFINEd in sequential order, from lowest line { number to highest line number, in the Source File Correlation commands { for one module. The source records these line numbers correlate with { may be in any order, of course. { { It should be clear from what follows that the source for one module may { come from many source files. This can be caused by plus-lists on the { compiler command (e.g., $FORTRAN/DEBUG A+B+C) and by INCLUDE statements { in the source. Also, source lines may come from modules within source { libraries as well as from independent source files. { { Form feeds in source files, or more precisely source file records which { contain nothing but a single form feed (CNTL-L) character, are counted { as individual sources lines in some languages but are ignored (not as- { signed line numbers) in other languages. DEBUG will handle either con- { vention, but DEBUG's default behavior is that form feed records are { ignored in sources files. They are not displayed and they do not count { toward the source file record number of subsequent source records. To { make DEBUG count such records, the DST$K_SRC_FORMFEED command must be { used. { { { { Define the location of the first command in the DST record. { AGGREGATE DST$SOURCE_CORR STRUCTURE TYPEDEF; dst$a_source_corr_header DST$HEADER; #dst$source_corr_base = :; END; { DST$SOURCE_CORR definition CONSTANT DST$K_SOURCE_CORR_HEADER_SIZE EQUALS #dst$source_corr_base; { { Define the offset for the location of the first command in the record. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_src_first_cmd = DST$K_SOURCE_CORR_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the command codes for all the Source File Correlation commands. { #dst$source_corr_cmd_min = 1; CONSTANT ( DST$K_SRC_DECLFILE, { 1, Declare a source file for this module DST$K_SRC_SETFILE, { 2, Set the current source file (word) DST$K_SRC_SETREC_L, { 3, Set source record number (longword) DST$K_SRC_SETREC_W, { 4, Set source record number (word) DST$K_SRC_SETLNUM_L, { 5, Set listing line number (longword) DST$K_SRC_SETLNUM_W, { 6, Set listing line number (word) DST$K_SRC_INCRLNUM_B, { 7, Increment listing line number (byte) DST$K_SRC_UNUSED1, { 8, Unused--available for future use DST$K_SRC_UNUSED2, { 9, Unused--available for future use DST$K_SRC_DEFLINES_W, { 10, Define N separate lines (word) DST$K_SRC_DEFLINES_B, { 11, Define N separate lines (byte) DST$K_SRC_UNUSED3, { 12, Unused--available for future use DST$K_SRC_UNUSED4, { 13, Unused--available for future use DST$K_SRC_UNUSED5, { 14, Unused--available for future use DST$K_SRC_UNUSED6, { 15, Unused--available for future use DST$K_SRC_FORMFEED { 16, Count Form-Feeds as source records ) equals #dst$source_corr_cmd_min increment 1 counter #source_corr_cmd_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_SRC_MIN_CMD EQUALS #dst$source_corr_cmd_min; CONSTANT DST$K_SRC_MAX_CMD EQUALS #source_corr_cmd_counter; { { Define the fields of the Source Line Correlation commands. Also define the { corresponding declaration macros. { AGGREGATE DST$SRC_COMMAND STRUCTURE TYPEDEF; { { Field common to all Source File Correlation commands. { dst$b_src_command BYTE UNSIGNED; { Command code dst$a_src_cmd_fields UNION; dst$a_src_decl_src STRUCTURE; { { The fields of the Declare Source File command. { dst$b_src_df_length BYTE UNSIGNED; { Length of this command dst$b_src_df_flags BYTE UNSIGNED; { Flag bits dst$w_src_df_fileid WORD UNSIGNED; { Source file's File ID dst$q_src_df_rms_cdt QUADWORD UNSIGNED; { Creation date and time or mod- { ule insertion date and time { { The following three fields are used to check whether we { have the right source file. The compiler can put -1 in these { to signify "don't care" (i.e., don't do the check). { dst$l_src_df_rms_ebk LONGWORD UNSIGNED; { End-of-File block number dst$w_src_df_rms_ffb WORD UNSIGNED; { First Free Byte in EOF block dst$b_src_df_rms_rfo BYTE UNSIGNED; { Record and File Organization { { The file name field - here is the start of the ASCIC name. { dst$b_src_df_filename BYTE UNSIGNED; { Source file name counted ASCII { (count byte) #dst$b_src_df_filename_base = :; END dst$a_src_decl_src; { { Fields used to access information in all other commands. { dst$l_src_unslong LONGWORD UNSIGNED; { Unsigned longword parameter dst$w_src_unsword WORD UNSIGNED; { Unsigned word parameter dst$b_src_unsbyte BYTE UNSIGNED; { Unsigned byte parameter END dst$a_src_cmd_fields; #dst$src_command_size = :; END; { DST$SRC_COMMAND definition CONSTANT DST$K_SRC_COMMAND_SIZE EQUALS #dst$src_command_size; { { Define the offset of the filename base in the Declare Source File { record { CONSTANT DST$K_SRC_DF_FILENAME_BASE EQUALS #dst$b_src_df_filename_base; IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_src_df_filename = DST$K_SRC_DF_FILENAME_BASE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Declare trailer field in the Declare Source File command. { AGGREGATE DST$SRC_CMDTRLR STRUCTURE TYPEDEF; dst$b_src_df_libmodname BYTE UNSIGNED; { Module name counted ASCII { (count byte) #dst$src_cmdtrlr_size = :; END; { DST$SRC_CMDTRLR definition CONSTANT DST$K_SRC_CMDTRLR_SIZE EQUALS #dst$src_cmdtrlr_size; IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_src_df_libmodname = DST$K_SRC_CMDTRLR_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { DECLARE SOURCE FILE (DST$K_SRC_DECLFILE) { { { This command declares a source file which contributes source lines to { the current module. It declares the name of the file, its creation { date and time, and various other attributes. The command also assigns { a one-word "file ID" to this source file. This is the format of the { Declare Source File command: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_DECLFILE) | { +---------------------------------------------------------------+ { byte | DST$B_SRC_DF_LENGTH | { +---------------------------------------------------------------+ { byte | DST$B_SRC_DF_FLAGS | { +---------------------------------------------------------------+ { word | DST$W_SRC_DF_FILEID | { +---------------------------------------------------------------+ { quad | DST$Q_SRC_DF_RMS_CDT | { +---------------------------------------------------------------+ { long | DST$L_SRC_DF_RMS_EBK | { +---------------------------------------------------------------+ { word | DST$W_SRC_DF_RMS_FFB | { +---------------------------------------------------------------+ { byte | DST$B_SRC_DF_RMS_RFO | { +---------------------------------------------------------------+ { var | DST$B_SRC_DF_FILENAME | { +---------------------------------------------------------------+ { var | DST$B_SRC_DF_LIBMODNAME | { +---------------------------------------------------------------+ { { { The fields in this command are the following: { { DST$B_SRC_DF_LENGTH - The length of this command, i.e. the number of { bytes remaining in the command after this field. { { DST$B_SRC_DF_FLAGS - Bit flags. { { These flags are reserved for future use and must be zero. { { DST$W_SRC_DF_FILEID - The one-word "File ID" of this source file. This { File ID, which can later be used in the Set File command, is { simply a unique number which the compiler assigns to each source { file which contributes source lines to the current module. Each { source file thus has a number (the File ID) and is identified by { that number in the Set File (DST$K_SRC_SETFILE) command. { { DST$Q_SRC_DF_RMS_CDT - The creation date and time of this source file. { This quadword quantity should be retrieved with a $XABDAT { extended attribute block from RMS via the $OPEN or $DISPLAY { system service. The creation date and time should be taken { from the XAB$Q_CDT field of the XAB. { { If the source file is a module in a source library, this field { should contain the module's Insertion Date and Time in the lib- { rary. This value should be retrieved with the LBR$SET_MODULE { Librarian call. The library file's creation date is not used. { { DST$L_SRC_DF_RMS_EBK - The End-of-File block number for this source { file. This longword quantity should be retrieved with a { $XABFHC extended attibute block from RMS via the $OPEN or { $DISPLAY system service. The End-of-File block number should { be taken from the XAB$L_EBK field of the XAB. { { This field should be zero for modules in source libraries. { { DST$W_SRC_DF_RMS_FFB - The first free byte of the End-of-File block { for this source file. This word quantity should be retrieved { with a $XABFHC extended attribute block from RMS via the $OPEN { or $DISPLAY system service. The first free byte value should { be taken from the XAB$W_FFB field of the XAB. { { This field should be zero for modules in source libraries. { { DST$B_SRC_DF_RMS_RFO - The file organization and record format of this { source file. This byte value should be retrieved with a { $XABFHC extended attribute block from RMS via the $OPEN or { $DISPLAY system service. The file organization and record { format should be taken from the XAB$B_RFO field of the XAB. { { This field should be zero for modules in source libraries. { { DST$B_SRC_DF_FILENAME - The full filename of the source file. This is { the fully specified filename, complete with device name and { version number, in which all wild cards and logical names have { been resolved. This string should be retrieved with a $NAM { block from RMS via the $OPEN or $SEARCH system service. The { desired string is the "Resultant String" specified by the { NAM$L_RSA, NAM$B_RSS, and NAM$B_RSL fields of the $NAM block. { Here the file name is represented as a Counted ASCII string (a { one-byte character count followed by the name string). { { DST$B_SRC_DF_LIBMODNAME - The source library module name (if applicable) { or the null string. If the source file is actually a module in { a source library, the DST$B_SRC_DF_FILENAME field gives the { filename of the source library and the DST$B_SRC_DF_LIBMODNAME { field gives the name of the source module within that library. { If the source file does not come from a source library, this { field (DST$B_SRC_DF_LIBMODNAME) contains the null (zero-length) { string. This field is represented as a Counted ASCII string. { SET SOURCE FILE (DST$K_SRC_SETFILE) { { { This command sets the current source file to the file denoted by the { one-word file ID given in the command. The set file is then the file { from which further source lines are taken when the corresponding list- { ing lines are defined. This is the format of the command: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_SETFILE) | { +---------------------------------------------------------------+ { word | DST$W_SRC_UNSWORD: The File ID of the desired source file | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { SRC_FILE := file ID from command { SRC_REC := set to current source record for this { source file { { { { SET SOURCE RECORD NUMBER LONG (DST$K_SRC_SETREC_L) { { { This command sets the current source file record number to the longword { value specified in the command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_SETREC_L) | { +---------------------------------------------------------------+ { long | DST$L_SRC_UNSLONG: The desired new source record number | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { SRC_REC := longword value from command { SET SOURCE RECORD NUMBER WORD (DST$K_SRC_SETREC_W) { { { This command set the current source file record number to the word { value specified in the command. It is thus a more compact form of { the DST$K_SRC_SETREC_L command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_SETREC_W) | { +---------------------------------------------------------------+ { word | DST$W_SRC_UNSWORD: The desired new source record number | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { SRC_REC := word value from command { { { { SET LINE NUMBER LONG (DST$K_SRC_SETLNUM_L) { { { This command set the current listing line number to a longword value { specified in the command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_SETLNUM_L) | { +---------------------------------------------------------------+ { long | DST$L_SRC_UNSLONG: The desired listing line number | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { LINE_NUM := longword value in commmand { SET LINE NUMBER WORD (DST$K_SRC_SETLNUM_W) { { { This command sets the current listing line number to a one-word value { specified in the command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_SETLNUM_W) | { +---------------------------------------------------------------+ { word | DST$W_SRC_UNSWORD: The desired listing line number | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { LINE_NUM := word value in command { { { { INCREMENT LINE NUMBER BYTE (DST$K_SRC_INCRLNUM_B) { { { This command increments the current listing line number by a one-byte { value specified in the command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_INCRLNUM_B) | { +---------------------------------------------------------------+ { byte | DST$B_SRC_UNSBYTE: The desired listing line number increment | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { LINE_NUM := LINE_NUM + byte value in command { COUNT FORM-FEEDS AS SOURCE RECORDS (DST$K_SRC_FORMFEED) { { { This command specifies that DEBUG should count source records which { consists of nothing but a Form-Feed character (CNTL-L) as being { distinct, numbered source records. In some languages, such records { are not considered to be source lines; instead they are regarded as { control information. The compiler then does not assign line numbers { to them and DEBUG ignores them completely--they are not displayed { as part of the source and they do not contribute to the source record { numbering of source files. However, if the DST$K_SRC_FORMFEED command { is specified in the Source File Correlation DST Record for a module, { then such records count as normal records; they can be displayed and { they are assigned source file record numbers. { { If used, this command must appear before any commands that actually { define source lines. Making it the first command in the first { Source File Correlation Record for the module is a good choice. { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_FORMFEED) | { +---------------------------------------------------------------+ { { { The semantics of this command is to set a mode flag which says to { count Form-Feed records as normal records. The default behavior { is to ignore Form-Feed records. { DEFINE N LINES WORD (DST$K_SRC_DEFLINES_W) { { { This command defines the source file and source record numbers for { a specified number of listing line numbers. The specified number is { given by a one-word count in the command. The command format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_DEFLINES_W) | { +---------------------------------------------------------------+ { word | DST$W_SRC_UNSWORD: The number of lines to define | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { DO the number of times specified in the command: { BEGIN { DEFINE(LINE_NUM, SRC_FILE, SRC_REC); { LINE_NUM := LINE_NUM + 1; { SRC_REC := SRC_REC + 1; { END; { { { { DEFINE N LINES BYTE (DST$K_SRC_DEFLINES_B) { { { This command defines the source file and source record number for { a specified number of listing line numbers. The specified number is { given by a one-byte count in the command. This is thus a more compact { form of the DST$K_SRC_DEFLINES_W command. Its format is: { { { +---------------------------------------------------------------+ { byte | DBG$B_SRC_COMMAND (= DST$K_SRC_DEFLINES_B) | { +---------------------------------------------------------------+ { byte | DST$B_SRC_UNSBYTE: The number of lines to define | { +---------------------------------------------------------------+ { { { The semantics of this command is: { { { DO the number of times specified in the command: { BEGIN { DEFINE(LINE_NUM, SRC_FILE, SRC_REC); { LINE_NUM := LINE_NUM + 1; { SRC_REC := SRC_REC + 1; { END; { { { { END OF SOURCE FILE CORRELATION DST RECORD DESCRIPTION. { G E M L O C A T O R P C - C O R R E L A T I O N { { D S T R E C O R D S { { { { The GEM Locator PC-Correlation DST record specifies the correlation { between locations in the source file, as determined by the compiler, { and PC addresses. It is thus the means whereby the compiler informs { the debugger about the source constructs which give rise to individual { instructions. { { This is the format of the GEM Locator PC-Correlation DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PCLOC) | { +---------------------------------------------------------------+ { var | | { | One or More GEM Locator PC-Correlation Commands | { | | { | | { +---------------------------------------------------------------+ { { { { After the two-byte header, each GEM Locator PC-Correlation DST record { contains a sequence of GEM Locator PC-Correlation commands. Each such { command sets or manipulates one or more state variables used by DEBUG { in the interpretation of these commands. The main state variable is { the current PC address, but there are several others as well. The { exact semantics of the various commands are described in the sections { that follow. { { GEM Locator PC-Correlation DST records are associated with the module { within which they appear. The must thus appear between the Module { Begin and the Module End DST records for the current module. There are { no further restrictions on where they may appear, however. In particu- { lar, they need not be nested within the routines or lexical blocks that { they describe. It is thus legal to generate all GEM Locator PC-Corre- { lation DST records for a module after the last Routine End DST record, { for instance. These records can also be interspersed between Routine { and Block Begin and End records in any way convenient for the compiler { implementer. However it is done, DEBUG treats them as belonging to the { module as a whole. { { The GEM Locator PC-Correlation information may be spread over as many { DST records as necessary. No GEM Locator PC-Correlation command may be { broken across record boundaries, but otherwise the GEM Locator PC-Corre- { lation DST records within a module are considered to constitute a single { command stream. The Continuation DST record may not be used to continue { GEM Locator PC-Correlation DST records. { { { { Define the fields of the GEM Locator PC-Correlation DST record. { AGGREGATE DST$GEM_LOC_HEADER STRUCTURE TYPEDEF; dst$a_gem_loc_header DST$HEADER; #dst$gem_loc_header_size = :; END; { DST$GEM_LOC_HEADER definition CONSTANT DST$K_GEM_LOC_HEADER_SIZE EQUALS #dst$gem_loc_header_size; { { Define the start address of GEM Locator PC-correlation data { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_gem_loc_data = DST$K_GEM_LOC_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the fields of the GEM Locator-PC Correlation commands. { AGGREGATE DST$PCLOC_COMMANDS STRUCTURE TYPEDEF; { { Field common to all GEM Locator-PC Correlation commands. { dst$b_pcloc_command BYTE; { Command code #dst$pcloc_cmd_size_noargs = :; { size with no args dst$pcloc_subcommand_args UNION; { DST$K_PCLOC_PNTS_INCR and DST$K_PCLOC_PNTS subcommands: { word line number, byte column number { dst$a_pcloc_pnts STRUCTURE; dst$w_pcloc_pnts_line WORD UNSIGNED; dst$b_pcloc_pnts_column BYTE UNSIGNED; END dst$a_pcloc_pnts; #dst$pcloc_cmd_size_pnts = :; { DST$K_PCLOC_PNTL_INCR and DST$K_PCLOC_PNTL subcommands: { longword line number, word column number { dst$a_pcloc_pntl STRUCTURE; dst$l_pcloc_pntl_line LONGWORD UNSIGNED; dst$w_pcloc_pntl_column WORD UNSIGNED; END dst$a_pcloc_pntl; #dst$pcloc_cmd_size_pntl = :; { DST$K_PCLOC_RNGS_INCR and DST$K_PCLOC_RNGS subcommands: { lowerbound: word line, byte column { upperbound: word line, byte column { dst$a_pcloc_rngs STRUCTURE; dst$w_pcloc_rngs_low_line WORD UNSIGNED; dst$b_pcloc_rngs_low_column BYTE UNSIGNED; dst$w_pcloc_rngs_high_line WORD UNSIGNED; dst$b_pcloc_rngs_high_column BYTE UNSIGNED; END dst$a_pcloc_rngs; #dst$pcloc_cmd_size_rngs = :; { DST$K_PCLOC_RNGL_INCR and DST$K_PCLOC_RNGL subcommands: { lowerbound: longword line, word column { upperbound: longword line, word column { dst$a_pcloc_rngl STRUCTURE; dst$l_pcloc_rngl_low_line LONGWORD UNSIGNED; dst$w_pcloc_rngl_low_column WORD UNSIGNED; dst$l_pcloc_rngl_high_line LONGWORD UNSIGNED; dst$w_pcloc_rngl_high_column WORD UNSIGNED; END dst$a_pcloc_rngl; #dst$pcloc_cmd_size_rngl = :; { DST$K_PCLOC_LINS_INCR and DST$K_PCLOC_LINS subcommands: { line: word unsigned { lower column: byte unsigned { upper column: byte unsigned { dst$a_pcloc_lins STRUCTURE; dst$w_pcloc_lins_line WORD UNSIGNED; dst$b_pcloc_lins_low_column BYTE UNSIGNED; dst$b_pcloc_lins_high_column BYTE UNSIGNED; END dst$a_pcloc_lins; #dst$pcloc_cmd_size_lins = :; { DST$K_PCLOC_SETPC64 subcommand: { 64-bit pc value. { dst$a_pcloc_setpc64 STRUCTURE; dst$q_pcloc_setpc64_value QUADWORD UNSIGNED; END dst$a_pcloc_setpc64; #dst$pcloc_cmd_size_setpc64 = :; { DST$K_PCLOC_SETPC32 subcommand: { 32-bit pc value. { dst$a_pcloc_setpc32 STRUCTURE; dst$l_pcloc_setpc32_value LONGWORD UNSIGNED; END dst$a_pcloc_setpc32; #dst$pcloc_cmd_size_setpc32 = :; { DST$K_PCLOC_EVENT_READ subcommand: { Two pointers into DST (offset from beginning of DST) { to the definitions of the symbols being read. At most { two symbols. If only one, second longword MBZ. { dst$a_pcloc_event_read STRUCTURE; dst$l_pcloc_event_read_sym1 LONGWORD UNSIGNED; dst$l_pcloc_event_read_sym2 LONGWORD UNSIGNED; END dst$a_pcloc_event_read; #dst$pcloc_cmd_size_event_read = :; { DST$K_PCLOC_EVNT_WRITE subcommand: { Pointer to DST (offset from beginning of DST) to the { definition of the symbol being modified. { dst$a_pcloc_event_write STRUCTURE; dst$l_pcloc_event_write_sym LONGWORD UNSIGNED; END dst$a_pcloc_event_write; #dst$pcloc_cmd_size_event_write = :; END dst$pcloc_subcommand_args; END; { DST$PCLOC_COMMANDS definition { Define the size of the GEM Locator-PC Correlation DSTs. { CONSTANT DST$K_PCLOC_CMD_SIZE_END EQUALS #dst$pcloc_cmd_size_noargs; CONSTANT DST$K_PCLOC_CMD_SIZE_PNTS EQUALS #dst$pcloc_cmd_size_pnts; CONSTANT DST$K_PCLOC_CMD_SIZE_PNTL EQUALS #dst$pcloc_cmd_size_pntl; CONSTANT DST$K_PCLOC_CMD_SIZE_RNGS EQUALS #dst$pcloc_cmd_size_rngs; CONSTANT DST$K_PCLOC_CMD_SIZE_RNGL EQUALS #dst$pcloc_cmd_size_rngl; CONSTANT DST$K_PCLOC_CMD_SIZE_LINS EQUALS #dst$pcloc_cmd_size_lins; CONSTANT DST$K_PCLOC_CMD_SIZE_INCR EQUALS #dst$pcloc_cmd_size_noargs; CONSTANT DST$K_PCLOC_CMD_SIZE_SETPC64 EQUALS #dst$pcloc_cmd_size_setpc64; CONSTANT DST$K_PCLOC_CMD_SIZE_SETPC32 EQUALS #dst$pcloc_cmd_size_setpc32; CONSTANT DST$K_PCLOC_CMD_SIZE_EVENT EQUALS #dst$pcloc_cmd_size_noargs; CONSTANT DST$K_PCLOC_CMD_SIZE_EVENT_RD EQUALS #dst$pcloc_cmd_size_event_read; CONSTANT DST$K_PCLOC_CMD_SIZE_EVENT_WR EQUALS #dst$pcloc_cmd_size_event_write; { { GEM LOCATOR PC-CORRELATION COMMANDS { { { Each GEM Locator PC-Correlation command consists of a command byte { followed by zero or more fields. The presence of the extra fields { is determined by the command byte. This illustration summarizes the { structure of one command: { { { +---------------------------------------------------------------+ { byte | COMMAND_BYTE | { +---------------------------------------------------------------+ { var | | { | Zero, or more Fields | { | | { +---------------------------------------------------------------+ { { { Define the command codes allowed in GEM Locator PC-Correlation commands. { #dst$k_pcloc_cmd_min = 0; CONSTANT ( DST$K_PCLOC_END, { 0, End of table DST$K_PCLOC_PNTS_INCR, { 1, Single point locator, short form, w/incr DST$K_PCLOC_PNTL_INCR, { 2, Single point locator, long form, w/incr DST$K_PCLOC_RNGS_INCR, { 3, Range locator, short form, with increment DST$K_PCLOC_RNGL_INCR, { 4, Range locator, long form, with increment DST$K_PCLOC_PNTS, { 5, Single point locator, short form, no incr DST$K_PCLOC_PNTL, { 6, Single point locator, long form, no incr DST$K_PCLOC_RNGS, { 7, Range locator, short form, no incr DST$K_PCLOC_RNGL, { 8, Range locator, long form, no incr DST$K_PCLOC_INCR, { 9, No locator, just incr DST$K_PCLOC_SETPC64, { 10, Set PC, 64bit value DST$K_PCLOC_SETPC32, { 11, Set PC, 32bit value DST$K_PCLOC_EVENT_INST, { 12, Instruction-level semantic event DST$K_PCLOC_EVENT_READ, { 13, Data flow (read) semantic event DST$K_PCLOC_EVENT_WRITE,{ 14, Data flow (complete write) semantic event DST$K_PCLOC_EVENT_CTRL, { 15, Control flow semantic event DST$K_PCLOC_EVENT_CALL, { 16, Control flow (call or return) DST$K_PCLOC_LINS, { 17, Short Locator on same line DST$K_PCLOC_LINS_INCR, { 18, Short Locator on same line, with increment DST$K_PCLOC_EVENT_PWRIT,{ 19, Data flow (partial write) semantic event DST$K_PCLOC_EVENT_LABEL,{ 20, Instruction is the target of a label ) equals #dst$k_pcloc_cmd_min increment 1 counter #pcloc_cmd_counter; { { Define minimum and maximum values for CASE bounds { CONSTANT DST$K_PCLOC_LOW EQUALS #dst$k_pcloc_cmd_min; { Smallest value allowed in the first { byte of a GEM Locator { PC-correlation command CONSTANT DST$K_PCLOC_HIGH EQUALS #pcloc_cmd_counter; { Largest value allowed in the first { byte of a GEM Locator { PC-correlation command { GEM LOCATOR PC-CORRELATION COMMAND SEMANTICS { { { The individual commands are described separately below. To clarify what { these commands actually do, each is followed by a formal semantic de- { scription using BLISS-like pseudo-code. This description show what the { command does to a number of state variables used by DEBUG when inter- { preting these commands. The state variables are the following: { { CURRENT_PC -- The current PC value (code address). { { The initial values of these state variables when the GEM Locator { PC-Correlation commands for a given module are interpreted are as { follows: { { CURRENT_PC = 0; { { The sections below describe the format and semantics of each of the { individual GEM Locator PC-Correlation commands. { { { { THE DST$K_PCLOC_END COMMAND { { This command terminates the GEM Locator PC-Correlation table. It takes { no arguments. { { { THE DST$K_PCLOC_PNTS_INCR COMMAND { { This command adds the specified locator information to a table { correlated by the CURRENT_PC then increments the CURRENT_PC value by { 4 (the size of one instruction). The locator describes a single { point in "short form", so the fields which follow the command byte { are a word line number and a byte column number, as shown below. { { +---------------------------------------------------------------+ { word | DST$W_PCLOC_PNTS_LINE | { +---------------------------------------------------------------+ { byte | DST$B_PCLOC_PNTS_COLUMN | { +---------------------------------------------------------------+ { { The semantics of the command are as follows: { { Add_Locator_To_Table(CURRENT_PC, PC_COMMAND[Correlation_Data]); { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_PNTS COMMAND { { This command is the same as the DST$K_PCLOC_PNTS_INCR command, { except that the CURRENT_PC is NOT incremented. All other aspects { of the command are the same. { { { THE DST$K_PCLOC_PNTL_INCR COMMAND { { This command adds the specified locator information to a table { correlated by the CURRENT_PC then increments the CURRENT_PC value by { 4 (the size of one instruction). The locator describes a single { point in "long form", so the fields which follow the command byte { are a longword line number and a word column number, as shown below. { { +---------------------------------------------------------------+ { long | DST$L_PCLOC_PNTL_LINE | { +---------------------------------------------------------------+ { word | DST$W_PCLOC_PNTL_COLUMN | { +---------------------------------------------------------------+ { { The semantics of the command are as follows: { { Add_Locator_To_Table(CURRENT_PC, PC_COMMAND[Correlation_Data]); { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_PNTL COMMAND { { This command is the same as the DST$K_PCLOC_PNTL_INCR command, { except that the CURRENT_PC is NOT incremented. All other aspects { of the command are the same. { { { THE DST$K_PCLOC_RNGS_INCR COMMAND { { This command adds the specified locator information to a table { correlated by the CURRENT_PC then increments the CURRENT_PC value by { 4 (the size of one instruction). The locator describes a range { in "short form", so the fields which follow the command byte { are a word line number and a byte column number--representing the { range's lower bound--and then a word line number and a byte column { number--representing the range's upper bound--as shown below. { { +---------------------------------------------------------------+ { word | DST$W_PCLOC_RNGS_LOW_LINE | { +---------------------------------------------------------------+ { byte | DST$B_PCLOC_RNGS_LOW_COLUMN | { +---------------------------------------------------------------+ { word | DST$W_PCLOC_RNGS_HIGH_LINE | { +---------------------------------------------------------------+ { byte | DST$B_PCLOC_RNGS_HIGH_COLUMN | { +---------------------------------------------------------------+ { { Compilers must ensure that the following holds: { { ASSERT (low_line <= high_line) { IF (low_line = high_line) THEN ASSERT(low_column <= high_column) { { That is, the lower bound of the range must be less than or equal to { the upper bound of the range. { { The semantics of the command are as follows: { { Add_Locator_To_Table(CURRENT_PC, PC_COMMAND[Correlation_Data]); { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_RNGS COMMAND { { This command is the same as the DST$K_PCLOC_RNGS_INCR command, { except that the CURRENT_PC is NOT incremented. All other aspects { of the command are the same. { { { THE DST$K_PCLOC_RNGL_INCR COMMAND { { This command adds the specified locator information to a table { correlated by the CURRENT_PC then increments the CURRENT_PC value by { 4 (the size of one instruction). The locator describes a range { in "long form", so the fields which follow the command byte { are a longword line number and a word column number--representing the { range's lower bound--and then a longword line number and a word column { number--representing the range's upper bound--as shown below. { { +---------------------------------------------------------------+ { long | DST$L_PCLOC_RNGL_LOW_LINE | { +---------------------------------------------------------------+ { word | DST$W_PCLOC_RNGL_LOW_COLUMN | { +---------------------------------------------------------------+ { long | DST$L_PCLOC_RNGL_HIGH_LINE | { +---------------------------------------------------------------+ { word | DST$W_PCLOC_RNGL_HIGH_COLUMN | { +---------------------------------------------------------------+ { { Compilers must ensure that the following holds: { { ASSERT (low_line <= high_line) { IF (low_line = high_line) THEN ASSERT(low_column <= high_column) { { That is, the lower bound of the range must be less than or equal to { the upper bound of the range. { { The semantics of the command are as follows: { { Add_Locator_To_Table(CURRENT_PC, PC_COMMAND[Correlation_Data]); { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_RNGL COMMAND { { This command is the same as the DST$K_PCLOC_RNGL_INCR command, { except that the CURRENT_PC is NOT incremented. All other aspects { of the command are the same. { { { THE DST$K_PCLOC_LINS_INCR COMMAND { { This command adds the specified locator information to a table { correlated by the CURRENT_PC then increments the CURRENT_PC value by { 4 (the size of one instruction). The locator describes a range { in "short line form", so the fields which follow the command byte { are a word line number and two byte column numbers. This is used { to describe ranges which occur on a single line, where the only { difference is the starting and ending column number. { { +---------------------------------------------------------------+ { word | DST$W_PCLOC_LINS_LINE | { +---------------------------------------------------------------+ { byte | DST$B_PCLOC_LINS_LOW_COLUMN | { +---------------------------------------------------------------+ { byte | DST$B_PCLOC_LINS_HIGH_COLUMN | { +---------------------------------------------------------------+ { { Compilers must ensure that the following holds: { { ASSERT(low_column <= high_column) { { That is, the lower bound of the range must be less than or equal to { the upper bound of the range. { { The semantics of the command are as follows: { { Add_Locator_To_Table(CURRENT_PC, PC_COMMAND[Correlation_Data]); { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_LINS COMMAND { { This command is the same as the DST$K_PCLOC_LINS_INCR command, { except that the CURRENT_PC is NOT incremented. All other aspects { of the command are the same. { { { THE DST$K_PCLOC_INCR COMMAND { { This command modifies the state of the CURRENT_PC variable. { It can be used when there is no correlation or semantic information { and the PC should just be skipped. There are no arguments to this { command. { { The semantics of the command are as follows: { { CURRENT_PC = CURRENT_PC + 4; { { { THE DST$K_PCLOC_SETPC64 COMMAND { { This command sets the CURRENT_PC to the value specified by the { quadword which follows. { { +---------------------------------------------------------------+ { quad | DST$Q_PCLOC_SETPC64_VALUE | { +---------------------------------------------------------------+ { { The semantics of the command are as follows: { { CURRENT_PC = PC_COMMAND[UNSIGNED_QUADWORD]; { { **NOTE**: currently, only the lower 32 bits of the value { are used. The upper longword is ignored. This command should { therefore not be used on AXP until the debugger is 64-bit aware. { { { { THE DST$K_PCLOC_SETPC32 COMMAND { { This command sets the CURRENT_PC to the value specified by the { longword which follows. { { +---------------------------------------------------------------+ { long | DST$L_PCLOC_SETPC32_VALUE | { +---------------------------------------------------------------+ { { The semantics of the command are as follows: { { CURRENT_PC = PC_COMMAND[UNSIGNED_LONGWORD]; { { { THE DST$K_PCLOC_EVENT_INST COMMAND { { This command adds the specified semantic event information to a table { correlated by the CURRENT_PC. The command takes no arguments. { { The semantics of the command are as follows: { { Add_Event_To_Table(CURRENT_PC, Instruction_Event); { { An INSTRUCTION EVENT means that the correlation information at the { CURRENT_PC (if there is any) is only interesting if the user is { stepping by instruction. Furthermore, it means that the correlation { should be ignored if the user is stepping by source lines. { { An example of this is instructions which load address constants { into registers. The debugger will ignore this correlation when the { user is stepping by source lines. The effect of this, especially for { debugging optimized code, is that the stepping appears much smoother. { { { THE DST$K_PCLOC_EVENT_READ COMMAND { { This command adds the specified semantic event information to a table { correlated by the CURRENT_PC. The command takes two arguments: { { +---------------------------------------------------------------+ { long | DST$L_PCLOC_EVENT_READ_SYM1 | { +---------------------------------------------------------------+ { long | DST$L_PCLOC_EVENT_READ_SYM2 | { +---------------------------------------------------------------+ { { The first longword is an offset from the beginning of the DST. It { points to the DST definition of one of the symbols which is being { read by the instruction. This field must not be zero, as there is { always one symbol being modified by the EVENT_READ command. { { The second longword is either zero or an offset from the beginning { of the DST. If zero, then the READ event only fetches one user-defined { symbol. If nonzero, then it points to the DST definition of the other { symbol which is being read by the instruction. { { The semantics of the command are as follows: { { Add_Event_To_Table(CURRENT_PC, Read_Event); { { A READ EVENT means that the instruction at the CURRENT_PC fetches { the value of one or two user-defined storage locations. Note that { not all instructions which modify registers or storage locations will { have this attribute -- only those which modify user symbols. { { { THE DST$K_PCLOC_EVENT_WRITE COMMAND { { This command adds the specified semantic event information to a table { correlated by the CURRENT_PC. The command takes one argument: { { +---------------------------------------------------------------+ { long | DST$L_PCLOC_EVENT_WRITE_SYM | { +---------------------------------------------------------------+ { { The longword is an offset from the beginning of the DST. It points { to the DST definition of the symbol which is being written by the { instruction. This field must not be zero, because by definition the { WRITE event modifies a user-defined symbol. { { The semantics of the command are as follows: { { Add_Event_To_Table(CURRENT_PC, Write_Event); { { A WRITE EVENT means that the instruction at the CURRENT_PC modifies { a user-defined storage location. Thus, not all instructions which { modify registers or storage locations will have this attribute. { { { THE DST$K_PCLOC_EVENT_CTRL COMMAND { { This command adds the specified semantic event information to a table { correlated by the CURRENT_PC. The command takes no arguments. { { The semantics of the command are as follows: { { Add_Event_To_Table(CURRENT_PC, Control_Event); { { A CONTROL EVENT means that the instruction at the CURRENT_PC either { might or will cause program control to be altered out-of-line. { Thus, either conditional or unconditional branches are marked as { CONTROL events. Note that instructions which implement CALL (JSB) { and RETURN semantics are excluded; see the CALL event. { { { THE DST$K_PCLOC_EVENT_CALL COMMAND { { This command adds the specified semantic event information to a table { correlated by the CURRENT_PC. The command takes no arguments. { { The semantics of the command are as follows: { { Add_Event_To_Table(CURRENT_PC, Call_Event); { { A CALL EVENT means that the instruction at the CURRENT_PC is either { a routine call instruction (JSB) or an instruction which returns { control from a routine to its caller (RET). { { { END OF GEM LOCATOR PC-CORRELATION DST RECORD DESCRIPTION. { C O N T I N U A T I O N D S T R E C O R D S { { { { When the text of a Debug Symbol Table record is longer than 255 bytes, { it is no longer possible to hold that text in a single DST record since { the DST$B_LENGTH field cannot hold a value larger than 255. In this { case it is necessary to generate the original DST record followed by { as many Continuation DST records as necessary to hold the full text. { The original DST record then holds at least 100 and at most 255 bytes of { text. Each Continuation DST record consists of the standard two-byte { header followed by the continued text of the original DST record. { { This is the format of the Continuation DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_CONTIN) | { +---------------------------------------------------------------+ { var | | { | | { | The Continued Text of the Previous DST Record | { | | { | | { | | { +---------------------------------------------------------------+ { { { { DEBUG reconstitutes a continued DST record by concatenating the text { of the first DST record with the text portions of its Continuation DST { records. In effect, the first two bytes of each Continuation DST record { are stripped out. Any further interpretation of the DST text is then { done on the concatenated copy. { { Certain kinds of DST records are not allowed to be continued with Con- { tinuation DST records. These records are Module Begin, Routine Begin, { Block Begin, Label, Label-or-Literal, Entry Point, PSECT, Line Number { PC-Correlation, and Source File Correlation DST records. In addition, { DST records with fixed sizes, such as Module End and Routine End DST { records, are not allowed to be continued. Line Number PC-Correlation { and Source File Correlation DST records cannot be continued with Con- { tinuation DST records, but one can have multiple such records in one { module; they can thus be continued, but through a different mechanism. { The records that really need to be continued, such as Standard Data { DST records and their variants (Descriptor Format and Trailing Value { Specification Format records), Separate Type Specification DST records, { and Type Specification DST records, can all be continued using the { Continuation DST record mechanism. { { { { Define the fields of the Continuation DST record. { AGGREGATE DST$CONTINUATION STRUCTURE TYPEDEF; dst$a_continuation_header DST$HEADER; #dst$continuation_header_size = :; END; { DST$CONTINUATION definition CONSTANT DST$K_CONTINUATION_HEADER_SIZE EQUALS #dst$continuation_header_size; { { Define the address offset for the continuing text... { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_contin = DST$K_CONTINUATION_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { G O T O and T A R G E T D S T R E C O R D S { { { The purpose of the GOTO and TARGET DST records is to allow the { compilers some flexibility in the order in which they generate { DST records. The GOTO DST record must point to a TARGET DST record. { When the debugger is scanning DST records in order to set a { module, and it encounters a GOTO DST record, this simply causes { the DST scanning to continue from the target of the GOTO. { The TARGET DST record is ignored by the debugger; its only purpose { is to check the validity of the GOTO. { { The "pointer" in the GOTO DST record is actually an offset relative { to the start of the whole DST. { { Example: Suppose routine B is nested inside of routine A. The order { of DSTs should then be: { { routine begin A { dsts for A { routine begin B { dsts for B { routine end B { routine end A { { However, suppose the compiler generates code "inside-out", so that { DSTs are first constructed for B. The compiler could then use the { GOTO DST as follows: { { goto target2 { target1: { routine begin B { dsts for B { routine end B { goto target3 { target2: { routine begin A { dsts for A { goto target1 { target3: { routine end A { { Even though it is allowed, compilers should try to avoid generating { DSTs "inside-out." The debugger is able to use DSTs generated in { such a fashion, however the information generated by the debugger { based on "inside-out" DSTs may not be as good as possible, or as { expected, intuitively by the user. { { { { This is the format of the Goto DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_GOTO) | { +---------------------------------------------------------------+ { long | DST$L_GOTO_PTR | { +---------------------------------------------------------------+ { { { This is the format of the Target DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_TARGET) | { +---------------------------------------------------------------+ { { { Define the fields of the GOTO DST record. { AGGREGATE DST$GOTO STRUCTURE TYPEDEF; dst$a_goto_header DST$HEADER; dst$l_goto_ptr LONGWORD UNSIGNED; { Target of the GOTO. This is an offset { to another DST record, relative to { the start of the whole DST. The { target DST record must have DST { type DST$K_TARGET. #dst$goto_size = :; END; { DST$GOTO definition CONSTANT DST$K_GOTO_SIZE EQUALS #dst$goto_size; { { F I X U P D S T R E C O R D S { { { Fixup DST records (new in version 4.4) are generated by the linker { in order to describe fixup information to DEBUG. This is mainly { needed for DSTs in shareable images, where addresses are relative { to the start of the shareable image. Fixup records are therefore { needed so DEBUG knows where in the DST are addresses that need { to be fixed up by adding in the base address of the shareable image. { { Fixup DST records are generated at the end of the DST, after the { final "Module End" record. There may be 0 or more bytes with zeroes { in them between the final "Module End" record and the first { DST$K_FIXUP record. There may be multiple DST$K_FIXUP records, { and the fixup information in them is just concantenated together { into a single fixup table. { { See the document [DEBUG.SPECS]SHAREABLE.MEM for more information. { { The format of the fixup record is: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_FIXUP) | { +---------------------------------------------------------------+ { var | The fixup information | { +---------------------------------------------------------------+ { { The format of the fixup information itself is: { { +-------------------+ { | Number of offsets | { +-------------------+ { | ASCIC image name | { +-------------------+ { | Offset | { +-------------------+ { | Offset | { +-------------------+ { | ... | { | | { +-------------------+ { | ... | { +-------------------+ { | Number of offsets | { +-------------------+ { | ASCIC image name | { +-------------------+ { | Offset | { +-------------------+ { | Offset | { +-------------------+ { | ... | { | | { +-------------------+ { { In the above, "ASCIC image name" is the name of the image whose base { address is to be added to the DST locations being fixed up. The offsets { are offsets from the start of the DST to the locations in the DST that need { to be fixed up. The debugger will add the base address of the specified { shareable image to the address found in that DST location, in order to { obtain the true run-time address of the object. { { The normal Fixup DST Record describes the DST locations of longword fields { containing addresses to be fixed up. { { If the field to be fixed up is a quadword, use the 64-bit version of the { fixup record: DST_RECORD[DST$W_TYPE]=DST$K_FIXUP_64. Everything about the { Fixup DST Record applies to the Fixup-64 DST Record except for the size of { the field being fixed. { { { S Y M B O L F I X U P D S T R E C O R D S { { { On Alpha, in order to support FORTRAN shared common, the Symbol Fixup { DST Record describes a set of addresses that need to be fixed up by { adding in the value of an entry in the symbol vector of a shareable { image. { { An image may contain any number of Symbol Fixup DST Records. All { Symbol Fixup DST Records follow all Fixup DST Records. The first { Symbol Fixup DST Record comes directly after the last Fixup DST Record { without any padding. { { The format of the fixup record is: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_SYMBOL_FIXUP (= 121)) | { +---------------------------------------------------------------+ { var | The fixup information | { +---------------------------------------------------------------+ { { The format of the fixup information itself is: { { +-------------------+ { | Number of offsets | { +-------------------+ { | ASCIC image name | { +-------------------+ { | Offset in sym-vec | { +-------------------+ { | Offset | { +-------------------+ { | Offset | { +-------------------+ { | ... | { | | { +-------------------+ { | ... | { +-------------------+ { | Number of offsets | { +-------------------+ { | ASCIC image name | { +-------------------+ { | Offset in sym-vec | { +-------------------+ { | Offset | { +-------------------+ { | Offset | { +-------------------+ { | ... | { | | { +-------------------+ { { In the above, "ASCIC image name" is the name of the shareable image { containing the symbol vector whose contents are to be added to DST { locations. "Offset in sym-vec" is the offset within the symbol vector of { the entry whose value is to be added to the DST locations being fixed up. { The Offsets are offsets from the start of the DST to the locations in the { DST that need to be fixed up. The debugger will add the value of the { symbol vector entry of the shareable image to the address found in that DST { location, in order to obtain the true run-time address of the object. { { The normal Symbol Fixup DST Record describes the DST locations of longword { fields containing addresses to be fixed up. { { If the field to be fixed up is a quadword, use the 64-bit version of the { symbol fixup record: DST_RECORD[DST$W_TYPE]=DST$K_SYMBOL_FIXUP. Everything { about the Symbol Fixup DST Record applies to the Symbol Fixup-64 DST Record { except for the size of the field being fixed. { { T H E O V E R L O A D E D S Y M B O L D S T R E C O R D { { { { The Overloaded Symbol DST record is used to indicate that a given { symbol name is overloaded. The record indicates which other symbols { in the DST are possible resolutions to the overloading. It is used { by the ADA compiler. { { In ADA, it is possible to have more than one routine of the same name { in the same scope. If the routine name is R, DEBUG disambiguates the { individual instances of the overloaded routine name with the invented { names R__1, R__2, R__3, and so on. DEBUG requires the ADA compiler to { generate normal DST records for these routines, using the invented { names. DEBUG also requires the ADA compiler to generate the Overloaded { Symbol DST record with the original overloaded name "R" in order to { inform DEBUG of the overloading. { { After the length and type fields, this record contains a Counted ASCII { string with the name of the overloaded symbol. Following the Counted { ASCII string, there is a word field containing a count of the number { of overloaded instances of the name in this scope. Next there is a { vector of pointers, one for each instance, pointing to the DST records { for the instances of the overloaded symbol. These DST pointers consist { of byte offsets relative to the start of the whole DST. { { This is the format of the Overloaded Symbol DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_OVERLOAD) | { +---------------------------------------------------------------+ { byte | DST$B_OL_NAME | { +---------------------------------------------------------------+ { var | | { | The Overloaded Symbol Name in ASCII | { | | { | (The name's length is given by DST$B_OL_NAME) | { | | { | | { +---------------------------------------------------------------+ { word | DST$W_OL_COUNT | { +---------------------------------------------------------------+ { var | DST$A_OL_VECTOR | { | | { | A Vector of Longword Pointers to the DST Records | { | | { | of the Symbols with Invented Names that Constitute | { | | { | the Instances of this Overloading | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Overloaded Symbol DST record. { AGGREGATE DST$OVERLOAD_HEADER STRUCTURE TYPEDEF; dst$a_ol_header DST$HEADER; dst$b_ol_name BYTE UNSIGNED; { Count byte of the overloaded symbol { name Counted ASCII string #dst$overload_header_size = :; END; { DST$OVERLOAD_HEADER definition CONSTANT DST$K_OVERLOAD_HEADER_SIZE EQUALS #dst$overload_header_size; { { Define the offset for the trailer field... The trailer fields start { at this location + .DST$B_OL_NAME { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ol_trailer = DST$K_OVERLOAD_HEADER_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the fields of the Overloaded Symbol DST record trailer portion. Also { define the corresponding declaration macro. { AGGREGATE DST$OVERLOAD_TRLR STRUCTURE TYPEDEF; dst$w_ol_count WORD UNSIGNED; { Number of instances in this scope #dst$overload_trailer_base = :; END; { DST$OVERLOAD_TRLR definition { { Provide an offset to the vector of DST pointers to instances { of the overloaded symbol. { CONSTANT DST$K_OVERLOAD_VECTOR_BASE EQUALS #dst$overload_trailer_base; IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ol_vector = DST$K_OVERLOAD_VECTOR_BASE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { This is a short BLISS example of how the trailer fields are accessed: { { { LOCAL { DSTPTR: REF DST$RECORD, { Pointer to DST record { OVERLOAD_COUNT, { The number of overloadings { OVERLOAD_TRAILER: { Pointer to DST record trailer { REF DST$OVERLOAD_TRLR, { { OVERLOAD_VECTOR: { Vector of DST-record pointers to the { REF VECTOR[,LONG]; { instances of this overloading { { { { Here we assume that DSTPTR points to the Overloaded Symbol DST record. { { { OVERLOAD_TRAILER = DSTPTR[DST$A_OL_TRALER] + .DSTPTR[DST$B_OL_NAME]; { OVERLOAD_COUNT = .OVERLOAD_TRAILER[DST$B_OL_COUNT]; { OVERLOAD_VECTOR = OVERLOAD_TRAILER[DST$A_OL_VECTOR]; { { S U B U N I T D S T R E C O R D S { { { { The Subunit DST record is used by ADA to describe ADA subunits. { The Subunit DST record appears immediately after the Routine { Begin record for the subunit. The Subunit DST record indicates { that the routine is a subunit, and gives the pathname indicating { the scope where the subunit logically belongs. { { An example of the use of the Subunit DST record is as folows: { { ADA program fragment DST { -------------------- --- { { Module Begin S0 { PROCEDURE S0 IS Routine Begin S0 { X: INTEGER; Data X of type L { PROCEDURE S1 IS SEPARATE; Data S1 of type ZEM { BEGIN ... { ... ... { END; Routine End S0 { Module End S0 { { Module Begin S1 { SEPARATE(S1) Routine Begin S1 { PROCEDURE S1 IS Subunit of "S0\S0\S0" { Y: INTEGER; Data Y of type L { BEGIN ... { ... ... { END; Routine End S1 { Module End S1 { { Things to note about the example are the following: { { 1) The pathname in the Subunit DST contains the module (S0 { in the example) as its first pathname element. Thus the { pathname "S0\S0" in this example means that S1 is nested { in routine S0 which is contained in module S0. { { 2) There is another S0 at the end of the list (i.e. "S0\S0\S0"). { That is the name of the module that is the parent of S1. { This name is used to find the parent of the subunit and set { it. { { 3) In order for the routine S1 to be visible from the module { S0, it is declared there as a data item of type ZEM (entry mask). { This means that if only module S0 is set, you can still set { breakpoints on routine S1. If both modules are set, there { is no problem - DEBUG will compare the addresses of the ZEM data item { S1 and the routine S1, and since they are the same, will not { give a "not unique" message. { { The subunit DST record will have an effect on the SET MODULE { command when the subunit module is set. Setting the subunit will { cause automatic setting of the parent. E.g., { { DBG> SHOW MODULE { module set { ------ --- { S0 no { S1 no { { DBG> SET MODULE S1 { %DEBUG-I-S1 is a subunit, also setting parent unit S0 { { DBG> SHOW MODULE { module set { ------ --- { S0 yes { S1 yes { { The reason for the automatic setting of the parent is, of course, { that symbols in the parent are also visible in the subunit. We { want to preserve that visibility in DEBUG. { { The following is the format of the Subunit DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_SUBUNIT) | { +---------------------------------------------------------------+ { byte | DST$B_SUBUNIT_PATHNAME_COUNT | { +---------------------------------------------------------------+ { var | parent module name, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | the first pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | the second pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | ... | { | | { +---------------------------------------------------------------+ { var | the last pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { { For example, if the subunit R3 is nested in { the routine R2, which is nested in the routine R1, { then the subunit DST record would be: { { +-----------------------+ { | length | { +-----------------------+ { | DST$K_SUBUNIT | { +-----------------------+ { | count = 4 | { +-----------------------+ { | "R1" in counted ascii | (module name) { +-----------------------+ { | "R1" in counted ascii | (module name) { +-----------------------+ { | "R1" in counted ascii | { +-----------------------+ { | "R2" in counted ascii | { +-----------------------+ { { Likewise, if the subunit R3 is nested in the { subunit R2, which is nested in the routine R1, { then the subunit DST record would be: { Note: R3's parent module is now R2 not R1. { { +-----------------------+ { | length | { +-----------------------+ { | DST$K_SUBUNIT | { +-----------------------+ { | count = 4 | { +-----------------------+ { | "R2" in counted ascii | (module name) { +-----------------------+ { | "R1" in counted ascii | (module name) { +-----------------------+ { | "R1" in counted ascii | { +-----------------------+ { | "R2" in counted ascii | { +-----------------------+ { { { Define the fields and size of the Subunit DST Record. { AGGREGATE DST$SUBUNIT STRUCTURE TYPEDEF; dst$a_subunit_header DST$HEADER; dst$b_subunit_pathname_count BYTE UNSIGNED; { The count byte specifying { the number of elements in { the pathname plus one for the { parent module name. #dst$subunit_header_size = :; END; { DST$SUBUNIT definition CONSTANT DST$K_SUBUNIT_SIZE EQUALS #dst$subunit_header_size; { Byte size of the fixed part of the { Subunit DST record { S E T M O D U L E D S T R E C O R D S { { { This used to be the with clause DST. Ada wished to use this for the { more general purpose of setting another module while setting this { module. This would cause the module to be "related" causing it to { be set and cancelled along with those modules that caused it to be { set via this DST. { { One use of this DST is by ADA to describe "with" clauses. A "with" { clause in ADA imports the definitions from another compilation unit. { { The other use is also by Ada to cause a generic module to be set so { that we might find the correct source for code described in that { module. This is the case of Ada generics. { { Set Module DST's must be contained with in the Module Begin and End { DSTs of the module that wishes to have the other module set also. { { The Set Module DST contains the name of the library package or { routine being imported. From DEBUG's point of view, this name should { be a module name. { { So, if several packages or routines are "with"ed, then one Set Module { DST should be generated for each of the items being "with"ed. { { For example: { { ADA program fragment DST { -------------------- --- { with P1,P2,P3; Module Begin "M" { procedure M is Routine Begin "M" { X: integer; Set Module DST "P1" { ... Set Module DST "P2" { begin Set Module DST "P3" { ... Data DST for "X" { end; ... { Routine End "M" { Module End "M" { { If the "with" clause imports definitions from a package, then { the presence of a Set Module DST causes automatic setting of the { package module when the importing module is set. This is the way { that DEBUG will achieve visibility of items in the package { within the importing module. For example, { { { DBG> SHOW MODULE { module set { ------ --- { P1 no { M no { { DBG> SET MODULE M { DBG> SHOW MODULE { module set { ------ --- { P1 yes { M yes { { The following is the format of the With Clause DST record: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_SET_MODULE) | { +---------------------------------------------------------------+ { byte | DST$B_SET_MODULE_NAME | { +---------------------------------------------------------------+ { var | | { | The name of the module to be set in ASCII | { | | { | (The name's length is given in DST$B_SET_MODULE_NAME) | { | | { +---------------------------------------------------------------+ { { { Define the fields of the With Clause DST record: { AGGREGATE DST$SET_MODULE STRUCTURE TYPEDEF; dst$a_set_module_header DST$HEADER; dst$b_set_module_name BYTE UNSIGNED; { The count byte of the name of { the module to set. #dst$set_module_header_size = :; END; { DST$SET_MODULE definition CONSTANT DST$K_SET_MODULE_SIZE EQUALS #dst$set_module_header_size; { Byte size of the fixed part of the { SET MODULE DST record { A D A U S E C L A U S E D S T R E C O R D S { { { { The Use Clause DST record describes "use" clauses in ADA. A { "use" clause makes the items in a package directly visible, { so that the user can reference them without the "package-name { dot" prefix. { { A "use" clause can appear at the start of any lexical unit { (i.e., routine, block, or package). The corresponding Use { Clause DST should appear immediately after the { Routine Begin, Block Begin, or Package Begin record defining { that lexical unit. { { The Use Clause DST contains a pathname specifying the package { that is being used. The first name in the pathname is the { module containing the "use"d package. If the "use"d package { is a library package then the second and last item in the { pathname is the name of the package. If the "use"d package { is nested in routines or other packages then they must appear { in the pathname. { { If more than one package is "use"d, then multiple Use Clause DST's { should be emitted (one for each package). For example: { { ADA program fragment DST { -------------------- --- { with P1,P2; Module Begin M1 { procedure M1 is With Clause "P1" { X1: integer; With Clause "P2" { use P1,P2; Routine Begin "M1" { procedure M2 Data DST for "X1" { X2: integer; Routine Begin "M2" { begin Use Clause "P1\P1" { ... Use Clause "P2\P2" { end; Data DST for "X2" { begin Routine End "M2" { ... Routine End "M1" { end; Module End "M1" { { When DEBUG sees a Use Clause DST, it looks up that package name { in the scope where it saw the Use Clause. It then builds internal { tables which capture the information in the Use Clause DSTs. { These tables are consulted during symbol lookup. { { The following is the format of the Use Clause DST record: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_USE_CLAUSE) | { +---------------------------------------------------------------+ { byte | DST$B_USE_PATHNAME_COUNT | { +---------------------------------------------------------------+ { var | the first pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | the second pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | ... | { | | { +---------------------------------------------------------------+ { var | the last pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { { For example, if the package P2 is nested in the library package P1, { and the program does "use P1.P2", then the structure of the { DST record would be: { { +-----------------------+ { | length | { +-----------------------+ { | DST$K_USE_CLAUSE | { +-----------------------+ { | count = 3 | { +-----------------------+ { | "P1" in counted ascii | (module name) { +-----------------------+ { | "P1" in counted ascii | { +-----------------------+ { | "P2" in counted ascii | { +-----------------------+ { { Define the fields of the Use Clause DST record: { AGGREGATE DST$USE_CLAUSE STRUCTURE TYPEDEF; dst$a_use_header DST$HEADER; dst$b_use_pathname_count BYTE UNSIGNED; { The count byte specifying { the number of elements in { the pathname #dst$use_clause_header_size = :; END; { DST$USE_CLAUSE definition CONSTANT DST$K_USE_CLAUSE_SIZE EQUALS #dst$use_clause_header_size; { Byte size of the fixed part of the { Use Clause DST record { A D A P A C K A G E R E A L - N A M E D S T { { This DST record is used to inform the debugger of the real name { of a package. This is needed because for a package "P", the DST { for the package spec will contain a constructed name such as { "P_" (in order to differentiate the spec from the body). The { debugger needs to know the real name of the package, without { relying on naming conventions. { { The placement of this DST record is after the "package spec begin" { record. For example, { { module begin "P_" { package spec begin "P_" { real name "P" { ...other DSTs... { package spec end { module end { { The following is the format of the "real name" DST record. { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_REAL_NAME) | { +---------------------------------------------------------------+ { byte | DST$B_REAL_NAME | { +---------------------------------------------------------------+ { var | The package's real name in ASCII | { | (The length of the name is given in DST$B_REAL_NAME) | { | ... | { +---------------------------------------------------------------+ { AGGREGATE DST$REAL_NAME STRUCTURE TYPEDEF; dst$a_real_name_header DST$HEADER; dst$b_real_name BYTE UNSIGNED; { The count byte for the ASCIC name #dst$real_name_header_size = :; END; { DST$REAL_NAME definition CONSTANT DST$K_REAL_NAME_SIZE EQUALS #dst$real_name_header_size; { Byte size of the fixed part of the { Real Name DST record { A D A P A C K A G E B O D Y - S P E C D S T { { { This DST record relates the body of a package to its spec. { ADA will put out a "package spec" begin-end pair of DSTs for { the spec, containing the name of the package "P". For the { body, it will put out a "package body" begin-end pair of DSTs { containing an invented name "P$BODY". Immediately after the { "package body begin" DST record, this DST$K_BODY_SPEC record { should be emitted to inform the debugger which package this { is the body of. For example, { { ADA program fragment DST { -------------------- --- { { package body P is package body begin "P$BODY" { begin body-spec "P.P" { --- definitions --- definitions { end; package body end "P$BODY" { { Note - DEBUG "knows" the scoping relationship between the body { and the spec (i.e., that the symbols in the spec are visible { in the body). Essentially, when DEBUG sees this DST record { it does an implicit "with" and "use" of the package spec from { the package body. It is not necessary for the compiler to { also put "WITH P" and "USE P" in the body of P. { { The following is the format of the Body-Spec DST record: { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_BODY_SPEC) | { +---------------------------------------------------------------+ { byte | DST$B_BODY_SPEC_PATHNAME_COUNT | { +---------------------------------------------------------------+ { var | the first pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | the second pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { var | ... | { | | { +---------------------------------------------------------------+ { var | the last pathname element, in counted ascii | { | ... | { +---------------------------------------------------------------+ { { This looks the same as the "use" clause DST above. { { +-----------------------+ { | length | { +-----------------------+ { | DST$K_BODY_SPEC | { +-----------------------+ { | count = 3 | { +-----------------------+ { | "P1" in counted ascii | (module name) { +-----------------------+ { | "P1" in counted ascii | { +-----------------------+ { | "P2" in counted ascii | { +-----------------------+ { { Define the fields of the Body-Spec DST record: { AGGREGATE DST$BODY_SPEC STRUCTURE TYPEDEF; dst$a_body_spec_header DST$HEADER; dst$b_body_spec_pathname_count BYTE UNSIGNED; { The pathname for the package #dst$body_spec_header_size = :; END; { DST$BODY_SPEC definition CONSTANT DST$K_BODY_SPEC_SIZE EQUALS #dst$body_spec_header_size; { Byte size of the fixed part of the { Body Spec DST record { A L I A S D S T { { This DST record is used to inform the debugger that a symbol { may also be refered to by another name. An example of this { is the renaming ability of Ada. For the scope that this DST { is in, the specific symbol may be referenced by either the { actual name or the assigned name (as given in this DST). { { This DST may appear anywhere and will then apply only to the { scope where it appears. This DST record contains the name of { the other module as a counted ascii string, and the "OFFSET" { field is a byte offset relative to the start of the DST for { that module. { { The Alias DST is also used to described C++ namespace aliasing. { See the description of C++ namespace support for more information. { { The following is the format of the "alias" DST record. { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_ALIAS) | { +---------------------------------------------------------------+ { long | DST$L_ALIAS_MOD_OFFSET | { +---------------------------------------------------------------+ { byte | DST$B_ALIAS_NAME | { +---------------------------------------------------------------+ { var | The alias (or new) name in counted ASCII | { | (The length of the name is given in DST$B_ALIAS_NAME) | { | ... | { +---------------------------------------------------------------+ { var | The name of the module that DST$L_ALIAS_MOD_OFFSET | { | is an offset from. (This name is represented in a | { | counted ASCII.) | { | ... | { +---------------------------------------------------------------+ { { AGGREGATE DST$ALIAS STRUCTURE TYPEDEF; dst$a_alias_header DST$HEADER; dst$l_alias_mod_offset LONGWORD UNSIGNED; { Offset from given module DST dst$b_alias_name BYTE UNSIGNED; { Length of alias name #dst$alias_header_size = :; END; { DST$ALIAS definition CONSTANT DST$K_ALIAS_SIZE EQUALS #dst$alias_header_size; { Byte size of the fixed part of the { Alias DST record { F U L F I L L S T Y P E D S T R E C O R D { { { { The Fulfills Type DST record is used in conjuction with the { Incomplete Type Spec DST record. This DST record gives the { debugger information about a type in another module (package { spec) that was not available. The following is an example { of how this DST is used. It works like this: { { pacakge P is { package Q is { type A is private; { private { type CELL; { type A is access CELL; { end; { end; { { package body P is { package body Q is { type CELL is array(1..10) of integer; { end; { end; { { The Fulfills Type DST record is generated in package body P to { tell the debugger about the type CELL. The type spec embedded { in the Fulfills Type DST record must be an Indirect Type Spec { or a X-Module Indirect Type Spec that points to the Incomplete { Type Spec generated in package spec P. (See the Incomplete Type { Spec description) { { The processing of the Fulfills DST allows multiple indirect DSTs { to be generated in order to find the incomplete type spec DST. This { is the case for Ada where a psuedo vector of indirect DSTs is { generated that point off to the actual incomplete type spec to { support fast recompilation. { { Just as with the Separate Type Specification DST record, a Fulfills { Type DST record must be immediately followed by a Type Specification, { Record Begin, or Enumeration Type Begin DST record which describes { the actual type spec that describes the type (CELL in this example). { This Type Specification DST may also be indirect to the actual { description type spec for the type but any type spec is accepted { here. { { When the debugger sees this DST record it'll go back to the pointed { to Incomplete Type Spec and fill in the last longword there to { point to the next DST record after the Fulfills Type Spec DST record, { so that all following references to the type in the package spec { will just follow the chain of indirection until it gets to the { actual type spec description of that type. { { This is the format of the Fulfills Type Spec. DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_FULFILLS_TYPE) | { +---------------------------------------------------------------+ { var | DST$A_FF_INCOMPLETE_TS | { | | { | Type Spec that points to an incomplete type spec. | { | This must be either an indirect or a x-module | { | indirect type spec. | { | | { +---------------------------------------------------------------+ { { { The Fulfills Type DST and the Incomplete Type Spec DST work together. { Once a module is SET that has one or more Fulfills Type DSTs in it { all the Incomplete types that it refers to get filled in, and stay { filled in for ever. For example, you may EXAMINE X at some point { and get a message that indicates that we have no type information { for X even though the module that contains X is SET. But once the { module that does contains the type information for X gets SET (even { if it is later CANCELled) the debugger will then have type information { on X and henceforth display it correctly. { { { Define the fields of the Fulfills Type DST record. { AGGREGATE DST$FULFILLS_TYPE STRUCTURE TYPEDEF; dst$a_fulfills_header DST$HEADER; #dst$fulfills_header_size = :; END; { DST$FULFILLS_TYPE definition CONSTANT DST$K_FULFILLS_TYPE_SIZE EQUALS #dst$fulfills_header_size; { Byte size of the fixed part of the { Fulfills Type DST record { { Define an offset for the first type specification { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ff_incomplete_ts = DST$K_FULFILLS_TYPE_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { T H E D E F I N I T I O N L I N E N U M B E R { { D S T R E C O R D { { { { NOTE: THIS DST RECORD IS NOT CURRENTLY SUPPORTED BY DEBUG. { IT CAN BE GENERATED BY COMPILERS, BUT IT WILL BE IGNORED. { { The Definition Line Number DST record specifies the listing line number { at which a data symbol or other object is defined or declared. The { intent is to make use of this information in future DEBUG commands so { that a user can see the declaration source line for a specified symbol. { The Definition Line Number DST record must immediately follow the data { DST record of the data object whose line of definition is being speci- { fied. { { This is the format of the Definition Line Number DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE = (DST$K_DEF_LNUM) | { +---------------------------------------------------------------+ { byte | Unused (Must Be Zero) | { +---------------------------------------------------------------+ { long | DST$L_DEF_LNUM_LINE | { +---------------------------------------------------------------+ { { { { Define the fields of the Definition Line Number DST record. The unused byte { in the DST record is reserved for future use. { AGGREGATE DST$DEF_LNUM STRUCTURE TYPEDEF; dst$a_def_lnum_header DST$HEADER; dst$b_def_lnum_mbz BYTE UNSIGNED; { Must Be Zero dst$l_def_lnum_line LONGWORD UNSIGNED; { The definition line number #dst$def_lnum_size = :; END; { DST$DEF_LNUM definition CONSTANT DST$K_DEF_LNUM_SIZE EQUALS #dst$def_lnum_size; { Byte size of Definition Line { Number DST record { T H E S T A T I C L I N K D S T R E C O R D { { { { The Static Link DST record specifies the "Static Link" for a routine. { The Static Link is a pointer to the VAX call frame for the proper up- { scope invocation of the outer routine within which the present invoca- { tion of the present routine is nested. The Static Link is thus used { when DEBUG does up-level addressing in response to user commands. A { Static Link DST Record is always associated with the inner-most routine { within whose Routine-Begin and Routine-End records it is nested. The { Static Link DST Record is optional--it need not be used by languages { or for routines which do not keep track of static links in their run- { time environments. In fact, the Static Link DST record only makes a { difference for recursive routines that pass routines as parameters, a { fairly obscure situation. { { This is the format of the Static Link DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (=DST$K_STATLINK) | { +---------------------------------------------------------------+ { var | DST$A_SL_VALSPEC | { | | { | A DST Value Specification Giving the Value of the | { | | { | Static Link, i.e. the FP Value of the Routine Invocation | { | | { | Statically Up-Scope from this Scope | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Static Link DST record. { AGGREGATE DST$STATLINK STRUCTURE TYPEDEF; dst$a_sl_header DST$HEADER; #dst$statlink_header_size = :; END; { DST$STATLINK definition CONSTANT DST$K_STATLINK_SIZE EQUALS #dst$statlink_header_size; { Byte size of the fixed part of the { Static Link DST record { { Define an offset for the location of Value Spec giving { the up-scope FP value { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_sl_valspec = DST$K_STATLINK_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { T H E P R O L O G D S T R E C O R D { { { { The Prolog DST record tells DEBUG where to put routine breakpoints. { It is used for routines that have prolog code that must be executed { before data objects can be freely examined or otherwise accessed { from DEBUG. Such prolog code typically sets up stack locations and { descriptors for formal parameters or other data objects. By putting { routine breakpoints on the first instruction after the prolog code, { as specified in the Prolog DST record, DEBUG ensures that all local { storage and formal parameters are accessible to the user. { { Prolog DST records are optional. If omitted for some routine, DEBUG { simply uses the routine start address for routine breakpoints or { tracepoints requested by the user. If specified, the Prolog DST { record is counted as belonging with the nearest Routine Begin or Entry { Point DST record before it, not counting nested routines. Placing { the Prolog DST record immediately after the Routine Begin or Entry { Point DST record with which it is associated is good practice. { { This is the format of the Prolog DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_PROLOG) | { +---------------------------------------------------------------+ { long | DST$L_PROLOG_BKPT_ADDR | { +---------------------------------------------------------------+ { { { { Define the fields of the Prolog DST record. { AGGREGATE DST$PROLOG STRUCTURE TYPEDEF; dst$a_prolog_header DST$HEADER; dst$l_prolog_bkpt_addr LONGWORD UNSIGNED; { The routine breakpoint address #dst$prolog_size = :; END; { DST$PROLOG definition CONSTANT DST$K_PROLOG_SIZE EQUALS #dst$prolog_size; { Byte size of the Prolog DST record { T H E P R O L O G L I S T D S T R E C O R D { { { The Prolog List DST Record is the same as the Prolog DST Record, except { that it describes a list of routine break addresses. { { Each of the addresses described by a prolog list record must be { distinct. Also, the addresses in the list must be sorted such that { the lowest address is described first. { { This is the format of the Prolog List DST record: { AGGREGATE DST$PROLIST STRUCTURE TYPEDEF; dst$w_prolist_header DST$HEADER; { Length, type (=DST$K_PROLOG_LIST) dst$lu_prolist_count LONGWORD UNSIGNED; { Count of break addresses { which follow #dst$prolist_header_size = :; END; CONSTANT DST$K_PROLIST_SIZE EQUALS #dst$prolist_header_size; { Byte size of the fixed part of the { Prolog list DST record { { Define an offset for the additional (variable) prolog information. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_prolist = DST$K_PROLIST_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the information for an routine break addresses { AGGREGATE DST$PROLIST_ENTRY STRUCTURE TYPEDEF; dst$lu_prolist_bkpt_addr LONGWORD UNSIGNED; { One routine break address #dst$prolist_entry_size = :; END; CONSTANT DST$K_PROLIST_ENTRY_SIZE EQUALS #dst$prolist_entry_size; { Byte size of a single prolog entry { { For Bliss, define a macro for defining an array of these structures { IFLANGUAGE BLISSF; LITERAL; KEYWORDMACRO DST$PROLIST_VECTOR(N = 1) = BLOCKVECTOR[(N), DST$K_PROLIST_ENTRY_SIZE, BYTE] FIELD(DST$PROLIST_ENTRY_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { The Epilog DST Record { { Some architectures provides no efficient way of stopping execution at { a routine's exit before the local variables are inaccessible. Lack of { this ability would preclude user access to local variables via { commands such as EXAMINE and DEPOSIT. Without additional software { support from compilers, the debugger would be constrained to { single-step the entire routine. { { A solution to this problem is to specify each routine's list of epilog { addresses in the symbol table. This is the purpose of the Epilog DST. { Epilog DSTs appear between Routine Begin and Routine End DSTs in the { same way as Prolog and Register DSTs do. { { The entries in the trailer of this DST represent the set of origins or { bounds of sequences of epilog instructions. DEBUG should place { breakpoints at the start of an epilog sequence if it is desired to { halt execution of the routine when it is about to return to its { caller. Note that these locations will differ from the addresses of { the actual return instructions for the routine in the presence of { epilog code. { { Special note: 23-Jun-97, Mark Arsenault { { Today I am adding a new DST type code: DST$K_EPILOGS. It is { has exactly the same semanitics as the pre-existing type code: { DST$K_EPILOG. The new one code is being added in order to solve { a backwards compatibility problem. The new support for inlining { routines requires epilog DSTs to appear between Block Begin/End { DSTs. The 'old' debugger complains about the 'old' Epilog DST { being used in this 'new' context. So the new type code is invented. { The old debugger does not complain about the new Epilog DST because { it has no knowledge of that new type code. { { Compilers should use the new DST type code (DST$K_EPILOGS) instead { of the old one (DST$K_EPILOG). { AGGREGATE DST$EPILOG STRUCTURE TYPEDEF; dst$w_epilog_header DST$HEADER; { Length, type (=DST$K_EPILOGS) dst$b_epilog_flags STRUCTURE; dst$v_epilog_addr_pairs_flag BITFIELD LENGTH 1; { Flag indicating subsequent list { contains pairs of addresses dst$v_epilog_mbz BITFIELD LENGTH 7; { Must Be Zero END dst$b_epilog_flags; dst$lu_epilog_count LONGWORD UNSIGNED; { Count of epilog address singletons or { pairs which follow #dst$epilog_header_size = :; END; { DST$EPILOG definition CONSTANT DST$K_EPILOG_SIZE EQUALS #dst$epilog_header_size; { Byte size of the fixed part of the { Epilog DST record { { Define an offset for the additional (variable) epilog information. { This includes the target addresses of routine's epilogs. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_epilogs = DST$K_EPILOG_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the information for an epilog singleton { AGGREGATE DST$EPI_SINGLETON STRUCTURE TYPEDEF; dst$lu_epilog_single_addr LONGWORD UNSIGNED; { Field within a singleton list element { which contains an epilog address #dst$epilog_singleton_size = :; END; { DST$EPI_SINGLETON definition CONSTANT DST$K_EPILOG_SINGLETON_SIZE EQUALS #dst$epilog_singleton_size; { Byte size of the Epilog Singleton { portion of an Epilog DST record { { For Bliss, define a macro for defining an array of these structures { IFLANGUAGE BLISSF; LITERAL; KEYWORDMACRO DST$EPILOG_SINGLETON(N = 1) = BLOCKVECTOR[(N), DST$K_EPILOG_SINGLETON_SIZE,BYTE] FIELD(DST$EPI_SINGLETON_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the information for an epilog pair { AGGREGATE DST$EPI_PAIR STRUCTURE TYPEDEF; dst$lu_epilog_pair_low_addr LONGWORD UNSIGNED; { Field within a pair list element { which contains the low bound of { a sequence of epilog code dst$lu_epilog_pair_high_addr LONGWORD UNSIGNED; { Field within a pair list element { which contains the high bound of { a sequence of epilog code #dst$epilog_pair_size = :; END; { DST$EPI_PAIR definition CONSTANT DST$K_EPILOG_PAIR_SIZE EQUALS #dst$epilog_pair_size; { Byte size of the Epilog Pair { portion of an Epilog DST record { { For Bliss, define a macro for defining an array of these structures { IFLANGUAGE BLISSF; LITERAL; KEYWORDMACRO DST$EPILOG_PAIR(N = 1) = BLOCKVECTOR[(N), DST$K_EPILOG_PAIR_SIZE,BYTE] FIELD(DST$EPI_PAIR_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { The Return DST Record { { Execution profilers may need to gather statistics on the amount of { time spent in specific routines in users' applications. In order to do { this, they must know the addresses of routines' return points. The { Return DST specifies each routine's list of return addresses in the { symbol table. This DST appears between Routine Begin and Routine End { DSTs in the same way as Epilog DSTs do. { AGGREGATE DST$RETURN STRUCTURE TYPEDEF; dst$w_return_header DST$HEADER; dst$b_return_mbz BYTE UNSIGNED; { Unused field, MBZ dst$lu_return_count LONGWORD UNSIGNED; { Count of return addresses #dst$return_header_size = :; END; { DST$RETURN definition CONSTANT DST$K_RETURN_SIZE EQUALS #dst$return_header_size; { Byte size of the fixed part of the { Return DST record { { Define the offset for the target addresses of routine's returns. { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_returns = DST$K_RETURN_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { T H E V E R S I O N N U M B E R D S T R E C O R D { { { { The Version Number DST record gives the version number of the compiler { that compiled the current module. The Version Number DST Record must { be nested within the Module Begin and Module End DST Records for the { module in question. DEBUG ignores this record except in special cases { when it is necessary to distinguish between old and new versions of the { compiler that generated a given object module. { { This is the format of the Version Number DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_VERSION) | { +---------------------------------------------------------------+ { byte | DST$B_VERSION_MAJOR | { +---------------------------------------------------------------+ { byte | DST$B_VERSION_MINOR | { +---------------------------------------------------------------+ { { { { Define the fields of the Version Number DST record. { AGGREGATE DST$VERSION STRUCTURE TYPEDEF; dst$a_version_header DST$HEADER; dst$b_version_major BYTE UNSIGNED; { The major version number dst$b_version_minor BYTE UNSIGNED; { The minor version number #dst$version_size = :; END; { DST$VERSION definition CONSTANT DST$K_VERSION_SIZE EQUALS #dst$version_size; { Byte size of the Version { Number DST record { T H E C O B O L G L O B A L A T T R I B U T E { { D S T R E C O R D { { { { The COBOL Global Attribute DST record indicates that the symbol whose { DST record immediately follows has the COBOL "global" attribute. This { attribute specifies that the symbol is visible in nested COBOL scopes { (routines) within the scope (routine) in which the symbol is declared. { Without this attribute, a symbol is only visible in its scope of decla- { ration but not within any nested scopes. In this regard, COBOL differs { from most other languages. DEBUG thus needs to know this attribute in { order to implement the COBOL scope rules correctly. { { The COBOL Global Attribute DST record is only generated by the COBOL { compiler. If it precedes the DST record for some symbol, that symbol { is deemed to have the COBOL global attribute; if it omitted, the sym- { bol is deemed not to have the global attribute. DEBUG ignores this { attribute for all other languages. { { This is the format of the COBOL Global Attribute DST record: { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_COBOLGBL) | { +---------------------------------------------------------------+ { { { Register DST Records { { The DSTs called the Register Save Begin, Register Save and Register { Save End are collectiv ely known as Register DSTs. They are used to { specify the location of saved registers within routines which do not { use the CALLx instructi ons' register save masks. See NEW-DSTS. MEM { for more informati on on the requireme nts for their design. { { The order of the sequence in which the various Register DSTs may { appear is as follows: { { A Register Save Begin DST marking the beginning of the sequence. { A sequence of Register Save DSTs. { A Register Save End DST marking the end of the sequence. { { The only DST record that can appear between a Register Save Begin and { a Register Save End is the Register Save DST. Each Register Save DST { contains the register number of a register being saved, and and a { valspec for the location where it is saved. Register Save DSTs must { appear in register-number order. { { Register DSTs may appear anywhere between a pair of Routine Begin and { Routine End, Package Specification Begin and Package Specification { End, or Package Body Begin and Package Body End DSTs, and will be { associated with the closest preceding unmatched Routine Begin, Package { Specification Begin, or Package Body Begin DST. An Entry Point DST { must not fall between a Register Save Begin DST and its associated { Routine or Package DST. A routine which saves no registers will have { no Register Save DSTs, and thus has no need to contain Register Save { Begin and Register Save End DSTs. { { Register Save Begin DST { { The save mask must be present whenever there is a Register Save DST { between a Register Save Begin and a Register Save End DST. It will be { used by the debugger to quickly determine which whether a given { register is represented by a Register Save DST, and thus each register { described by Register Save DST must have its corresponding bit set in { the mask. The mask is optional in order to allow Register Save Begin { DSTs to be represented more compactly. This might be desirable if new { fields added the future might require the DST to be generated for { routines that do not have any saved registers to describe. Undefined { bits in the DST$BU_REGBEG_FLAGS field must be set to zero for { compatibility purposes. { { The count field for the save mask is an unsigned byte named { DST$BU_SAVE_MASK_LENGTH which contains the length of the following bit { mask in units of bytes. The bit mask itself is named DST$V_SAVE_MASK, { and follows the count byte. The bits are numbered according to the VAX { convention - that is, starting from 0, in increasing order of { significance within a byte, and increasing as the (VAX) byte address { increases. The register's position in the bitvector is fixed for a { particular target architecture, and implies the size and memory { alignment requirements of the register. { { 68K targets should use the following register numbering scheme: { { Register Register number Register size (in bits) { A0 0 32 { ... ... 32 { A7 7 32 { D0 8 32 { ... ... 32 { D7 15 32 { FP0 16 96 { ... ... 96 { FP7 23 96 { AGGREGATE DST$REG_SAVE_BEGIN STRUCTURE TYPEDEF; dst$w_regbeg_header DST$HEADER; dst$bu_regbeg_flags STRUCTURE; { Flag bits dst$v_regbeg_save_mask_flag BITFIELD LENGTH 1; { Register save mask is present dst$v_regbeg_mbz BITFIELD LENGTH 7; { Must Be Zero END dst$bu_regbeg_flags; dst$bu_regbeg_save_mask_length BYTE UNSIGNED; { Save mask length, in bytes #dst$regbeg_header_size = :; END; { DST$REG_SAVE_BEGIN definition CONSTANT DST$K_REGISTER_SAVE_BEGIN_SIZE EQUALS #dst$regbeg_header_size; { Byte size of the fixed part of the { Register Save DST record { { Force the datatype name to be consistent with the old DSTRECRDS.REQ. { The problem is that SDL generates a fieldset name longer than 32 { characters if we don't do this... { IFLANGUAGE BLISSF; LITERAL; MACRO DST$REGISTER_SAVE_BEGIN = DST$REG_SAVE_BEGIN%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the offset to the save mask bitvector { IFLANGUAGE BLISSF; LITERAL; MACRO dst$v_regbeg_save_mask_base = DST$K_REGISTER_SAVE_BEGIN_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Register Save DST { { This DST has a standard valspec at the same offset from the beginning { of the DST as the valspec in Standard Data DSTs. This allows the { relevant symbols in the DST$STD_FIELDS field set to be used to access { the value specification. The valspec gives the address of the location { where a register is saved while the routine associated with the DST is { executing. The saved register is designated by the value of the { DST$B_REG_SAVE_REGNUM field. The same register numbering as the { Register Save Begin DST's save mask is used. If the valspec is a split { lifetime valspec, then the register is saved in the corresponding { locations only while the PC has a value within one of the valspec's PC { ranges. AGGREGATE DST$REGISTER_SAVE STRUCTURE TYPEDEF; dst$w_reg_save_header DST$HEADER; dst$a_reg_save_valspec DST$VAL_SPEC; { Save location valspec (flags, value) dst$bu_reg_save_regnum BYTE UNSIGNED; { Register number #dst$reg_save_size = :; END; { DST$REGISTER_SAVE definition CONSTANT DST$K_REGISTER_SAVE_SIZE EQUALS #dst$reg_save_size; { Byte size of the Register { Save DST record { { Register Save End DST { AGGREGATE DST$REGISTER_SAVE_END STRUCTURE TYPEDEF; dst$w_regend_header DST$HEADER; #dst$regend_size = :; END; { DST$REGISTER_SAVE_END definition CONSTANT DST$K_REGISTER_SAVE_END_SIZE EQUALS #dst$regend_size; { Byte size of the Register { Save End DST record { { Exception DST { { When an exception is raised in an Ada program, it is useful for the { runtime system to refer to it by name when informing the user of the { exception. DEBUG refers to exception names symbolically during the { SHOW CALLS and SHOW STACK commands, and as the value of the new { %ADAEXC_NAME lexical. { { VAX Ada provides access to exception names via signal argument blocks. { { XD Ada does not store exception names on the target system, and { represents exceptions via a longword quantity ("exception number"). { Therefore Exception DSTs must be used to map exception numbers to { exception names. { { One Exception DST should exist for each exception defined in the { application. The DSTs should appear in increasing order of exception { value. { { In order to make the exception names visible to XDEBUG at the earliest { time after startup, the Exception DSTs should appear between the { Module Begin and Module End DSTs of some module which is automatically { set by XDEBUG upon startup. This can be reconciled with the XD Ada { builder's inability to delay the completion of the main module's DSTs { until all the object modules have been processed by emitting the { Exception DSTs in a dummy module at the end of the symbol table. If it { is referenced from the main program unit via a Set Module DST, then it { will satisfy the need to be set during XDEBUG startup. { { The dummy module's name should be some reserved value which will not { intrude on the user's module name space. Also, it should have the { DST$V_MODBEG_HIDE flag set in its Module Begin DST so that it is not { displayed by the user's SHOW MODULE commands. This design does not { specify whether the XD Ada compiler must emit the Set Module DST, or { whether the builder may insert it in the symbol table as it is { constructing it. This choice may be made jointly by the compiler and { builder developers. { { The name of the module which defined the exception may contained in { Exception DSTs in order to aid formatting tools which convert .XDS { files to other symbol table formats. The module name is provided by { the optional DST$B_EXCEPTION_MOD_NAME trailer field, as well as the { flag bit DST$V_EXCEPTION_MOD_NAME_FLAG which indicates its presence. { XDEBUG does not access the module name at present, because it has no { need for this information. { { If XDEBUG encounters an Exception DST with a value which matches an { existing list entry, it will only be diagnosed as an error if the name { of the duplicate list entry does not match the name being added. This { will prevent spurious errors caused by a user explicitly canceling and { setting the main program's module. If this were not done, then { subsequent settings of the module would try to insert the exception { names into the list twice. The comparison used when matching names { will be case-sensitive. { { Because XDEBUG will construct a table indexed by user-defined { exception numbers based at zero, it is important that the set of { numbers be small and dense to avoid wasted heap space in the debugger. { AGGREGATE DST$EXCEPTION STRUCTURE TYPEDEF; dst$w_exception_header DST$HEADER; dst$bu_exception_flags STRUCTURE; { Flag field (spare bits must be zero) dst$v_exception_mod_name_flag BITFIELD LENGTH 1; { Defining module's name is present dst$v_exception_mbz BITFIELD LENGTH 7; { Must Be Zero END dst$bu_exception_flags; dst$lu_exception_value LONGWORD UNSIGNED; { Exception value (number) dst$a_exception_variant UNION; dst$b_exception_name BYTE UNSIGNED; { Count byte of the exception name { field, a counted ASCII string dst$b_exception_trlr_offs BYTE UNSIGNED; { Byte offset to the Exception DST { optional record trailer fields END dst$a_exception_variant; #dst$exception_header_size = :; END; { DST$EXCEPTION definition CONSTANT DST$K_EXCEPTION_SIZE EQUALS #dst$exception_header_size; { Byte size of the fixed part of the { Exception DST record { { Define the base address for the offset to optional Exception DST { record trailer fields. The trailer field is optionally located at { DST_RECORD[DST$A_EXCEPTION_TRLR_BASE] + .DST_RECORD[DST$B_EXCEPTION_TRLR_OFFS] { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_exception_trlr_base = DST$K_EXCEPTION_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the trailer record structure { AGGREGATE DST$EXCEPTION_TRAILER STRUCTURE TYPEDEF; dst$b_exception_mod_name BYTE UNSIGNED; { Count byte of the optional name of the { module which defined this exception #dst$exception_trailer_size = :; END; { DST$EXCEPTION_TRAILER definition CONSTANT DST$K_EXCEPTION_TRAILER_SIZE EQUALS #dst$exception_trailer_size; { Byte size of the fixed part of the { exception trailer portion of { the DST record { C++ Support { { The ability to embed functions, static variables and class definitions { within other classes means that classes constitute a richer and more { complex form of named scope in C++ than structs form in C. This will be { dealt with by relaxing certain rules about what DSTs may appear between { Record Begin and Record End DSTs for C++ programs. { { A class type named "C" will be denoted by a Record Begin DST with the { name "C", followed by the members of "C", and terminated by a Record { End DST. The DST$L_RECBEG_SIZE field of the Record Begin DST will { contain the size of an entire object of the class, including the size { of any inherited subobjects. { { Non-static data members of a class will be denoted, as usual, by a Data { Symbol DST with a valkind of DST$K_VFLAGS_BITOFFS. The offset will be { with respect to the most ancestral non-virtual class (that is, the { offset will account as much as possible for the size of any preceeding { non-virtual base classes). { { Members of base classes are not defined explicitly in DST description { of the derived class. Instead, the Base Class DST defines the { relationship between base and derived classes. { { Static data members of a class will be denoted by a Data Symbol DST { with a valspec with the appropriate static address. { { Member functions of a class will be represented by Routine DSTs. { Routine Begin-End DSTs appearing at Record DST nesting level will be { interpreted as a member function of that class. { { Virtual member functions are indicated by a Virtual Function DST { within the Routine Begin-End DSTs. { { Enumeration literals can be declared within classes. They are scoped { the same as class members. The debugger will accept enumeration type { begin-end and element DSTs within class begin-end DSTs. Similarly, { typedefs can be declared within classes. They will be handled the { same way. { { Template declarations are described via Template Declaration DSTs. They { tell the debugger that a template with a particular name was declared at a { particular point (scope). This allows the debugger to correctly interpret { template generated names as entered by the user into the debugger command { line. Template instances are represented, in the usual way, having normal { C++ template names, such as "Array". (In this example, the compiler { would generate a Template Declaration DST for "Array".) Note that there is { no explicit connection in the DSTs between a Template Declaration DST and { other DSTs describing the symbols generated from that template. { { C++ member functions are passed the address of an object prefixed in { the source code for the member function call. The address is passed by { displacing all the normal actual parameters in the argument list and { passing the prefix object's address first, as C and C++ prepend the { address of a stack temporary for struct-valued function return values. { The prefix argument of a struct-valued member function will immediately { follow the return value pointer. { { Debug must be able to locate the prefix argument in the argument list { in order to compute the addresses of non-static data members while { within the scope of a non-static member function. { { Earlier versions of this document defined a This DST, which identified { the DST describing the This parameter. The This DST been removed { because it is inconvenient for Gem to produce and it not important for { the debugger to receive. The purpose of the This DST was to reduce the { amount of C++-specific semantics and implementation details that the { debugger must contain. However, the This DST provided very little { towards this goal, since, even with it, the debugger would still need { to understand that within the scope of a member function references to { the class's data members are implicitly using the This pointer. Given { that the debugger must contain that knowledge, it does not seem like a { big deal to also require the debugger to understand that the This { pointer is the first parameter of a member function whose name is { "this". { { Base Class DSTs { { The base classes of a C++ class must be known by Debug in order to { represent inheritance information used for such operations as { displaying non-static base class data members. { { A non-virtual base class's subobject is located at a fixed (known at { compile-time) offset from the beginning of its derived object. For a { non-virtual base class, the Base Class DST describes this fixed { offset. { { A virtual base class's subobject is located at varying (not known at { compile-time) offset from the the beginning of its derived object. For { a virtual base class, the Base Class DST describes the index in the { corresponding btbl array of the element that contains offset from the { the beginning of its derived object. { { Base Class DSTs appear within Record Begin-End DSTs. They appear { as siblings of the data members and member functions of their { corresponding classes. All Base Class DSTs for a class must appear { after the Record Begin DST of that class and before any member DSTs { of that class. The order of Base Class DST must match the order of { derivations in the source. [Note: it's not clear that the debugger { actually cares about the order of base class derivations.] { { The DST$V_BASE_CLASS_VIRTUAL bit will be set iff the referenced base { class is declared as a virtual base class. { { The DST$L_BASE_CLASS_DST longword contains the offset of a Record Begin { DST for the base class. The offset is relative to the beginning of the { DSTs. { { If the DST$V_BASE_CLASS_VIRTUAL bit is set, then the { DST$L_BASE_CLASS_VALUE field denotes the index in the corresponding { btbl array of the element that contains offset from the beginning { of its derived object. { { If the DST$V_BASE_CLASS_VIRTUAL bit is clear, then the { DST$L_BASE_CLASS_VALUE field denotes the offset of the beginning of the { base class subobject from the beginning of its derived object. The { offset must be expressed in units of bits. { AGGREGATE DST$BASE_CLASS STRUCTURE TYPEDEF; dst$w_base_class_header DST$HEADER; dst$b_base_class_flags STRUCTURE; dst$v_base_class_virtual BITFIELD LENGTH 1; { base is virtual dst$v_base_class_unused BITFIELD LENGTH 7; { must be zero END dst$b_base_class_flags; dst$l_base_class_dst LONGWORD UNSIGNED; { Base class's DST offset. This is an { offset to another DST record, relative { to the start of the whole DST. dst$l_base_class_value LONGWORD UNSIGNED; { see comments above #dst$base_class_size = :; END; CONSTANT DST$K_BASE_CLASS_SIZE EQUALS #dst$base_class_size; { Virtual Function DSTs { { There is a need to represent the address computation algorithm for { virtual member functions. { { A virtual member function is a member function whose address is { obtained at call sites via a virtual function dispatch table (vtbl). { Vtbls are accessed via a pointer (vptr) in the object which is the { prefix argument to the call. { { Virtual Function DSTs are optional. If omitted for some routine, Debug { assumes that the routine is non-virtual. If specified, the Virtual { Function DST is interpreted as belonging with the routine corresponding { to the current routine nest. A Virtual Function DST outside of a { routine begin-end pair is erroneous. Placing the Virtual Function DST { soon after the Routine Begin DST with which it is associated is good { practice. { { The DST$A_VIRT_FUNC_VALSPEC field represents contains the index of { element containing the target address of the virtual function within { the class's vtbl. { { In order to compute the addresses of virtual functions and virtual base { classes for an object, Debug must know the locations of two pointers { within the object. The virtual function dispatch table (vtbl) is { pointed to by the vptr, and the virtual base class table (btbl) is { pointed to by the bptr. { { A Vptr will be described in the DSTs by a data member named '__vptr'. { The type of that data member will describe the virtual table. The { virtual table must be described as a one-dimensional array. The { debugger will treat the DST$L_VIRT_FUNC_INDEX field of the Virtual { Function DST as an index into the array described by the corresponding { '__vptr' data member. { { Similarly, a Bptr will be described in the DSTs by a data member named { '__bptr'. For virtual base classes, the debugger will treat the { DST$A_BASE_CLASS_VALUE field of the Base Class DST as an index into the { array described by the corresponding '__bptr' data member. { AGGREGATE DST$VIRT_FUNC STRUCTURE TYPEDEF; dst$w_virt_func_header DST$HEADER; dst$b_virt_func_flags STRUCTURE; dst$v_virt_func_unused BITFIELD LENGTH 8; { must be zero END dst$b_virt_func_flags; dst$l_virt_func_index LONGWORD UNSIGNED; { function's index into vtbl #dst$virt_func_size = :; END; CONSTANT DST$K_VIRT_FUNC_SIZE EQUALS #dst$virt_func_size; { Type Signature DSTs { { There is a need to represent overloaded routines with identical { user-supplied names and distinct argument list type signatures for C++ { support. Debug will use the type signature information to help users { disambiguate overloaded function names. { { Type Signature DSTs are optional. If specified, the Type Signature DST { is interpreted as belonging with the routine corresponding to the { current routine nest. A Type Signature DST outside of a routine { begin-end pair is erroneous. Placing the Type Signature DST soon after { the Routine Begin DST with which it is associated is good practice. { { Every function described in the DSTs should have a Type Signature DST { associated with it. Type Signature DSTs apply to both member and { non-member functions. (Note that non-member functions can be { overloaded just like member functions.) For consistency of debugger { displays (such as that resulting from SHOW SYMBOL function-name) even { functions that are not overloaded should be provided with type { signatures. When there are multiple Routine DSTs for a particular { function in a compilation unit, a Type Signature DST should be provided { with any one (or more than one) of those Routine DSTs. { { The DST$A_TYPE_SIG_STRING field is an ASCIC string containing the type { signature for the function. It is recommended that, for consistency, { the C++ compiler create Type Signature DSTs for all functions, whether { or not they are overloaded. { { The format of type signature strings is left to the compiler. The { debugger will compare type signatures very simply. Each different type { signature should be given a unique type signature string. The compiler { should be consistent in its inclusion of lexically unimportant white { space (if it includes any at all). Remember to include "const" and { "volatile" when appropriate. { { The only thing the debugger will do with type signature strings is to { display them to the user. { { Are Type Signature DSTs necessary? Couldn't the debugger calculate { type signatures by demangling mangled names (as Ladebug does)? The { problem with doing that is that mangled names are limited to 31 { characters on VMS (linker imposed limitation). Hence, on VMS, mangled { names loose type information fairly quickly and so do not constitute { are robust type signature encoding. { { Overloaded functions should be described using the Overloaded Symbol { DST, see ALPHA_DSTRECRDS.SDL and the example at the end of this { document. The Overloaded Symbol DST contains the real name of the { function (the simple name that the C++ programmer uses to refer to the { symbol (in the example 'h')). The Overloaded Symbol DST points at the { Routine Begin DSTs for each of the overloaded functions with a given { name in a particular scope. The Routine Begin DSTs each contain an { invented name for the function (in the example, 'h__1', 'h__2', { 'h__3'). The invented names are meant to give the debugger a set of { unique names within the particular scope, while the Overloaded Symbol { DST tells the debugger what the real name is. The C++ compiler is { currently inventing names of the form: real-name__N, where N is { 1,2,3,... This is a good choice. { { The debugger does not need or want to be told about mangled names. { { Type signature stringes are encoded in order to reduce DST size. The name { of the class of the member function is encoded as '@'. The function name { is encoded as '#'. In general, there can be any number of @'s and #'s in { the type signature string. { AGGREGATE DST$TYPE_SIG STRUCTURE TYPEDEF; dst$a_type_sig_header DST$HEADER; dst$b_type_sig_flags STRUCTURE; dst$v_type_sig_unused BITFIELD LENGTH 8; { must be zero END dst$b_type_sig_flags; dst$b_type_sig_string BYTE UNSIGNED; { count byte for the ASCIC name #dst$type_sig_header_size = :; END; CONSTANT DST$K_TYPE_SIG_SIZE EQUALS #dst$type_sig_header_size; { Byte size of the fixed part of the { Type Signature DST record { C++ Attribute DSTs { { There are a number of C++ attributes that need to be represented in the { DSTs and, for many of them, there's no convenient place in existing DST { records to put them. { { The C++ Attribute DST is interpreted as belonging with the symbol whosed { DST record immediately follows the C++ Attribute DST record. { { When using the C++ Attribute DST for a particular symbol, set those { bits that apply. Other bits are assumed to either be the default { setting (e.g., non-static) or to not apply. { { Use the C++ Attribute DST as follows. { { Record Begin: class, struct, union, or namespace (default is class) { { Data member: static or non-static (default is non-static) { { Member function: static or non-static (default is non-static) { { AGGREGATE DST$CXX_ATTRIBUTES STRUCTURE TYPEDEF; dst$w_cxxa_header DST$HEADER; dst$w_cxxa_flags STRUCTURE; dst$v_cxxa_unused1 BITFIELD LENGTH 1; { must be zero dst$v_cxxa_unused2 BITFIELD LENGTH 1; { must be zero dst$v_cxxa_unused3 BITFIELD LENGTH 1; { must be zero dst$v_cxxa_namespace BITFIELD LENGTH 1; { is a namespace dst$v_cxxa_struct BITFIELD LENGTH 1; { is a struct dst$v_cxxa_union BITFIELD LENGTH 1; { is a class dst$v_cxxa_static BITFIELD LENGTH 1; { member is static dst$v_cxxa_unused BITFIELD LENGTH 9; { must be zero END dst$w_cxxa_flags; #dst$cxxa_size = :; END; CONSTANT DST$K_CXX_ATTRIBUTES_SIZE EQUALS #dst$cxxa_size; { Template Declaration DSTs { { Template declarations are described via Template Declaration DSTs. They { tell the debugger that a template with a particular name was declared at a { particular point (scope). This allows the debugger to correctly interpret { template generated names as entered by the user into the debugger command { line. Template instances are represented, in the usual way, having normal { C++ template names, such as "Array". (In this example, the compiler { would generate a Template Declaration DST for "Array".) Note that there is { no explicit connection in the DSTs between a Template Declaration DST and { other DSTs describing the symbols generated from that template. { AGGREGATE DST$TEMP_DECL STRUCTURE TYPEDEF; dst$w_temp_decl_header DST$HEADER; dst$b_temp_decl_name BYTE UNSIGNED; { The count byte for the Counted { ASCII Template Name #dst$temp_decl_size = :; END; CONSTANT DST$K_TEMP_DECL_SIZE EQUALS #dst$temp_decl_size; { Namespace Support -- Using DSTs { { Namepaces will be represented in the DSTs very much like classes { are: using Record Begin and Record End DSTs, with namespace member { declarations/definitions occurring between the Record Begin and { Record End DSTs. A namespace { Record Begin DST will be preceded by a C++ Attributes DST with the { namespace attribute set. { { The compiler will coalesce all extensions of a namespace with the { original namespace definition, and describe the namespace in the DSTs { as a single namespace definition (via a single Record Begin-End { construct). { { Unnamed namespaces will be described via a Record Begin DST with a null { name field. Unnamed namespaces are defined such that they have an { implicit using directive. In the DSTs, the compiler will make that { using directive explicit so that the debugger will not have to treat { unnamed namespaces as a special case. { { As is done with class members, when a namespace member is separated into { distinct declaration and definition parts, the compiler will describe the { member in the DST as if there is was a single definition. For example, { the compiler will describe the following { { namespace A { void f(); } { void A::f() { ... } { { as { { namespace A { void f() { ... } } { { A namespace alias definition is described via an Alias DST with a null { module name field, indicating the current module. { { When there are multiple definitions of a given namespace alias within a { particular declarative region, the compiler should coalesce them { generating a single Alias DST for that namespace alias in that scope. { { { Using DST { ========= { { Using DSTs will be used to describe both using declarations and using { directives. { { A using declaration is describing via a Using DST which points at the used { member. The Using DST must appear in the correct DST context { corresponding to the scope of the using declaration in the program being { described. { { A single using declaration matching multiple symbols is described in { the DSTs via multiple Using DSTs, one for each symbol matched. { { When a using declaration brings names from a base class into a derived { class scope, member functions in the derived class override and/or hide { member functions with the same name and parameter types in the base { class (rather than conflicting). [7.3.3-13] Such hidden base class { member functions should not be described by Using DSTs. { { A using directive is describing via a Using DST which points at the { used namespace definition. The Using DST must appear in the correct { DST context corresponding to the scope of the using directive in the { program being described. { AGGREGATE DST$USING STRUCTURE TYPEDEF; dst$w_using_header DST$HEADER; dst$l_using_dst LONGWORD UNSIGNED; { DST offset of the used namespace or { namespace member. This is an offset to { another DST record, relative to the start { of the whole DST. #dst$using_size = :; END; CONSTANT DST$K_USING_SIZE EQUALS #dst$using_size; { O B S O L E T E D S T R E C O R D S { { { There are several obsolete DST records. These are records that were { at one time generated by compilers, but are no longer used by any cur- { rent version of any Digital compiler. Some of these records were not { properly thought out and were abandoned when it was realized that their { intended uses could not be implemented. Others were at one time used { and useful, but were generated by now-obsolete compilers. Such records { are not generated by current compiler versions, and the capabilities { they provided are now provided by more general mechanisms in other DST { records. { { None of the obsolete DST records should be generated by any future { compilers, and their use will not necessarily be supported by DEBUG. { { { THE GLOBAL-IS-NEXT DST RECORD { { The Global-is-Next DST record is now obsolete. It consisted of just the { DST$W_LENGTH byte and the DST$W_TYPE byte. DST$K_GLOBNXT was the type { code. The purpose of this record was never properly thought out and { no support for it was ever implemented. It should not be generated by { any future compilers or compiler versions. { { { THE EXTERNAL-IS-NEXT DST RECORD { { The External-is-Next DST record is now obsolete. It consisted of just { the DST$W_LENGTH byte and the DST$W_TYPE byte. DST$K_EXTRNXT was the { type code. The purpose of this record was never properly thought out { and no support for it was ever implemented. It should not be generated { by any future compilers or compiler versions. { { { THE THREADED-CODE PC-CORRELATION DST RECORD { { This DST record is identical in format to the Line Number PC-Correlation { DST record except that the record type code is DST$K_LINE_NUM_REL_R11. { It was used by an obsolete COBOL compiler according to legend (the memo- { ries are a bit hazy by now). The idea was that the threaded code gene- { rated by this compiler consisted of a vector of longwords where each { longword contained the address of a run-time support routine to call. { Register R11 pointed to the beginning of this vector. The code gene- { rated for a source line thus consisted of some number of longwords { with addresses to call (or perhaps jump to--the exact details are lost { in the mists of time). The line number PC-correlation information { passed to DEBUG consisted of line numbers correlated with byte-offsets { relative to R11 (i.e., to the start of the threaded code). Breakpoints { were placed on a specified line by looking up the corresponding offset { relative to R11 and then storing an address within DEBUG into that { location. When the location was reached, DEBUG was entered. DEBUG { could then convert the "PC", i.e. the threaded-code location, back to { a line number to announce the breakpoint. It is not clear how, or even { whether, tracing, stepping, and watchpoints were implemented. { { The Threaded-Code PC-Correlation DST record is no longer supported by { DEBUG and should not be generated by any current or future compilers. { { { THE COBOL HACK DST RECORD { { The COBOL Hack DST record was at one time used to support formal argu- { ments to COBOL procedures. It has now been superceded by the more { general Value Specification mechanism, and is thus obsolete. It is { no longer generated by the COBOL compiler, and it should not be gene- { rated by any current or future compilers. Future versions of DEBUG { may not support it. { { The fields of this record consist of the fields of the Standard Data { DST record followed by a type field that specifies the data type and { then a sequence of commands for the DEBUG stack machine. (See the sec- { tion on Value Specifications for details on the DEBUG stack machine.) { The result of interpreting the stack machine routine is the address of { the object described by this record. The DST$B_VFLAGS and DST$L_VALUE { fields are zero unless the object has a descriptor. In this latter { case they specify the location of the descriptor. The result of the { stack machine routine is placed in the DSC$A_POINTER field of the { descriptor before it is used. In addition, if it is an array descrip- { tor, the DSC$A_A0 field is added to the result of the stack machine { routine and the result is placed in the DSC$A_A0 field before the { descriptor is used. { { The type field following the name field contains the VAX Standard Type { Code of the object being described here. If the object also has a { descriptor, its DSC$B_DTYPE field must agree with this code. { { The stack machine commands used in this context are those described { in the section entitled "The DEBUG Stack Machine" in the chapter on { DST Value Specifications. { { This is the format of the COBOL Hack DST record: { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (=DST$K_COB_HACK) | { +---------------------------------------------------------------+ { byte | DST$B_VFLAGS | { +---------------------------------------------------------------+ { long | DST$L_VALUE | { +---------------------------------------------------------------+ { byte | DST$B_NAME | { +---------------------------------------------------------------+ { var | | { | The Name of the Data Symbol in ASCII | { | | { | (The name's length is given by DST$B_NAME) | { | | { | | { +---------------------------------------------------------------+ { byte | DST$B_CH_TYPE | { +---------------------------------------------------------------+ { var | DST$A_CH_STKRTN_ADDR | { | | { | Instruction Sequence for the DEBUG Stack Machine | { | | { | | { | | { +---------------------------------------------------------------+ { { { Define the fields of the Cobol Hack DST record. Also define the declaration { macro for the trailer fields. { AGGREGATE DST$COB_HACK STRUCTURE TYPEDEF; dst$a_cobhack_fields DST$DATA_DST; #dst$cobhack_header_size = :; END; { DST$COB_HACK definition CONSTANT DST$K_COB_HACK_SIZE EQUALS #dst$cobhack_header_size; { Byte size of the fixed part of the { COBOL Hack DST record { { Definition of the offset to the trailer fields in the COBOL Hack DST { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_cobhack_trlr = DST$K_COB_HACK_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { { Define the COBOL Hack DST trailer fields structure { AGGREGATE DST$CH_TRLR STRUCTURE TYPEDEF; dst$b_ch_type BYTE UNSIGNED; { VAX standard data type #dst$cobhack_trailer_size = :; END; { DST$CH_TRLR definition CONSTANT DST$K_CH_TRLR_SIZE EQUALS #dst$cobhack_trailer_size; { Byte size of the fixed part of the { COBOL Hack DST trailer record { { Define the offset for the start of stack routine code in the { COBOL Hack trailer record { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_ch_stkrtn_addr = DST$K_CH_TRLR_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { VALUE SPECIFICATION DST RECORDS { { { The Value Specification DST record contains nothing but a DST Value { Specification. However, there appears to be no use for this record { since all DST Value Specifications that are actually used appear in { other DST records. This record was probably designed with some use { in mind, but was then abandoned when better ways of addressing the { original need were devised. DEBUG ignores this DST record, and it { is believed that no compilers actually generate it. This DST record { should not be generated by any future compilers. { { This is the format of the Value Specification DST record: { { { { +---------------------------------------------------------------+ { word | DST$W_LENGTH | { +---------------------------------------------------------------+ { word | DST$W_TYPE (= DST$K_VALSPEC) | { +---------------------------------------------------------------+ { var | | { | A DST Value Specification | { | | { | | { +---------------------------------------------------------------+ { { { { Define the fields of the Value Specification DST record. { AGGREGATE DST$VALSPEC STRUCTURE TYPEDEF; dst$a_valspec_header DST$HEADER; #dst$valspec_header_size = :; END; { DST$VALSPEC definition CONSTANT DST$K_VALSPEC_SIZE EQUALS #dst$valspec_header_size; { Byte size of the fixed part of the { Valspec DST record { { Define the offset for the start location of the Value Specification { IFLANGUAGE BLISSF; LITERAL; MACRO dst$a_vs_valspec_addr = DST$K_VALSPEC_SIZE, 0, 0, 0%; END_LITERAL; END_IFLANGUAGE BLISSF; { D S T R E C O R D D E C L A R A T I O N M A C R O { { { { This macro allows BLISS symbols which are declared DST$RECORD or { REF DST$RECORD to be qualified by all the field names present in { the various DST record formats. It is anticipated that users will { declare separate symbols for field sets which describe trailing { fields in DST records; a pointer to the PSECT DST record trailer, { for example, would be declared to be a REF DST$PSECT_TRAILER. { Separate macros are supplied above for all such trailer fields. { { Define the declaration macro for all DST records. { IFLANGUAGE BLISSF; LITERAL; MACRO DST$RECORD = BLOCK [256,BYTE] FIELD ( DST$HEADER_FIELDSET, ! ! The rest of these are defined in alphabetic order, for easy lookup ! DST$ALIAS_FIELDSET, DST$BASE_CLASS_FIELDSET, DST$BLI_FIELDS_FIELDSET, DST$BLISS_FIELD_FIELDSET, DST$BLISS_FIELD_BEGIN_FIELDSET, DST$BLOCK_BEGIN_FIELDSET, DST$BLOCK_END_FIELDSET, DST$BODY_SPEC_FIELDSET, DST$CONTINUATION_FIELDSET, DST$CXX_ATTRIBUTES_FIELDSET, DST$DATA_HEADER_FIELDSET, DST$DATA_DST_FIELDSET, DST$DEF_LNUM_FIELDSET, DST$DESCRIPTOR_FORMAT_FIELDSET, DST$DIS_RANGES_FIELDSET, DST$ENTRY_FIELDSET, DST$ENUM_BEGIN_FIELDSET, DST$EPILOG_FIELDSET, DST$EXCEPTION_FIELDSET, DST$FULFILLS_TYPE_FIELDSET, DST$GOTO_FIELDSET, DST$INLINE_FIELDSET, DST$LINE_NUM_HEADER_FIELDSET, DST$MODULE_BEGIN_FIELDSET, DST$OVERLOAD_HEADER_FIELDSET, DST$PACKAGE_BODY_BEGIN_FIELDSET, DST$PACKAGE_BODY_END_FIELDSET, DST$PACKAGE_SPEC_BEGIN_FIELDSET, DST$PACKAGE_SPEC_END_FIELDSET, DST$PCLOC_COMMANDS_FIELDSET, DST$PROLOG_FIELDSET, DST$PROLIST_FIELDSET, DST$PSECT_FIELDSET, DST$REAL_NAME_FIELDSET, DST$REG_SAVE_BEGIN_FIELDSET, DST$REGISTER_SAVE_FIELDSET, DST$REGISTER_SAVE_END_FIELDSET, DST$RETURN_FIELDSET, DST$ROUTINE_BEGIN_FIELDSET, DST$ROUTINE_END_FIELDSET, DST$ROUTINE_UNALLOC_FIELDSET, DST$SET_MODULE_FIELDSET, DST$SOURCE_CORR_FIELDSET, DST$STATLINK_FIELDSET, DST$SUBUNIT_FIELDSET, DST$TEMP_DECL_FIELDSET, DST$TRAILING_VALSPEC_FIELDSET, DST$TYPE_SIG_FIELDSET, DST$XVS_SPEC_FIELDSET, DST$TYPE_SPEC_FIELDSET, DST$TYPSPEC_FIELDSET, DST$USE_CLAUSE_FIELDSET, DST$USING_FIELDSET, DST$VARIANT_VALUE_FIELDSET, DST$VERSION_FIELDSET, DST$VIRT_FUNC_FIELDSET, ! ! The following are obsolete ! DST$CH_TRLR_FIELDSET, DST$COB_HACK_FIELDSET, DST$VALSPEC_FIELDSET) %; END_LITERAL; END_IFLANGUAGE BLISSF; { { Close the #ifndef bracket { IFLANGUAGE CC; LITERAL; #endif /* DSTRECRDS_H */ END_LITERAL; END_IFLANGUAGE CC; { { END OF ALPHA_DSTRECRDS.SDL. { END_MODULE ALPHA_DSTRECRDS;