IBM OS/2 16/32-bit Object Module Format (OMF) Specification


Revision 11

June 14, 2001 11:00 am

The information furnished herein is on an "as-is" basis, and IBM makes no warranties, either express or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. In no event will IBM be liable for any damages arising from the use of the information contained herein, including infringement of any proprietary rights, or for any lost profits or other incidental and/or consequential damages, even if IBM has been advised of the possibility of such damages.

FURTHERMORE, THIS DOCUMENTATION IS IN A PRELIMINARY FORM; IS NOT COMPLETE; HAS NOT YET BEEN TESTED, VALIDATED OR REVIEWED; MAY CONTAIN ERRORS, OMISSIONS, INACCURACIES OR THE LIKE; AND IS SUBJECT TO BEING CHANGED, REVISED OR SUPERSEDED IN WHOLE OR IN PART BY IBM. IBM DOES NOT ASSUME ANY RESPONSIBILITY TO NOTIFY ANY PARTIES, COMPANIES, USERS, AND OR OTHERS OF DEFECTS, DEFICIENCIES, CHANGES, ERRORS OR OTHER FAILINGS OR SHORTCOMING OF THE DOCUMENTATION.

This document is being furnished by IBM for evaluation/development feedback purposes only and IBM does not guarantee that IBM will make this document generally available. RECIPIENT'S USE OF THIS DOCUMENT IS LIMITED TO RECIPIENT'S PERSONAL USE FOR THE SOLE PURPOSE OF CREATING TOOLS FOR THE OS/2 OPERATING SYSTEM.

IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Commercial Relations, IBM Corporation, Purchase, NY, 10577.

The following copyright notice protects this document under the Copyright laws of the United States and other countries which prohibits such actions as, but not limited to, copying, distributing, modifying, and making derivative works.

Notice to US Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

The following terms are trademarks of International Business Machines Corporation in the United States and/or other countries:

IBM
Operating System/2
OS/2


Contents

1 - Introduction
2 - Record Format
3 - Frequent Object Record Subfields
3.1 - Names
3.2 - Indexed References
3.3 - Numeric 2 and 4 byte fields
4 - Order of records
5 - Object Record Types
5.1 - 80H THEADR Translator Header Record
5.2 - 82H LHEADR Library Header Record
5.3 - 88H COMENT Comment Record
5.4 - 88H IMPDEF Import Definition Record (comment class A0, subtype 01)
5.5 - 88H EXPDEF Export Definition Record (comment class A0, subtype 02)
5.6 - 88H INCDEF Incremental Compilation Record (comment class A0, subtype 03)
5.7 - 88H LNKDIR C++ Directives Record (comment class A0, subtype 05)
5.8 - 88H LIBMOD Library Module Name Record (comment class A3)
5.9 - 88H EXESTR Executable String Record (comment class A4)
5.10 - 88H INCERR Incremental Compilation Error Record(comment class A6)
5.11 - 88H NOPAD No Segment Padding Record (comment class A7)
5.12 - 88H WKEXT Weak Extern Record (comment class A8)
5.13 - 88H LZEXT Lazy Extern Record (comment class A9)
5.14 - 88H IDMDLL Identifier Manipulator DLL Record (comment class AF)
5.15 - 88H PharLap Format Record (comment class AA)
5.16 - 8AH or 8BH MODEND Module End Record
5.17 - 8CH EXTDEF External Names Definition Record
5.18 - 90H or 91H PUBDEF Public Names Definition Record
5.19 - 94H or 95H LINNUM Line Number Record
5.20 - 96H LNAMES List of Names Record
5.21 - 98H or 99H SEGDEF Segment Definition Record
5.22 - 9AH GRPDEF Group Definition Record
5.23 - 9CH or 9DH FIXUPP Fixup Record
5.24 - A0H or A1H LEDATA Logical Enumerated Data Record
5.25 - A2H or A3H LIDATA Logical Iterated Data Record
5.26 - B0H COMDEF Communal Names Definition Record
5.27 - B2H or B3H BAKPAT Backpatch Record
5.28 - B4H or B5H LEXTDEF Local External Names Definition Record
5.29 - B6H or B7H LPUBDEF Local Public Names Definition Record
5.30 - B8H LCOMDEF Local Communal Names Definition Record
5.31 - C2H or C3H COMDAT Initialized Communal Data Record
5.32 - C4H or C5H LINSYM Symbol Line Numbers Record
5.33 - C6H ALIAS Alias Definition Record
5.34 - C8H or C9H NBKPAT Named Backpatch Record

1 Introduction

This document describes the IBM 16/32-bit Object Module Format, also known as the IBM-OMF format. Also see Tool Interface Standards Portable Formats Specification, Tool Interface Standards Committee (Version 1.0), Section III for detail of the TIS-OMF format. Both OMF specifications are virtually identical but the TIS specification is the most current and is the specification used by most modern compilers for OS/2 such as IBM VisualAge C++ for OS/2.


2 Record Format

All object records confirm to the following format:

Figure 2-1: Standard object module record format

1 Byte

2 Bytes

<variable length>

1 byte

Record Type

Record Length

Record Contents

Chk Sum or 0

< record length in bytes >

The Record Type field is a 1-byte field containing the hexadecimal number that identifies the type of object record. The format is determined by the least significant bit of the Record Type field. Note that this does not govern Use32/Use16 segment attributes; it simply specifies the size of certain numeric fields within the record. An odd Record Type indicates that 32-bit values are present. An even Record Type indicates that those fields contain16-bit values. The fields affected are described with each record.

An entire record occupies Record Length + 3 bytes. The record length does not include the count for the record type and record length fields. Unless otherwise noted within the record definition, the record length should not exceed 1024 bytes.

The Record Contents are determined by the record type.

The Chk Sum field is a 1-byte field that contains the negative sum (modulo 256) of all other bytes in the record. The byte sum over the entire record, ignoring overflow, is zero.

Note: LINK386 ignores the value of the Chk Sum byte.


3 Frequent Object Record Subfields

The contents of each record are determined by the record type, but certain subfields appear frequently; the format of such fields is described next.

3.1 Names

Name strings are encoded as an 8-bit unsigned count followed by a string of "count" characters. The character set is usually some ASCII subset. A null name is specified by a single byte of 0 (indicating a string of length zero).

3.2 Indexed References

Certain items are ordered by occurrence, and referenced by index (starting index is 1). Index fields can contain 0, indicating not-present, or values from 1 through 7FFF. The index is encoded as 1 or 2 bytes.

If the index number is in the range 0-7H, the high-order bit (bit 7) is 0 and the low-order bits contain the index number, so the field is only 1 byte long. If the index number is in the range 80-7FFFH, the field is 2 bytes long. The high-order bit of the first byte in the field is set to 1, and the high-order byte of the index number which must be in the range (0-7FH) fits in the remaining 7 bits. The low-order byte of the index number is specified in the second byte of the field. A 16-bit value is obtained as follows:

if (first_byte & 0x80)
    index_word = (first_byte & 7F) * 0x100 + second_byte;
else
    index_word = first_byte

3.2.1 Type indices

The type index is treated as an index field when a record is parsed (occupies one or two bytes, occurs in PUBDEF, COMDEF, EXTDEF records). They are encoded as described under indexed references.

Note: At present, no type checking is done by the linker. If any link-time semantics are defined, that information will be recorded somewhere within this document.

3.2.2 Ordered Collections

Certain records and record groups are ordered; the ordering is obtained from the order of the record types within the file together with the ordering of repeated fields within these records. Such ordered collections are referenced by index, counting from 1 (index 0 indicates unknown or decline-to-state).

For example, there may be many LNAMES records within a module and each of those records may contain many names. The names are indexed starting at 1 for the first name in the first LNAMES record encountered while reading the file, 2 for the second name in the first record, etc., and the highest index for the last name in the last LNAMES record encountered.

The ordered collections are:

3.3 Numeric 2 and 4 byte fields

Words and double words (16 and 32 bit quantities) are stored in Intel byte order (lowest address is least significant).

