#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