86rel(FP) 6 January 1993 86rel(FP) Name 86rel - Intel 8086 Relocatable Format for Object Modules Syntax #include <sys/relsym86.h> Description Intel 8086 Relocatable Format, or 86rel, is the object module format gen- erated by masm(CP), and the input format for the linker ld(CP). The include file relsym86.h specifies appropriate definitions to access 86rel format files from C. For the technical details of the 86rel format, see Intel 8086 Object Module Format External Product Specification. An 86rel consists of one or more variable length records. Each record has at least three fields: the record type, length, and checksum. The first byte always denotes the record type. There are thirty-one dif- ferent record types. Only eleven are used by ld(CP) and masm(CP). The word after the first byte is the length of the record in bytes, exclusive of the first three bytes. Following the length word are typically one or more fields. Each record type has a specific sequence of fields, some of which may be optional or of varying length. The last byte in each record is a checksum. The checksum byte contains the sum modulo 256 of all other bytes in the record. The sum modulo 256 of all bytes in a record, includ- ing the checksum byte, should equal zero. With few exceptions, 86rel strings are length prefixed and have no trail- ing null. The first byte contains a number between 0 and 40, which is the remaining length of the string in bytes. Although the Intel specifi- cation limits the character set to upper case letters, digits, and the characters ``?'', ``@'', ``:'', ``.'', and ``_'', masm(CP) uses the com- plete ASCII character set. The Intel Object Module Format (OMF) specification uses the term ``index'' to mean a positive integer in either the range 0 to 127 or 128 to 32,768. This terminology is retained in this document and elsewhere in the 86rel literature. An index has one or two bytes. If the first byte has a leading 0 bit, the index is assumed to have only one byte, and the remainder of the byte represents a positive integer between 0 and 127. If the second byte has a leading 1 bit, the index is assumed to take up two bytes, and the remainder of the word represents a positive integer between 128 and 32,768. Following is a list of record types and the hexadecimal values of their first byte, as defined in relsym86.h. #define MRHEADR 0x6e /* rel module header */ #define MREGINT 0x70 /* register initialization */ #define MREDATA 0x72 /* explicit (enumerated) data image */ #define MRIDATA 0x74 /* repeated (iterated) data image */ #define MOVLDEF 0x76 /* overlay definition */ #define MENDREC 0x78 /* block or overlay end record */ #define MBLKDEF 0x7a /* block definition */ #define MBLKEND 0x7c /* block end */ #define MDEBSYM 0x7e /* debug symbols */ #define MTHEADR 0x80 /* module header, usually first in a rel file */ #define MLHEADR 0x82 /* link module header */ #define MPEDATA 0x84 /* absolute data image */ #define MPIDATA 0x86 /* absolute repeated (iterated) data image */ #define MCOMENT 0x88 /* comment record */ #define MMODEND 0x8a /* module end record */ #define M386END 0x8b /* 32 bit module end record */ #define MEXTDEF 0x8c /* external definition */ #define MTYPDEF 0x8e /* type definition */ #define MPUBDEF 0x90 /* public definition */ #define MPUB386 0x91 /* 32 bit public definition */ #define MLOCSYM 0x92 /* local symbols */ #define MLOC386 0x93 /* 32 bit local symbols */ #define MLINNUM 0x94 /* source line number */ #define MLIN386 0x95 /* 32 bit source line number */ #define MLNAMES 0x96 /* name list record */ #define MSEGDEF 0x98 /* segment definition */ #define MSEG386 0x99 /* 32 bit segment definition */ #define MGRPDEF 0x9a /* group definition */ #define MFIXUPP 0x9c /* fix up previous data image */ #define MFIX386 0x9d /* fix up previous 32 bit data image */ #define MNONE1 0x9e /* none */ #define MLEDATA 0xa0 /* logical data image */ #define MLED386 0xa1 /* 32 bit logical data image */ #define MLIDATA 0xa2 /* logical repeated (iterated) data image */ #define MLID386 0xa3 /* 32 bit logical repeated (iterated) data image */ #define MLIBHED 0xa4 /* library header */ #define MLIBNAM 0xa6 /* library names record */ #define MLIBLOC 0xa8 /* library module locations */ #define MLIBDIC 0xaa /* library dictionary */ #define MCOMDEF 0xb0 /* communal names definition */ #define MBAKPAT 0xb2 /* backpatch record */ #define MBAK386 0xb3 /* 32 bit backpatch record */ #define MLOCEXD 0xb4 /* external definition visible within module only */ #define MLOCPUB 0xb6 /* public definition visible within module only */ #define MLPB386 0xb7 /* 32 bit public visible within module only */ #define MLOCCOM 0xb8 /* communal name visible within module only */ #define MLIBHDR 0xf0 /* library header */ #define MLIBDHD 0xf1 /* library dictionary header */ In the following discussion, the main features of each record type are given. If the record is not used by either masm(CP) or ld(CP), it is not listed. THEADR The record type byte is 0x80. The THEADR record specifies the name of the source module at assembly time (see Notes). The only field is the T-MODULENAME, which contains a length-prefixed string derived from the base name of the source module. COMENT The record type byte is 0x88. The COMENT record may contain a remark generated by the compiler system. masm(CP) inserts the string ``UNIX 8086 ASSEMBLER.'' MODEND The record type byte is 0x8a. The MODEND record terminates a module. It can specify whether the current module is to be used as the entry point to the linked executable. If the module is an entry point, the MODEND record can then specify the address of the entry point within the executable. EXTDEF The record type byte is 0x8c. The EXTDEF record contains the names and types of symbols defined in other modules by a PUBDEF record (see below). This corresponds to the C storage class ``extern.'' The fields consist of one or more length-prefixed strings, each followed by a type index. The indices reference a TYPDEF record seen earlier in the module. masm(CP) generates only one EXTDEF per exterior sym- bol. TYPDEF The record type byte is 0x8e. The TYPDEF record gives a description of the type (size and storage attributes) of an object or objects. This description can then be referenced by EXTDEF, PUBDEF, and other records. PUBDEF The record type byte is 0x90. The PUBDEF record gives a list of one or more names that may be referenced by other modules at link time (``publics''). The list of names is preceded by group and segment indices, which reference the location of the start of the list of publics within the current seg- ment and group. If the segment and group indices are zero, a frame number is given to provide an absolute address in the module. The list consists of one or more of length- prefixed strings, each associated with a 16-bit offset within the current segment and a type index referring to a TYPDEF. LNAMES The record type byte is 0x96. The LNAMES record gives a series of length-prefixed strings which are associated with name indices within the current module. Each name is indexed in the sequence given, starting with 1. The names may then be referenced within the current module by succes- sive SEGDEF and GRPDEF records to provide strings for seg- ments, classes, overlays or groups. SEGDEF The record type byte is 0x98. The SEGDEF record provides an index for referencing a segment, and information concerning segment addressing and attributes. This index may be used by other records to refer to the segment. The first byte in the record after the length field gives information about the alignment and about combination attributes of the seg- ment. The next word is the segment length in bytes. Seg- ments are restricted to a maximum of 65,536 bytes in length. Following this word is an index for the segment. In addi- tion, the SEGDEF can optionally end with class and/or over- lay index fields. GRPDEF The record type is 0x9a. The GRPDEF record provides a name to reference several segments. The group name is imple- mented as an index. FIXUPP The record byte is 0x9c. The FIXUPP record specifies one or more load-time address modifications (``fixups''). Each fixup refers to a location in a preceding LEDATA (see below) record. The fixup is specified by four data: a location, a mode, a target and a frame. The frame and target may be specified explicitly or by reference to an already defined fixup. LEDATA The record type byte is 0xa0. This record provides a con- tiguous text or data image which the loader ld(CP) uses to construct a portion of an 8086 run-time executable. The image might require additional processing (see FIXUPP) before being loaded into the executable. The image is pre- ceded by two fields, a segment index and an enumerated data offset. The segment index (see INDEX) specifies a segment given by a previously seen SEGDEF. The enumerated data offset (a word) specifies the offset from the start of this segment. Notes If you attempt to load a number of modules assembled under the same basename, the loader will try to put them all in one big segment. In 286 programs, segment size is limited to 64K. In a large program, the resulting segment size can easily exceed 64K. A large model code execut- able results from the link of one or more modules, composed of segments that aggregate into greater than 64K of text. Be sure that the assembly-time name of the module has the same basename as the source. This can occur if the source module is preprocessed not by cc(CP), but, for example, by hand or shell script, prior to assembly. The following example is incorrect: #incorrect cc -E module1.c | filter > x.c cc x.c mv x.o module1.o cc -E module2.c | filter > x.c cc x.c mv x.o module2.o cc -E module3.c | filter > x.c cc x.c mv x.o module3.o ld module1.o module2.o module3.o Each module should have a unique name when assembled, as follows: #correct cc -E module1.c | filter > x.c cc -S x.c mv x.s module1.s as module1.s ld module1.o module2.o module3.o See also as(CP), ld(CP) Standards conformance 86rel is an extension of AT&T System V provided by Santa Cruz Operation.