Certain records, notably SEGDEF, PUBDEF, LINNUM, LEDATA, LIDATA, FIXUPP and MODEND, contain size, offset, and displacement values which may be 32 bit quantities for Use32 segments. The encoding is as follows.

See § 5.21, "98H or 99H SEGDEF Segment Definition Record" for an explanation of Use16/Use32 segments.


4 Order of records

The record order is chosen so that bind/link passes through an object module are minimized. This differs from the previous less specific ordering in that all symbolic information (in particular, all export and public symbols) must occur at the start of the object module. This order is recommended but not mandatory.

Identifier record(s):

Must be the first record.

Records processed by Link Pass one:

May occur in any order but must precede the Link pass separator if it is present.

This group of records is indexed together, so External Index fields in FIXUPP records may refer to any of the record types listed.

Link pass separator (optional):

COMENT class A2 indicating that pass 1 of the linker is complete.
When this record is encountered, LINK immediately starts Pass 2; no records after this comment are read in Pass 1. All the above listed records must come before this comment record. For greater linking speed, all LIDATA, LEDATA, FIXUPP and LINNUM records should come after the A2 comment record, but this is not required.
In LINK, Pass 2 begins again at the start of the object module, so LIDATA records, etc., are processed in Pass 2 no matter where they are placed in the object module.

Records ignored by link pass one and processed by link pass two:

May come before or after link pass two:

Terminator record:


5 Object Record Types

5.1 80H THEADR Translator Header Record

5.1.1 Description:

The THEADR record contains the name of the object module. This name identifies an object module within an object library or in messages produced by the linker.

Figure 2-2: THEADR Translator Header Record

1 Byte

2 Bytes

1 Byte

<variable length>

1 byte

80

Record Length

String Length

Name String

Chk Sum or 0

The String Length byte gives the number of characters in the name string; the name string itself is ASCII. This name is usually that of the source program (if supplied by the language translator), or may be specified directly by the programmer (e.g. TITLE pseudo-op).

This record must occur as the first object record. More than one header record is allowed (as a result of an object bind, or if source arose from multiple files as a result of include processing).

Note: The name string is always present; a null name is allowed but not recommended (not much information for a debugger that way).

5.2 82H LHEADR Library Header Record

5.2.1 Description:

This record is very similar to the THEADR record. It is used to indicate the name of a module within a library file (which has a different organization internally than an object module).

5.2.2 Record format:

Figure 2-3: LHEADR Library Header Record

1 Byte

2 Bytes

1 Byte

<variable length>

1 byte

82

Record Length

String Length

Name String

Chk Sum or 0

Note: In LINK, THEADR and LHEADR records are handled identically.

5.3 88H COMENT Comment Record

5.3.1 Description:

The COMENT record contains a character string that may represent a plain text comment, a symbol meaningful to a program such as LINK or LIB, or some binary coded information that alters the linking process. The comment records are actually a group of items, classified by "comment class".

Figure 2-4: COMENT Comment Record

1 Byte

2 Bytes

1 Byte

1 Byte

<Record length - 3>

1 byte

88

Record Length

Comment Type

Comment Class

Commentary byte string (optional)

Chk Sum or 0

5.3.2 Comment Type

The comment type byte is bit-significant; layout is:

< 1 byte >

NP

NL

0

0

0

0

0

0

where

NP

is set if the comment is to be preserved by object bind utilities

NL

is set if the comment is not for display by object bind utilities

5.3.3 Comment class and commentary byte string

The comment class is an 8-bit numeric which conveys information by its value (accompanied by a null byte string), or indicates the information to be found in the accompanying byte string. The byte string's length is determined from the record length, not by an initial count byte.

The values in use currently are the following:

0 Translator

For translator; may name the source language or translator. Recommended: translator name and version plus optimization level used for compilation be recorded here. Other compiler or assembler options can be included, although current practice seems to be to place these under comment class 9D.

01 Intel copyright

Ignored by the linker.

02 through 9B Intel reserved

The values from 9C through FF are ignored by Intel products.

9C MS-DOS version -- obsolete

Ignored by linker

9D Memory Model -- ignored

Ignored by linker

9E DOSSEG

Sets the linkers DOSSEG switch. The byte string is null. This record is included in the startup module in each language library. It directs the linker to use the standardized segment ordering, according to the naming conventions documented with DOS, OS/2 and accompanying language products.

9F Library indicator

The byte string contains a library file name (without a lead count byte and without an extension). Can be over-ridden via NOD link switch.

A0 OMF extensions

This class consists of a set of records, identified by subtype (first byte of commentary string). Values supported by the OS/2 2.0 linker are

01 IMPDEF

Import definition record. See § 5.4, "88H IMPDEF Import Definition Record (comment class A0, subtype 01)" for a complete description.

02 EXPDEF

Export definition record. See § 5.5, "88H EXPDEF Export Definition Record (comment class A0, subtype 02)" for a complete description.

03 INCDEF

Incremental compilation record. See § 5.6, "88H INCDEF Incremental Compilation Record (comment class A0, subtype 03)" for a complete description.

04 Protected Memory Library

Relevant to 32 bit DLL's.This comment record is inserted in the object module by the compiler when it encounters a compiler option or pragma indicating a protected DLL. The linker then sets a flag in the header of the executable file (DLL) to indicate that the DLL should be loaded in such a way that its shared code and data is protected from corruption.

When the flag is set in the EXE header, the loader loads the selector of the protected memory area into the DS while performing run-time fixups (relocations). All other DLL's and applications get the regular DGROUP selector, which doesn't allow access to the protected memory area set up by the operating system.

05 LNKDIR

C++ linker directives record. See § 5.7, "88H LNKDIR C++ Directives Record (comment class A0, subtype 05)" for a complete description.

06-FF Reserved for Microsoft.

presence of any unrecognized subtype causes LINKER to generate a fatal error.

A1 Symbolic debug information

This comment class is now used solely to indicate the version of the symbolic debug information.
The byte string will be a version number (8-bit numeric) followed by an ASCII character string indicating the style of symbol and line number (LINNUM) information. Current values are

n,'C','V'

CodeView style

n,'D','X'

AIX style

n,'H','L'

IBM PM Debugger

A2 Link Pass

This record conveys information to the linker about the organization of the file. At present, a single sub-extension is defined. The commentary string is

01

Optional

Subclass 01 indicates the start of link pass 2 records; this may be followed by anything at all, which will be ignored by the linker (determined from the RecLength). When this comment appears, the linker can rest assured that only LEDATA, LIDATA, FIXUPP, LINNUM and the terminal MODEND records will occur after this. All other record types, plus THREAD fixups, occur before.
WARNING: It is assumed that this comment will not be present in a module whose MODEND record contains a program starting address.

A3 LIBMOD indicator

Library module comment record. Ignored by LINK386.

A4 EXESTR indicator

Executable Module Identification String.
A commentary string specifying a string to be placed in the executable module, but which is not loaded with the load module.

A6 INCERR

Incremental compilation error. See § 5.10, "88H INCERR Incremental Compilation Error Record(comment class A6)" for a complete description.

A7 NOPAD

No segment padding. Ignored by LINK386.

A8 WKEXT

Weak Extern record. See § 5.12, "88H WKEXT Weak Extern Record (comment class A8)" for a complete description.

A9 LZEXT

Lazy Extern record. Ignored by LINK386.

AA PHARLAP

PharLap Format record. Ignored by LINK386.

AE IPADATA

Interprocedural Analysis Data Record.
This comment record is used by IBM interprocedural analysis and optimization tools to store and retrieve binary data during the compilation and linking processes. Records of this type are to be ignored by the linker.

AF IDMDLL indicator

Identifier Manipulator Dynamic Link Library. See § 5.14, "88H IDMDLL Identifier Manipulator DLL Record (comment class AF)" for a complete description.

B2H-BFH

Unused

C0H-FFH

Reserved for user-defined comment classes.

Note: A COMENT record can appear almost anywhere in an object module. Only two restrictions apply:

5.4 88H IMPDEF Import Definition Record (comment class A0, subtype 01)

5.4.1 Description:

This record describes the imported names for a module.

