/****************************   coff.h   *************************************
* Author:        Agner Fog
* Date created:  2006-07-15
* Last modified: 2022-08-31
* Project:       objconv
* Module:        coff.h
* Description:
* Header file for definition of structures in MS Windows COFF Intel x86 (PE)
* object file format.
*
* Copyright 2006-2022 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_t Machine;              // Machine ID (magic number)
 uint16_t NumberOfSections;     // number of sections
 uint32_t TimeDateStamp;        // time & date stamp 
 uint32_t PSymbolTable;         // file pointer to symbol table
 uint32_t NumberOfSymbols;      // number of symbol table entries 
 uint16_t SizeOfOptionalHeader; // size of optional header
 uint16_t 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_t VirtualAddress;              // Image relative address of table
   uint32_t Size;                        // Size of table
};

// Extended structure used internally with virtual address translated to section:offset
struct SCOFF_ImageDirAddress : public SCOFF_IMAGE_DATA_DIRECTORY {
   int32_t  Section;                     // Section containing table
   uint32_t SectionOffset;               // Offset relative to section
   uint32_t FileOffset;                  // Offset relative to file
   uint32_t MaxOffset;                   // Section size - SectionOffset
   const char * Name;                  // Name of table
};

// Optional header
union SCOFF_OptionalHeader {
   // 32 bit version
   struct {
      uint16_t Magic;                    // Magic number
      uint8_t  LinkerMajorVersion;
      uint8_t  LinkerMinorVersion;
      uint32_t SizeOfCode;
      uint32_t SizeOfInitializedData;
      uint32_t SizeOfUninitializedData;
      uint32_t AddressOfEntryPoint;      // Entry point relative to image base
      uint32_t BaseOfCode;
      uint32_t BaseOfData;
      // Windows specific fields
      int32_t  ImageBase;                // Image base
      uint32_t SectionAlignment;
      uint32_t FileAlignment;
      uint16_t MajorOperatingSystemVersion;
      uint16_t MinorOperatingSystemVersion;
      uint16_t MajorImageVersion;
      uint16_t MinorImageVersion;
      uint16_t MajorSubsystemVersion;
      uint16_t MinorSubsystemVersion;
      uint32_t Win32VersionValue;        // must be 0
      uint32_t SizeOfImage;
      uint32_t SizeOfHeaders;
      uint32_t CheckSum;
      uint16_t Subsystem;
      uint16_t DllCharacteristics;
      uint32_t SizeOfStackReserve;
      uint32_t SizeOfStackCommit;
      uint32_t SizeOfHeapReserve;
      uint32_t SizeOfHeapCommit;
      uint32_t LoaderFlags;              // 0
      uint32_t 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_t Magic;                    // Magic number
      uint8_t  LinkerMajorVersion;
      uint8_t  LinkerMinorVersion;
      uint32_t SizeOfCode;
      uint32_t SizeOfInitializedData;
      uint32_t SizeOfUninitializedData;
      uint32_t AddressOfEntryPoint;      // Entry point relative to image base
      uint32_t BaseOfCode;
      // Windows specific fields
      int64_t  ImageBase;                // Image base
      uint32_t SectionAlignment;
      uint32_t FileAlignment;
      uint16_t MajorOperatingSystemVersion;
      uint16_t MinorOperatingSystemVersion;
      uint16_t MajorImageVersion;
      uint16_t MinorImageVersion;
      uint16_t MajorSubsystemVersion;
      uint16_t MinorSubsystemVersion;
      uint32_t Win32VersionValue;        // must be 0
      uint32_t SizeOfImage;
      uint32_t SizeOfHeaders;
      uint32_t CheckSum;
      uint16_t Subsystem;
      uint16_t DllCharacteristics;
      uint64_t SizeOfStackReserve;
      uint64_t SizeOfStackCommit;
      uint64_t SizeOfHeapReserve;
      uint64_t SizeOfHeapCommit;
      uint32_t LoaderFlags;              // 0
      uint32_t 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_t Flags;
   uint32_t DateTime;
   uint16_t VersionMajor;
   uint16_t VersionMinor;
   uint32_t DLLNameRVA;                  // Image-relative address of DLL name
   uint32_t OrdinalBase;                 // Ordinal number of first export
   uint32_t AddressTableEntries;         // Number of entries in export address table
   uint32_t NamePointerEntries;          // Number of entries in name pointer table
   uint32_t ExportAddressTableRVA;       // Image-relative address of export address table
   uint32_t NamePointerTableRVA;         // Image-relative address of export name pointer table
   uint32_t OrdinalTableRVA;             // Image-relative address of ordinal table
};

// Import directory table
struct SCOFF_ImportDirectory {
   uint32_t ImportLookupTableRVA;        // Image-relative address of import lookup table
   uint32_t DateTime;
   uint32_t ForwarderChain;
   uint32_t DLLNameRVA;                  // Image-relative address of DLL name string
   uint32_t ImportAddressTableRVA;       // Image-relative address of import address table
};

// Import hint/name table entry
struct SCOFF_ImportHintName {
   uint16_t Hint;                        // Index into export name pointer table
   char   Name[2];                     // Variable length
};

// Base relocation block header
struct SCOFF_BaseRelocationBlock {
   uint32_t PageRVA;                     // Image-relative base to add to offset
   uint32_t BlockSize;                   // Size of SCOFF_BaseRelocationBlock plus all SCOFF_BaseRelocation
};

// Base relocation block entry
struct SCOFF_BaseRelocation {
   uint16_t Offset:12;                   // Offset relative to PageRVA
   uint16_t 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_t  VirtualSize;    // size of section when loaded. (Should be 0 for object files, but it seems to be accumulated size of all sections)
 uint32_t  VirtualAddress; // subtracted from offsets during relocation. preferably 0
 uint32_t  SizeOfRawData;  // section size in file
 uint32_t  PRawData;       // file  to raw data for section
 uint32_t  PRelocations;   // file  to relocation entries
 uint32_t  PLineNumbers;   // file  to line number entries
 uint16_t  NRelocations;   // number of relocation entries
 uint16_t  NLineNumbers;   // number of line number entries
 uint32_t  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_t Fname;    // function name symbol table index, if Line == 0
  uint32_t Addr;     // section-relative address of code that corresponds to line
 };
 uint16_t 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_t Value;
      int16_t  SectionNumber;
      uint16_t Type;
      uint8_t  StorageClass;
      uint8_t  NumAuxSymbols;
   } s;
   // Auxiliary symbol table entry types:

   // Function definition
   struct {
      uint32_t TagIndex; // Index to .bf entry
      uint32_t TotalSize; // Size of function code
      uint32_t PointerToLineNumber; // Pointer to line number entry
      uint32_t PointerToNextFunction; // Symbol table index of next function
      uint16_t x_tvndx;      // Unused
   } func;

   // .bf abd .ef
   struct {
      uint32_t Unused1;
      uint16_t SourceLineNumber; // Line number in source file
      uint16_t Unused2;
      uint32_t Unused3; // Pointer to line number entry
      uint32_t PointerToNextFunction; // Symbol table index of next function
      uint16_t Unused4;      // Unused
   } bfef;

   // Weak external
   struct {
      uint32_t TagIndex; // Symbol table index of alternative symbol2
      uint32_t Characteristics; //
      uint32_t Unused1; 
      uint32_t Unused2; 
      uint16_t 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_t zeroes; // zeroes if name file name longer than 18
      uint32_t offset; // string table entry
   } stringindex;

   // Section definition
   struct {
      uint32_t Length;
      uint16_t NumberOfRelocations;  // Number of relocation entries for the section
      uint16_t NumberOfLineNumbers;  // Number of line-number entries for the section
      uint32_t CheckSum;             // Checksum for communal data
      uint16_t Number;               // Index of associated section (for COMDAT selection 5)
      uint8_t  Selection;            // COMDAT selection number
      uint8_t  Unused1[3];           // Unused
   } 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_t)0)      // external symbol
#define COFF_SECTION_ABSOLUTE ((int16_t)-1)  // value of symbol is absolute
#define COFF_SECTION_DEBUG ((int16_t)-2)     // debugging symbol - value is meaningless
#define COFF_SECTION_N_TV ((int16_t)-3)      // indicates symbol needs preload transfer vector
#define COFF_SECTION_P_TV ((int16_t)-4)      // indicates symbol needs postload transfer vector
#define COFF_SECTION_REMOVE_ME ((int16_t)-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_t 
#define T_UINT  14 // unsigned integer 
#define T_ULONG  15 // uint32_t 
#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_t VirtualAddress;   // Section-relative address of relocation source
  uint32_t SymbolTableIndex; // Zero-based index into symbol table
  uint16_t 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_t 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
