diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /common/quicktime_win32/PEFBinaryFormat.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'common/quicktime_win32/PEFBinaryFormat.h')
| -rw-r--r-- | common/quicktime_win32/PEFBinaryFormat.h | 1111 |
1 files changed, 1111 insertions, 0 deletions
diff --git a/common/quicktime_win32/PEFBinaryFormat.h b/common/quicktime_win32/PEFBinaryFormat.h new file mode 100644 index 0000000..35dd3ef --- /dev/null +++ b/common/quicktime_win32/PEFBinaryFormat.h @@ -0,0 +1,1111 @@ +/* + File: PEFBinaryFormat.h + + Contains: PEF Types and Macros + + Version: QuickTime 7.3 + + Copyright: (c) 2007 (c) 1993-2001 by Apple Computer, Inc., all rights reserved. + + Bugs?: For bug reports, consult the following page on + the World Wide Web: + + http://developer.apple.com/bugreporter/ + +*/ + + +#ifndef __PEFBINARYFORMAT__ +#define __PEFBINARYFORMAT__ + +#ifndef __MACTYPES__ +#include <MacTypes.h> +#endif + + + + +#if PRAGMA_ONCE +#pragma once +#endif + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=mac68k +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(push, 2) +#elif PRAGMA_STRUCT_PACK + #pragma pack(2) +#endif + + + +/* -------------------------------------------------------------------------------------------- */ +/* Almost all types are padded for natural alignment. However the PEFExportedSymbol type is */ +/* 10 bytes long, containing two 32 bit fields and one 16 bit field. Arrays of it must be */ +/* packed, so it requires "68K" alignment. Setting this globally to 68K should also help */ +/* ensure consistent treatment across compilers. */ + + + +/* ======================================================================================== */ +/* Overall Structure */ +/* ================= */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* This header contains a complete set of types and macros for dealing with the PEF executable */ +/* format. While some description is provided, this header is not meant as a primary source */ +/* of documentation on PEF. An excellent specification of PEF can be found in the Macintosh */ +/* Runtime Architectures book. This header is primarily a physical format description. Thus */ +/* it depends on as few other headers as possible and structure fields have obvious sizes. */ +/* */ +/* The physical storage for a PEF executable is known as a "container". This refers to just */ +/* the executable itself, not the file etc. E.g. if five DLLs are packaged in a single file's */ +/* data fork, that one data fork has five containers within it. */ +/* */ +/* A PEF container consists of an overall header, followed by one or more section headers, */ +/* followed by the section name table, followed by the contents for the sections. Some kinds */ +/* of sections have specific internal representation. The "loader" section is the most common */ +/* of these special sections. It contains information on the exports, imports, and runtime */ +/* relocations required to prepare the executable. PEF containers are self contained, all */ +/* portions are located via relative offsets. */ +/* */ +/* */ +/* +-------------------------------+ */ +/* | Container Header | 40 bytes */ +/* +-------------------------------+ */ +/* | Section 0 header | 28 bytes each */ +/* |...............................| */ +/* | - - - - | */ +/* |...............................| */ +/* | Section n-1 header | */ +/* +-------------------------------+ */ +/* | Section Name Table | */ +/* +-------------------------------+ */ +/* | Section x raw data | */ +/* +-------------------------------+ */ +/* | - - - - | */ +/* +-------------------------------+ */ +/* | Section y raw data | */ +/* +-------------------------------+ */ +/* */ +/* */ +/* The sections are implicitly numbered from 0 to n according to the order of their headers. */ +/* The headers of the instantiated sections must precede those of the non-instantiated */ +/* sections. The ordering of the raw data is independent of the section header ordering. */ +/* Each section header contains the offset for that section's raw data. */ + + + +/* =========================================================================================== */ +/* Container Header */ +/* ================ */ + + + +struct PEFContainerHeader { + OSType tag1; /* Must contain 'Joy!'.*/ + OSType tag2; /* Must contain 'peff'. (Yes, with two 'f's.)*/ + OSType architecture; /* The ISA for code sections. Constants in CodeFragments.h.*/ + UInt32 formatVersion; /* The physical format version.*/ + UInt32 dateTimeStamp; /* Macintosh format creation/modification stamp.*/ + UInt32 oldDefVersion; /* Old definition version number for the code fragment.*/ + UInt32 oldImpVersion; /* Old implementation version number for the code fragment.*/ + UInt32 currentVersion; /* Current version number for the code fragment.*/ + UInt16 sectionCount; /* Total number of section headers that follow.*/ + UInt16 instSectionCount; /* Number of instantiated sections.*/ + UInt32 reservedA; /* Reserved, must be written as zero.*/ +}; +typedef struct PEFContainerHeader PEFContainerHeader; +enum { + kPEFTag1 = FOUR_CHAR_CODE('Joy!'), /* For non-Apple compilers: 0x4A6F7921.*/ + kPEFTag2 = FOUR_CHAR_CODE('peff'), /* For non-Apple compilers: 0x70656666.*/ + kPEFVersion = 0x00000001 +}; + + +enum { + kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader) +}; + +#define PEFFirstSectionNameOffset(container) \ + ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) ) + + + +/* =========================================================================================== */ +/* Section Headers */ +/* =============== */ + + + +struct PEFSectionHeader { + SInt32 nameOffset; /* Offset of name within the section name table, -1 => none.*/ + UInt32 defaultAddress; /* Default address, affects relocations.*/ + UInt32 totalLength; /* Fully expanded size in bytes of the section contents.*/ + UInt32 unpackedLength; /* Size in bytes of the "initialized" part of the contents.*/ + UInt32 containerLength; /* Size in bytes of the raw data in the container.*/ + UInt32 containerOffset; /* Offset of section's raw data.*/ + UInt8 sectionKind; /* Kind of section contents/usage.*/ + UInt8 shareKind; /* Sharing level, if a writeable section.*/ + UInt8 alignment; /* Preferred alignment, expressed as log 2.*/ + UInt8 reservedA; /* Reserved, must be zero.*/ +}; +typedef struct PEFSectionHeader PEFSectionHeader; +enum { + /* Values for the sectionKind field.*/ + /* Section kind values for instantiated sections.*/ + kPEFCodeSection = 0, /* Code, presumed pure & position independent.*/ + kPEFUnpackedDataSection = 1, /* Unpacked writeable data.*/ + kPEFPackedDataSection = 2, /* Packed writeable data.*/ + kPEFConstantSection = 3, /* Read-only data.*/ + kPEFExecDataSection = 6, /* Intermixed code and writeable data.*/ + /* Section kind values for non-instantiated sections.*/ + kPEFLoaderSection = 4, /* Loader tables.*/ + kPEFDebugSection = 5, /* Reserved for future use.*/ + kPEFExceptionSection = 7, /* Reserved for future use.*/ + kPEFTracebackSection = 8 /* Reserved for future use.*/ +}; + + +enum { + /* Values for the shareKind field.*/ + kPEFProcessShare = 1, /* Shared within a single process.*/ + kPEFGlobalShare = 4, /* Shared across the entire system.*/ + kPEFProtectedShare = 5 /* Readable across the entire system, writeable only to privileged code.*/ +}; + + + + +/* =========================================================================================== */ +/* Packed Data Contents */ +/* ==================== */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The raw contents of a packed data section are a sequence of byte codes. The basic format */ +/* has a 3 bit opcode followed by a 5 bit count. Additional bytes might be used to contain */ +/* counts larger than 31, and to contain a second or third count. Further additional bytes */ +/* contain actual data values to transfer. */ +/* */ +/* All counts are represented in a variable length manner. A zero in the initial 5 bit count */ +/* indicates the actual value follows. In this case, and for the second and third counts, the */ +/* count is represented as a variable length sequence of bytes. The bytes are stored in big */ +/* endian manner, most significant part first. The high order bit is set in all but the last */ +/* byte. The value is accumulated by shifting the current value up 7 bits and adding in the */ +/* low order 7 bits of the next byte. */ + + +enum { + /* The packed data opcodes.*/ + kPEFPkDataZero = 0, /* Zero fill "count" bytes.*/ + kPEFPkDataBlock = 1, /* Block copy "count" bytes.*/ + kPEFPkDataRepeat = 2, /* Repeat "count" bytes "count2"+1 times.*/ + kPEFPkDataRepeatBlock = 3, /* Interleaved repeated and unique data.*/ + kPEFPkDataRepeatZero = 4 /* Interleaved zero and unique data.*/ +}; + + +enum { + kPEFPkDataOpcodeShift = 5, + kPEFPkDataCount5Mask = 0x1F, + kPEFPkDataMaxCount5 = 31, + kPEFPkDataVCountShift = 7, + kPEFPkDataVCountMask = 0x7F, + kPEFPkDataVCountEndMask = 0x80 +}; + + +#define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift ) + +#define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask ) + +#define PEFPkDataComposeInstr(opcode,count5) \ + ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) ) + + + +/* -------------------------------------------------------------------------------------------- */ +/* The following code snippet can be used to input a variable length count. */ +/* */ +/* count = 0; */ +/* do { */ +/* byte = *bytePtr++; */ +/* count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask); */ +/* } while ( (byte & kPEFPkDataVCountEndMask) != 0 ); */ +/* */ +/* The following code snippet can be used to output a variable length count to a byte array. */ +/* This is more complex than the input code because the chunks are output in big endian order. */ +/* Think about handling values like 0 or 0x030000. */ +/* */ +/* count = 1;. */ +/* tempValue = value >> kPEFPkDataCountShift; */ +/* while ( tempValue != 0 ) { */ +/* count += 1; */ +/* tempValue = tempValue >> kPEFPkDataCountShift; */ +/* } */ +/* */ +/* bytePtr += count; */ +/* tempPtr = bytePtr - 1; */ +/* *tempPtr-- = value; // ! No need to mask, only the low order byte is stored. */ +/* for ( count -= 1; count != 0; count -= 1 ) { */ +/* value = value >> kPEFPkDataCountShift; */ +/* *tempPtr-- = value | kPEFPkDataCountEndMask; */ +/* } */ + + + +/* =========================================================================================== */ +/* Loader Section */ +/* ============== */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The loader section contains information needed to prepare the code fragment for execution. */ +/* This includes this fragment's exports, the import libraries and the imported symbols from */ +/* each library, and the relocations for the writeable sections. */ +/* */ +/* +-----------------------------------+ <-- containerOffset --------+ */ +/* | Loader Info Header | 56 bytes | */ +/* |-----------------------------------| | */ +/* | Imported Library 0 | 24 bytes each | */ +/* |...................................| | */ +/* | - - - | | */ +/* |...................................| | */ +/* | Imported Library l-1 | | */ +/* |-----------------------------------| | */ +/* | Imported Symbol 0 | 4 bytes each | */ +/* |...................................| | */ +/* | - - - | | */ +/* |...................................| | */ +/* | Imported Symbol i-1 | | */ +/* |-----------------------------------| | */ +/* | Relocation Header 0 | 12 bytes each | */ +/* |...................................| | */ +/* | - - - | | */ +/* |...................................| | */ +/* | Relocation Header r-1 | | */ +/* |-----------------------------------| <-- + relocInstrOffset -----| */ +/* | Relocation Instructions | | */ +/* |-----------------------------------| <-- + loaderStringsOffset --| */ +/* | Loader String Table | | */ +/* |-----------------------------------| <-- + exportHashOffset -----+ */ +/* | Export Hash Slot 0 | 4 bytes each */ +/* |...................................| */ +/* | - - - | */ +/* |...................................| */ +/* | Export Hash Slot h-1 | */ +/* |-----------------------------------| */ +/* | Export Symbol Key 0 | 4 bytes each */ +/* |...................................| */ +/* | - - - | */ +/* |...................................| */ +/* | Export Symbol Key e-1 | */ +/* |-----------------------------------| */ +/* | Export Symbol 0 | 10 bytes each */ +/* |...................................| */ +/* | - - - | */ +/* |...................................| */ +/* | Export Symbol e-1 | */ +/* +-----------------------------------+ */ + + + +struct PEFLoaderInfoHeader { + SInt32 mainSection; /* Section containing the main symbol, -1 => none.*/ + UInt32 mainOffset; /* Offset of main symbol.*/ + SInt32 initSection; /* Section containing the init routine's TVector, -1 => none.*/ + UInt32 initOffset; /* Offset of the init routine's TVector.*/ + SInt32 termSection; /* Section containing the term routine's TVector, -1 => none.*/ + UInt32 termOffset; /* Offset of the term routine's TVector.*/ + UInt32 importedLibraryCount; /* Number of imported libraries. ('l')*/ + UInt32 totalImportedSymbolCount; /* Total number of imported symbols. ('i')*/ + UInt32 relocSectionCount; /* Number of sections with relocations. ('r')*/ + UInt32 relocInstrOffset; /* Offset of the relocation instructions.*/ + UInt32 loaderStringsOffset; /* Offset of the loader string table.*/ + UInt32 exportHashOffset; /* Offset of the export hash table.*/ + UInt32 exportHashTablePower; /* Export hash table size as log 2. (Log2('h'))*/ + UInt32 exportedSymbolCount; /* Number of exported symbols. ('e')*/ +}; +typedef struct PEFLoaderInfoHeader PEFLoaderInfoHeader; + + +/* =========================================================================================== */ +/* Imported Libraries */ +/* ------------------ */ + + +struct PEFImportedLibrary { + UInt32 nameOffset; /* Loader string table offset of library's name.*/ + UInt32 oldImpVersion; /* Oldest compatible implementation version.*/ + UInt32 currentVersion; /* Current version at build time.*/ + UInt32 importedSymbolCount; /* Imported symbol count for this library.*/ + UInt32 firstImportedSymbol; /* Index of first imported symbol from this library.*/ + UInt8 options; /* Option bits for this library.*/ + UInt8 reservedA; /* Reserved, must be zero.*/ + UInt16 reservedB; /* Reserved, must be zero.*/ +}; +typedef struct PEFImportedLibrary PEFImportedLibrary; +enum { + /* Bits for the PEFImportedLibrary options field.*/ + kPEFWeakImportLibMask = 0x40, /* The imported library is allowed to be missing.*/ + kPEFInitLibBeforeMask = 0x80 /* The imported library must be initialized first.*/ +}; + + + + +/* =========================================================================================== */ +/* Imported Symbols */ +/* ---------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The PEFImportedSymbol type has the following bit field layout. */ +/* */ +/* 3 */ +/* 0 7 8 1 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | symbol class | offset of symbol name in loader string table | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 8 bits --->|<-- 24 bits ---------------------------------->| */ + + + +struct PEFImportedSymbol { + UInt32 classAndName; +}; +typedef struct PEFImportedSymbol PEFImportedSymbol; +enum { + kPEFImpSymClassShift = 24, + kPEFImpSymNameOffsetMask = 0x00FFFFFF, + kPEFImpSymMaxNameOffset = 0x00FFFFFF /* 16,777,215*/ +}; + +#define PEFImportedSymbolClass(classAndName) ((UInt8) ((classAndName) >> kPEFImpSymClassShift)) +#define PEFImportedSymbolNameOffset(classAndName) ((classAndName) & kPEFImpSymNameOffsetMask) + +#define PEFComposeImportedSymbol(class,nameOffset) \ + ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) ) + +enum { + /* Imported and exported symbol classes.*/ + kPEFCodeSymbol = 0x00, + kPEFDataSymbol = 0x01, + kPEFTVectorSymbol = 0x02, + kPEFTOCSymbol = 0x03, + kPEFGlueSymbol = 0x04, + kPEFUndefinedSymbol = 0x0F, + kPEFWeakImportSymMask = 0x80 +}; + + + + +/* =========================================================================================== */ +/* Exported Symbol Hash Table */ +/* -------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* Exported symbols are described in four parts, optimized for speed of lookup. These parts */ +/* are the "export hash table", the "export key table", the "export symbol table", and the */ +/* "export name table". Overall they contain a flattened representation of a fairly normal */ +/* hashed symbol table. */ +/* */ +/* The export hash table is an array of small fixed size elements. The number of elements is */ +/* a power of 2. A 32 bit hash word for a symbol is converted into an index into this array. */ +/* Each hash slot contains a count of the number of exported symbols that map to this slot and */ +/* the index of the first of those symbols in the key and symbol tables. Of course some hash */ +/* slots will have a zero count. */ +/* */ +/* The key and symbol tables are also arrays of fixed size elements, one for each exported */ +/* symbol. Their entries are grouped by hash slot, those elements mapping to the same hash */ +/* slot are contiguous. The key table contains just the full 32 bit hash word for each */ +/* exported symbol. The symbol table contains the offset of the symbol's name in the string */ +/* table and other information about the exported symbol. */ +/* */ +/* To look up an export you take the hashword and compute the hash slot index. You then scan */ +/* the indicated portion of the key table for matching hashwords. If a hashword matches, you */ +/* look at the corresponding symbol table entry to find the full symbol name. If the names */ +/* match the symbol is found. */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The following function may be used to compute the hash table size. Signed values are used */ +/* just to avoid potential code generation overhead for unsigned division. */ +/* */ +/* UInt8 PEFComputeHashTableExponent ( SInt32 exportCount ) */ +/* { */ +/* SInt32 exponent; */ +/* */ +/* const SInt32 kExponentLimit = 16; // Arbitrary, but must not exceed 30. */ +/* const SInt32 kAverageChainLimit = 10; // Arbitrary, for space/time tradeoff. */ +/* */ +/* for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) { */ +/* if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break; */ +/* } */ +/* */ +/* return exponent; */ +/* */ +/* } // PEFComputeHashTableExponent () */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The PEFExportedSymbolHashSlot type has the following bit field layout. */ +/* */ +/* 1 1 3 */ +/* 0 3 4 1 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | symbol count | index of first export key | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 14 bits -------------->|<-- 18 bits ---------------------->| */ + + + +struct PEFExportedSymbolHashSlot { + UInt32 countAndStart; +}; +typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot; +enum { + kPEFHashSlotSymCountShift = 18, + kPEFHashSlotFirstKeyMask = 0x0003FFFF, + kPEFHashSlotMaxSymbolCount = 0x00003FFF, /* 16,383*/ + kPEFHashSlotMaxKeyIndex = 0x0003FFFF /* 262,143*/ +}; + +#define PEFHashTableIndex(fullHashWord,hashTablePower) \ + ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) ) + +#define PEFHashSlotSymbolCount(countAndStart) ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift)) +#define PEFHashSlotFirstKey(countAndStart) ((countAndStart) & kPEFHashSlotFirstKeyMask) + +#define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey) \ + ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) ) + + + +/* =========================================================================================== */ +/* Exported Symbol Hash Key */ +/* ------------------------ */ + + + +struct PEFSplitHashWord { + UInt16 nameLength; + UInt16 hashValue; +}; +typedef struct PEFSplitHashWord PEFSplitHashWord; +struct PEFExportedSymbolKey { + union { + UInt32 fullHashWord; + PEFSplitHashWord splitHashWord; + } u; +}; +typedef struct PEFExportedSymbolKey PEFExportedSymbolKey; +enum { + kPEFHashLengthShift = 16, + kPEFHashValueMask = 0x0000FFFF, + kPEFHashMaxLength = 0x0000FFFF /* 65,535*/ +}; + +#define PEFHashNameLength(fullHashWord) ((UInt32) ((fullHashWord) >> kPEFHashLengthShift)) +#define PEFHashValue(fullHashWord) ((fullHashWord) & kPEFHashValueMask) + +#define PEFComposeFullHashWord(nameLength,hashValue) \ + ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) ) + + + +/* ---------------------------------------------------------------------------------------------------- */ +/* The following function computes the full 32 bit hash word. */ +/* */ +/* UInt32 PEFComputeHashWord ( BytePtr nameText, // ! First "letter", not length byte. */ +/* UInt32 nameLength ) // ! The text may be zero terminated. */ +/* { */ +/* BytePtr charPtr = nameText; */ +/* SInt32 hashValue = 0; // ! Signed to match old published algorithm. */ +/* UInt32 length = 0; */ +/* UInt32 limit; */ +/* UInt32 result; */ +/* UInt8 currChar; */ +/* */ +/* #define PseudoRotate(x) ( ( (x) << 1 ) - ( (x) >> 16 ) ) */ +/* */ +/* for ( limit = nameLength; limit > 0; limit -= 1 ) { */ +/* currChar = *charPtr++; */ +/* if ( currChar == NULL ) break; */ +/* length += 1; */ +/* hashValue = PseudoRotate ( hashValue ) ^ currChar; */ +/* } */ +/* */ +/* result = (length << kPEFHashLengthShift) | */ +/* ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask)); */ +/* */ +/* return result; */ +/* */ +/* } // PEFComputeHashWord () */ + + + +/* =========================================================================================== */ +/* Exported Symbols */ +/* ---------------- */ + + + +struct PEFExportedSymbol { /* ! This structure is 10 bytes long and arrays are packed.*/ + UInt32 classAndName; /* A combination of class and name offset.*/ + UInt32 symbolValue; /* Typically the symbol's offset within a section.*/ + SInt16 sectionIndex; /* The index of the section, or pseudo-section, for the symbol.*/ +}; +typedef struct PEFExportedSymbol PEFExportedSymbol; + +/* -------------------------------------------------------------------------------------------- */ +/* The classAndName field of the PEFExportedSymbol type has the following bit field layout. */ +/* */ +/* 3 */ +/* 0 7 8 1 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | symbol class | offset of symbol name in loader string table | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 8 bits --->|<-- 24 bits ---------------------------------->| */ + + +enum { + kPEFExpSymClassShift = 24, + kPEFExpSymNameOffsetMask = 0x00FFFFFF, + kPEFExpSymMaxNameOffset = 0x00FFFFFF /* 16,777,215*/ +}; + +#define PEFExportedSymbolClass(classAndName) ((UInt8) ((classAndName) >> kPEFExpSymClassShift)) +#define PEFExportedSymbolNameOffset(classAndName) ((classAndName) & kPEFExpSymNameOffsetMask) + +#define PEFComposeExportedSymbol(class,nameOffset) \ + ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) ) + +enum { + /* Negative section indices indicate pseudo-sections.*/ + kPEFAbsoluteExport = -2, /* The symbol value is an absolute address.*/ + kPEFReexportedImport = -3 /* The symbol value is the index of a reexported import.*/ +}; + + + + +/* =========================================================================================== */ +/* Loader Relocations */ +/* ================== */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The relocations for a section are defined by a sequence of instructions for an abstract */ +/* machine that is specifically geared to performing relocations commonly needed for the "CFM" */ +/* code generation model. These instructions occur in 16 bit chunks. Most instructions have */ +/* just a single chunk. Instructions that are larger than 16 bits have an opcode and some of */ +/* the operands in the first chunk, with other operands in following chunks. */ +/* */ +/* ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk. The */ +/* ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc. */ + + + + +typedef UInt16 PEFRelocChunk; +struct PEFLoaderRelocationHeader { + UInt16 sectionIndex; /* Index of the section to be fixed up.*/ + UInt16 reservedA; /* Reserved, must be zero.*/ + UInt32 relocCount; /* Number of 16 bit relocation chunks.*/ + UInt32 firstRelocOffset; /* Offset of first relocation instruction.*/ +}; +typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader; + +/* -------------------------------------------------------------------------------------------- */ +/* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the */ +/* ! total number of bytes of relocation instructions. While most relocation instructions are */ +/* ! 16 bits long, some are longer so the number of complete relocation instructions may be */ +/* ! less than the relocCount value. */ + + + +/* ------------------------------------------------------------------------------------ */ +/* The PEFRelocField macro is a utility for extracting relocation instruction fields. */ + + +#define PEFRFShift(offset,length) (16 - ((offset) + (length))) +#define PEFRFMask(length) ((1 << (length)) - 1) + +#define PEFRelocField(chunk,offset,length) \ + ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) ) + + + +/* =========================================================================================== */ +/* Basic Relocation Opcodes */ +/* ------------------------ */ + + +/* -------------------------------------------------------------------------------------------- */ +/* The number of opcode bits varies from 2 to 7. The enumeration and switch table given here */ +/* are defined in terms of the most significant 7 bits of the first instruction chunk. An */ +/* instruction is decoded by using the most significant 7 bits as an index into the opcode */ +/* table, which in turn contains appropriately masked forms of the most significant 7 bits. */ +/* The macro PEFRelocBasicOpcode assumes a declaration of the form. */ +/* */ +/* UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes }; */ + + +enum { + kPEFRelocBasicOpcodeRange = 128 +}; + +#define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9]) + + + +/* -------------------------------------------------------------------------------------------- */ +/* The relocation opcodes, clustered by major and minor groups. The instructions within a */ +/* cluster all have the same bit field layout. The enumeration values use the high order 7 */ +/* bits of the relocation instruction. Unused low order bits are set to zero. */ + +enum { + kPEFRelocBySectDWithSkip = 0x00, /* Binary: 00x_xxxx*/ + kPEFRelocBySectC = 0x20, /* Binary: 010_0000, group is "RelocRun"*/ + kPEFRelocBySectD = 0x21, /* Binary: 010_0001*/ + kPEFRelocTVector12 = 0x22, /* Binary: 010_0010*/ + kPEFRelocTVector8 = 0x23, /* Binary: 010_0011*/ + kPEFRelocVTable8 = 0x24, /* Binary: 010_0100*/ + kPEFRelocImportRun = 0x25, /* Binary: 010_0101*/ + kPEFRelocSmByImport = 0x30, /* Binary: 011_0000, group is "RelocSmIndex"*/ + kPEFRelocSmSetSectC = 0x31, /* Binary: 011_0001*/ + kPEFRelocSmSetSectD = 0x32, /* Binary: 011_0010*/ + kPEFRelocSmBySection = 0x33, /* Binary: 011_0011*/ + kPEFRelocIncrPosition = 0x40, /* Binary: 100_0xxx*/ + kPEFRelocSmRepeat = 0x48, /* Binary: 100_1xxx*/ + kPEFRelocSetPosition = 0x50, /* Binary: 101_000x*/ + kPEFRelocLgByImport = 0x52, /* Binary: 101_001x*/ + kPEFRelocLgRepeat = 0x58, /* Binary: 101_100x*/ + kPEFRelocLgSetOrBySection = 0x5A, /* Binary: 101_101x*/ + kPEFRelocUndefinedOpcode = 0xFF /* Used in masking table for all undefined values.*/ +}; + + + +/* ---------------------------------------------------------------------------- */ +/* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode */ +/* beyond the 7 used by the dispatch table. To be precise it has 6 plus 4 but */ +/* the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra */ +/* subopcode bits. */ + +enum { + kPEFRelocLgBySectionSubopcode = 0x00, /* Binary: 0000*/ + kPEFRelocLgSetSectCSubopcode = 0x01, /* Binary: 0001*/ + kPEFRelocLgSetSectDSubopcode = 0x02 /* Binary: 0010*/ +}; + +#define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F) + + + +/* -------------------------------------------------------------------------------------------- */ +/* The initial values for the opcode "masking" table. This has the enumeration values from */ +/* above with appropriate replications for "don't care" bits. It is almost certainly shorter */ +/* and faster to look up the masked value in a table than to use a branch tree. */ + + +#define PEFMaskedBasicOpcodes \ + \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x00 .. 0x03 */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x04 .. 0x07 */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x08 .. 0x0B */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x0C .. 0x0F */ \ + \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x10 .. 0x13 */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x14 .. 0x17 */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x18 .. 0x1B */ \ + kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, kPEFRelocBySectDWithSkip, /* 0x1C .. 0x1F */ \ + \ + kPEFRelocBySectC, kPEFRelocBySectD, kPEFRelocTVector12, kPEFRelocTVector8, /* 0x20 .. 0x23 */ \ + kPEFRelocVTable8, kPEFRelocImportRun, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x24 .. 0x27 */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x28 .. 0x2B */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x2C .. 0x2F */ \ + \ + kPEFRelocSmByImport, kPEFRelocSmSetSectC, kPEFRelocSmSetSectD, kPEFRelocSmBySection, /* 0x30 .. 0x33 */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x34 .. 0x37 */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x38 .. 0x3B */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x3C .. 0x3F */ \ + \ + kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, /* 0x40 .. 0x43 */ \ + kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, kPEFRelocIncrPosition, /* 0x44 .. 0x47 */ \ + \ + kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, /* 0x48 .. 0x4B */ \ + kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, kPEFRelocSmRepeat, /* 0x4C .. 0x4F */ \ + \ + kPEFRelocSetPosition, kPEFRelocSetPosition, kPEFRelocLgByImport, kPEFRelocLgByImport, /* 0x50 .. 0x53 */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x54 .. 0x57 */ \ + \ + kPEFRelocLgRepeat, kPEFRelocLgRepeat, kPEFRelocLgSetOrBySection, kPEFRelocLgSetOrBySection, /* 0x58 .. 0x5B */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x5C .. 0x5F */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x60 .. 0x63 */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x64 .. 0x67 */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x68 .. 0x6B */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x6C .. 0x6F */ \ + \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x70 .. 0x73 */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x74 .. 0x77 */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, /* 0x78 .. 0x7B */ \ + kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode, kPEFRelocUndefinedOpcode /* 0x7C .. 0x7F */ + + + +/* =========================================================================================== */ +/* RelocBySectDWithSkip Instruction (DDAT) */ +/* --------------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocBySectDWithSkip" (DDAT) instruction has the following bit field layout. */ +/* */ +/* 1 1 */ +/* 0 1 2 9 0 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |0 0| skip count | rel count | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | 2 |<-- 8 bits --->|<-- 6 --->| */ +/* */ +/* ! Note that the stored skip count and reloc count are the actual values! */ + +enum { + kPEFRelocWithSkipMaxSkipCount = 255, + kPEFRelocWithSkipMaxRelocCount = 63 +}; + +#define PEFRelocWithSkipSkipCount(chunk) PEFRelocField ( (chunk), 2, 8 ) +#define PEFRelocWithSkipRelocCount(chunk) PEFRelocField ( (chunk), 10, 6 ) + +#define PEFRelocComposeWithSkip(skipCount,relocCount) \ + ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) ) + + + +/* =========================================================================================== */ +/* RelocRun Group (CODE, DATA, DESC, DSC2, VTBL, SYMR) */ +/* --------------------------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocRun" group includes the "RelocBySectC" (CODE), "RelocBySectD" (DATA), */ +/* "RelocTVector12" (DESC), "RelocTVector8" (DSC2), "RelocVTable8" (VTBL), and */ +/* "RelocImportRun" (SYMR) instructions. This group has the following bit field layout. */ +/* */ +/* 1 */ +/* 0 2 3 6 7 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |0 1 0| subop.| run length | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | 3 |<- 4 ->|<-- 9 bits ----->| */ +/* */ +/* ! Note that the stored run length is the actual value minus 1, but the macros deal with the */ +/* ! actual value! */ + +enum { + kPEFRelocRunMaxRunLength = 512 +}; + +#define PEFRelocRunSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 ) +#define PEFRelocRunRunLength(chunk) (PEFRelocField ( (chunk), 7, 9 ) + 1) + +#define PEFRelocComposeRun(subopcode,runLength) \ + ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) ) + +#define PEFRelocComposeBySectC(runLength) PEFRelocComposeRun ( 0, (runLength) ) +#define PEFRelocComposeBySectD(runLength) PEFRelocComposeRun ( 1, (runLength) ) +#define PEFRelocComposeTVector12(runLength) PEFRelocComposeRun ( 2, (runLength) ) +#define PEFRelocComposeTVector8(runLength) PEFRelocComposeRun ( 3, (runLength) ) +#define PEFRelocComposeVTable8(runLength) PEFRelocComposeRun ( 4, (runLength) ) +#define PEFRelocComposeImportRun(runLength) PEFRelocComposeRun ( 5, (runLength) ) + + + +/* =========================================================================================== */ +/* RelocSmIndex Group (SYMB, CDIS, DTIS, SECN) */ +/* ------------------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocSmIndex" group includes the "RelocSmByImport" (SYMB), "RelocSmSetSectC" (CDIS), */ +/* "RelocSmSetSectD" (DTIS) and "RelocSmBySection" (SECN) instructions. This group has the */ +/* following bit field layout. */ +/* */ +/* 1 */ +/* 0 2 3 6 7 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |0 1 1| subop.| index | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* | 3 |<- 4 ->|<-- 9 bits ----->| */ +/* */ +/* ! Note that the stored index is the actual value! */ + +enum { + kPEFRelocSmIndexMaxIndex = 511 +}; + +#define PEFRelocSmIndexSubopcode(chunk) PEFRelocField ( (chunk), 3, 4 ) +#define PEFRelocSmIndexIndex(chunk) PEFRelocField ( (chunk), 7, 9 ) + +#define PEFRelocComposeSmIndex(subopcode,index) \ + ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) ) + +#define PEFRelocComposeSmByImport(index) PEFRelocComposeSmIndex ( 0, (index) ) +#define PEFRelocComposeSmSetSectC(index) PEFRelocComposeSmIndex ( 1, (index) ) +#define PEFRelocComposeSmSetSectD(index) PEFRelocComposeSmIndex ( 2, (index) ) +#define PEFRelocComposeSmBySection(index) PEFRelocComposeSmIndex ( 3, (index) ) + + + +/* =========================================================================================== */ +/* RelocIncrPosition Instruction (DELT) */ +/* ------------------------------------ */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocIncrPosition" (DELT) instruction has the following bit field layout. */ +/* */ +/* 1 */ +/* 0 3 4 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 0 0| offset | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<- 4 ->|<-- 12 bits ---------->| */ +/* */ +/* ! Note that the stored offset is the actual value minus 1, but the macros deal with the */ +/* ! actual value! */ + +enum { + kPEFRelocIncrPositionMaxOffset = 4096 +}; + +#define PEFRelocIncrPositionOffset(chunk) (PEFRelocField ( (chunk), 4, 12 ) + 1) + +#define PEFRelocComposeIncrPosition(offset) \ + ( 0x8000 | ((UInt16)((offset)-1)) ) + + + +/* =========================================================================================== */ +/* RelocSmRepeat Instruction (RPT) */ +/* ------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocSmRepeat" (RPT) instruction has the following bit field layout. */ +/* */ +/* 1 */ +/* 0 3 4 7 8 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 0 1| chnks | repeat count | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<- 4 ->|<- 4 ->|<-- 8 bits --->| */ +/* */ +/* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the */ +/* ! macros deal with the actual values! */ + +enum { + kPEFRelocSmRepeatMaxChunkCount = 16, + kPEFRelocSmRepeatMaxRepeatCount = 256 +}; + +#define PEFRelocSmRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 4, 4 ) + 1) +#define PEFRelocSmRepeatRepeatCount(chunk) (PEFRelocField ( (chunk), 8, 8 ) + 1) + +#define PEFRelocComposeSmRepeat(chunkCount,repeatCount) \ + ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) ) + + + +/* =========================================================================================== */ +/* RelocSetPosition Instruction (LABS) */ +/* ----------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocSetPosition" (LABS) instruction has the following bit field layout. */ +/* */ +/* 1 1 */ +/* 0 5 6 5 0 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 1 0 0 0| offset (high) | | offset (low) | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| */ +/* */ +/* ! Note that the stored offset is the actual value! */ + +enum { + kPEFRelocSetPosMaxOffset = 0x03FFFFFF /* 67,108,863*/ +}; + +#define PEFRelocSetPosOffsetHigh(chunk) PEFRelocField ( (chunk), 6, 10 ) + +#define PEFRelocSetPosFullOffset(firstChunk,secondChunk) \ + ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) ) + +#define PEFRelocComposeSetPosition_1st(fullOffset) \ + ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) ) +#define PEFRelocComposeSetPosition_2nd(fullOffset) \ + ( (UInt16) ((UInt32)(fullOffset) & 0xFFFF) ) + + + +/* =========================================================================================== */ +/* RelocLgByImport Instruction (LSYM) */ +/* ---------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocLgByImport" (LSYM) instruction has the following bit field layout. */ +/* */ +/* 1 1 */ +/* 0 5 6 5 0 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 1 0 0 1| index (high) | | index (low) | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 6 ---->|<-- 10 bits ------>| |<-- 16 bits ------------------>| */ +/* */ +/* ! Note that the stored offset is the actual value! */ + +enum { + kPEFRelocLgByImportMaxIndex = 0x03FFFFFF /* 67,108,863*/ +}; + +#define PEFRelocLgByImportIndexHigh(chunk) PEFRelocField ( (chunk), 6, 10 ) + +#define PEFRelocLgByImportFullIndex(firstChunk,secondChunk) \ + ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) ) + +#define PEFRelocComposeLgByImport_1st(fullIndex) \ + ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) ) +#define PEFRelocComposeLgByImport_2nd(fullIndex) \ + ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) ) + + + +/* =========================================================================================== */ +/* RelocLgRepeat Instruction (LRPT) */ +/* -------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocLgRepeat" (LRPT) instruction has the following bit field layout. */ +/* */ +/* 1 1 1 */ +/* 0 5 6 9 0 5 0 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 1 1 0 0| chnks | rpt (high)| | repeat count (low) | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| */ +/* */ +/* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with */ +/* ! the actual value! The stored repeat count is the actual value! */ + +enum { + kPEFRelocLgRepeatMaxChunkCount = 16, + kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF /* 4,194,303*/ +}; + +#define PEFRelocLgRepeatChunkCount(chunk) (PEFRelocField ( (chunk), 6, 4 ) + 1) +#define PEFRelocLgRepeatRepeatCountHigh(chunk) PEFRelocField ( (chunk), 10, 6 ) + +#define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk) \ + ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) ) + +#define PEFRelocComposeLgRepeat_1st(chunkCount,fullRepeatCount) \ + ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) ) +#define PEFRelocComposeLgRepeat_2nd(chunkCount,fullRepeatCount) \ + ( (UInt16) ((UInt32)(fullRepeatCount) & 0xFFFF) ) + + + +/* =========================================================================================== */ +/* RelocLgSetOrBySection Group (LSEC) */ +/* ---------------------------------- */ + + + +/* -------------------------------------------------------------------------------------------- */ +/* The "RelocLgSetOrBySection" (LSEC) instruction is a group including the "RelocLgBySection", */ +/* "RelocLgSetSectC" and "RelocLgSetSectD" instructions. This group has the following bit */ +/* field layout. */ +/* */ +/* 1 1 1 */ +/* 0 5 6 9 0 5 0 5 */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |1 0 1 1 0 1| subop | idx (high)| | index (low) | */ +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/* |<-- 6 --->|<- 4 ->|<-- 6 --->| |<-- 16 bits ------------------>| */ +/* */ +/* ! Note that the stored index is the actual value! */ + +enum { + kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF /* 4,194,303*/ +}; + +#define PEFRelocLgSetOrBySectionSubopcode(chunk) PEFRelocField ( (chunk), 6, 4 ) +#define PEFRelocLgSetOrBySectionIndexHigh(chunk) PEFRelocField ( (chunk), 10, 6 ) + +#define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk) \ + ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) ) + +#define PEFRelocComposeLgSetOrBySection_1st(subopcode,fullIndex) \ + ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) ) +#define PEFRelocComposeLgSetOrBySection_2nd(subopcode,fullIndex) \ + ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) ) + +#define PEFRelocComposeLgBySection(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) ) +#define PEFRelocComposeLgSetSectC(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) ) +#define PEFRelocComposeLgSetSectD(fullIndex) PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) ) + + + +#if PRAGMA_STRUCT_ALIGN + #pragma options align=reset +#elif PRAGMA_STRUCT_PACKPUSH + #pragma pack(pop) +#elif PRAGMA_STRUCT_PACK + #pragma pack() +#endif + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif + + +#endif /* __PEFBINARYFORMAT__ */ + |