5.4.2 Record format:

One import symbol is described; the subrecord format is

Figure 2-5: IMPDEF Import Definition Record

1

1

<variable>

<variable>

2 or <variable> (bytes)

01

Ord Flag

InternalName

ModuleName

EntryIdent

where:

01

identifies the subtype as an IMPDEF

OrdFlag

is a byte; if zero the import is identified by name. If nonzero, it is identified by ordinal. Determines the form of the EntryIdent field.

InternalName

in <count, char> string format and is the name used within this module for the import symbol. This name will occur again in an EXTDEF record.

ModuleName

in <count, char> string format and is the name of the module which supplies an export symbol matching this import.

EntryIdent

is an ordinal or the name used by the exporting module for the symbol, depending upon the OrdFlag.
If this field is an ordinal (OrdFlag nonzero), it is a 16-bit word. If this is a name, and the first byte of the name is zero, then the exported name is the same as the import name (in the InternalName field). Otherwise, it is the imported name in <count, char> string format (as exported by ModuleName).

Note: IMPDEF records are created by the utility IMPLIB, which builds an "import library" from a module definition file or dynamic-link library.

5.5 88H EXPDEF Export Definition Record (comment class A0, subtype 02)

5.5.1 Description:

This record describes the exported names for a module.

5.5.2 Record format:

One exported entry point is described; the subrecord format is

Figure 2-6: EXPDEF Export Definition Record

1

1

<variable>

<variable>

2 (bytes)

02

ExpFlag

ExportedName

InternalName

ExportOrdinal

<conditional>

where:

02

identifies the subtype as an EXPDEF

ExpFlag

is a bit-significant 8-bit field.

< 1 byte >

OrdBit

ResidentName

NoData

ParmCount

1

1

1

< 5 bits >

OrdBit
Set if the item is exported by ordinal; in this case the ExportOrdinal field is present.
ResidentName
Set if the exported name is to be kept resident by the system loader; this is an optimization for frequently used items imported by name.
NoData
Set if the entry point does not use initialized data (either instanced or global).
ParmCount
Number of parameter words. The ParmCount field is set to zero for all but callgates to 16-bit segments.

Exported Name

in <count, char> string format. Name to be used when the entry point is imported by name.

Internal Name

in <count, char> string format. If the name length is zero, the internal name is the same as the Exported Name. Otherwise, it is the name by which the entry point known within this module. This name will appear as a PUBDEF or LPUBDEF name.

ExportOrdinal

present if the OrdBit is set; it is a 16-bit numeric whose value is the ordinal used (must be non-zero).

Note: EXPDEFs are produced by the compiler when the keyword _export is used in a source file.

5.6 88H INCDEF Incremental Compilation Record (comment class A0, subtype 03)

5.6.1 Description:

This record is used for incremental compilation. Every FIXUPP and LINNUM record following an INCDEF record will adjust all external index values and line number values by the appropriate delta. The deltas are cumulative if there is more than one INCDEF per module.

5.6.2 Record format:

The subrecord format is

Figure 2-7: INCDEF Incremental Compilation Record

1

2

2

<variable> (bytes)

03

EXTDEF delta

LINNUM delta

padding

The EXTDEF delta and LINNUM delta fields are signed.

Padding (zeros) is added by Quick C to allow for expansion of the object module during incremental compilation and linking.

Note: Negative deltas are allowed.

5.7 88H LNKDIR C++ Directives Record (comment class A0, subtype 05)

5.7.1 Description:

This record is used by the compiler to pass directives and flags to the linker.

5.7.2 Record format:

The subrecord format is

Figure 2-8: LNKDIR C++ Directives Record

1

1

1

1 (bytes)

05

Bit Flags

Pseudocode Vers

CV Vers

The format of the Bit Flags byte is:

< 1 byte >

0

0

0

0

0

Run MPC

Omit CV Publics

New EXE

1

1

1

1

1

1

1

1

The low-order bit, if set, indicates that LINK386 should output the new EXE format; this flag is ignored for all but linking of Pseudocode applications. (Pseudocode requires a segmented executable).

The second low-order bit indicates that LINK386 should not output the $PUBLICS subsection of the CodeView info.

The third low-order bit indicates that MPC (Microsoft Make Pseudocode Utility) should be run.

Pseudocode Version

One byte indicating the Pseudocode interpreter version number.

CodeView Version

One byte indicating the CodeView version number.

Note: The presence of this record in an object module will indicate the presence of global symbols records. The linker will not emit a Publics section for those modules with this comment record and a $SYMBOLS section.

5.8 88H LIBMOD Library Module Name Record (comment class A3)

5.8.1 Description:

The LIBMOD comment record is used only by the LIB utility, not by LINK. It gives the name of an object module within a library, allowing LIB to preserve the library file name in the THEADR record and still identify the module names that make up the library. Since the module names is the basename of the .OBJ file that was built into the library, it may be completely different from the final library name.

5.8.2 Record format:

The subrecord format is

Figure 2-9: LNKDIR Library Module Name Record

1

<variable> (bytes)

A3

Module Name

The record contains only the ASCII string of the module name, in <count, char> format. The module name has no path and no extension, just the base of the module name.

Note: LIB adds a LIBMOD record when a .OBJ file is added to a library and strips the LIBMOD record when a .OBJ file is removed from a library, so typically this record only exists in .LIB files.

5.9 88H EXESTR Executable String Record (comment class A4)

5.9.1 Description:

The EXESTR comment record implements the ANSI and XENIX/UNIX features in C:

5.9.2 Record format:

The subrecord format is

Figure 2-10: EXESTR Executable String Record

1

<variable> (bytes)

A4

arbitrary text

The linker will copy the text in the "arbitrary text" field byte for byte to the end of the executable file. The text will not be included in the program load image.

Note: If CodeView information is present, the text will not be at the end of the file, but somewhere before so as not to interfere with the Code View signature.

There is no limit to the number of EXESTR comment records.

5.10 88H INCERR Incremental Compilation Error Record(comment class A6)

5.10.1 Description:

This comment record will cause the linker to terminate with the fatal error saying something to the effect of "invalid object -- error encountered during incremental compilation".

The purpose of this is for the case when an incremental compilation fails and the user tries to manually link. The object module cannot be deleted, in order to preserve the base for the next incremental compilation.

5.10.2 Record format:

The subrecord format is

Figure 2-11: INCERR Incremental Compilation Error Record

1

(bytes)

A6

No fields

5.11 88H NOPAD No Segment Padding Record (comment class A7)

5.11.1 Description:

This comment record identifies a set of segments which are to be excluded from the padding imposed with the /PADDATA or /PADCODE options.

5.11.2 Record format:

The subrecord format is

Figure 2-12: NOPAD No Segment Padding Record

1

1 or 2 (bytes)

A7

SEGDEF Index

The SEGDEF Index is the standard OMF index type of 1 or 2 bytes. It may be repeated.

Note: LINK386 ignores NOPAD coment records.

5.12 88H WKEXT Weak Extern Record (comment class A8)

5.12.1 Description:

This record marks a set of external names as "weak", and for every weak extern associates another external name to use as the default resolution.

5.12.2 Record format:

The subrecord format is

Figure 2-13: WKEXT Weak Extern Record

1

1 or 2

1 or 2 (bytes)

A8

Weak EXTDEF Index

Default resolution EXTDEF Index

< Repeated >

The Weak EXTDEF Index field is the 1 or 2 byte index to the EXTDEF of the extern which is weak.

The Default Resolution EXTDEF Index is the 1 or 2 byte index to the EXTDEF of the extern that will be used to resolve the extern if no "stronger" link is found to resolve it.

Note: There are two ways to cancel the "weakness" of a weak extern; both result in the extern becoming a "strong" extern (the same as an EXTDEF). They are:

  1. if a PUBDEF for the weak extern is linked in,
  2. if an EXTDEF for the weak extern is found in another module (including libraries).

5.13 88H LZEXT Lazy Extern Record (comment class A9)

5.13.1 Description:

This record marks a set of external names as "lazy", and for every lazy extern associates another external name to use as the default resolution.

