DISM-32 Native Mode Disassembler, V4.0 DISM32 is a program that runs on VAX/VMS systems and has the function of converting executable, shareable, and system images created by the VAX/VMS Linker back into MACRO-32 source files. It can be run with the DCL RUN command or defined as a foreign command: $ DIS*M32 :== $dev:[dir]DISM32 and invoked with a parameter. The one parameter (which will be prompted for if forgotten) is the file specification of the image file to disassemble (default filespec is defdev:[defdir].EXE). The disassembler will attempt to open the image file, determine the image type, and convert it into a MACRO source file located in the current default directory with the same file name as the image file and a filetype of .MAR. The disassembler may also create auxiliary output files in the current directory. The disassembler will only work on native mode images (no compatibility mode), but will handle normal executables, shareable images, executable files containing device driver images, and images linked /SYSTEM. The disassembler generates symbolic output, filling in labels and procedure names for its symbol table from: 1) the VMS system symbol table file SYS$SYSTEM:SYS.STB, 2) the Run-Time Library entry definition modules SYS$P1_VECTORS and RMS$GLOBALS, 3) the Debug Symbol Table (DST) and Global Symbol Table (GST) of the image file, 4) the GST's of any shareable images the image is linked to, 5) a user-defined symbol table file in disassembler internal form, and, finally, if no other definitions occur, 6) it makes them up from the data/code type and address of the label. The disassembler determines how to process the labels it discovers on pass 1 by how they are referenced, i.e. if a label is referenced as the address of a F_floating variable, it will be tagged as being F_floating type. On pass 2, the disassembler uses the most important type for each symbol in determining how to process image data following the symbol. Symbol types recognized, along with their bit-mask values for the .SYM file the disassembler outputs, are, in order of importance: 00000001 CALLS/CALLG procedure entry mask 00000002 JSB/BSBB/BSBW subroutine entry 00000004 JMP label 08000000 device driver FDT entry 04000000 device driver reinitialization table 02000000 device driver initialization table 01000000 device driver DDT 00800000 device driver DPT 00400000 FORTRAN precompiled FORMAT statement* 00200000 RMS control blocks (FAB, RAB, etc.)* 00100000 shareable image transfer vectors 00080000 extended data attributes, see explanation below 00040000 00020000 octaword 00010000 EDITPC instruction pattern 00008000 table (MOVTC, SPANC, CRC, etc. instructions) 00004000 trailing numeric string 00002000 leading separate string 00001000 packed decimal (BCD) string 00000800 ASCII character string 00000400 H_floating value 00000200 G_floating 00000100 D_floating 00000080 F_floating 00000040 quadword (also descriptors) 00000020 longword (also address pointers) 00000010 word 00000008 byte Some of these are not completely supported yet; the disassembler is still growing as need requires its functions to increase. The types marked with (*) are never recognized automatically by the disassembler, but must be specified by the user via an input .SYM file (see below). If the extended data attributes bit is specified in the symbol table type mask, it indicates that the data type is of a complex type that couldn't fit in the normal type mask because it required additional context (and also we ran out of bits in the type mask). The additional context consists of an extended attribute number, indicating the data type, and a value associated with the attribute. The attributes currently supported and the meaning of the related values are as follows: 1 LIB$TPARSE state table (value is address of keyword table) 2 LIB$TPARSE keyword table (value is address of state table) 3 LIB$TPARSE state table entry (value is address of keyword table) 4 SYS$GETDVI item list (value is not used) 5 SYS$GETJPI item list (value is not used) 6 SYS$GETQUI item list (value is not used) 7 SYS$GETSYI item list (value is not used) 8 SYS$SNDJBC item list (value is not used) 9 SYS$CHANGE_ACL item list (value is not used) 10 SYS$CHKPRO, SYS$CHECK_ACCESS item list (value is not used) 11 SYS$CRELNM, SYS$TRNLNM item list (value is not used) 12 SYS$CREPRC quota list (value is not used) 13 SYS$FILESCAN item list (value is not used) 14 SYS$GETLKI item list (value is not used) 15 SYS$GETUAI, SYS$SETUAI item list (value is not used) 16 SYS$MOUNT item list (value is not used) The auxiliary output files the disassembler generates in the current default directory are: 1) filespec.SYM - the final version of the symbol table the disassembler uses. format is (in FORTRAN) FORMAT(Z8,X,Z8,X,I4,X,Z8,X,A), one symbol entry per line, where the first Z8 field is the hexadecimal value of the symbol, the second Z8 field is the hexadecimal bit-mask of all standard data types (see table above) the symbol is used with, the I4 field is the extended attribute number, the last Z8 field is the extended attribute associated value, and the A field is the symbol name (up to 31 characters). 2) filespec.DST - the Debug Symbol Table dump, only for images that have a DST. This is an ASCII text file narrating the contents of the DST. 3) filespec.MOD_LIN - the module/line number accounting of the image, only for images with a DST. This is an ASCII text file describing the module and line number structure of the image. 4) filespec.GST - a copy of a shareable image's global symbol table, in standard VAX/VMS Linker binary .STB file format. Only created if file being disassembled is a shareable image with a GST. The disassembler looks for a .SYM file in the current directory before it begins processing the image file. This file is in exactly the same format as the output .SYM file, and it is used to preload the symbol table with values, types, and names; generally, this is good for forcing a meaningful symbol name when an image does not have a DST to define the symbol, or for changing the type of a symbol (for example, a procedure is referenced by a PUSHAB in a CALLS argument list and is therefore treated as BYTE type instead of PROCEDURE type). If an old .SYM file does not exist, the disassembler ignores the condition and goes on without one. The disassembler then looks at the image transfer vectors and the DST and uses those to preload the symbol table. During pass 1, any code-type symbols (PROCEDURE, SUBROUTINE, or JUMP) are used as points to start disassembling code from in the hopes of finding more labels. This repeats until the disassembler can't find any executable symbols it hasn't already started disassembling from. Thus ends pass 1. In the symbol table analysis phase, the symbol table and line number table are sorted into ascending address order, and attempts to find names for symbols begins, in the order described earlier. Also, data structures that might contain pointers to other data structures (or even code) are analyzed to add the additional entries to the symbol table; if new code symbols are found, pass 1 is rerun to analyze the new symbols. In pass 2, the disassembler just runs from beginning to end of the image, changing processing types as it reaches a new symbol table entry with a different most-important type. For device driver images, the disassembler recognizes them because they are executable (as opposed to shareable), have no transfer addresses, and the first few bytes of them look like a Driver Prologue Table (DPT), as checked by the DPT$B_TYPE and DPT$W_SIZE fields. The disassembler will announce when it is assuming that an image is a device driver, and will then process all data found in the driver's DPT, initialization tables, DDT, and FDT in an attempt to initially build the symbol table. For compatibility mode images, the disassembler recognizes that the image header type specifies TKB instead of LINK-32 and rejects the image. For other strange but native-mode image types (CLI, BPA, etc.) the disassembler accepts them but displays a warning message. For system images, the disassembler recognizes them because the image header type word is no value known to VAX/VMS. The disassembler gives the user the option of quitting or treating the image as a system image. If a system image, the user must enter the base address in hexadecimal when prompted. Note that, since a system image has no mechanism for locating any initial symbols, a .SYM input file is generally required to disassemble a system image into something other than a stream of longwords. For normal executables and shareables linked on version V3 or earlier of VAX/VMS, the disassembler will attempt to open a V3 copy of VMSRTL to resolve shareable image references if such occur. A file called VMSRTL_V3.EXE is expected to be in the same directory as DISM32.EXE (not necessarily the current default) and will be used to resolve such references; this file is a renamed copy of the VMSRTL.EXE file found in SYS$LIBRARY on a V3 system. The disassembler works best when processing code that follows the normal rules of civilized programming, as defined by DEC. However, a fair amount of DEC (and third party) code does not follow the rules that DEC gave to everyone else, so some images may break the disassembler or require careful manipulation of the .SYM file to get meaningful output. Also note that for device driver images for a different major version of VAX/VMS than the one the disassembler is running under (which is supplying SYS$SYSTEM:SYS.STB to the disassembler), the references to the I/O executive probably won't disassemble properly in regards to I/O executive entry point symbols.