MWCC/includes/compiler/MachO.h

287 lines
6.1 KiB
C

#ifndef COMPILER_MACHO_H
#define COMPILER_MACHO_H
#include "compiler/common.h"
#include "compiler/CompilerTools.h"
typedef struct MachOReloc MachOReloc;
typedef struct MachOSection MachOSection;
typedef struct MachOSegment MachOSegment;
typedef struct MachOSymbol MachOSymbol;
typedef struct SymbolData SymbolData;
struct SymbolData {
union {
char *name;
SInt32 strx;
} u;
UInt8 type;
SInt16 desc;
UInt32 value;
MachOSection *section;
};
typedef enum RelocType {
RT_0,
RT_1,
RT_2,
RT_3,
RT_4,
RT_5,
RT_6,
RT_7,
RT_8,
RT_9
} RelocType;
typedef struct RelocDataT {
RelocType type;
UInt8 privFlag;
UInt8 x2;
UInt8 x3;
UInt32 x4;
MachOSection *section;
UInt32 gapC;
MachOSection *sect10;
char *name;
SInt32 x18;
} RelocDataT;
#define N_GSYM 0x20
#define N_FNAME 0x22
#define N_FUN 0x24
#define N_STSYM 0x26
#define N_LCSYM 0x28
#define N_BNSYM 0x2E
#define N_OPT 0x3C
#define N_RSYM 0x40
#define N_SLINE 0x44
#define N_ENSYM 0x4E
#define N_SSYM 0x60
#define N_SO 0x64
#define N_OSO 0x66
#define N_LSYM 0x80
#define N_BINCL 0x82
#define N_SOL 0x84
#define N_PARAMS 0x86
#define N_VERSION 0x88
#define N_OLEVEL 0x8A
#define N_PSYM 0xA0
#define N_EINCL 0xA2
#define N_ENTRY 0xA4
#define N_LBRAC 0xC0
#define N_EXCL 0xC2
#define N_RBRAC 0xE0
#define N_BCOMM 0xE2
#define N_ECOMM 0xE4
#define N_ECOML 0xE8
#define N_LENG 0xFE
#define N_STAB 0xE0
#define N_PEXT 0x10
#define N_TYPE 0x0E
#define N_EXT 0x01
#define N_UNDF 0
#define N_ABS 2
#define N_SECT 0xE
#define N_PBUD 0xC
#define N_INDR 0xA
// Mach-O header
struct mach_header {
uint32_t magic;
SInt32 cputype;
SInt32 cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
#define MH_MAGIC 0xfeedface
#define MH_OBJECT 1
#define CPU_TYPE_POWERPC 18
#define CPU_SUBTYPE_MC98000_ALL 0
// load commands
#define LC_SEGMENT 1
#define LC_SYMTAB 2
#define LC_DYSYMTAB 11
// segments
struct segment_command {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint32_t vmaddr;
uint32_t vmsize;
uint32_t fileoff;
uint32_t filesize;
SInt32 maxprot;
SInt32 initprot;
uint32_t nsects;
uint32_t flags;
};
// sections
struct section {
char sectname[16];
char segname[16];
uint32_t addr;
uint32_t size;
uint32_t offset;
uint32_t align;
uint32_t reloff;
uint32_t nreloc;
uint32_t flags;
uint32_t reserved1;
uint32_t reserved2;
};
#define S_REGULAR 0
#define S_ZEROFILL 1
#define S_CSTRING_LITERALS 2
#define S_4BYTE_LITERALS 3
#define S_8BYTE_LITERALS 4
#define S_LITERAL_POINTERS 5
#define S_NON_LAZY_SYMBOL_POINTERS 6
#define S_LAZY_SYMBOL_POINTERS 7
#define S_SYMBOL_STUBS 8
#define S_MOD_INIT_FUNC_POINTERS 9
#define S_MOD_TERM_FUNC_POINTERS 10
#define S_COALESCED 11
#define S_GB_ZEROFILL 12
#define S_INTERPOSING 13
#define S_16BYTE_LITERALS 14
#define S_ATTR_PURE_INSTRUCTIONS 0x80000000
#define S_ATTR_NO_TOC 0x40000000
#define S_ATTR_STRIP_STATIC_SYMS 0x20000000
#define S_ATTR_NO_DEAD_STRIP 0x10000000
#define S_ATTR_LIVE_SUPPORT 0x8000000
#define S_ATTR_SELF_MODIFYING_CODE 0x4000000
#define S_ATTR_DBUG 0x2000000
#define S_ATTR_SOME_INSTRUCTIONS 0x400
#define S_ATTR_EXT_RELOC 0x200
#define S_ATTR_LOC_RELOC 0x100
// symbols
struct symtab_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t symoff;
uint32_t nsyms;
uint32_t stroff;
uint32_t strsize;
};
struct dysymtab_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t ilocalsym;
uint32_t nlocalsym;
uint32_t iextdefsym;
uint32_t nextdefsym;
uint32_t iundefsym;
uint32_t nundefsym;
uint32_t tocoff;
uint32_t ntoc;
uint32_t modtaboff;
uint32_t nmodtab;
uint32_t extrefsymoff;
uint32_t nextrefsyms;
uint32_t indirectsymoff;
uint32_t nindirectsyms;
uint32_t extreloff;
uint32_t nextrel;
uint32_t locreloff;
uint32_t nlocrel;
};
struct nlist {
int32_t n_strx;
uint8_t n_type;
uint8_t n_sect;
int16_t n_desc;
uint32_t n_value;
};
// relocations
enum reloc_type_ppc {
PPC_RELOC_VANILLA,
PPC_RELOC_PAIR,
PPC_RELOC_BR14,
PPC_RELOC_BR24,
PPC_RELOC_HI16,
PPC_RELOC_LO16,
PPC_RELOC_HA16,
PPC_RELOC_LO14,
PPC_RELOC_SECTDIFF,
PPC_RELOC_PB_LA_PTR,
PPC_RELOC_HI16_SECTDIFF,
PPC_RELOC_LO16_SECTDIFF,
PPC_RELOC_HA16_SECTDIFF,
PPC_RELOC_JBSR,
PPC_RELOC_LO14_SECTDIFF,
PPC_RELOC_LOCAL_SECTDIFF
};
#define R_SCATTERED 0x80000000
#ifdef __MWERKS__
#pragma options align=mac68k
#endif
struct MachOSection {
struct section section;
GList glist;
MachOReloc *firstReloc;
MachOReloc *lastReloc;
int x5C;
UInt32 num;
UInt32 id;
MachOSection *next;
};
struct MachOSegment {
struct segment_command cmd;
MachOSection *firstSection;
MachOSection *lastSection;
MachOSegment *next;
};
struct MachOReloc {
char length; // size of the relocation
char reltype;
char is_extern;
char is_pcrel; // was relocated pc relative already
UInt32 address; // offset to what is being relocated
UInt32 value;
MachOReloc *next;
};
struct MachOSymbol {
SymbolData data;
UInt32 index;
MachOSymbol *next;
};
#ifdef __MWERKS__
#pragma options align=reset
#endif
extern void MachO_Setup(void);
extern void MachO_Finish(void);
extern void MachO_Cleanup(void);
extern MachOSegment *MachO_CreateSegment(char *segname, int maxprot, int initprot, UInt32 flags);
extern MachOSection *MachO_CreateSection(MachOSegment *segment, char *segname, char *sectname, UInt32 align, UInt32 flags, UInt32 sectionID);
extern GList *MachO_GetGList(MachOSection *section);
extern void MachO_SetSectionSize(void);
extern void MachO_Relocate(MachOSection *section, UInt32 address, UInt32 value, char length, char is_pcrel, Boolean is_extern, int reltype);
extern UInt32 MachO_DeclareSymbol(char *name, MachOSection *section, UInt32 value, Boolean isAbsolute, short type, short desc);
extern void MachO_ReOrderSections(void);
extern void MachO_AddIndirectSymbol(SInt32 symbol);
extern UInt32 MachO_NumIndirectSym(void);
extern SInt32 MachO_OutputStab(SymbolData *data, SInt32 strIndex);
#endif