5.13.2 Record format:

The subrecord format is

Figure 2-14: LZEXT Lazy Extern Record

1

1 or 2

1 or 2 (bytes)

A9

Lazy EXTDEF Index

Default resolution EXTDEF Index

< Repeated >

The Lazy EXTDEF Index field is the 1 or 2 byte index to the EXTDEF of the extern which is weak.

The Default Resolution EXTDEF Index is the 1 or 2 byte index to the EXTDEF of the extern that will be used to resolve the extern if no "stronger" link is found to resolve it.

Note: There are two ways to cancel the "laziness" of a lazy extern; both result in the extern becoming a "strong" extern (the same as an EXTDEF). They are:

  1. if a PUBDEF for the weak extern is linked in,
  2. if an EXTDEF for the weak extern is found in another module (including libraries).

5.14 88H IDMDLL Identifier Manipulator DLL Record (comment class AF)

5.14.1 Description:

This record provides the name and initialization parameters of a DLL that will demangle the compiler generated mangled names. The linker will use this DLL when displaying error messages.

5.14.2 Record format:

The Subrecord Format is:

Figure 2-15: IDMDLL Identifier Manipulator DLL Record

1

1

<Name Length>

1

<Parms Length> (bytes)

AF

Name Length

DLL Name

Parms Length

Demangle Init Parameters

The Name Length byte gives the number of characters in the DLL Name; the DLL Name itself is ASCII.

The DLL Name is the name of the Identifier Manipulator Dynamic Link Library provided by the language. This DLL is used to demangle an internal identifier when that identifier will be displayed in an error message.

The Parms Length byte gives the number of characters in the Demangle Init Parameters; the Demangle Init Parameters itself is ASCII.

The Demangle Init Parameters provides information (to the DLL) on how internal identifiers are mangled.

The linker will not scan forward for an IDMDLL record when an identifier will be displayed. This record should occur near the beginning of the file.

IDMDLL class COMENT records are processed during pass 1 of the linker.

Note: Because object oriented compilers allow for two functions to have the same name but different parameters, the compiler uniquely identifies each function by changing the name of the function. This is known as mangling. An example of this would be:

User Prototype

Compiler Generated Mangled Name

void doit( int, float )
void doit( const char * )
_doit__Fif _doit__FCPc

INITDEMANGLEID

Receive initialization parameters specified in the IDMDLL COMENT record.

DEMANGLEID

Demangles first parameter (identifier, "_add__i_ii") to appropriate prototype (i.e. "int add(int, int)") and returns result in second parameter.

unsigned short pascal far INITDEMANGLEID(char far * psInitParms);
unsigned short pascal far DEMANGLEID(char far * psMangledName, char far * pszPrototype, unsigned long BufferLen);

Note: Languages may also wish to provide 32-bit functions for use by 32-bit linkers, when they become available. Function prototypes look like:

unsigned long _System InitDemangleID32(char * psInitParms);
unsigned long _System DemangleID32(char * psMangledName, char * pszPrototype, unsigned long BufferLen);

5.15 88H PharLap Format Record (comment class AA)

5.15.1 Description:

The OMF extension designed by PharLap is called "Easy OMF-386" and changes to the affected record types are described in this section.

Most modifications involve only a substitution of 32-bit (4-byte) fields for what were formerly 16-bit (2-byte) fields. In the two cases where the changes involve more than just a field size (in the SEGDEF and FIXUPP records), the information is mentioned in this section but complete details are given in the sections describing the specific records.

5.15.2 Record format:

The subrecord format is

Figure 2-16: PharLap Format Record

1

5 (bytes)

AA

"80386"

Note: The AA comment record should come immediately after the sole THEADR record. Presence of the comment record indicates that the following other record types have fields that are expanded from 16-bit to 32-bit values:

SEGDEF

offset field and offset field length

PUBDEF

offset field

LEDATA

offset field

LIDATA

offset field (note that repeat count field is still 16 bits)

FIXUPP

target displacement in explicit FIXUP subrecord

BLKDEF

return address offset field

LINNUM

offset field

MODEND

target displacement field

FIXUPP records have the added Loc values of 5 and 6. See § 5.23, "9CH or 9DH FIXUPP Fixup Record" for details.
SEGDEF records have added alignment values (for 4-byte alignment and 4K byte alignment) and an added optional byte at the end which contains the Use16/Use32 bit flag and access attributes (read/write/execute) for the segment. See § 5.21, "98H or 99H SEGDEF Segment Definition Record" for details.
LINK386 ignores PHARLAP coment records.

5.16 8AH or 8BH MODEND Module End Record

5.16.1 Description:

The MODEND record denotes the end of the object module. It also indicates whether the object module contains a main routine in a program, and it can, optionally, contain a reference to a programs entry point.

5.16.2 Record format:

Figure 2-17: MODEND Module End Record

1 Byte

2 Bytes

1 Byte

1 Byte

1 or 2

1 or 2

2 or 4 Bytes

1 Byte

8A or 8B

Record Length

Module Type

End Data

Frame Datum Index

Target Datum Index

Target Displacement

Chk Sum or 0

< Start Address (conditional) >

5.16.3 Module Type

The module type byte is bit-significant; layout is:

< 1 byte >

MATTR

Main Strt

Seg Bit

0

0

0

0

0

2 bits

1

1

1

1

1

1

where:

MATTR
is a 2-bit field

Main

is set if the module is a main module

Strt

is set if the module contains a start address; if this bit is set, the field starting with the EndDat byte is present and specifies the start address.

SegBit
Reserved. Only 0 is supported by OS/2.
X
This bit should be set (as described for OMF86). However, as is the case for the OMF86 linkers, the value will be ignored.

5.16.4 Start Address

The Start Address subfield is present only if the Strt bit in the Module Type byte is set. Its format is identical to the FixDat, Frame Datum, Target Datum, and Target displacement in a FIXUP subrecord of a FIXUPP record. The displacement (if present) is a 4 byte field if the record type is 8BH and is a 2-byte field if the record type is 8AH. This value provides the initial contents of CS:(E)IP.

The start address must be given in the MODEND record of the root module if overlays are used.

Note: A MODEND record can appear only as the last record in an object module.

It is assumed that the link pass separator comment record (COMENT A2, subtype 01) will not be present in a module whose MODEND record contains a program starting address.

5.17 8CH EXTDEF External Names Definition Record

5.17.1 Description:

The EXTDEF record contains a list of symbolic external references -- that is, references to symbols defined in other object modules. The linker resolves external references by matching the symbols declared in EXTDEF records with symbols declared in PUBDEF records.

5.17.2 Record format:

Figure 2-18: EXTDEF External Names Definition Record

1 Byte

2 Bytes

1 Byte

<string length>

1 or 2

1 Byte

8C

Record Length

String Length

External Name String

Type Index

Chk Sum or 0

< repeated >

This record provides a list of unresolved references, identified by name and with optional associated type information. The external names are ordered by occurrence jointly with the COMDEF and LEXTDEF records and referenced by an index in other records (FIXUPPs); the name may not be null. Indices start from one.

String Length is a 1-byte field containing the length of the name field that follows it. The length of the name is restricted to 255 bytes.

The Type Index is encoded as an index field and contains debug information. No type checking is performed by the linker.

Note: The linker imposes a limit of 1023 external names.

5.18 90H or 91H PUBDEF Public Names Definition Record

5.18.1 Description:

The PUBDEF record contains a list of public names. It makes items defined in this object module available to satisfy external references in other modules with which it is bound or linked.

The symbols are also available for export if so indicated in an EXPDEF comment record.

5.18.2 Record format:

Figure 2-19: PUBDEF Public Names Definition Record

1

2 Bytes

1 or 2

1 or 2

2 Bytes

1 Byte

<string length>

2 or 4

1 or 2

1 Byte

90 or 91

Record Length

Base Group Index

Base Segment Index

Base Frame

String Length

Public Name string

Public Offset

Type Index

Chk Sum or 0

<cond>

< repeated >

5.18.3 Base Group, Base Segment and Base Frame

