kolibrios-gitea/programs/develop/objconv/coff.h
turbocat 60a4b1c9ef Added objconv port.
git-svn-id: svn://kolibrios.org@9683 a494cfbc-eb01-0410-851d-a64ba20cac60
2022-02-06 11:09:00 +00:00

538 lines
23 KiB
C

/**************************** coff.h *************************************
* Author: Agner Fog
* Date created: 2006-07-15
* Last modified: 2008-06-04
* Project: objconv
* Module: coff.h
* Description:
* Header file for definition of structures in MS Windows COFF Intel x86 (PE)
* object file format.
*
* Copyright 2006-2008 GNU General Public License http://www.gnu.org/licenses
* Parts (c) 1995 DJ Delorie GNU General Public License
*****************************************************************************/
/*****************************************************************************
* Note: The COFF data structures do not fit the default alignment of modern
* compilers. All structures should be compiled without any alignment padding.
* The specification of structure packing is not standardized among compilers.
* You may remove or replace the #pragma pack directives if you make sure that
* you never use the sizeof() operator or pointer arithmetics on any of the
* structures that need packing. See coff.cpp for examples.
*****************************************************************************/
#ifndef PECOFF_H
#define PECOFF_H
/********************** FILE HEADER **********************/
struct SCOFF_FileHeader {
uint16 Machine; // Machine ID (magic number)
uint16 NumberOfSections; // number of sections
uint32 TimeDateStamp; // time & date stamp
uint32 PSymbolTable; // file pointer to symbol table
uint32 NumberOfSymbols; // number of symbol table entries
uint16 SizeOfOptionalHeader; // size of optional header
uint16 Flags; // Flags indicating attributes
};
// Values of Machine:
#define PE_MACHINE_I386 0x14c
#define PE_MACHINE_X8664 0x8664
// Bits for Flags:
#define PE_F_RELFLG 0x0001 // relocation info stripped from file
#define PE_F_EXEC 0x0002 // file is executable (no unresolved external references)
#define PE_F_LNNO 0x0004 // line numbers stripped from file
#define PE_F_LSYMS 0x0008 // local symbols stripped from file
// Structure used in optional header
struct SCOFF_IMAGE_DATA_DIRECTORY {
uint32 VirtualAddress; // Image relative address of table
uint32 Size; // Size of table
};
// Extended structure used internally with virtual address translated to section:offset
struct SCOFF_ImageDirAddress : public SCOFF_IMAGE_DATA_DIRECTORY {
int32 Section; // Section containing table
uint32 SectionOffset; // Offset relative to section
uint32 FileOffset; // Offset relative to file
uint32 MaxOffset; // Section size - SectionOffset
const char * Name; // Name of table
};
// Optional header
union SCOFF_OptionalHeader {
// 32 bit version
struct {
uint16 Magic; // Magic number
uint8 LinkerMajorVersion;
uint8 LinkerMinorVersion;
uint32 SizeOfCode;
uint32 SizeOfInitializedData;
uint32 SizeOfUninitializedData;
uint32 AddressOfEntryPoint; // Entry point relative to image base
uint32 BaseOfCode;
uint32 BaseOfData;
// Windows specific fields
int32 ImageBase; // Image base
uint32 SectionAlignment;
uint32 FileAlignment;
uint16 MajorOperatingSystemVersion;
uint16 MinorOperatingSystemVersion;
uint16 MajorImageVersion;
uint16 MinorImageVersion;
uint16 MajorSubsystemVersion;
uint16 MinorSubsystemVersion;
uint32 Win32VersionValue; // must be 0
uint32 SizeOfImage;
uint32 SizeOfHeaders;
uint32 CheckSum;
uint16 Subsystem;
uint16 DllCharacteristics;
uint32 SizeOfStackReserve;
uint32 SizeOfStackCommit;
uint32 SizeOfHeapReserve;
uint32 SizeOfHeapCommit;
uint32 LoaderFlags; // 0
uint32 NumberOfRvaAndSizes;
// Data directories
SCOFF_IMAGE_DATA_DIRECTORY ExportTable;
SCOFF_IMAGE_DATA_DIRECTORY ImportTable;
SCOFF_IMAGE_DATA_DIRECTORY ResourceTable;
SCOFF_IMAGE_DATA_DIRECTORY ExceptionTable;
SCOFF_IMAGE_DATA_DIRECTORY CertificateTable;
SCOFF_IMAGE_DATA_DIRECTORY BaseRelocationTable;
SCOFF_IMAGE_DATA_DIRECTORY Debug;
SCOFF_IMAGE_DATA_DIRECTORY Architecture; // 0
SCOFF_IMAGE_DATA_DIRECTORY GlobalPtr; // 0
SCOFF_IMAGE_DATA_DIRECTORY TLSTable;
SCOFF_IMAGE_DATA_DIRECTORY LoadConfigTable;
SCOFF_IMAGE_DATA_DIRECTORY BoundImportTable;
SCOFF_IMAGE_DATA_DIRECTORY ImportAddressTable;
SCOFF_IMAGE_DATA_DIRECTORY DelayImportDescriptor;
SCOFF_IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
SCOFF_IMAGE_DATA_DIRECTORY Reserved; // 0
} h32;
// 64 bit version
struct {
uint16 Magic; // Magic number
uint8 LinkerMajorVersion;
uint8 LinkerMinorVersion;
uint32 SizeOfCode;
uint32 SizeOfInitializedData;
uint32 SizeOfUninitializedData;
uint32 AddressOfEntryPoint; // Entry point relative to image base
uint32 BaseOfCode;
// Windows specific fields
int64 ImageBase; // Image base
uint32 SectionAlignment;
uint32 FileAlignment;
uint16 MajorOperatingSystemVersion;
uint16 MinorOperatingSystemVersion;
uint16 MajorImageVersion;
uint16 MinorImageVersion;
uint16 MajorSubsystemVersion;
uint16 MinorSubsystemVersion;
uint32 Win32VersionValue; // must be 0
uint32 SizeOfImage;
uint32 SizeOfHeaders;
uint32 CheckSum;
uint16 Subsystem;
uint16 DllCharacteristics;
uint64 SizeOfStackReserve;
uint64 SizeOfStackCommit;
uint64 SizeOfHeapReserve;
uint64 SizeOfHeapCommit;
uint32 LoaderFlags; // 0
uint32 NumberOfRvaAndSizes;
// Data directories
SCOFF_IMAGE_DATA_DIRECTORY ExportTable;
SCOFF_IMAGE_DATA_DIRECTORY ImportTable;
SCOFF_IMAGE_DATA_DIRECTORY ResourceTable;
SCOFF_IMAGE_DATA_DIRECTORY ExceptionTable;
SCOFF_IMAGE_DATA_DIRECTORY CertificateTable;
SCOFF_IMAGE_DATA_DIRECTORY BaseRelocationTable;
SCOFF_IMAGE_DATA_DIRECTORY Debug;
SCOFF_IMAGE_DATA_DIRECTORY Architecture; // 0
SCOFF_IMAGE_DATA_DIRECTORY GlobalPtr; // 0
SCOFF_IMAGE_DATA_DIRECTORY TLSTable;
SCOFF_IMAGE_DATA_DIRECTORY LoadConfigTable;
SCOFF_IMAGE_DATA_DIRECTORY BoundImportTable;
SCOFF_IMAGE_DATA_DIRECTORY ImportAddressTable;
SCOFF_IMAGE_DATA_DIRECTORY DelayImportDescriptor;
SCOFF_IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
SCOFF_IMAGE_DATA_DIRECTORY Reserved; // 0
} h64;
};
// Value of Magic for optional header
#define COFF_Magic_PE32 0x10B
#define COFF_Magic_PE64 0x20B
// Export directory table
struct SCOFF_ExportDirectory {
uint32 Flags;
uint32 DateTime;
uint16 VersionMajor;
uint16 VersionMinor;
uint32 DLLNameRVA; // Image-relative address of DLL name
uint32 OrdinalBase; // Ordinal number of first export
uint32 AddressTableEntries; // Number of entries in export address table
uint32 NamePointerEntries; // Number of entries in name pointer table
uint32 ExportAddressTableRVA; // Image-relative address of export address table
uint32 NamePointerTableRVA; // Image-relative address of export name pointer table
uint32 OrdinalTableRVA; // Image-relative address of ordinal table
};
// Import directory table
struct SCOFF_ImportDirectory {
uint32 ImportLookupTableRVA; // Image-relative address of import lookup table
uint32 DateTime;
uint32 ForwarderChain;
uint32 DLLNameRVA; // Image-relative address of DLL name string
uint32 ImportAddressTableRVA; // Image-relative address of import address table
};
// Import hint/name table entry
struct SCOFF_ImportHintName {
uint16 Hint; // Index into export name pointer table
char Name[2]; // Variable length
};
// Base relocation block header
struct SCOFF_BaseRelocationBlock {
uint32 PageRVA; // Image-relative base to add to offset
uint32 BlockSize; // Size of SCOFF_BaseRelocationBlock plus all SCOFF_BaseRelocation
};
// Base relocation block entry
struct SCOFF_BaseRelocation {
uint16 Offset:12; // Offset relative to PageRVA
uint16 Type:4; // Base relocation type
};
// Base relocation types
#define COFF_REL_BASED_ABSOLUTE 0 // Ignore
#define COFF_REL_BASED_HIGH 1 // High 16 bits
#define COFF_REL_BASED_LOW 2 // Low 16 bits
#define COFF_REL_BASED_HIGHLOW 3 // 32 bits
#define COFF_REL_BASED_HIGHADJ 4 // Two consecutive records: 16 bits high, 16 bits low
#define COFF_REL_BASED_DIR64 10 // 64 bits
/********************** SECTION HEADER **********************/
struct SCOFF_SectionHeader {
char Name[8]; // section name
uint32 VirtualSize; // size of section when loaded. (Should be 0 for object files, but it seems to be accumulated size of all sections)
uint32 VirtualAddress; // subtracted from offsets during relocation. preferably 0
uint32 SizeOfRawData; // section size in file
uint32 PRawData; // file to raw data for section
uint32 PRelocations; // file to relocation entries
uint32 PLineNumbers; // file to line number entries
uint16 NRelocations; // number of relocation entries
uint16 NLineNumbers; // number of line number entries
uint32 Flags; // flags
};
// Section flags values
#define PE_SCN_CNT_CODE 0x00000020 // section contains executable code
#define PE_SCN_CNT_INIT_DATA 0x00000040 // section contains initialized data
#define PE_SCN_CNT_UNINIT_DATA 0x00000080 // section contains unintialized data
#define PE_SCN_LNK_INFO 0x00000200 // section contains comments or .drectve
#define PE_SCN_LNK_REMOVE 0x00000800 // will not be part of the image. object files only
#define PE_SCN_LNK_COMDAT 0x00001000 // section contains communal data
#define PE_SCN_ALIGN_1 0x00100000 // Align data by 1
#define PE_SCN_ALIGN_2 0x00200000 // Align data by 2
#define PE_SCN_ALIGN_4 0x00300000 // Align data by 4
#define PE_SCN_ALIGN_8 0x00400000 // Align data by 8
#define PE_SCN_ALIGN_16 0x00500000 // Align data by 16
#define PE_SCN_ALIGN_32 0x00600000 // Align data by 32
#define PE_SCN_ALIGN_64 0x00700000 // Align data by 64
#define PE_SCN_ALIGN_128 0x00800000 // Align data by 128
#define PE_SCN_ALIGN_256 0x00900000 // Align data by 256
#define PE_SCN_ALIGN_512 0x00a00000 // Align data by 512
#define PE_SCN_ALIGN_1024 0x00b00000 // Align data by 1024
#define PE_SCN_ALIGN_2048 0x00c00000 // Align data by 2048
#define PE_SCN_ALIGN_4096 0x00d00000 // Align data by 4096
#define PE_SCN_ALIGN_8192 0x00e00000 // Align data by 8192
#define PE_SCN_ALIGN_MASK 0x00f00000 // Mask for extracting alignment info
#define PE_SCN_LNK_NRELOC_OVFL 0x01000000 // section contains extended relocations
#define PE_SCN_MEM_DISCARDABLE 0x02000000 // section is discardable
#define PE_SCN_MEM_NOT_CACHED 0x04000000 // section cannot be cached
#define PE_SCN_MEM_NOT_PAGED 0x08000000 // section is not pageable
#define PE_SCN_MEM_SHARED 0x10000000 // section can be shared
#define PE_SCN_MEM_EXECUTE 0x20000000 // section is executable
#define PE_SCN_MEM_READ 0x40000000 // section is readable
#define PE_SCN_MEM_WRITE 0x80000000 // section is writeable
/* names of "special" sections
#define _TEXT ".text"
#define _DATA ".data"
#define _BSS ".bss"
#define _COMMENT ".comment"
#define _LIB ".lib" */
/********************** LINE NUMBERS **********************/
/* 1 line number entry for every "breakpointable" source line in a section.
* Line numbers are grouped on a per function basis; first entry in a function
* grouping will have l_lnno = 0 and in place of physical address will be the
* symbol table index of the function name.
*/
//#pragma pack(push, 1)
struct SCOFF_LineNumbers {
union {
uint32 Fname; // function name symbol table index, if Line == 0
uint32 Addr; // section-relative address of code that corresponds to line
};
uint16 Line; // line number
};
// Warning: Size does not fit standard alignment!
// Use SIZE_SCOFF_LineNumbers instead of sizeof(SCOFF_LineNumbers)
#define SIZE_SCOFF_LineNumbers 6 // Size of SCOFF_LineNumbers packed
//#pragma pack(pop)
/******** Symbol table entry and auxiliary Symbol table entry ********/
//#pragma pack(push, 1) //__attribute__((packed));
union SCOFF_SymTableEntry {
// Normal symbol table entry
struct {
char Name[8];
uint32 Value;
int16 SectionNumber;
uint16 Type;
uint8 StorageClass;
uint8 NumAuxSymbols;
} s;
// Auxiliary symbol table entry types:
// Function definition
struct {
uint32 TagIndex; // Index to .bf entry
uint32 TotalSize; // Size of function code
uint32 PointerToLineNumber; // Pointer to line number entry
uint32 PointerToNextFunction; // Symbol table index of next function
uint16 x_tvndx; // Unused
} func;
// .bf abd .ef
struct {
uint32 Unused1;
uint16 SourceLineNumber; // Line number in source file
uint16 Unused2;
uint32 Unused3; // Pointer to line number entry
uint32 PointerToNextFunction; // Symbol table index of next function
uint16 Unused4; // Unused
} bfef;
// Weak external
struct {
uint32 TagIndex; // Symbol table index of alternative symbol2
uint32 Characteristics; //
uint32 Unused1;
uint32 Unused2;
uint16 Unused3; // Unused
} weak;
// File name
struct {
char FileName[18];// File name
} filename;
// String table index
struct { // MS COFF uses multiple aux records rather than a string table entry!
uint32 zeroes; // zeroes if name file name longer than 18
uint32 offset; // string table entry
} stringindex;
// Section definition
struct {
uint32 Length;
uint16 NumberOfRelocations; // Line number in source file
uint16 NumberOfLineNumbers;
uint32 CheckSum; // Pointer to line number entry
uint16 Number; // Symbol table index of next function
uint8 Selection; // Unused
uint8 Unused1[3];
} section;
};
// Warning: Size does not fit standard alignment!
// Use SIZE_SCOFF_SymTableEntry instead of sizeof(SCOFF_SymTableEntry)
#define SIZE_SCOFF_SymTableEntry 18 // Size of SCOFF_SymTableEntry packed
// values of weak.Characteristics
#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
/*
#define N_BTMASK (0xf)
#define N_TMASK (0x30)
#define N_BTSHFT (4)
#define N_TSHIFT (2) */
//#pragma pack(pop)
/********************** Section number values for symbol table entries **********************/
#define COFF_SECTION_UNDEF ((int16)0) // external symbol
#define COFF_SECTION_ABSOLUTE ((int16)-1) // value of symbol is absolute
#define COFF_SECTION_DEBUG ((int16)-2) // debugging symbol - value is meaningless
#define COFF_SECTION_N_TV ((int16)-3) // indicates symbol needs preload transfer vector
#define COFF_SECTION_P_TV ((int16)-4) // indicates symbol needs postload transfer vector
#define COFF_SECTION_REMOVE_ME ((int16)-99)// Specific for objconv program: Debug or exception section being removed
/*
* Type of a symbol, in low N bits of the word
#define T_NULL 0
#define T_VOID 1 // function argument (only used by compiler)
#define T_CHAR 2 // character
#define T_SHORT 3 // short integer
#define T_INT 4 // integer
#define T_LONG 5 // long integer
#define T_FLOAT 6 // floating point
#define T_DOUBLE 7 // double word
#define T_STRUCT 8 // structure
#define T_UNION 9 // union
#define T_ENUM 10 // enumeration
#define T_MOE 11 // member of enumeration
#define T_UCHAR 12 // unsigned character
#define T_USHORT 13 // uint16
#define T_UINT 14 // unsigned integer
#define T_ULONG 15 // uint32
#define T_LNGDBL 16 // long double
*/
/*
* derived types, in n_type
#define DT_NON (0) // no derived type
#define DT_PTR (1) // pointer
#define DT_FCN (2) // function
#define DT_ARY (3) // array
#define BTYPE(x) ((x) & N_BTMASK)
#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
*/
/********************** Storage classes for symbol table entries **********************/
#define COFF_CLASS_NULL 0
#define COFF_CLASS_AUTOMATIC 1 // automatic variable
#define COFF_CLASS_EXTERNAL 2 // external symbol
#define COFF_CLASS_STATIC 3 // static
#define COFF_CLASS_REGISTER 4 // register variable
#define COFF_CLASS_EXTERNAL_DEF 5 // external definition
#define COFF_CLASS_LABEL 6 // label
#define COFF_CLASS_UNDEFINED_LABEL 7 // undefined label
#define COFF_CLASS_MEMBER_OF_STRUCTURE 8 // member of structure
#define COFF_CLASS_ARGUMENT 9 // function argument
#define COFF_CLASS_STRUCTURE_TAG 10 // structure tag
#define COFF_CLASS_MEMBER_OF_UNION 11 // member of union
#define COFF_CLASS_UNION_TAG 12 // union tag
#define COFF_CLASS_TYPE_DEFINITION 13 // type definition
#define COFF_CLASS_UNDEFINED_STATIC 14 // undefined static
#define COFF_CLASS_ENUM_TAG 15 // enumeration tag
#define COFF_CLASS_MEMBER_OF_ENUM 16 // member of enumeration
#define COFF_CLASS_REGISTER_PARAM 17 // register parameter
#define COFF_CLASS_BIT_FIELD 18 // bit field
#define COFF_CLASS_AUTO_ARGUMENT 19 // auto argument
#define COFF_CLASS_LASTENTRY 20 // dummy entry (end of block)
#define COFF_CLASS_BLOCK 100 // ".bb" or ".eb"
#define COFF_CLASS_FUNCTION 101 // ".bf" or ".ef"
#define COFF_CLASS_END_OF_STRUCT 102 // end of structure
#define COFF_CLASS_FILE 103 // file name
#define COFF_CLASS_LINE 104 // line # reformatted as symbol table entry
#define COFF_CLASS_SECTION 104 // line # reformatted as symbol table entry
#define COFF_CLASS_ALIAS 105 // duplicate tag
#define COFF_CLASS_WEAK_EXTERNAL 105 // duplicate tag
#define COFF_CLASS_HIDDEN 106 // ext symbol in dmert public lib
#define COFF_CLASS_END_OF_FUNCTION 0xff // physical end of function
/********************** Type for symbol table entries **********************/
#define COFF_TYPE_FUNCTION 0x20 // Symbol is function
#define COFF_TYPE_NOT_FUNCTION 0x00 // Symbol is not a function
/********************** Relocation table entry **********************/
//#pragma pack(push, 1) //__attribute__((packed));
struct SCOFF_Relocation {
uint32 VirtualAddress; // Section-relative address of relocation source
uint32 SymbolTableIndex; // Zero-based index into symbol table
uint16 Type; // Relocation type
};
#define SIZE_SCOFF_Relocation 10 // Size of SCOFF_Relocation packed
//#pragma pack(pop)
/********************** Relocation types for 32-bit COFF **********************/
#define COFF32_RELOC_ABS 0x00 // Ignored
#define COFF32_RELOC_DIR16 0x01 // Not supported
#define COFF32_RELOC_REL16 0x02 // Not supported
#define COFF32_RELOC_DIR32 0x06 // 32-bit absolute virtual address
#define COFF32_RELOC_IMGREL 0x07 // 32-bit image relative virtual address
#define COFF32_RELOC_SEG12 0x09 // not supported
#define COFF32_RELOC_SECTION 0x0A // 16-bit section index in file
#define COFF32_RELOC_SECREL 0x0B // 32-bit section-relative
#define COFF32_RELOC_SECREL7 0x0D // 7-bit section-relative
#define COFF32_RELOC_TOKEN 0x0C // CLR token
#define COFF32_RELOC_REL32 0x14 // 32-bit EIP-relative
/********************** Relocation types for 64-bit COFF **********************/
// Note: These values are obtained by my own testing.
// I haven't found any official values
#define COFF64_RELOC_ABS 0x00 // Ignored
#define COFF64_RELOC_ABS64 0x01 // 64 bit absolute virtual address
#define COFF64_RELOC_ABS32 0x02 // 32 bit absolute virtual address
#define COFF64_RELOC_IMGREL 0x03 // 32 bit image-relative
#define COFF64_RELOC_REL32 0x04 // 32 bit, RIP-relative
#define COFF64_RELOC_REL32_1 0x05 // 32 bit, relative to RIP - 1. For instruction with immediate byte operand
#define COFF64_RELOC_REL32_2 0x06 // 32 bit, relative to RIP - 2. For instruction with immediate word operand
#define COFF64_RELOC_REL32_3 0x07 // 32 bit, relative to RIP - 3. (useless)
#define COFF64_RELOC_REL32_4 0x08 // 32 bit, relative to RIP - 4. For instruction with immediate dword operand
#define COFF64_RELOC_REL32_5 0x09 // 32 bit, relative to RIP - 5. (useless)
#define COFF64_RELOC_SECTION 0x0A // 16-bit section index in file. For debug purpose
#define COFF64_RELOC_SECREL 0x0B // 32-bit section-relative
#define COFF64_RELOC_SECREL7 0x0C // 7-bit section-relative
#define COFF64_RELOC_TOKEN 0x0D // CLR token = 64 bit absolute virtual address. Inline addend ignored
#define COFF64_RELOC_SREL32 0x0E // 32 bit signed span dependent
#define COFF64_RELOC_PAIR 0x0F // pair after span dependent
#define COFF64_RELOC_PPC_REFHI 0x10 // high 16 bits of 32 bit abs addr
#define COFF64_RELOC_PPC_REFLO 0x11 // low 16 bits of 32 bit abs addr
#define COFF64_RELOC_PPC_PAIR 0x12 // pair after REFHI
#define COFF64_RELOC_PPC_SECRELO 0x13 // low 16 bits of section relative
#define COFF64_RELOC_PPC_GPREL 0x15 // 16 bit signed relative to GP
#define COFF64_RELOC_PPC_TOKEN 0x16 // CLR token
/********************** Strings **********************/
#define COFF_CONSTRUCTOR_NAME ".CRT$XCU" // Name of constructors segment
// Function prototypes
// Function to put a name into SCOFF_SymTableEntry. Put name in string table
// if longer than 8 characters
uint32 COFF_PutNameInSymbolTable(SCOFF_SymTableEntry & sym, const char * name, CMemoryBuffer & StringTable);
// Function to put a name into SCOFF_SectionHeader. Put name in string table
// if longer than 8 characters
void COFF_PutNameInSectionHeader(SCOFF_SectionHeader & sec, const char * name, CMemoryBuffer & StringTable);
#endif // #ifndef PECOFF_H