From 8b1cc287833f2d86665807500b20485bcb99d2f5 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 31 Jan 2007 20:25:13 -0800 Subject: [PATCH] templates to prepare for Mach-O i386 and Universal ("fat") executables --- src/p_mach.cpp | 84 ++++++---- src/p_mach.h | 401 +++++++++++++++++++++++++++++++++------------- src/p_mach_enum.h | 106 ++++++++++++ 3 files changed, 445 insertions(+), 146 deletions(-) create mode 100644 src/p_mach_enum.h diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 14ddc5b3..42a5d3b1 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -39,12 +39,17 @@ static const static const #include "stub/powerpc-darwin.macho-fold.h" -PackMachPPC32::PackMachPPC32(InputFile *f) : - super(f), n_segment(0), rawmseg(0), msegcmd(0) +template +PackMachBase::PackMachBase(InputFile *f, unsigned flavor, unsigned count, + unsigned size) : + super(f), my_thread_flavor(flavor), my_thread_state_word_count(count), + my_thread_command_size(size), + n_segment(0), rawmseg(0), msegcmd(0) { } -PackMachPPC32::~PackMachPPC32() +template +PackMachBase::~PackMachBase() { delete [] msegcmd; delete [] rawmseg; @@ -69,8 +74,9 @@ Linker *PackMachPPC32::newLinker() const return new ElfLinkerPpc32; } +template void -PackMachPPC32::addStubEntrySections(Filter const *) +PackMachBase::addStubEntrySections(Filter const *) { addLoader("MACOS000", NULL); //addLoader(getDecompressorSections(), NULL); @@ -84,14 +90,16 @@ PackMachPPC32::addStubEntrySections(Filter const *) } -void PackMachPPC32::defineSymbols(Filter const *) +template +void PackMachBase::defineSymbols(Filter const *) { // empty } +template void -PackMachPPC32::buildMachLoader( +PackMachBase::buildMachLoader( upx_byte const *const proto, unsigned const szproto, upx_byte const *const fold, @@ -142,11 +150,15 @@ PackMachPPC32::buildLoader(const Filter *ft) stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry), stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft ); } -void PackMachPPC32::patchLoader() { } -void PackMachPPC32::updateLoader(OutputFile *) {} -void -PackMachPPC32::patchLoaderChecksum() +template +void PackMachBase::patchLoader() { } + +template +void PackMachBase::updateLoader(OutputFile *) {} + +template +void PackMachBase::patchLoaderChecksum() { unsigned char *const ptr = getLoader(); l_info *const lp = &linfo; @@ -160,8 +172,9 @@ PackMachPPC32::patchLoaderChecksum() lp->l_checksum = upx_adler32(ptr, lsize); } -static int __acc_cdecl_qsort -compare_segment_command(void const *const aa, void const *const bb) +template +int __acc_cdecl_qsort +PackMachBase::compare_segment_command(void const *const aa, void const *const bb) { Mach_segment_command const *const a = (Mach_segment_command const *)aa; Mach_segment_command const *const b = (Mach_segment_command const *)bb; @@ -174,8 +187,7 @@ compare_segment_command(void const *const aa, void const *const bb) return 0; } -void -PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader +void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader { // offset of p_info in compressed file overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); @@ -189,8 +201,7 @@ PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader fo->write(&linfo, sizeof(linfo)); } -void -PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader +void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader { BE32 disp; unsigned const zero = 0; @@ -208,7 +219,8 @@ PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader // which follows in the file (or end-of-file). Optimize for common case // where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap. -unsigned PackMachPPC32::find_SEGMENT_gap( +template +unsigned PackMachBase::find_SEGMENT_gap( unsigned const k ) { @@ -242,8 +254,8 @@ unsigned PackMachPPC32::find_SEGMENT_gap( return lo - hi; } -void -PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body +template +void PackMachBase::pack2(OutputFile *fo, Filter &ft) // append compressed body { Extent x; unsigned k; @@ -304,12 +316,23 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body #undef PAGE_SIZE #define PAGE_MASK (~0u<<12) #define PAGE_SIZE -PAGE_MASK -void -PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header + +void PackMachPPC32::pack1_setup_threado(OutputFile *const fo) +{ + threado.cmd = Mach_segment_command::LC_UNIXTHREAD; + threado.cmdsize = sizeof(threado); + threado.flavor = my_thread_flavor; + threado.count = my_thread_state_word_count; + memset(&threado.state, 0, sizeof(threado.state)); + fo->write(&threado, sizeof(threado)); +} + +template +void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header { mhdro = mhdri; mhdro.ncmds = 2; - mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado); + mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size; mhdro.flags = Mach_header::MH_NOUNDEFS; fo->write(&mhdro, sizeof(mhdro)); @@ -329,12 +352,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea segcmdo.flags = 0; fo->write(&segcmdo, sizeof(segcmdo)); - threado.cmd = Mach_segment_command::LC_UNIXTHREAD; - threado.cmdsize = sizeof(threado); - threado.flavor = Mach_thread_command::PPC_THREAD_STATE; - threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT; - memset(&threado.state, 0, sizeof(threado.state)); - fo->write(&threado, sizeof(threado)); + pack1_setup_threado(fo); sz_mach_headers = fo->getBytesWritten(); memset((char *)&linfo, 0, sizeof(linfo)); @@ -343,8 +361,8 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea return; } -void -PackMachPPC32::unpack(OutputFile *fo) +template +void PackMachBase::unpack(OutputFile *fo) { fi->seek(overlay_offset, SEEK_SET); p_info hbuf; @@ -414,8 +432,8 @@ PackMachPPC32::unpack(OutputFile *fo) } -bool -PackMachPPC32::canPack() +template +bool PackMachBase::canPack() { fi->seek(0, SEEK_SET); fi->readx(&mhdri, sizeof(mhdri)); @@ -462,6 +480,8 @@ PackMachPPC32::canPack() return 0 < n_segment; } +template class PackMachBase; +template class PackMachBase; /* vi:ts=4:et */ diff --git a/src/p_mach.h b/src/p_mach.h index 205ad8b2..38b13b77 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -29,160 +29,294 @@ #ifndef __UPX_P_MACHO_H #define __UPX_P_MACHO_H +// Apparently, Mach_fat_header and Mach_fat_arch have the endianness +// of the machine on which they were created. We must deal with both kinds. +struct Mach_fat_header { + unsigned magic; + enum e8 { + FAT_MAGIC = 0xcafebabe + }; + unsigned nfat_arch; // Number of Mach_fat_arch which follow. +}; +struct Mach_fat_arch { + unsigned cputype; + unsigned cpusubtype; + unsigned offset; + unsigned size; + unsigned align; /* shift count; log base 2 */ +}; + /************************************************************************* -// Mach Mach Object executable +// Mach Mach Object executable; all structures are target-endian **************************************************************************/ -struct Mach_header { - BE32 magic; - enum { - MH_MAGIC = 0xfeedface - }; - BE32 cputype; - enum { - CPU_TYPE_POWERPC = 18 - }; - BE32 cpysubtype; - BE32 filetype; - enum { - MH_EXECUTE = 2 - }; - BE32 ncmds; - BE32 sizeofcmds; - BE32 flags; - enum { - MH_NOUNDEFS = 1 - }; +namespace N_Mach { + +// integral types +template +struct MachITypes +{ + typedef TWord Word; + typedef TXword Xword; + typedef TAddr Addr; + typedef TOff Off; +}; + +template +struct Mach_header +{ + typedef typename TMachITypes::Word Word; + + Word magic; + Word cputype; + Word cpysubtype; + Word filetype; + Word ncmds; + Word sizeofcmds; + Word flags; +#define WANT_MACH_HEADER_ENUM 1 +#include "p_mach_enum.h" } __attribute_packed; -struct Mach_segment_command { - BE32 cmd; - enum { - LC_SEGMENT = 0x1, - LC_THREAD = 0x4, - LC_UNIXTHREAD = 0x5, - LC_LOAD_DYLINKER = 0xe - }; - BE32 cmdsize; +template +struct Mach_header64 +{ // only difference is padding to 0 mod 8 + typedef typename TMachITypes::Word Word; + + Word magic; + Word cputype; + Word cpysubtype; + Word filetype; + Word ncmds; + Word sizeofcmds; + Word flags; + Word reserved; // pad to 0 mod 8 +#define WANT_MACH_HEADER_ENUM 1 +#include "p_mach_enum.h" +} +__attribute_packed; + +template +struct Mach_segment_command +{ + typedef typename TMachITypes::Word Word; + typedef typename TMachITypes::Addr Addr; + typedef typename TMachITypes::Off Off; + + Word cmd; + Word cmdsize; char segname[16]; - BE32 vmaddr; - BE32 vmsize; - BE32 fileoff; - BE32 filesize; - BE32 maxprot; - enum { - VM_PROT_READ = 1, - VM_PROT_WRITE = 2, - VM_PROT_EXECUTE = 4 - }; - BE32 initprot; - BE32 nsects; - BE32 flags; + Addr vmaddr; + Addr vmsize; + Off fileoff; + Off filesize; + Word maxprot; + Word initprot; + Word nsects; + Word flags; +#define WANT_MACH_SEGMENT_ENUM 1 +#include "p_mach_enum.h" } __attribute_packed; -struct Mach_section { +template +struct Mach_section_command +{ + typedef typename TMachITypes::Word Word; + typedef typename TMachITypes::Addr Addr; + typedef typename TMachITypes::Off Off; + char sectname[16]; char segname[16]; - BE32 addr; /* memory address */ - BE32 size; /* size in bytes */ - BE32 offset; /* file offset */ - BE32 align; /* power of 2 */ - BE32 reloff; /* file offset of relocation entries */ - BE32 nreloc; /* number of relocation entries */ - BE32 flags; /* section type and attributes */ - enum { - S_REGULAR = 0, - S_ZEROFILL, - S_CSTRING_LITERALS, - S_4BYTE_LITERALS, - S_8BYTE_LITERALS, - S_LITERAL_POINTERS, - S_NON_LAZY_SYMBOL_POINTERS, - S_LAZY_SYMBOL_POINTERS, - S_SYMBOL_STUBS, - S_MOD_INIT_FUNC_POINTERS, - S_MOD_TERM_FNC_POINTERS, - S_COALESCED - }; - enum { - S_ATTR_PURE_INSTRUCTIONS = 0x80000000, - S_ATTR_NO_TOC = 0x40000000, - S_ATTR_STRIP_STATIC_SYMS = 0x20000000, - S_ATTR_SOME_INSTRUCTIONS = 0x00000400, - S_ATTR_EXT_RELOC = 0x00000200, - S_ATTR_LOC_RELOC = 0x00000100 - }; - BE32 reserved1; - BE32 reserved2; - + Addr addr; /* memory address */ + Addr size; /* size in bytes */ + Word offset; /* file offset */ // FIXME: 64 bit? + Word align; /* power of 2 */ + Word reloff; /* file offset of relocation entries */ + Word nreloc; /* number of relocation entries */ + Word flags; /* section type and attributes */ + Word reserved1; + Word reserved2; +#define WANT_MACH_SECTION_ENUM 1 +#include "p_mach_enum.h" } __attribute_packed; -struct Mach_ppc_thread_state { - BE32 srr0; /* Instruction address register (PC; entry addr) */ - BE32 srr1; /* Machine state register (supervisor) */ - BE32 r0, r1, r2, r3, r4, r5, r6, r7; - BE32 r8, r9,r10,r11,r12,r13,r14,r15; - BE32 r16,r17,r18,r19,r20,r21,r22,r23; - BE32 r24,r25,r26,r27,r28,r29,r30,r31; +template +struct Mach_ppc_thread_state +{ + typedef typename TMachITypes::Addr Addr; - BE32 cr; /* Condition register */ - BE32 xer; /* User's integer exception register */ - BE32 lr; /* Link register */ - BE32 ctr; /* Count register */ - BE32 mq; /* MQ register (601 only) */ + Addr srr0; /* Instruction address register (PC; entry addr) */ + Addr srr1; /* Machine state register (supervisor) */ + Addr r0, r1, r2, r3, r4, r5, r6, r7; + Addr r8, r9,r10,r11,r12,r13,r14,r15; + Addr r16,r17,r18,r19,r20,r21,r22,r23; + Addr r24,r25,r26,r27,r28,r29,r30,r31; - BE32 vrsave; /* Vector Save Register */ + Addr cr; /* Condition register */ // FIXME: Word? + Addr xer; /* User's integer exception register */ + Addr lr; /* Link register */ + Addr ctr; /* Count register */ + Addr mq; /* MQ register (601 only) */ + + Addr vrsave; /* Vector Save Register */ } __attribute_packed; -struct Mach_thread_command { - BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ - BE32 cmdsize; /* total size of this command */ - BE32 flavor; - enum { - PPC_THREAD_STATE = 1 - }; - BE32 count; /* sizeof(following_thread_state)/4 */ - enum { - PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4 - }; - struct Mach_ppc_thread_state state; +} // namespace N_Mach + +namespace N_Mach32 { + +template +struct Mach_i386_thread_state +{ + typedef typename TMachITypes::Word Word; + + Word eax, ebx, ecx, edx; + Word edi, esi, ebp; + Word esp, ss; + Word eflags; + Word eip, cs; + Word ds, es, fs, gs; } __attribute_packed; +} // namespace N_Mach32 + +namespace N_Mach64 { + +template +struct Mach_ppc_thread_state64 +{ + typedef typename TMachITypes::Word Word; + typedef typename TMachITypes::Xword Xword; + + Xword srr0; /* Instruction address register (PC; entry addr) */ + Xword srr1; /* Machine state register (supervisor) */ + Xword r0, r1, r2, r3, r4, r5, r6, r7; + Xword r8, r9,r10,r11,r12,r13,r14,r15; + Xword r16,r17,r18,r19,r20,r21,r22,r23; + Xword r24,r25,r26,r27,r28,r29,r30,r31; + + Word cr; /* Condition register */ + Xword xer; /* User's integer exception register */ + Xword lr; /* Link register */ + Xword ctr; /* Count register */ + + Word vrsave; /* Vector Save Register */ +} +__attribute_packed; + +} // namespace N_Mach64 + +namespace N_Mach { + +template +struct MachClass_32 +{ + typedef TP BeLePolicy; + + // integral types + typedef typename TP::U16 U16; + typedef typename TP::U32 U32; + typedef typename TP::U64 U64; + typedef N_Mach::MachITypes MachITypes; + typedef typename MachITypes::Addr Addr; + + // Mach types + typedef N_Mach::Mach_header Mach_header; + typedef N_Mach::Mach_segment_command Mach_segment_command; + typedef N_Mach::Mach_section_command Mach_section_command; + typedef N_Mach::Mach_ppc_thread_state Mach_ppc_thread_state; +}; + +template +struct MachClass_64 +{ + typedef TP BeLePolicy; + + // integral types + typedef typename TP::U16 U16; + typedef typename TP::U32 U32; + typedef typename TP::U64 U64; + typedef N_Mach::MachITypes MachITypes; + + // Mach types + typedef N_Mach::Mach_header64 Mach_header; + typedef N_Mach::Mach_segment_command Mach_segment_command; + typedef N_Mach::Mach_section_command Mach_section_command; +}; + +} // namespace N_Mach + +typedef N_Mach::MachClass_32 MachClass_Host32; +typedef N_Mach::MachClass_64 MachClass_Host64; +typedef N_Mach::MachClass_32 MachClass_BE32; +typedef N_Mach::MachClass_64 MachClass_BE64; +typedef N_Mach::MachClass_32 MachClass_LE32; +typedef N_Mach::MachClass_64 MachClass_LE64; + +// shortcuts +typedef MachClass_Host32::Mach_segment_command Mach32_segment_command; +typedef MachClass_Host32::Mach_section_command Mach32_section_command; +typedef MachClass_Host32::Mach_ppc_thread_state Mach_ppc_thread_state; + +typedef MachClass_Host64::Mach_segment_command Mach64_segment_command; +typedef MachClass_Host64::Mach_section_command Mach64_section_command; + +typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command; +typedef MachClass_BE32::Mach_section_command MachBE32_section_command; + +typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command; +typedef MachClass_BE64::Mach_section_command MachBE64_section_command; + +typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command; +typedef MachClass_LE32::Mach_section_command MachLE32_section_command; + +typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command; +typedef MachClass_LE64::Mach_section_command MachLE64_section_command; #include "p_unix.h" -class PackMachPPC32 : public PackUnixBe32 +template +class PackMachBase : public PackUnix { - typedef PackUnixBe32 super; + typedef PackUnix super; +protected: + typedef TMachClass MachClass; + typedef typename MachClass::BeLePolicy BeLePolicy; + typedef typename MachClass::MachITypes MachITypes; + // integral types + typedef typename MachClass::U16 U16; + typedef typename MachClass::U32 U32; + typedef typename MachClass::U64 U64; + typedef typename MachClass::Addr Addr; + // Mach types + typedef typename MachClass::Mach_header Mach_header; + typedef typename MachClass::Mach_segment_command Mach_segment_command; + typedef typename MachClass::Mach_section_command Mach_section_command; + public: - PackMachPPC32(InputFile *f); - virtual ~PackMachPPC32(); + PackMachBase(InputFile *f, unsigned, unsigned, unsigned); + virtual ~PackMachBase(); virtual int getVersion() const { return 13; } - virtual int getFormat() const { return UPX_F_MACH_PPC32; } - virtual const char *getName() const { return "Mach/ppc32"; } - virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; } - virtual const int *getCompressionMethods(int method, int level) const; - virtual const int *getFilters() const; // called by the generic pack() virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack2(OutputFile *, Filter &); // append compressed data - virtual void pack3(OutputFile *, Filter &); // append loader - virtual void pack4(OutputFile *, Filter &); // append PackHeader + virtual void pack3(OutputFile *, Filter &) = 0; // append loader + virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader + virtual void pack1_setup_threado(OutputFile *const fo) = 0; virtual void unpack(OutputFile *fo); virtual bool canPack(); virtual unsigned find_SEGMENT_gap(unsigned const k); protected: - virtual void buildLoader(const Filter *ft); virtual Linker* newLinker() const; virtual void patchLoader(); virtual void patchLoaderChecksum(); @@ -196,6 +330,12 @@ protected: virtual void defineSymbols(Filter const *); virtual void addStubEntrySections(Filter const *); + static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb); + + unsigned my_thread_flavor; + unsigned my_thread_state_word_count; + unsigned my_thread_command_size; + unsigned n_segment; unsigned sz_segment; unsigned sz_mach_headers; @@ -205,11 +345,44 @@ protected: Mach_header mhdro; Mach_segment_command segcmdo; - Mach_thread_command threado; struct l_info linfo; }; +class PackMachPPC32 : public PackMachBase +{ + typedef PackMachBase super; + +public: + PackMachPPC32(InputFile *f) : super(f, Mach_thread_command::PPC_THREAD_STATE, + sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { } + virtual ~PackMachPPC32(); + virtual int getFormat() const { return UPX_F_MACH_PPC32; } + virtual const char *getName() const { return "Mach/ppc32"; } + virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; } +protected: + virtual const int *getCompressionMethods(int method, int level) const; + virtual const int *getFilters() const; + + virtual void pack1_setup_threado(OutputFile *const fo); + virtual void pack3(OutputFile *, Filter &); // append loader + virtual void pack4(OutputFile *, Filter &); // append PackHeader + virtual Linker* newLinker() const; + virtual void buildLoader(const Filter *ft); + + struct Mach_thread_command + { + BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ + BE32 cmdsize; /* total size of this command */ + BE32 flavor; + BE32 count; /* sizeof(following_thread_state)/4 */ + Mach_ppc_thread_state state; + #define WANT_MACH_THREAD_ENUM + #include "p_mach_enum.h" + } threado + __attribute_packed; +}; + #endif /* already included */ diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h new file mode 100644 index 00000000..9128886b --- /dev/null +++ b/src/p_mach_enum.h @@ -0,0 +1,106 @@ +/* p_mach_enum.h -- + + This file is part of the UPX executable compressor. + + Copyright (C) 2007 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + John F. Reiser + + */ + + +/************************************************************************* +// Use the preprocessor to work around +// - that the types embedding these enums have to be PODs, and +// deriving from an empty base class (which is the ususal C++ way +// of "importing" enums) does not yield a POD any more +// - that older compilers do not correctly perform EBCO +**************************************************************************/ + +#ifdef WANT_MACH_HEADER_ENUM /*{*/ +#undef WANT_MACH_HEADER_ENUM + enum { // magic + MH_MAGIC = 0xfeedface + }; + enum { // cputype + CPU_TYPE_I386 = 7, + CPU_TYPE_POWERPC = 0x00000012, + CPU_TYPE_POWERPC64 = 0x01000012 + }; + enum { // filetype + MH_EXECUTE = 2 + }; + enum { // flags + MH_NOUNDEFS = 1 + }; +#endif /*}*/ + +#ifdef WANT_MACH_SEGMENT_ENUM /*{*/ +#undef WANT_MACH_SEGMENT_ENUM + enum { // cmd + LC_SEGMENT = 0x1, + LC_THREAD = 0x4, + LC_UNIXTHREAD = 0x5, + LC_LOAD_DYLINKER = 0xe, + LC_SEGMENT_64 = 0x19 + }; + enum { // maxprot + VM_PROT_READ = 1, + VM_PROT_WRITE = 2, + VM_PROT_EXECUTE = 4 + }; +#endif /*}*/ + +#ifdef WANT_MACH_SECTION_ENUM /*{*/ +#undef WANT_MACH_SECTION_ENUM + enum { // section flags + S_REGULAR = 0, + S_ZEROFILL, + S_CSTRING_LITERALS, + S_4BYTE_LITERALS, + S_8BYTE_LITERALS, + S_LITERAL_POINTERS, + S_NON_LAZY_SYMBOL_POINTERS, + S_LAZY_SYMBOL_POINTERS, + S_SYMBOL_STUBS, + S_MOD_INIT_FUNC_POINTERS, + S_MOD_TERM_FNC_POINTERS, + S_COALESCED + }; + enum { + S_ATTR_PURE_INSTRUCTIONS = 0x80000000, + S_ATTR_NO_TOC = 0x40000000, + S_ATTR_STRIP_STATIC_SYMS = 0x20000000, + S_ATTR_SOME_INSTRUCTIONS = 0x00000400, + S_ATTR_EXT_RELOC = 0x00000200, + S_ATTR_LOC_RELOC = 0x00000100 + }; +#endif /*}*/ + +#ifdef WANT_MACH_THREAD_ENUM /*{*/ +#undef WANT_MACH_THREAD_ENUM + enum { // thread flavor + PPC_THREAD_STATE = 1 + }; +#endif /*}*/ + +/* +vi:ts=4:et +*/ +