The base group and segment are indices specifying previously defined SEGDEF and GRPDEF records. The group index may be zero, meaning that no group is associated with this PUBDEF record.

The Base Frame field is present only if the Base Segment is zero, but the content of the Base Frame is always ignored by the linker.

The Segment Index is normally nonzero and no Base Frame is present.

The Base Frame is normally used for absolute addressing when the Group and Segment Index are both zero. Absolute addressing is not fully supported in the linker.

5.18.4 Public name, Public Offset and Type Index

The public name string is in <count, char> form and cannot be null. The maximum length of a public name is 255 bytes.

The public offset is a 2 or 4 byte numeric field containing the offset of the location referred to by the public name.

This offset is assumed to lie within the segment, group or frame specified in the public base field.

The Type Index field is encoded in index format; it contains either debug type information or zero. This field is ignored by the OS/2 2.0 linker.

Note: All defined functions and initialized global variables generate PUBDEF records.

5.19 94H or 95H LINNUM Line Number Record

5.19.1 Description:

The LINNUM record relates line number within language source statements to addresses in the object code.

5.19.1 Record format:

Figure 2-20: LINNUM Line Number Record

1 Byte

2 Bytes

1 or 2

2 Bytes

<variable>

1 Byte

94 or 95

Record Length

Base Group Index

Base Segment Index

Debugger Style Specific Information

Chk Sum or 0

< repeated >

Associates a source line number with translated code or data. The LINNUM record is only generated when the debug option is selected and is therefore specific to the debug information. Refer to the specific debug documentation for more information.

5.19.3 Base Group and Base Segment

The Base group and Base segment are indices specifying previously defined GRPDEF and SEGDEF records. The group index is ignored. The segment index must be nonzero unless the debugger style is version 3 or greater of the IBM PM debugger format.

5.20 96H LNAMES List of Names Record

5.20.1 Description:

The LNAMES record is a list of names that can be referenced by subsequent SEGDEF and GRPDEF records in the object module.

The names are ordered by occurrence and referenced by index from subsequent records. More than one LNAMES record may appear.

The names themselves are used as segment, class and group names.

5.20.2 Record format:

Figure 2-21: LNAMES List of Names Record

1 Byte

2 Bytes

< string length >

1 Byte

96

Record Length

String Length

Name String

Chk Sum or 0

< repeated >

Each name appears in count/char format, and a null name is valid. The character set is ASCII.

Note: The linker imposes a limit of 255 logical names per object module.

Any LNAMES records in an object module must appear before the records that refer to them. Because it does not refer to any other type of object record, an LNAMES record usually appears near the start of an object module.

5.21 98H or 99H SEGDEF Segment Definition Record

5.21.1 Description:

The SEGDEF record describes a logical segment in an object module. It defines the segment's name, length and alignment, as well as the way the segment can be combined with other logical segments at bind, link and load time.

Object records that follow the SEGDEF record can refer to it to identify a particular segment. The SEGDEF records are ordered by occurrence and are referenced by segment indexes (origin 1) in subsequent records.

5.21.2 Record format:

Figure 2-22: SEGDEF Segment Definition Record

1 Byte

2 Bytes

<variable>

2 or 4 Bytes

1 or 2 Byte

1 or 2 Byte

1 or 2 Byte

1 Byte

98 or 99

Record Length

Segment Attribute

Segment Length

Segment Name Index

Class Name Index

Overlay Name Index

Chk Sum or 0

5.21.3 Segment Attributes

The segment attribute is bit-significant; the layout is:

3 bits

3 bits

1 bit

1bit

2 bytes

1 byte

A

C

B

P

Frame Number

Offset

<cond>

<cond>

The fields have the following meaning:

A

alignment, a 3-bit field, which specifies the alignment required when this program segment is placed within a logical segment. Values are:

0

absolute segment

1

relocatable, byte aligned

2

relocatable, word (2 byte, 16-bit) aligned

3

relocatable, paragraph (16 byte) aligned

4

relocatable, aligned on page (4K byte) boundary.

5

relocatable, aligned on double word (4 byte) boundary

6

not supported

7

not defined

The new values are A=4 and A=5. Dword alignment is expected to be useful as 32-bit memory paths become more prevalent. Page-align maps to the 80386 hardware page size of 4K bytes.

C

combination, a 3-bit field, which determines the way the program segment is mapped into a logical segment. Values are:

0

private, do not combine with any other program segment

1

reserved

2

public, combine by appending at an offset which meets the alignment requirement

3

reserved

4

same as C=2 (public)

5

stack, combine as for C=2.

6

common, combine by overlay using maximum size

7

same as C=2 (public)

B

big, used as the high order bit of the segment length field. If this bit is set the segment length value must be zero and the segment's size is 2ª32 or 4Gbytes long.

P

Holds the descriptor table B/D bit value (this is the descriptor table D bit for code segments and the B bit for data segments).
If zero, then segment is no larger than 64K (if data) and 16-bit addressing and operands are the default (if code). This is a Use16 segment.
If not zero, then the segment is no larger than 64k (if data) and 32-bit addressing and operands are the default (if code). This is a Use32 segment.

Note: This is the only method for defining Use32 segments.

Frame Number

Frame number from a previous FIXUPP record. Present only for an absolute segment (A=0).

Offset

Ignored by the linker. Present only for an absolute segment (A=0).

5.21.4 Segment Length

The Segment Length is a 2 or 4 byte numeric quantity and specifies the number of bytes in this program segment.

Note: For record type 98H, the length can be from 0 to 64K; if a segment is exactly 64KB in size, segment length should be 0 and the B field in the ACPB byte should be 1. For record type 99H, the length can be from 0 to 4G; If segment is exactly 4Gbytes in size, segment length should be set to zero and the B field in the ACBP byte should be set to 1.

5.21.5 Segment Name Index, Class Name Index, Overlay Name Index

The three name indices refer to names that appeared in previous LNAMES record(s). The linker ignores the overlay name index. The full name of a segment consists of the segment and class names. Segments in different object modules are normally combined according to the A and C values if their full names are identical. These indices must be nonzero, although the name itself may be null.

The segment name index identifies the segment with a name. the name need not be unique -- other segments of the same name will be concatenated onto the first segment with that name. The name may have been assigned by the programmer, or it may have been generated by the compiler.

The class name index identifies the segment with a class name (such as CODE, DATA or STACK). The linker places segments with the same class name into a contiguous area of memory in the run-time memory map.

The overlay index is ignored by the linker.

Note: The linker imposes a limit of 255 SEGDEF records per object module.

The following name/class combinations are reserved:

$$TYPE

Reserved for Debug types.

$$SYMBOLS

Reserved for Debug names.

CODE32

Reserved for IBM C Compiler.

DATA32

Reserved for IBM C Compiler.

CONST32

Reserved for IBM C Compiler.

BSS32

Reserved for IBM C Compiler.

DGROUP32

Reserved for IBM C Compiler.

5.22 9AH GRPDEF Group Definition Record

5.22.1 Description:

The GRPDEF record causes the program segments defined by SEGDEF records to be collected together (grouped). For OS/2 2.0, the segments are combined into a logical segment which is to be addressed through a single selector for flat memory.

5.22.2 Record format:

Figure 2-23: GRPDEF Group Definition Record

1 Byte

2 Bytes

1 or 2 Bytes

1 Byte

1 or 2 Bytes

1 Byte

9A

Record Length

Group Name Index

FF

Segment Def. Index

Chk Sum or 0

< repeated >

This record causes the program segments identified by SEGDEF records to be collected together (grouped) within a logical segment which is to be addressed through a single selector.

5.22.3 Group Name

The group name is specified as an index into a previously defined LNAMES name and must be nonzero.

Groups from different object modules are coalesced if their names are identical.

5.22.4 Group Components

The group's components are segments, specified as indices into previously defined SEGDEF records.

The first byte of each group component is a type field for the remainder of the component. The linker requires a type value of FFH and always assumes that the component contains a segment index value.

The component fields are usually repeated so that all segments constituting a group can be included in one GRPDEF record.

