Linker Overview Linker Overview - The primary purpose of a linker is to produce an file which can be executed by an operating system. - In DOS, executable files come in three flavors: "EXE" files "COM" files "SYS" files - The input to the linker comes from module(s) called translator modules. - Individual translator modules can be stored in "OBJ" files. "OBJ" files are produce by language translators such as assemblers and compilers. - Libraries of translator modules can be stored in "LIB" files which are produced by a librarian from either "OBJ" files or other "LIB" files. - A linker can process translator modules from either "OBJ" or "LIB" files, but at least one module must have come from an "OBJ" file. - All translator modules from "OBJ" files will be included in the executable file, but only modules which resolve externals come from "LIB" files. Comparison of Executable Files - "EXE" files have a header which contains relocation and other information which permit "EXE" files to have multiple segments. This header sets "EXE" files apart from the other executable file types. Programs are written starting at address 0 (relative to where the program is loaded in memory). - "COM" files have no header. "COM" files are written starting a address 100H because the "COM" file is loaded immediately after the program segment prefix (PSP) which is 100H bytes long. At the start of the program, the CS and DS segment registers point to the PSP. "EXE" files which have an empty relocation table can be converted to "COM" files by the "EXE2BIN" program. - "SYS" files are more closely related to "COM" files than "EXE" files. "SYS" files are loaded once at DOS initialization time. Since there is no PSP, the programs are written starting at address 0. However, like "COM" files, "SYS" files must have an empty relocation table. Contents of Executable Files "EXE" files "SYS" files 旼컴컴컴컴컴컴컴컴커 旼컴컴컴컴컴� � "EXE" header � 쿹oad module쳐커 쳐컴컴컴컴컴컴컴컴캑 읕컴컴컴컴컴� � � relocation table � � 쳐컴컴컴컴컴컴컴컴캑 旼컴컴� � � load module 쳐컴컴컴컴컴컴컴컴컴캑org 0쳐컴컴컴컴컴컴컴컴컴켸 읕컴컴컴컴컴컴컴컴켸 읕컴컴� "COM" files 旼컴컴컴컴컴� 旼컴컴컴커 쿹oad module쳐컴컴컴컴컴컴컴컴큢rg 100H� 읕컴컴컴컴컴� 읕컴컴컴켸 - Each of the above contents are described in detail in the following slides. "EXE" File Header 旼컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿚ffset� Description � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �00-01 � The "EXE" file signature 4D5AH. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �02-03 � Length of the "EXE" file modulo 512. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �04-05 � Number of 512-byte pages. If the last page is not full it is � � � still included in the count. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �06-07 � Number of relocation items. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �08-09 � Num of 16-byte paras occupied by "EXE" header and relo table. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �0A-0B � Number of paragraphs required immediately after load module. � � � The linker computes the number of uninitialized bytes at the � � � end of the load module. Instead of writing these bytes to � � � the "EXE" file, the linker sets this value to provide space � � � for this data. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �0C-0D � Max number of paras which may be required immediately after � � � the "EXE" file. This value comes from the CPARMAXALLOC switch.� 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �0E-11 � Offset/Segment displacement into the load module of initial � � � SP/SS/. The displacement is converted to an actual address by � � � adding the base address of the load module. Since there may � � � be several stack segments in the translator modules, the � � � linker uses the highest address of the largest segment with � � � the stack attribute. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �12-13 � Word checksum computed as minus the sum of all the words in � � � the file. Overflows are ignored. DOS will not validate the � � � checksum if this value is set to zero � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �14-17 � Offset/Segment displacement into the load module of the � � � initial IP/CS. The displacement is converted to an actual � � � address by adding the base address of the load module. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �18-19 � Lgh of "EXE" file header. (Used to find start of relo table.) � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �1A-1B � Overlay number. This is zero for the main program. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �1C-1D � Always 0001H. � 읕컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 Note: "EXE" file header routines are in "EXECFILE.C" (handout page 9) Relocation Table The number of relocation items is specified at offset 06-07 in the "EXE" file header. The offset of the relocation table is located at offset 18-19 in the "EXE" file header. Usually this value is 001EH, but can be larger if the "EXE" file header has been extended. The relocation table can be viewed as an array of Offset/Segment displacements into the load module. For each address, the segment portion of the base address of the load module is added to the word at that displacement. The only time a relocation item is needed is when a fixup involves a segment. As we will see later, this can only be caused by base and pointer type fixups. As an example of a how a relocation item is generated, consider the following: foo db 'a' bar dd foo Note that the contents of "bar" is the address of "foo", but the actual address of "foo" is not known until the program is loaded in memory. All that is known at link time is how far (i.e., the displacement) into the load module "foo" and "bar" are located. Only the displacement of "foo" is stored at link time. But, the linker makes a relocation entry showing that "bar"+2 must be relocated. Load Module By far, the generation of the load module is the trickest part of producing an executable file. The contents of the load module is generated from the contents of translator modules stored in "OBJ" and "LIB" files. Much of the structure of translator modules comes from the assembler directives. In turn, those directives are related to the architecture of the 80x86 family of micros. Here are some of the important directives: SEGMENT/ENDS is used to give a logical name along with grouping and combining information for the segments. The linker is responsible for arranging and combining these logical segments into the physical segments which comprise a load module. EXTRN/PUBLIC is used access data across translator modules. A detailed description of the format of translator modules follows. Terminology and Abbreviations MAS - Memory Address Space: The memory capable of being addressed by the hardware architecture. T-MODULE - Translator Module: This is a unit of object code produced by a language translator. They may be stored individually in "OBJ" files or collections may be stored in "LIB" files. FRAME: A contiguous 64K chunk of MAS. FRAME NUMBER: Paragraph number where a FRAME begins. CANONIC FRAME: For the 8086, each byte of memory is encompassed by up to 4096 FRAMEs. The CANONIC FRAME frame is lowest FRAME NUMBER which encompasses that byte. LSEG - Logical Segment: Data and code between SEGMENT - ENDS directives. PSEG - Physical Segment: A collection of one or more LSEGs placed into a load module. Fixup Overview Not all references to MAS can be resolved at translation time. This can happen when one T-MODULE must access data located in another T-MODULE. When this happens, the language translator places an entry in the T-MODULE so that the linker can complete the address reference. Such entries in a T-MODULE are called "Fixups". In order for the linker to complete the address reference, it needs five pieces of information: The LOCATION in memory where the reference occurs. This is the address which must be fixed up. The type of LOCATION in memory where the reference occurs. Whether the fixup is relative to the IP or not. This is refered to as the fixup MODE. The TARGET address which LOCATION is referencing. The FRAME number in the segment register used to reference the TARGET address. LOCATION Types There are five types of LOCATIONs. They are POINTER, BASE, OFFSET, HIBYTE, and LOBYTE. The relative position and length of each LOCATION type from a LOCATION, X is given below: 旼컴컴컴컴컫컴컴컴컴컴쩡컴컴컴컴컫컴컴컴컴컴� � X+0 � X+1 � X+2 � X+3 � 읕컴컴컴컴컨컴컴컴컴컴좔컴컴컴컴컨컴컴컴컴컴� 쳐횸OBYTE컴� 쳐횴IBYTE컴� 쳐컴컴컴OFFSET컴컴컴컴� 쳐컴컴컴횭ASE컴컴컴컴캑 쳐컴컴컴컴컴컴컴컴횾OINTER컴컴컴컴컴컴컴컴컴� Fixup Modes There are two fixup modes. Both modes stem from the architecture of the 80x86 microprocessor family. The TARGET may be addressed directly via the offset/segment mechanism. This fixup mode is called "segment-relative". The other manner a TARGET may be addressed is relative to the IP. For example, the TARGET of the 80x86 jump instructions (e.g., JE, JC, JA, etc) are all relative to the IP. This fixup mode is called "self-relative". Note that the self-relative mode is relative to the value of the IP when the instruction executes. In all cases, the IP points to the first byte of the instruction following the one being executed. TARGET The TARGET is the location in MAS being referenced by LOCATION. There are four basic ways of specifying the TARGET. The four methods of specifying a TARGET are: TARGET is specified relative to an LSEG. TARGET is specified relative to a group. TARGET is specified relative to an external symbol. TARGET is specified relative to an absolute FRAME. The four primary methods specify a displacement while the four secondary methods do not specify a displacement (because the displacement is 0). Primary TARGET Methods 旼컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿘ethod� Notation � Description � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � T0 쿞I(segment),displacement 쿟he TARGET is at the specified � � � 쿭isplacement in the LSEG segment. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � T1 쿒I(group),displacement 쿟he TARGET is at the specified � � � 쿭isplacement in the group. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � T2 쿐I(external),displacement쿟he TARGET is at the specified � � � 쿭isplacement past the external. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � T3 쿑R(frame),displacement 쿟he TARGET is at the specified � � � 쿭isplacement past FRAME NUMBER frame.� 읕컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 Example: SI(foo),4 means the TARGET is 4 bytes into the LSEG foo. Several T-MODULES could have an LSEG named foo which may be combined into a PSEG foo. So, the final displacement in the PSEG foo may not be 4. The linker must take this into consideration. Secondary TARGET Methods 旼컴컴컫컴컴컴컴컴컴쩡컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿘ethod� Notation � Description � 쳐컴컴컵컴컴컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� � T4 쿞I(segment) 쿟he TARGET is the base of the LSEG segment. � 쳐컴컴컵컴컴컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� � T5 쿒I(group) 쿟he TARGET is the base of the group. � 쳐컴컴컵컴컴컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� � T6 쿐I(external)쿟he TARGET is the specified external. � 쳐컴컴컵컴컴컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� � T7 쿑R(frame) 쿟he TARGET is the specified frame. � 읕컴컴컨컴컴컴컴컴컴좔컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� FRAME The FRAME portion of a fixup specifies the FRAME NUMBER that will be used as the frame of reference for LOCATION's reference to TARGET. Typically, this frame of reference is one of the segment registers. The FRAME NUMBER in the segment register is specified via the assembler "ASSUME" directive. Even if the fixup is self-relative, the TARGET must still be in the FRAME given by the FRAME NUMBER in the segment register. So, a FRAME is required for both segment-relative fixups and self-relative fixups. There are seven methods of specifying a FRAME: A segment A group An external An absolute FRAME NUMBER LOCATION's FRAME TARGET's FRAME No FRAME specified FRAME Methods 旼컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿘ethod� Description � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F0 쿟he FRAME for the fixup is the CANONIC FRAME of the PSEG � � 쿬ontaining the LSEG. (Since the fixup is generated at � � 퀃ranslation time, an LSEG is specified.) � � 쿙otation: EI(segment) � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F1 쿟he FRAME for the fixup is the CANONIC FRAME of the PSEG � � 쿹ocated lowes in MAS. A group is specified. � � 쿙otation: GI(group) � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F2 쿟he FRAME for the fixup is specified by an external. � � 쿟ypically, the external is located in a T-MODULE different � � 쿯rom the T-MODULE generating the fixup. � � 쿙otation: EI(external) � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F3 쿟he absolute FRAME number is specified. � � 쿙otation: FR(FRAME) � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F4 쿟he FRAME is the CANONIC FRAME of the PSEG containing LOCATION.� � 쿙otation: LOCATION � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F5 쿟he FRAME is determined by the TARGET. Notation: TARGET � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F6 쿙o frame of reference specified. Notation: NONE � 읕컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 FRAME Method F2 cases When FRAME method F2 is specified (FRAME is specified by an external), there are three cases depending on how the external is defined: 旼컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿘ethod� Description � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F2a 쿔f the external is defined relative to an LSEG which is not in � � 쿪 group then the FRAME is the CANONIC FRAME of the PSEG � � 쿬ontaining the LSEG. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F2b 쿔f the external is defined absolutely and not in a group, then � � 퀃he FRAME is the CANONIC FRAME of the external. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캐 � F2c 쿔f the external is associated with a group, the FRAME is the � � 쿎ANONIC FRAME of the PSEG in the group with the lowest MAS. � 읕컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 FRAME Method F5 cases When FRAME method F2 is specified (FRAME is specified by the TARGET), there are four cases depending on how the TARGET was specified: 旼컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿘ethod� Description � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F5a 쿔f the TARGET method is T0 or T4, then FRAME is the CANONIC � � 쿑RAME of PSEG containing TARGET. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F5b 쿔f the TARGET method is T1 or T5, then FRAME is the CANONIC � � 쿑RAME of PSEG in the same group as TARGET and with the lowest � � 쿘AS. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F5c 쿔f the TARGET method is T2 or T6, then the FRAME is determined � � 쿫y the rules given in FRAME method F2. � 쳐컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � F5d 쿔f the TARGET method is T3 or T7, then the FRAME is the FRAME � � 쿙UMBER specified by the TARGET. � 읕컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 Performing a Fixup Regardless of the fixup mode (segment-relative or self-relative), the first step in performing a fixup is to insure that the TARGET is addressable given the FRAME of reference. That is, the TARGET must lie between FRAME and FRAME+65535 inclusive. FRAME � TARGET � FRAME+65535 If this is not the case, a warning is given. After verifying that TARGET can be addressed by FRAME, how a fixup is performed depends of the FIXUP mode. Self-Relative Fixups Self-relative fixups are permitted for LOBYTE and OFFSET type LOCATIONs only. If the LOCATION type is HIBYTE, BASE, or POINTER, no fixup is performed and an error message is given. For self-relative fixups, the value of the PC (CS:IP) when the instruction is executed must be determined. Then, the DISTANCE to the TARGET from the PC is computed. The formulae for DISTANCE and PC are given below: PC = LOCATION + 1 (If LOCATION type is LOBYTE) PC = LOCATION + 2 (If LOCATION type is OFFSET) DISTANCE = TARGET - PC For LOBYTE locations, an error is issued when DISTANCE falls outside of -128 � DISTANCE � 127. The fixup is performed by adding DISTANCE to LOCATION. For LOBYTE LOCATIONs, DISTANCE is added modulo 256. For OFFSET LOCATIONs, DISTANCE is added modulo 65536. Segment-Relative Fixups For segment-relative fixups, DISTANCE = TARGET - FRAME. If DISTANCE falls outside of 0 � DISTANCE � 65535, a warning is issued. The following table gives how to perform the fixup depending on LOCATION type: 旼컴컴컴컫컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿗OCATION� Action � � type � � 쳐컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 쿗OBYTE 쿏ISTANCE is added (modulo 256) to low order byte at LOCATION.� 쳐컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 쿓IBYTE 쿏ISTANCE is added (modulo 256) to high order byte at LOCATION� 쳐컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 쿚FFSET 쿏ISTANCE is added (modulo 65536) to the word at LOCATION. � 쳐컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 쿍ASE 쿑RAME is added (modulo 65536) to the word at LOCATION. � 쳐컴컴컴컵컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캐 쿛OINTER 쿏ISTANCE is added (modulo 65536) low order word at LOCATION. � � 쿌 relocation item for the word at LOCATION is created. � � 쿑RAME is added (modulo 65536) to the high order word of the � � 쿏WORD at LOCATION. A relocation item for the high order word� � 쿽f the DWORD at LOCATION is created. � 읕컴컴컴컨컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 T-MODULE Record Format Basics All T-MODULE records have the following basic format: 旼컴컴컫컴컴컴컫컴컴컴컴컴컴컴컴컴컴쩡컴컴� 쿝ecord� Record쿔nformation Specific쿎heck� Field Names컴컴컴컴�>� Type � Length� to Record Type � Sum � 쳐컴컴컵컴컴컴컵컴컴컴컴컴컴컴컴컴컴탠컴컴� Field Lengths컴컴컴�>� 1 � 2 � Record Length - 1 � 1 � (bytes) 읕컴컴컨컴컴컴컨컴컴컴컴컴컴컴컴컴컴좔컴컴� Record Type -- This one byte field identifies the type of T-MODULE record. Record Length -- This word contains the number of bytes in all following fields (including the checksum). Information Specific to Record Type -- This field contains the data for the specified Record Type. Check Sum -- This byte contains the negative of the sum of all the preceding bytes in the record. Therefore, the sum of all the bytes in the record will be 0. T-MODULE Record Format -- Bit Fields Bit fields are denoted as follows: 旼컴컴쩡컴컴쩡컴컴� � Bit � Bit � Bit � Field Name컴컴컴컴컴컴>쿑ield쿑ield쿑ield� � 1 � 2 � n � 쳐컴컴탠컴컴탠컴컴� Field Length컴컴컴컴컴>� 4 � 1 � 3 � (bits) 쳐컴컴좔컴컴좔컴컴� � byte � 읕컴컴컴컴컴컴컴컴� T-MODULE Record Format -- INDEX Fields There are three special kinds of fields in a T-MODULE record: "INDEX" fields: 旼컴컴� 쿔NDEX� 쳐컴컴� � 1-2 � 읕컴컴� An INDEX field is one or two bytes long. If the high order bit of the first byte of the INDEX is 0, then the INDEX is one byte long and the value is the remaining 7 bits (0 - 127). Otherwise, the INDEX is two bytes long and the value of the INDEX is the low order 7 bits of the first byte * 256 plus the second byte. T-MODULE Record Format -- NAME Fields The format of a "NAME" field is: 旼컴컴컫컴컴컴컴컴커 � NAME � NAME � 쿗ength� � 쳐컴컴컵컴컴컴컴컴캑 � 1 쿙AME Length� 읕컴컴컨컴컴컴컴컴켸 Note: NAMEs of 0 bytes are permitted. The NAME is not NULL terminated. T-MODULE Record Format -- VALUE Fields The format of "VALUE" fields is: 旼컴컫컴컴컴� 쿎ode쿙umber� 쳐컴컵컴컴컴� � 1 � 0-4 � 읕컴컨컴컴컴� When 0 � Code � 128, the Number field is omitted and the VALUE is Code. When Code = 129, the Number field is 2 bytes long, and the VALUE is Number. When Code = 132, the Number field is 3 bytes long, and the VALUE is Number. When Code = 136, the Number field is 4 bytes long, and the VALUE is Number. T-MODULE Record Format -- T-MODULE Header 旼컴쩡컴컴컫컴컴컴컴컴컴컫컴컴커 � 쿝ecord쿟-MODULE NAME쿎heck� �80H쿗ength� � Sum � 쳐컴탠컴컴컵컴컴컴컴컴컴컵컴컴캑 � 1 � 2 � NAME � 1 � 읕컴좔컴컴컨컴컴컴컴컴컴컨컴컴켸 This record type must be the first record in the T-MODULE, and it names the T-MODULE. Frequently, the T-MODULE NAME is the name of the source file to the language translator. T-MODULE Record Format -- List of NAMEs (LNAMEs) 旼컴쩡컴컴컫컴컴컴컴컴컴쩡컴컴� � 쿝ecord� 쿎heck� �96H쿗ength쿗ogical NAME� Sum � 쳐컴탠컴컴컵컴컴컴컴컴컴탠컴컴� � 1 � 2 � NAME � 1 � 읕컴좔컴컴컵컴컴컴컴컴컴탠컴컴� 읕훣epeated컴� Each Logical NAME is entered into a "List of NAMES" (LNAME) in the order they are encountered in type 96H records. The list index starts at 1 (0 means not specified). There may be more than one type 96H record in a T-MODULE. When this occurs, append the Logical NAMEs to the list. The Logical NAME field is repeated. The number of repetitions is determined by the Record Length. T-MODULE Record Format -- LSEG Definition (SEGDEF) 旼컴쩡컴컴컫컴컴컴컴컫컴컴컴컫컴컴컴컫컴컴컫컴컴컴컫컴컴커 � 쿝ecord� Segment 쿞egment쿞egment쿎lass쿚verlay쿎heck� �90H쿗ength쿌ttribute쿗ength � INDEX 쿔NDEX� INDEX � Sum � 쳐컴탠컴컴컵컴컴컴컴컵컴컴컴컵컴컴컴컵컴컴컵컴컴컴컵컴컴캑 � 1 � 2 � 1-4 � 2 � INDEX 쿔NDEX� INDEX � 1 � 읕컴좔컴컴컨컴컴컴컴컨컴컴컴컨컴컴컴컨컴컴컨컴컴컴컨컴컴켸 Segment Attribute: 旼컴컫컴컴컴컴컴컴쩡컴컴커 ACBP: 旼쩡쩡쩡� 쿌CBP쿑RAME NUMBER쿚ffset� 쿌쿎쿍쿛� 쳐컴컵컴컴컴컴컴컴탠컴컴캑 쳐탠탠탠� � 1 � 2 � 1 � �3�3�1�1� 읕컴컵컴컴컴컴컴컴좔컴컴캑 쳐좔좔좔� 읕컴훏onditional컴컴� � Byte � 읕컴컴컴� Note: ACBP.P must be 0. There is one SEGDEF record for each LSEG in a T-MODULE. Like the LNAME list, this forms a list of LSEGs (indexed from 1). T-MODULE Record Format -- SEGDEF.ACBP.A The following table gives the meaning of the A field of the ACBP field: 旼쩡컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿌� Description � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �0쿟his is an absolute segment. The FRAME NUMBER and Offset fields of � � 퀃he Segment Attribute field will be present. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �1쿟his is a relocatable, byte-aligned LSEG. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �2쿟his is a relocatable, word-aligned LSEG. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �2쿟his is a relocatable, paragraph-aligned LSEG. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �4쿟his is a relocatable, page-aligned LSEG. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �5쿟his is a relocatable, DWORD-aligned LSEG. � 읕좔컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 T-MODULE Record Format -- SEGDEF.ACBP.C The following table gives the meaning of the C field of the ACBP field: 旼쩡컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿎� Description � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �0쿟he LSEG is private and may not be combined. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �1쿢ndefined. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �2쿟he LSEG is public and may be combined with other LSEGs of the same � � 쿻ame. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �3쿢ndefined. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �4쿟he LSEG is public and may be combined with other LSEGs of the same � � 쿻ame. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �5쿟he LSEG is a stack segment and may be combined with other LSEGs of � � 퀃he same name. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �6쿟he LSEG is a common segment and must be combined with other LSEGs � � 쿽f the same name. � 쳐탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 �7쿟he LSEG is public and may be combined with other LSEGs of the same � � 쿻ame. � 읕좔컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 T-MODULE Record Format -- Notes on Combining LSEGs which can be combined and are not common are combined as follows: 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿗SEG data for first T-MODULE � 쳐컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿌lignment Gap for second T-MODULE� 쳐컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿗SEG data for second T-MODULE � 쳐컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� � /// � 쳐컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿌lignment Gap for last T-MODULE � 쳐컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� 쿗SEG data for last T-MODULE � 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴� The resultant PSEG is the combined length of the above. For common LSEGs, the length of the PSEG is the length of the largest LSEG. Therefore, the length of the PSEG cannot be determined until all the T-MODULEs are processed. For this reason, data cannot be loaded into common segments until fixup time. T-MODULE Record Format -- LSEG Definition (SEGDEF) 旼컴쩡컴컴컫컴컴컴컴컫컴컴컴컫컴컴컴컫컴컴컫컴컴컴컫컴컴커 � 쿝ecord� Segment 쿞egment쿞egment쿎lass쿚verlay쿎heck� �90H쿗ength쿌ttribute쿗ength � INDEX 쿔NDEX� INDEX � Sum � 쳐컴탠컴컴컵컴컴컴컴컵컴컴컴컵컴컴컴컵컴컴컵컴컴컴컵컴컴캑 � 1 � 2 � 1-4 � 2 � INDEX 쿔NDEX� INDEX � 1 � 읕컴좔컴컴컨컴컴컴컴컨컴컴컴컨컴컴컴컨컴컴컨컴컴컴컨컴컴켸 Segment Length -- If ACBP.B is 0, then this is the length of the LSEG. If ACBP.B is 1, then the Segment Length must be 0 and the length of the LSEG is 65536 bytes. Segment INDEX -- This is an INDEX into the LNAME list. LNAME[Segment INDEX] is the name of the LSEG. Class INDEX -- This is an INDEX into the LNAME list. LNAME[Class INDEX] is the name of the LSEG. Overlay INDEX -- This is an INDEX into the LNAME list. LNAME[Class INDEX] is the name of the LSEG. T-MODULE Record Format -- Group Definition (GRPDEF) 旼컴쩡컴컴컫컴컴컴컴컴컫컴컫컴컴컫컴컴커 � 쿝ecord쿒roup NAME � 쿗SEG 쿎heck� �9AH쿗ength� INDEX 쿑FH쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컴컴컴컵컴컵컴컴컵컴컴캑 � 1 � 2 � INDEX � 1 쿔NDEX� 1 � 읕컴좔컴컴컨컴컴컴컴컴컵컴컨컴컴컵컴컴켸 읕repeated� Like the LNAME list and SEGDEF list, the GRPDEFs form a list (indexed relative to 1) of groups. The is one GRPDEF record for each group in the T-MODULE. Group NAME INDEX -- LNAME[Group NAME INDEX] is the name of the group. LSEG INDEX -- This field is repeated once for each LSEG in the group. The LSEG INDEX is the INDEX into the LSEG list which corresponds to the LSEG in the group. T-MODULE Record Format -- Public Definition (PUBDEF) 旼컴쩡컴컴컫컴컴컫컴컴컴컫컴컴컴쩡컴컴컫컴컴컴쩡컴컴쩡컴컴� � 쿝ecord쿒roup쿞egment쿑RAME 쿛ublic쿛ublic쿟ype 쿎heck� �90H쿗ength쿔NDEX� INDEX 쿙UMBER� NAME 쿚ffset쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컵컴컴컴컵컴컴컴탠컴컴컵컴컴컴탠컴컴탠컴컴� � 1 � 2 쿔NDEX� INDEX � 0-2 � NAME � 2 쿔NDEX� 1 � 읕컴좔컴컴컨컴컴컨컴컴컴컨컴컴컴탠컴컴컨컴컴컴좔컴컴탠컴컴� 읕컴컴repeated컴컴컴� Group INDEX -- If the public(s) are defined is an LSEG which is part of a group, then this is the index into the group list. Segment INDEX -- If the public(s) are defined in an LSEG, this is the index into the LSEG list. FRAME NUMBER -- This field is only present if the public(s) are absolute (indicated by both Group INDEX and Segment INDEX being zero). When present, this is the FRAME NUMBER used to reference the public(s). T-MODULE Record Format -- Public Definition (PUBDEF) 旼컴쩡컴컴컫컴컴컫컴컴컴컫컴컴컴쩡컴컴컫컴컴컴쩡컴컴쩡컴컴� � 쿝ecord쿒roup쿞egment쿑RAME 쿛ublic쿛ublic쿟ype 쿎heck� �90H쿗ength쿔NDEX� INDEX 쿙UMBER� NAME 쿚ffset쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컵컴컴컴컵컴컴컴탠컴컴컵컴컴컴탠컴컴탠컴컴� � 1 � 2 쿔NDEX� INDEX � 0-2 � NAME � 2 쿔NDEX� 1 � 읕컴좔컴컴컨컴컴컨컴컴컴컨컴컴컴탠컴컴컨컴컴컴좔컴컴탠컴컴� 읕컴컴repeated컴컴컴� Public NAME -- This is the name of the public. Public Offset -- This is the distance of the start of the public from the group, LSEG or FRAME. Type INDEX -- This is ignored. T-MODULE Record Format -- Public Definition (EXTDEF) 旼컴쩡컴컴컫컴컴컴컴쩡컴컴쩡컴컴� � 쿝ecord쿐xternal쿟ype 쿎heck� 쿍CH쿗ength� NAME 쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컴컴탠컴컴탠컴컴� � 1 � 2 � NAME 쿔NDEX� 1 � 읕컴좔컴컴컵컴컴컴컴좔컴컴탠컴컴� 읕컴repeated컴켸 Like the LNAMEs, SEGDEFs, and GRPDEFs, the EXTDEFs form a list (indexed relative to 1) of the external names used in this T-MODULE. External NAME -- This is the name of the external public symbol. Type INDEX -- This is ignored. T-MODULE Record Format -- Logical Enumerated Data (LEDATA) 旼컴쩡컴컴컫컴컴컴컫컴컴컴쩡컴컴컴컫컴컴커 � 쿝ecord쿞egment� � 쿎heck� 쿌0H쿗ength� INDEX 쿚ffset� Data � Sum � 쳐컴탠컴컴컵컴컴컴컵컴컴컴탠컴컴컴컵컴컴캑 � 1 � 2 � INDEX � 2 � 1 � 1 � 읕컴좔컴컴컨컴컴컴컨컴컴컴탠컴컴컴컵컴컴켸 픯epeated� Segment INDEX -- This data is to be loaded into the LSEG corresponding to SEGDEF list entry SEGDEF[Segment INDEX]. Offset -- This data is to be loaded starting at this offset in the LSEG. Data -- The byte(s) to be loaded. No more than 1024 can be loaded by an LEDATA record. T-MODULE Record Format -- Logical Iterated Data (LIDATA) 旼컴쩡컴컴컫컴컴컴컫컴컴컴쩡컴컴컴컴컫컴컴커 � 쿝ecord쿞egment� � Iterated 쿎heck� 쿌2H쿗ength� INDEX 쿚ffset쿏ata Block� Sum � 쳐컴탠컴컴컵컴컴컴컵컴컴컴탠컴컴컴컴컵컴컴캑 � 1 � 2 � INDEX � 2 � variable � 1 � 읕컴좔컴컴컨컴컴컴컨컴컴컴탠컴컴컴컴컵컴컴켸 읕repeated켸 Segment INDEX -- This data is to be loaded into the LSEG corresponding to SEGDEF list entry SEGDEF[Segment INDEX]. Offset -- This data is to be loaded starting at this offset in the LSEG. Iterated Data Block -- This is (recursively) defined later, but the total size cannot exceed 1024 bytes. T-MODULE Record Format -- Logical Iterated Data (LIDATA) Iterated Data Block: 旼컴컴컫컴컴컫컴컴컴컴� 쿝epeat쿍lock� � 쿎ount 쿎ount� Content� 쳐컴컴컵컴컴컵컴컴컴컴� � 2 � 2 퀆ariable� 읕컴컴컨컴컴컨컴컴컴컴� Repeat Count -- If Block Count is zero then Content is interpreted as a string of bytes of length Repeat Count. If Block Count is zero, then this is the number of times the Content field is repeated. Block Count -- If this is zero, then the Content field is interpreted as a string of bytes of length Repeat Count. If this is non-zero, then the Content field contains a string of Block Count Iterated Data Blocks. Content -- This is either a string of bytes as described above or it is a string of Iterated Data Blocks. T-MODULE Record Format -- Fixup Record (FIXUPP) 旼컴쩡컴컴컫컴컴컴컴쩡컴컴� � 쿝ecord� Thread 쿎heck� �9CH쿗ength쿽r Fixup� Sum � 쳐컴탠컴컴컵컴컴컴컴탠컴컴� � 1 � 2 퀆ariable� 1 � 읕컴좔컴컴컵컴컴컴컴탠컴컴� 픯epeated� Thread or Fixup -- This field can be either a Thread (high order bit is 0) or Fixup (high order bit is 1). A Thread is a default TARGET or FRAME method. There are four TARGET threads and four FRAME threads. Thread fields are used to store the default TARGET or FRAME method. A Fixup type field specifies the five pieces of information (discussed earlier) necessary to perform a fixup. T-MODULE Record Format -- Thread Thread: 旼컴컴컫컴컴컴커 Thread Data: 旼쩡쩡쩡컴컴컫컴컴커 쿟hread쿟hread � �0쿏�0쿘ethod쿟hred� � Data � INDEX � 쳐탠탠탠컴컴컵컴컴캑 쳐컴컴컵컴컴컴캑 �1�1�1� 3 � 2 � � 1 �0-INDEX� 쳐좔좔좔컴컴컨컴컴캑 읕컴컴컨컴컴컴켸 � byte � 읕컴컴컴컴컴컴컴컴켸 D -- If D is zero then a TARGET thread is being specified, otherwise a FRAME thread is being specified. Method -- This is the TARGET or FRAME method. For TARGET threads, only the four primary methods are specified. All seven FRAME methods can be specified. Thred -- This is the TARGET or FRAME thread number being specified. Thread INDEX -- This is not present when F4, F5 or F6 is being specified. In all other cases, this is either a Segment, Group or External index depending on the Method. T-MODULE Record Format -- Fixup 旼컴컴쩡컴컴컴쩡컴컴컴쩡컴컴컴쩡컴컴커 쿗OCAT� Fixup � FRAME 쿟ARGET 쿟ARGET� � 쿘ethods� INDEX 쿔NDEX 쿚ffset� 쳐컴컴탠컴컴컴탠컴컴컴탠컴컴컴탠컴컴캑 � 2 � 1 �0-INDEX�0-INDEX� 0-2 � 읕컴컴좔컴컴컴좔컴컴컴좔컴컴컴좔컴컴켸 LOCAT: 旼쩡컴컫컫컴컴컴컴쩡컴컴컴컴� � � � 쿗OCATION쿗E/LIDATA� �1쿘ode�0� Type � Offset � 쳐탠컴컵컵컴컴컴컴탠컴컴컴컴� �1� 1 �1� 3 � 10 � 쳐좔컴컨컨컴컴컴컴좔컴컴컴컴� 쿹ow byte high byte� Note: Low and high bytes 읕컴컴컴컴컴컴컴컴컴컴컴컴컴� are swapped. Mode -- If Mode is 0 then this is a self-relative fixup, otherwise it is a segment-relative fixup. Self-relative fixups on LIDATA are not permitted. T-MODULE Record Format -- Fixup LOCAT: 旼쩡컴컫컫컴컴컴컴쩡컴컴컴컴� � � � 쿗OCATION쿗E/LIDATA� �1쿘ode�0� Type � Offset � 쳐탠컴컵컵컴컴컴컴탠컴컴컴컴� �1� 1 �1� 3 � 10 � 쳐좔컴컨컨컴컴컴컴좔컴컴컴컴� 쿹ow byte high byte� 읕컴컴컴컴컴컴컴컴컴컴컴컴컴� LOCATION Type: 旼컴컴컴컫컴컴컴컴컴컴컴컴� 쿗OCATION쿟ype Description� 쳐컴컴컴컵컴컴컴컴컴컴컴컴� � 0 � LOBYTE � 쳐컴컴컴컵컴컴컴컴컴컴컴컴� � 1 � OFFSET � 쳐컴컴컴컵컴컴컴컴컴컴컴컴� � 2 � BASE � 쳐컴컴컴컵컴컴컴컴컴컴컴컴� � 3 � POINTER � 쳐컴컴컴컵컴컴컴컴컴컴컴컴� � 4 � HIBYTE � 읕컴컴컴컨컴컴컴컴컴컴컴컴� T-MODULE Record Format -- Fixup LOCAT: 旼쩡컴컫컫컴컴컴컴쩡컴컴컴컴� � � � 쿗OCATION쿗E/LIDATA� �1쿘ode�0� Type � Offset � 쳐탠컴컵컵컴컴컴컴탠컴컴컴컴� �1� 1 �1� 3 � 10 � 쳐좔컴컨컨컴컴컴컴좔컴컴컴컴� 쿹ow byte high byte� 읕컴컴컴컴컴컴컴컴컴컴컴컴컴� LE/LIDATA Offset -- This field is used to determine the LOCATION information for the fixup. This offset is actually an offset into the last LEDATA or LIDATA record. The LEDATA or LIDATA contains the base LSEG and offset information. Note that for LIDATA records, each time the data at LE/LIDATA Offset is repeated, the fixup must occur. T-MODULE Record Format -- Fixup 旼컴컴쩡컴컴컴쩡컴컴컴쩡컴컴컴쩡컴컴커 쿗OCAT� Fixup � FRAME 쿟ARGET 쿟ARGET� � 쿘ethods� INDEX 쿔NDEX 쿚ffset� 쳐컴컴탠컴컴컴탠컴컴컴탠컴컴컴탠컴컴캑 � 2 � 1 �0-INDEX�0-INDEX� 0-2 � 읕컴컴좔컴컴컴좔컴컴컴좔컴컴컴좔컴컴켸 Fixup Methods: 旼쩡컴컴쩡쩡쩡컴컴커 쿑쿑RAME쿟쿛쿟ARGET� F -- 쳐탠컴컴탠탠탠컴컴캑 If F is 1 then FRAME is a thread, �1� 3 �1�1� 2 � else FRAME is the FRAME method. 쳐좔컴컴좔좔좔컴컴캑 � byte � T -- 읕컴컴컴컴컴컴컴컴켸 If T is 1 then TARGET is a thread, else TARGET is the TARGET method. FRAME -- This is either the FRAME method (F=0) or a FRAME thread (F=1). TARGET -- This is either the TARGET method (T=0) or a TARGET thread (T=1). P -- If P=0 then the primary TARGET methods are used and the TARGET Offset field will be present. T-MODULE Record Format -- Fixup 旼컴컴쩡컴컴컴쩡컴컴컴쩡컴컴컴쩡컴컴커 쿗OCAT� Fixup � FRAME 쿟ARGET 쿟ARGET� � 쿘ethods� INDEX 쿔NDEX 쿚ffset� 쳐컴컴탠컴컴컴탠컴컴컴탠컴컴컴탠컴컴캑 � 2 � 1 �0-INDEX�0-INDEX� 0-2 � 읕컴컴좔컴컴컴좔컴컴컴좔컴컴컴좔컴컴켸 FRAME INDEX -- Depending on the FRAME method, this is either a Segment, Group, or External INDEX. This will be present only when a FRAME thread is not used (F=0). TARGET INDEX -- Depending on the TARGET method, this is either a Segment, Group, or External INDEX. This will be present only when a TARGET thread is not used (T=0). TARGET Offset -- The TARGET is TARGET Offset bytes from the Segment, Group, or External given by TARGET INDEX. T-MODULE Record Format -- T-MODULE End (MODEND) 旼컴쩡컴컴컫컴컴쩡컴컴컴컫컴컴커 � 쿝ecord쿐nd � Start 쿎heck� �8AH쿗ength쿟ype쿌ddress � Sum � 쳐컴탠컴컴컵컴컴탠컴컴컴컵컴컴캑 � 1 � 2 � 1 퀆ariable� 1 � 읕컴좔컴컴컨컴컴좔컴컴컴컨컴컴켸 End Type: Attribute: 旼컴컴컴컴쩡쩡� 旼컴컴컴컴쩡컴컴컴컴컴컴컴컴컴컴컴컴커 쿌ttribute�0�1� 쿌ttribute쿏escription � 쳐컴컴컴컴탠탠� 쳐컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴캑 � 2 �5�1� � 0 쿙on-main, no Start Address� 쳐컴컴컴컴좔좔� 쳐컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴캑 � byte � � 1 쿙on-main, Start Address � 읕컴컴컴컴컴컴� 쳐컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴캑 � 2 쿘ain, no Start Address � 쳐컴컴컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴캑 � 3 쿘ain, Start Address � 읕컴컴컴컴좔컴컴컴컴컴컴컴컴컴컴컴컴켸 T-MODULE Record Format -- T-MODULE End (MODEND) Start Address: 旼컴컴컴쩡컴컴컴쩡컴컴컴쩡컴컴커 � Fixup � FRAME 쿟ARGET 쿟ARGET� 쿘ethods� INDEX 쿔NDEX 쿚ffset� 쳐컴컴컴탠컴컴컴탠컴컴컴탠컴컴캑 � 1 �0-INDEX�0-INDEX� 0-2 � 읕컴컴컴좔컴컴컴좔컴컴컴좔컴컴켸 The above fields work exactly the same as they do in a FIXUPP record. The start address is computed from the FRAME and TARGET specified above. The initial CS is the FRAME NUMBER of the FRAME, and the initial IP is TARGET - FRAME. T-MODULE Record Format -- Comment Record (COMENT) 旼컴쩡컴컴컫컴컴컴컫컴컴컴컴쩡컴컴� � 쿝ecord쿎omment� 쿎heck� �88H쿗ength� Type 쿎omment � Sum � 쳐컴탠컴컴컵컴컴컴컵컴컴컴컴탠컴컴� � 1 � 2 � 2 퀆ariable� 1 � 읕컴좔컴컴컨컴컴컴컨컴컴컴컴좔컴컴� Comment Type: 旼컴컴쩡컴컫컫컴컴커 쿛urge쿗ist�0쿎lass� 쳐컴컴탠컴컵컵컴컴캑 � 1 � 1 �6� 8 � 쳐컴컴좔컴컨컨컴컴캑 � word � 읕컴컴컴컴컴컴컴컴켸 Purge -- COMENT record should not be deleted by utilities which can delete comments (Purge=1). List -- COMENT record should not be listed by utilities which can list comments (LIST=1). T-MODULE Record Format -- Comment Record (COMENT) 旼컴컴쩡컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 쿎lass� Description � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 129 쿏o not do a default library search. � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 157 쿘emory model information is in the Comment field. � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 158 쿢se the "DOSSEG" ordering. � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 159 쿗ibrary name is in the Comment field. � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 161 쿎odeview (registered trademark of Microsoft) information is � � 쿾resent. � 쳐컴컴탠컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴캑 � 162 쿛ass 1 of linker can stop processing T-MODULE here. � 읕컴컴좔컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 T-MODULE Record Format -- Communal Definition (COMDEF) 旼컴쩡컴컴컫컴컴컴쩡컴컴쩡컴컴컴컴컴쩡컴컴컴컴컫컴컴커 � � 쿞ymbol쿟ype 쿑ar or Near� Communal 쿎heck� 쿍0H쿗ength� NAME 쿔NDEX� Communal � Size � Sum � 쳐컴탠컴컴컵컴컴컴탠컴컴탠컴컴컴컴컴탠컴컴컴컴컵컴컴캑 � 1 � 2 � NAME 쿔NDEX� 1 � variable � 1 � 읕컴좔컴컴컨컴컴컴좔컴컴좔컴컴컴컴컴좔컴컴컴컴컨컴컴켸 Symbol NAME -- This is the name of the communal symbol. It is placed in the list of external symbols just as if it were an EXTDEF record. If a PUBDEF record with the same Symbol NAME is encountered, it overrides the COMDEF. Type INDEX -- This is ignored. Far or Near Communal -- Far communals have a 61H coded here. Near communals have a 62H coded here. The ultimate size of the communal is the largest communal. T-MODULE Record Format -- Communal Definition (COMDEF) For near communals, Communal Size is: 旼컴컴� 쿞IZE � 쿣ALUE� 쳐컴컴� 쿣ALUE� 읕컴컴� For far communals, Communal Size is: 旼컴컴쩡컴컴� 쿎OUNT쿞IZE � The size of the communal is: 쿣ALUE쿣ALUE� 쳐컴컴탠컴컴� COUNT VALUE * SIZE VALUE 쿣ALUE쿣ALUE� 읕컴컴좔컴컴� Near communals go in DGROUP. Far communals go in HUGE_BSS and are packed as compactly as possible into PSEGs of no more than 64K. T-MODULE Record Format -- Forward Reference Fixups (FORREF) 旼컴쩡컴컴컫컴컴컴컫컴컴쩡컴컴컫컴컴컴컴쩡컴컴� � � 쿞egment� � � Fixup 쿎heck� 쿍2H쿗ength� INDEX 쿞ize쿚ffset� Data � Sum � 쳐컴탠컴컴컵컴컴컴컵컴컴탠컴컴컵컴컴컴컴탠컴컴� � 1 � 2 � INDEX � 1 � 2 퀆ariable� 1 � 읕컴좔컴컴컨컴컴컴컨컴컴탠컴컴컨컴컴컴컴탠컴컴� 읕컴repeated컴컴� Segment INDEX -- The Forward Reference Fixup is to be applied to the LSEG element whose index into the SEGDEF list is Segment INDEX. Size -- This specifies the size of the Fixup Data fields. The Fixup Data fields are a byte when Size = 0, a word when Size = 1, or a DWORD when Size = 2. Offset -- This is the Offset into the LSEG specified by Segment Index where the fixup is applied. Fixup Data -- This value is added at the specified Offset. Note: The FORREF record may occur before the LE/LIDATA records which load data into the LSEG. Therefore, FORREFs must be applied at fixup time. T-MODULE Record Format -- Local External Definition (MODEXT) 旼컴쩡컴컴컫컴컴컴컴쩡컴컴쩡컴컴� � 쿝ecord쿐xternal쿟ype 쿎heck� 쿍4H쿗ength� NAME 쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컴컴탠컴컴탠컴컴� � 1 � 2 � NAME 쿔NDEX� 1 � 읕컴좔컴컴컵컴컴컴컴좔컴컴탠컴컴� 읕컴repeated컴켸 The fields of the MODEXT record function just like the EXTDEF record except that the external is local to this T-MODULE only. The External NAME is included in the list of externals. T-MODULE Record Format -- Local Public Definition (MODPUB) 旼컴쩡컴컴컫컴컴컫컴컴컴컫컴컴컴쩡컴컴컫컴컴컴쩡컴컴쩡컴컴� � 쿝ecord쿒roup쿞egment쿑RAME 쿛ublic쿛ublic쿟ype 쿎heck� 쿍6H쿗ength쿔NDEX� INDEX 쿙UMBER� NAME 쿚ffset쿔NDEX� Sum � 쳐컴탠컴컴컵컴컴컵컴컴컴컵컴컴컴탠컴컴컵컴컴컴탠컴컴탠컴컴� � 1 � 2 쿔NDEX� INDEX � 0-2 � NAME � 2 쿔NDEX� 1 � 읕컴좔컴컴컨컴컴컨컴컴컴컨컴컴컴탠컴컴컨컴컴컴좔컴컴탠컴컴� 읕컴컴repeated컴컴컴� The fields of the MODPUB record function just like the PUBDEF record except that the public symbol is local to this T-MODULE only. T-MODULE Record Format -- Line Number (LINNUM) 旼컴쩡컴컴컫컴컴컴컴컴쩡컴컴� � 쿝ecord� 쿎heck� �94H쿗ength� Data � Sum � 쳐컴탠컴컴컵컴컴컴컴컴탠컴컴� � 1 � 2 � 1 � 1 � 읕컴좔컴컴컵컴컴컴컴컴탠컴컴� 읕repeated켸 The LINNUM record is ignored by the linker. T-MODULE Record Format -- Type Definition (TYPDEF) 旼컴쩡컴컴컫컴컴컴컴컴쩡컴컴� � 쿝ecord� 쿎heck� �8EH쿗ength� Data � Sum � 쳐컴탠컴컴컵컴컴컴컴컴탠컴컴� � 1 � 2 � 1 � 1 � 읕컴좔컴컴컵컴컴컴컴컴탠컴컴� 읕repeated켸 The TYPDEF record is ignored by the linker. T-MODULE Record Format -- Record Order Object modules are parsed via recursive descent as defined below: t_module:: THEADR seg_grp {component} modtail seg_grp:: {LNAMES | SEGDEF | EXTDEF} {TYPDEF | EXTDEF | GRPDEF} component:: data | debug_record data:: content_def | thread_def | COMDEF | TYPDEF | PUBDEF | EXTDEF | FORREF | MODPUB | MODEXT debug_record:: LINNUM content_def:: data_record {FIXUPP} thread_def:: FIXUPP (containing only thread fields) data_record:: LIDATA | LEDATA modtail:: MODEND Primary Internal Data Structure 旼컴컴컴컴컴커 旼컴컴컴컴� 旼컴컴컴컴컴컴컴컴커 � Segment #1 쳐컴컴컴컴컴�>� LSEG #1 쳐컴컴컴컴컴컴>� LSEG #1 Contents � 읕컴컴쩡컴컴켸 읕컴컫컴컴� 읕컴컴컴컴컴컴컴컴켸 � � � ^ � 旼컴컴컴컴� 旼컴컴컴컴컴컴컴컴커 � � LSEG #2 쳐컴컴컴컴컴컴>� LSEG #2 Contents � � 읕컴컫컴컴� 읕컴컴컴컴컴컴컴컴켸 � ^ � /// ^ 旼컴컴컴컴컴커 旼컴컴컴컴� 旼컴컴컴컴컴컴컴컴커 � Segment #2 쳐컴컴컴컴컴�>� LSEG #1 쳐컴컴컴컴컴컴>� LSEG #1 Contents � 읕컴컴쩡컴컴켸 읕컴컫컴컴� 읕컴컴컴컴컴컴컴컴켸 � � � ^ � 旼컴컴컴컴� 旼컴컴컴컴컴컴컴컴커 ^ � LSEG #2 쳐컴컴컴컴컴컴>� LSEG #2 Contents � /// 읕컴컫컴컴� 읕컴컴컴컴컴컴컴컴켸 ^ /// Temp File The linker employs a temp file to save information which can only be processed after all the T-MODULEs have been processed. The information which must be saved is: Fixups LE/LIDATA for common LSEGS FORREF records The temp file is deleted when processing is complete. Library File Format library_file:: header_page {t_modules} trailer_page {directory_pages} header_page :: 旼컴쩡컴컴컫컴컴컴컴컫컴컴컴컴컫컴컴컴컴컴쩡� � 쿝ecord쿏irectory쿏irectory� � � 쿑0H쿗ength� Offset � Pages � Pad �0� 쳐컴탠컴컴컵컴컴컴컴컵컴컴컴컴컵컴컴컴컴컴탠� � 1 � 2 � 4 � 2 � 1 �1� 읕컴좔컴컴컨컴컴컴컴컨컴컴컴컴컵컴컴컴컴컴탠� (prime) 읕repeated켸 t_modules :: The t_modules are as described above except a pad is added after the MODEND record to make the t_module occupy a full page. The page size is the header_page Record Length + 3. trailer_page :: 旼컴쩡컴컴컫컴컴컴컴컴쩡� � 쿝ecord� � � 쿑1H쿗ength� Pad �0� 쳐컴탠컴컴컵컴컴컴컴컴탠� � 1 � 2 � 1 �1� 읕컴좔컴컴컵컴컴컴컴컴탠� 읕repeated켸 Library File Format -- Directory directory_pages :: public_pointer_array {public_entry} pad Notes: A directory page is always 512 bytes. A directory page can contain up to 37 public entries. public_pointer_array -- This is a 38 byte array which is used to point into the public_entry field. To determine where public i is located in the directory page, take the ith byte of the public_pointer_array (relative 0) and multiple it by 2. That byte will be the beginning of the public_entry for ith public in the directory. The 38th entry is used to point to the beginning of the free space in directory page. public_entry :: 旼컴컴컴쩡컴컴컴커 � Public쿞tarting� � NAME � Page � 쳐컴컴컴탠컴컴컴캑 � NAME � 2 � 읕컴컴컴좔컴컴컴켸 Library File Format -- Finding a Public The library directory employs a two-tiered hashing scheme to store public names in its directory. A detailed description of the algorithm is given later, but for now the following general aspects of the algoritm are useful. To start the search, you need to know which directory page to start searching, and if you don't find it in that page, which directory page to search next. Once in a directory page, you have to know which entry to use to begin the search and which entry to search next if it was not found. We will call the four required values STARTING_PAGE, DELTA_PAGE, STARTING_ENTRY, and DELTA_ENTRY. The detail on how to compute these values is give later. Start with directory page STARTING_PAGE. On that page, examine public_entry STARTING_ENTRY. There are three cases. This could be the public symbol you desire, in which case you are done. The public_pointer_array for this entry could be zero, in which case the symbol is not in the library. Or, this the public symbol at STARTING_ENTRY could be some other public symbol. In this case, add DELTA_ENTRY (modulo 37) to the STARTING_ENTRY and examine that public entry. Since there are at most 37 entries in any directory page, examine no more than 37 entries in any given page. If you have tried all entries on a page, proceed to the next page by adding DELTA_PAGE (modulo Directory_Pages) to STARTING_PAGE and continue the process. When you move to a new page, continue processing the public entries where you left off. To compute the STARTING_PAGE, DELTA_PAGE, STARTING_ENTRY, and DELTA_ENTRY, view a NAME field as if it were an array of bytes containing the public name: 旼컴컴컫컴컴쩡컴컫컴컴쩡//컫컴컴컴� NAME컴컴컴�>쿗ength쿫yte쿫yte쿫yte� � byte � 쳐컴컴컵컴컴탠컴컵컴컴탠//컵컴컴컴� � 1 � 1 � 1 � 1 � � 1 � 쳐컴컴컵컴컴탠컴컵컴컴탠//컵컴컴컴� index컴컴컴>� 0 � 1 � 2 � 3 � 쿗ength� 읕컴컴컨컴컴좔컴컨컴컴좔//컨컴컴컴� Then, the following code define the values: STARTING_PAGE, DELTA_PAGE, STARTING_ENTRY, DELTA_ENTRY := 0; for i := 0 .. Length-1 STARTING_PAGE := STARTING_PAGE+(NAME[i] or 20H) xor (<>STARTING_ENTRY); DELTA_ENTRY := DELTA_ENTRY+(NAME[i] or 20H) xor (>>DELTA_ENTRY); end for; if DELTA_ENTRY = 0 then DELTA_ENTRY := 1; if DELTA_PAGE = 0 then DELTA_PAGE := 1; Note: << is circular shift left twice and >> is circular shift right twice. �