Note: This record is frequently followed by a THREAD fixup.

5.23 9CH or 9DH FIXUPP Fixup Record

5.23.1 Description:

The FIXUPP record contains information that allows the linker to resolve (fix up) and eventually relocate references between object modules. FIXUPP records describe the LOCATION of each address value to be fixed up, the TARGET address to which the fixup refers and the FRAME relative to which the address computation is performed.

5.23.3 Record format:

Figure 2-24: FIXUPP Fixup Record

1 Byte

2 Bytes

< from the record length >

1 Byte

9C or 9D

Record Length

THREAD subrecord or

FIXUP subrecord

Chk Sum or 0

< repeated >

Record type 9DH is new for LINK386; it has a Target Displacement field of 32 bits rather than 16 bits, and the LOC field of the LOCAT word has been extended to 4 bits (using the previously unused higher-order 'S' bit) to allow new LOC values of 9, 11 and 13.

Each subrecord in a FIXUPP object record either defines a thread for subsequent use, or refers to a data location in the nearest previous LEDATA or LIDATA record. The high order bit of the subrecord determines the subrecord type: if the high order bit is 0, the subrecord is a THREAD subrecord; if the high order bit is 1, the subrecord is a FIXUP subrecord. Subrecords of different types may be mixed within one object record.

Information that determines how to resolve a reference can be specified explicitly in a FIXUP subrecord, or can be specified within a FIXUP subrecord by a reference to a previous THREAD subrecord. A THREAD subrecord describes only the method to be used by the linker to refer to a particular target or frame. Because the same THREAD can be referenced in several subsequent FIXUP subrecords, a FIXUPP object record that uses THREADs may be smaller than one in which THREADs are not used.

THREAD subrecords can be referenced in the same object record in which they appear and also in subsequent FIXUPP object records.

5.23.3 THREAD

There are 4 frame threads and 4 target threads; not all need be defined and they can be redefined by later THREAD subrecords in the same or later FIXUPP object records. The frame threads are used to specify the Frame Datum field in a later FIXUP subrecord: the target threads are used to specify the Target Datum field in a later FIXUP subrecord.

A THREAD subrecord defines a thread, and does not require that a previous LEDATA or LIDATA record occur.

The layout of the THREAD subrecord is as follows:

< 1 Byte >

1 or 2 Bytes

0

D

0

METHOD

THRED

Index

1

1

1

3 bits

2 bits

<conditional>

0

The high order bit is zero to indicate that this is a THREAD subrecord.

D

is 0 for a target thread, 1 for a frame thread

METHOD

is a 3-bit field.
For target threads, only the lower two bits of the field are used; the high-order bit of the method is derived from the P bit in the FixDat field of the FIXUP subrecords that refer to this thread. The full list of methods is given here for completeness. This field determines the kind of index required to specify the Target Datum.

T0

specified by a SEGDEF index

T1

specified by a GRPDEF index

T2

specified by a EXTDEF index

T3

specified by an explicit frame number (not supported by the linker)

T4

specified by a SEGDEF index only; the displacement in the FIXUP subrecord is assumed to be 0.

T5

specified by a GRPDEF index only; the displacement in the FIXUP subrecord is assumed to be 0.

T6

specified by a EXTDEF index only; the displacement in the FIXUP subrecord is assumed to be 0.

The index type specified by the target thread method is encoded in the index field.
For frame threads, the method field determines the Frame Datum field of subsequent FIXUP subrecords that refer to this thread. Values for the method field are:

F0

the FRAME is specified by a SEGDEF index

F1

the FRAME is specified by a GRPDEF index

F2

the FRAME is specified by a EXTDEF index. The linker determines the FRAME from the external name's corresponding PUBDEF record in another object module, which specifies either a logical segment or a group.

F3

invalid (The FRAME is identified by an explicit frame number; this is not supported by the linker)

F4

the FRAME is determined by the segment index of the previous LEDATA or LIDATA record (i.e. the segment in which the location is defined).

F5

the FRAME is determined by the TARGET's segment, group or external index

F6

invalid

The index field is present for frame methods F0, F1, and F2 only.

THRED

is a 2-bit field and determines the thread number (0 through 3, for the 4 threads of each kind).

Index

is a conditional field that contains an index value that refers to a previous SEGDEF, GRPDEF or EXTDEF record. The field is only present if the thread method is 0, 1 or 2. If method 3 were supported by the linker, the Index field would contain an explicit frame number.

5.23.4 FIXUP

A FIXUP subrecord gives the how/what/why/where/who information required to convert a reference when program segments are combined or placed within logical segments. It applies to the nearest previous LEDATA or LIDATA record, which must be defined before the FIXUP. This FIXUP subrecord is as follows:

2 Bytes

1 Bytes

1 or 2 Bytes

1 or 2 Bytes

2 or 4 Bytes

LOCAT

FixDat

Frame Datum

Target Datum

Target Displacement

<cond>

<cond>

<conditional>

where the LOCAT field has an unusual format. Contrary to the usual byte order in Intel data structures, the most significant bits of the LOCAT field are found in the low-order, rather than the high-order byte.

The LOCAT field is:

< low byte >

< high byte >

1

M

LOC

Data Record Offset

1

1

4 bits

10 bits

where:

1

the high bit of the low-order byte is set to indicate a FIXUP subrecord.

M

is the mode, M=1 for segment-relative and M=0 for self-relative fixups

LOC

is a 4-bit field which determines what type of location is to be fixed up:

0

Low-order byte (8-bit displacement or low byte of 16-bit offset)

1

16-bit Offset

2

16-bit Base - logical segment base (selector)

3

32-bit Long pointer (16-bit base : 16-bit offset)

4

Hi-order byte (high byte of 16-bit offset) No linker support for this type.

5

16-bit loader-resolved offset, treated as LOC=1 by the linker

CONFLICT PharLap OMF uses LOC=5 to indicate a 32-bit offset, where Microsoft and IBM use LOC=9.

6

not defined, reserved

CONFLICT PharLap OMF uses LOC=6 to indicate a 48-bit pointer (16-bit base : 32-bit offset) where Microsoft and IBM use LOC=11.

7

not defined, reserved

9

32-bit offset

11

48-bit pointer (16-bit base : 32-bit offset)

13

32-bit loader-resolved offset, treated as LOC=9 by the linker

Data Record Offset

The Data record offset indicates the position of the location to be fixed up in the LEDATA or LIDATA record immediately preceding the FIXUPP record. This offset indicates either a byte in the data field of an LEDATA record or a data byte in the content field of an iterated data block in an LIDATA record.

The FixDat bit layout is:

F

FRAME

T

P

TARGT

1

3 bits

1

1

2 bits

and is interpreted as follows:

F

If F=1, the frame is given by a frame thread whose number is in the FRAME field (modulo 4). There is no frame datum field in the subrecord.
If F=0, the frame method (in the range F0 to F5) is explicitly defined in this FIXUP subrecord. The method is stored in the FRAME field.

FRAME

3-bit numeric, interpreted according to the F bit. The Frame Datum field is present and is an index field for frame methods F0, F1, and F2 only.

T

If T=1 the target is defined by a target thread whose thread number is given in the 2-bit TARGT field. The TARGT field contains a number between 0 and 3 that refers to a previous thread field containing the target method. The P bit, combined with the two low-order bits of the method field in the THREAD subrecord, determines the target method.
If T=0 the target is specified explicitly in this FIXUP subrecord. In this case, the P bit and the TARGT field can be considered a 3-bit field analogous to the FRAME field.

P

Determines whether the target displacement field is present.
If P=1 there is no displacement field.
If P=0, the displacement field is present.

TARGT

is a 2-bit numeric, which gives the lower two bits of the target method (if T=0) or gives the target thread number (if T=1).

Frame Datum

is an index field that refers to a previous SEGDEF, GRPDEF or EXTDEF record, depending on the FRAME method.

Target Datum

contains a segment index, a group index or an external index depending on the TARGET method.

Target Displacement

a 16-bit or 32-bit field is present only if the P bit in the FixDat field is set to 0, in which case the Target Displacement field contains the offset used in methods 0, 1 and 2 of specifying a TARGET.

Note: FIXUPP records are used to fix references in the immediately preceding LEDATA, LIDATA or COMDAT record.

The FRAME is the translator's way of telling the linker the contents of the segment register used for the reference; the TARGET is the item being referenced whose address was not completely resolved by the translator. In protect mode, the only legal segment register value are selectors; every segment and group of segments is mapped through some selector and addressed by offset within the underlying memory defined by that selector.

5.24 A0H or A1H LEDATA Logical Enumerated Data Record

5.24.1 Description:

This record provides contiguous binary data -- executable code or program data -- which is part of a program segment. The data is eventually copied into the program's executable binary image by the linker.

The data bytes may be subject to relocation or fix-up as determined by the presence of a subsequent FIXUPP record but otherwise requires no expansion when mapped to memory at run time.

5.24.2 Record Format:

Figure 2-25: LEDATA Logical Enumerated Data Record

1 Byte

2 Bytes

1 or 2 Bytes

2 or 4 Bytes

<from Record Length>

1 Byte

A0 or A1

Record Length

SegIndex

Enum Data Offset

Data Bytes

Chk Sum or 0

Record type A1H is new for LINK386; it has an Enumerated Data Offset field of 32 bits rather than 16 bits.

5.24.3 Segment Index

The SegIndex must be nonzero and is the index of a previously defined SEGDEF record. This is the segment into which the data in this LEDATA record is to be placed.

5.24.4 Enumerated Data Offset

The enumerated data offset is a 2 or 4 byte field (depending on the record type) which determines the offset at which the first data byte is to be placed relative to the start of the SEGDEF segment. Successive data bytes occupy successively higher locations.

5.24.5 Data Bytes

The maximum number of data bytes is 1024, so that a FIXUPP location field, which is 10 bits, can reference any of these data bytes. The number of data bytes is computed as the RecLength minus 5 minus the size of the SegIndex field (1 or 2 bytes).

Note: Record type A1H has offset stored as a 32-bit numeric. Record type A0 encodes the offset value as a 16-bit numeric (zero extended if applied to a Use32 segment).

If the LEDATA requires fixup, a FIXUPP record must immediately follow the LEDATA record.

5.25 A2H or A3H LIDATA Logical Iterated Data Record

5.25.1 Description:

Like the LEDATA record, the LIDATA record contains binary data -- executable code or program data. The data in an LIDATA record, however, is specified as a repeating pattern (iterated), rather than by explicit enumeration.

The data in an LIDATA record may be modified by the linker if the LIDATA record is immediately followed by a FIXUPP record.

5.25.2 Record format:

Figure 2-26: LIDATA Logical Iterated Data Record

1 Byte

2 Bytes

1 or 2 Bytes

4 Bytes

<from Record Length>

1 Byte

A2 or A3

Record Length

SegIndex

Data Offset

Data Block

Chk Sum or 0

< repeated >

Record type A3H is new for LINK386; it has Iterated Data Offset and Repeat Count fields of 32 bits rather than 16 bits.

5.25.3 Segment Index and Data Offset

The segment index and data offset (2 or 4 bytes) are the same as for an LEDATA record. The index must be nonzero.

5.25.4 Data Block

The data blocks have the following form:

2 or 4 Bytes

2 Bytes

< repeated >

Repeat Count

Block Count

Data Block

5.25.5 Repeat Count

The Repeat Count is a 16-bit or 32-bit value which determines the number of repeats of the content field. The Repeat Count is 32 bits only if the record type is A3.

CONFLICT: The PharLap OMF uses a 16-bit repeat count even in 32-bit records.

5.25.6 Block Count

The Block Count is a 16-bit word whose value determines the interpretation of the content portion, as follows:

0

indicates that the content field that follows is a one byte "count" value followed by "count" data bytes. The data bytes will be mapped to memory, repeated Repeat Count times.

!=0

indicates the content field that follows is comprised of one or more Data Blocks. The Block Count value specifies the number of Data Blocks (recursive definition).

Note: A subsequent FIXUPP record may occur; the fixup is applied before the iterated data block is expanded. It is a translator error for a fixup to reference any of the count fields.

5.26 B0H COMDEF Communal Names Definition Record

5.26.1 Description:

The COMDEF record declares a list of one or more communal variables (uninitialized static data, or data that may match initialized static data in another compilation group).

The size of such a variable is the maximum size defined in any module naming the variable as communal or public. The placement of communal variables is determined by the data type using established conventions (see data type and communal length below).

5.26.2 Record format:

Figure 2-27: COMDEF Communal Names Definition Record

1 Byte

2 Bytes

1 or 2

<string>

1 or 2 Bytes

1 Byte

<from data type>

1 Byte

B0

Record Length

Str. Len

Communal Name

Type Index

Data Type

Communal Length

Chk Sum or 0

< repeated >

5.26.3 Communal Name

The name is in <count, char> string format (and name may be null). Near and Far communals from different object files are matched at bind or link time if their names agree; the variable's size is the maximum of the sizes specified (subject to some constraints, as documented below).

5.26.4 Type Index

Encodes symbol information; it is parsed as an index field (one or 2 bytes), and not inspected by the linker.

5.26.5 Data Type and Communal Length

The data type field indicates the contents of the Communal Length field. All Data type values for Near data indicate that the Communal Length field has only one numeric value: the amount of memory to be allocated for the communal variable. All Data Type values for Far data indicate that the Communal Length field has two numeric values: the first is the number of elements and the second is the element size.

The DataType is one of the following hex values:

61H

FAR data; length specified as number of elements followed by element size in bytes.

62H

NEAR data; length specified as number of bytes.

The communal length is a single numeric or a pair of numeric fields (as specified by the Data Type), encoded as follows:

1 byte

value 0 through 128 (80 hex)

3 byte

byte 81 hex, followed by a 16-bit word whose value is used (range 0 to 64K-1)

4 byte

byte 84 hex, followed by a 3 byte value (range 0 to 16M-1)

5 byte

byte 88 hex, followed by a 4 byte value (range -2G-1 to 2G-1, signed)

Groups of name, type index, segment type and communal length fields can be repeated so that more than one communal variable can be declared in the same COMDEF record.

Note: If a public or exported symbol with the same name is found in another module with which this is bound or linked, the linker gives a multiple defined symbol error message,

5.27 B2H or B3H BAKPAT Backpatch Record

5.27.1 Description:

This record is for backpatches to locations which cannot be conveniently handled by a FIXUPP at reference time. For example, forward references in a one-pass compiler. It is essentially a specialized fixup.

5.27.2 Record format:

Figure 2-28: BAKPAT Backpatch Record

1 Byte

2 Bytes

1 or 2 Bytes

1 Byte

2 or 4 Bytes

2 or 4 Bytes

1 Byte

B2 or B3

Record Length

SegIndex

Loc Type

Offset

Value

Chk Sum or 0

< repeated >

SegIndex

Segment index to which all "backpatch" fixups are to be applied. Note that, in contrast to FIXUPPs, these records need not follow the data record to be fixed up. Hence, the segment to which the backpatch applies must be specified explicitly.

LocTyp

Type of location to be patched; the only valid values are:

0

8-bit lobyte

1

16-bit offset

9

32-bit offset, record type B3 only

Offset and value

Note: BAKPAT records can occur anywhere in the object module following the SEGDEF record to which they refer. They do not have to immediately follow the appropriate LEDATA record as FIXUPP record do.

These records are buffered by the linker in Pass 2 until the end of the module, after applying all other FIXUPPs. The linker then processes the records as fixups.

5.28 B4H or B5H LEXTDEF Local External Names Definition Record

5.28.1 Description:

This record is identical in form to the EXTDEF record described earlier. However, the symbols named in this record are not visible outside the module in which they are defined.

5.28.2 Record format:

Figure 2-29: LEXTDEF Local External Names Definition Record

1 Byte

2 Bytes

1 Byte

<string length>

1 or 2

1 Byte

B4 or B5

Record Length

String Length

External Name String

Type Index

Chk Sum or 0

< repeated >

Note: There is no semantic difference between the B4 and B5 flavors.

5.29 B6H or B7H LPUBDEF Local Public Names Definition Record

5.29.1 Description:

This record is identical in form to the PUBDEF record described earlier. However, the symbols named in this record are not visible outside the module in which they are defined.

5.29.2 Record format:

Figure 2-30: LPUBDEF Local Public Names Definition Record

1

2 Bytes

1 or 2

1 or 2

2 Bytes

1 Byte

<string length>

2 or 4

1 or 2

1 Byte

B6 or B7

Record Length

Base Group Index

Base Segment Index

Base Frame

String Length

Public Name string

Public Offset

Type Index

Chk Sum or 0

<cond>

< repeated >

5.30 B8H LCOMDEF Local Communal Names Definition Record

5.30.1 Description:

This record is identical in form to the COMDEF record described earlier. However, the symbols named in this record are not visible outside the module in which they are defined.

5.30.2 Record format:

Figure 2-31: LCOMDEF Local Communal Names Definition Record

1 Byte

2 Bytes

1 or 2

<string>

1 or 2 Bytes

1 Byte

<from data type>

1 Byte

B8

Record Length

Str. Len

Communal Name

Type Index

Data Type

Communal Length

Chk Sum or 0

< repeated >

5.31 C2H or C3H COMDAT Initialized Communal Data Record

5.31.1 Description:

The purpose of the COMDAT record is to combine logical blocks of code and data which may be duplicated across a number of compiled modules.

5.31.2 Record format:

Figure 2-32: COMDAT Initialized Communal Data Record

1

2

1

1

1

2 or 4

1 or 2

1 or 2

<string length>

1

1 Byte

C2 or C3

Record Length

Flag

Attr.

Align

Enum Data Offset

Type Index

Public Base

Public Name string

DAT

Chk Sum or 0

<con>

<repeat>

5.31.3 Flags

This field contains three defined bits:

01H

Continuation bit. If clear, then this COMDAT record establishes a new instance of the COMDAT variable, otherwise the data is a continuation of the previous COMDAT of the symbol.

02H

Iterated data bit. If clear, the DAT field contains enumerated data, otherwise the DAT field contains iterated data, as in an LIDATA record.

04H

Local COMDAT. The public name is local.

5.31.4 Attr

This field contains two 4-bit fields: the selection criteria to be used, the allocation type and the ordinal specifying the type of allocation to be performed. Values are:

Selection criteria (high-order 4 bits):

00H

No match - only one instance of this COMDAT allowed.

10H

Pick any - pick any instance of this COMDAT record.

20H

Same size - pick any, but instances must have the same length or linker will generate an error.

30H

Exact Match - pick any, but checksums of instances must match of linker will generate an error. Fixups are ignored.

40H - F0H

reserved.

Allocation Type (low-order 4 bits):

00H

Explicit - allocate in the segment specified in the ensuing public base field.

01H

Far Code - allocate as CODE16. The linker will create segments to contain all COMDATs of this type.

02H

Far DATA - allocate as DATA16. The linker will create segments to contain all COMDATs of this type.

03H

CODE32 - allocate as CODE32. The linker will create segments to contain all COMDATs of this type.

04H

DATA32 - allocate as DATA32. The linker will create segments to contain all COMDATs of this type.

05H - 0FH

Reserved.

5.31.5 Align

These codes are based on the ones used by the SEGDEF record:

0

use value from SEGDEF.

1

byte aligned.

2

word (2 byte) aligned.

3

paragraph (16 byte) aligned.

4

4K page aligned.

5

dword (4 byte) aligned.

6

not defined.

7

not defined.

5.31.6 Enum Data Offset

This field specifies an offset relative to the beginning location of the symbol specified in the public name field and defines the relative location of the first byte of the DAT field. Successive data bytes in the DAT field occupy higher locations of memory. This works very much like the offset field in an LEDATA record, but instead of an offset relative to a segment, this is relative to the beginning of the COMDAT symbol.

5.31.7 Type Index

The type index field is encoded in index format; it contains either debug type information or an old-style TYPDEF index. If this index is zero, there is no associated type data. Old-style TYPDEF indices are ignored by the linker. Present linkers do no type checking.

5.31.8 Public Base

This field is conditional and is identical to the public base stored in the public base field in the PUBDEF record. This field is only present if the allocation type field specifies explicit allocation.

5.31.9 Public Name

This field is a regular length prefixed name.

5.31.10 DAT

The DAT field provides up to 1024 consecutive bytes of data. If there are fixups, they must be emitted in a FIXUPP record that follows the COMDAT record. The data can be either enumerated or iterated, depending on the flags field.

Note: While creating addressing frames, the linker will add the COMDAT data to the appropriate logical segments, adjusting their sizes. At that time the offset at which the data will go inside the logical segment will be calculated. Next, the linker will create physical segments from adjusted logical segments reporting any 64K boundary overflows.

5.32 C4H or C5H LINSYM Symbol Line Numbers Record

5.32.1 Description:

This record will be used to output numbers for functions specified via COMDATs.

5.32.2 Record format:

Figure 2-33: LINSYM Symbol Line Numbers Record

1 Byte

2 Bytes

1 Byte

<variable>

2 Bytes

2 or 4 Bytes

1 Byte

C4 or C5

Record Length

Flags

Symbol Name Base

Line Number

Line Number Offset

Chk Sum or 0

< repeated >

5.32.3 Flags

This field contains two defined bits:

01H

Continuation bit. If clear, then this COMDAT record establishes a new instance of the COMDAT variable, otherwise the data is a continuation of the previous COMDAT of the symbol.

04H

Local COMDAT

The Symbol Name Base is a length-preceded name of the base of the LINSYM record.

The Line Number is an unsigned number in the range 0 to 65535.

The Line Number Offset field is the offset relative to the base specified by the symbol name base. The size of this field depends on the record type.

Note: Record type C5H identical to C4H except that the Line Number Offset field is 4 bytes instead of 2.

5.33 C6H ALIAS Alias Definition Record

5.33.1 Description:

This record has been introduced to support link-time aliasing, or a method by which compilers or assembles may direct the linker to substitute all references to one symbol for another.

5.33.2 Record format:

Figure 2-34: ALIAS Alias Definition Record

1 Byte

2 Bytes

<variable>

<variable>

1 Byte

C6

Record Length

Alias Name

Substitute Name

Chk Sum or 0

< repeated >

The Alias Name field is a regular length-preceded name of the alias symbol.

The Substitute Name field is a regular length-preceded name of the substitute symbol.

Note: The record will consist of two symbolic names: the alias symbol and the substitute symbol. The alias symbol behaves very much like a PUBDEF in that it must be unique. If a PUBDEF of an alias symbol is encountered or another ALIAS record with a different substitute symbol is encountered, a redefinition error should be emitted by the linker.

5.34 C8H or C9H NBKPAT Named Backpatch Record

5.34.1 Description:

The Named Backpatch record is like a BAKPAT record, except that it refers to a COMDAT, by name, rather than an LIDATA or LEDATA record.

5.34.2 Record format:

Figure 2-35: NBKPAT Named Backpatch Record

1 Byte

2 Bytes

1 Byte

<variable>

2 or 4 Bytes

2 or 4 Bytes

1 Byte

C8 or C9

Record Length

Loc Type

Public Name

Offset

Value

Chk Sum or 0

< repeated >

5.34.3 LocType

Type of location to be patched; the only valid values are:

0

8-bit byte

1

16-bit word

2

32-bit dword, record type C9 only

0x80

local COMDAT

5.34.4 Public Name

Length-preceded name of the COMDAT to back patch.

5.34.5 Offset and Value

These fields are 16-bits for record type C8, 32-bits for C9.

The Offset specifies the location to be patched, as an offset into the COMDAT.

The associated Value is added to the location being patched (unsigned addition, ignoring overflow). The Value field is fixed length (16-bit or 32-bit, depending on the record type) to make object module processing easier.


IBM OS/2 16/32-bit Object Module Format (OMF) Specification - 14 Jun 2001