1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

templates to prepare for Mach-O i386 and Universal ("fat") executables

This commit is contained in:
John Reiser 2007-01-31 20:25:13 -08:00
parent 78364ac830
commit 8b1cc28783
3 changed files with 445 additions and 146 deletions

View File

@ -39,12 +39,17 @@ static const
static const static const
#include "stub/powerpc-darwin.macho-fold.h" #include "stub/powerpc-darwin.macho-fold.h"
PackMachPPC32::PackMachPPC32(InputFile *f) : template <class T>
super(f), n_segment(0), rawmseg(0), msegcmd(0) PackMachBase<T>::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 <class T>
PackMachBase<T>::~PackMachBase()
{ {
delete [] msegcmd; delete [] msegcmd;
delete [] rawmseg; delete [] rawmseg;
@ -69,8 +74,9 @@ Linker *PackMachPPC32::newLinker() const
return new ElfLinkerPpc32; return new ElfLinkerPpc32;
} }
template <class T>
void void
PackMachPPC32::addStubEntrySections(Filter const *) PackMachBase<T>::addStubEntrySections(Filter const *)
{ {
addLoader("MACOS000", NULL); addLoader("MACOS000", NULL);
//addLoader(getDecompressorSections(), NULL); //addLoader(getDecompressorSections(), NULL);
@ -84,14 +90,16 @@ PackMachPPC32::addStubEntrySections(Filter const *)
} }
void PackMachPPC32::defineSymbols(Filter const *) template <class T>
void PackMachBase<T>::defineSymbols(Filter const *)
{ {
// empty // empty
} }
template <class T>
void void
PackMachPPC32::buildMachLoader( PackMachBase<T>::buildMachLoader(
upx_byte const *const proto, upx_byte const *const proto,
unsigned const szproto, unsigned const szproto,
upx_byte const *const fold, 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_entry, sizeof(stub_powerpc_darwin_macho_entry),
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft ); stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
} }
void PackMachPPC32::patchLoader() { }
void PackMachPPC32::updateLoader(OutputFile *) {}
void template <class T>
PackMachPPC32::patchLoaderChecksum() void PackMachBase<T>::patchLoader() { }
template <class T>
void PackMachBase<T>::updateLoader(OutputFile *) {}
template <class T>
void PackMachBase<T>::patchLoaderChecksum()
{ {
unsigned char *const ptr = getLoader(); unsigned char *const ptr = getLoader();
l_info *const lp = &linfo; l_info *const lp = &linfo;
@ -160,8 +172,9 @@ PackMachPPC32::patchLoaderChecksum()
lp->l_checksum = upx_adler32(ptr, lsize); lp->l_checksum = upx_adler32(ptr, lsize);
} }
static int __acc_cdecl_qsort template <class T>
compare_segment_command(void const *const aa, void const *const bb) int __acc_cdecl_qsort
PackMachBase<T>::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 a = (Mach_segment_command const *)aa;
Mach_segment_command const *const b = (Mach_segment_command const *)bb; 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; return 0;
} }
void void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{ {
// offset of p_info in compressed file // offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); 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)); fo->write(&linfo, sizeof(linfo));
} }
void void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; BE32 disp;
unsigned const zero = 0; 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 // 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. // where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
unsigned PackMachPPC32::find_SEGMENT_gap( template <class T>
unsigned PackMachBase<T>::find_SEGMENT_gap(
unsigned const k unsigned const k
) )
{ {
@ -242,8 +254,8 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
return lo - hi; return lo - hi;
} }
void template <class T>
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
{ {
Extent x; Extent x;
unsigned k; unsigned k;
@ -304,12 +316,23 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
#undef PAGE_SIZE #undef PAGE_SIZE
#define PAGE_MASK (~0u<<12) #define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK #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 <class T>
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
{ {
mhdro = mhdri; mhdro = mhdri;
mhdro.ncmds = 2; mhdro.ncmds = 2;
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado); mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
mhdro.flags = Mach_header::MH_NOUNDEFS; mhdro.flags = Mach_header::MH_NOUNDEFS;
fo->write(&mhdro, sizeof(mhdro)); fo->write(&mhdro, sizeof(mhdro));
@ -329,12 +352,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
segcmdo.flags = 0; segcmdo.flags = 0;
fo->write(&segcmdo, sizeof(segcmdo)); fo->write(&segcmdo, sizeof(segcmdo));
threado.cmd = Mach_segment_command::LC_UNIXTHREAD; pack1_setup_threado(fo);
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));
sz_mach_headers = fo->getBytesWritten(); sz_mach_headers = fo->getBytesWritten();
memset((char *)&linfo, 0, sizeof(linfo)); memset((char *)&linfo, 0, sizeof(linfo));
@ -343,8 +361,8 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
return; return;
} }
void template <class T>
PackMachPPC32::unpack(OutputFile *fo) void PackMachBase<T>::unpack(OutputFile *fo)
{ {
fi->seek(overlay_offset, SEEK_SET); fi->seek(overlay_offset, SEEK_SET);
p_info hbuf; p_info hbuf;
@ -414,8 +432,8 @@ PackMachPPC32::unpack(OutputFile *fo)
} }
bool template <class T>
PackMachPPC32::canPack() bool PackMachBase<T>::canPack()
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(&mhdri, sizeof(mhdri)); fi->readx(&mhdri, sizeof(mhdri));
@ -462,6 +480,8 @@ PackMachPPC32::canPack()
return 0 < n_segment; return 0 < n_segment;
} }
template class PackMachBase<MachClass_BE32>;
template class PackMachBase<MachClass_LE32>;
/* /*
vi:ts=4:et vi:ts=4:et
*/ */

View File

@ -29,160 +29,294 @@
#ifndef __UPX_P_MACHO_H #ifndef __UPX_P_MACHO_H
#define __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 { namespace N_Mach {
BE32 magic;
enum { // integral types
MH_MAGIC = 0xfeedface template <class TWord, class TXword, class TAddr, class TOff>
}; struct MachITypes
BE32 cputype; {
enum { typedef TWord Word;
CPU_TYPE_POWERPC = 18 typedef TXword Xword;
}; typedef TAddr Addr;
BE32 cpysubtype; typedef TOff Off;
BE32 filetype; };
enum {
MH_EXECUTE = 2 template <class TMachITypes>
}; struct Mach_header
BE32 ncmds; {
BE32 sizeofcmds; typedef typename TMachITypes::Word Word;
BE32 flags;
enum { Word magic;
MH_NOUNDEFS = 1 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; __attribute_packed;
struct Mach_segment_command { template <class TMachITypes>
BE32 cmd; struct Mach_header64
enum { { // only difference is padding to 0 mod 8
LC_SEGMENT = 0x1, typedef typename TMachITypes::Word Word;
LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5, Word magic;
LC_LOAD_DYLINKER = 0xe Word cputype;
}; Word cpysubtype;
BE32 cmdsize; 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 <class TMachITypes>
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]; char segname[16];
BE32 vmaddr; Addr vmaddr;
BE32 vmsize; Addr vmsize;
BE32 fileoff; Off fileoff;
BE32 filesize; Off filesize;
BE32 maxprot; Word maxprot;
enum { Word initprot;
VM_PROT_READ = 1, Word nsects;
VM_PROT_WRITE = 2, Word flags;
VM_PROT_EXECUTE = 4 #define WANT_MACH_SEGMENT_ENUM 1
}; #include "p_mach_enum.h"
BE32 initprot;
BE32 nsects;
BE32 flags;
} }
__attribute_packed; __attribute_packed;
struct Mach_section { template <class TMachITypes>
struct Mach_section_command
{
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
char sectname[16]; char sectname[16];
char segname[16]; char segname[16];
BE32 addr; /* memory address */ Addr addr; /* memory address */
BE32 size; /* size in bytes */ Addr size; /* size in bytes */
BE32 offset; /* file offset */ Word offset; /* file offset */ // FIXME: 64 bit?
BE32 align; /* power of 2 */ Word align; /* power of 2 */
BE32 reloff; /* file offset of relocation entries */ Word reloff; /* file offset of relocation entries */
BE32 nreloc; /* number of relocation entries */ Word nreloc; /* number of relocation entries */
BE32 flags; /* section type and attributes */ Word flags; /* section type and attributes */
enum { Word reserved1;
S_REGULAR = 0, Word reserved2;
S_ZEROFILL, #define WANT_MACH_SECTION_ENUM 1
S_CSTRING_LITERALS, #include "p_mach_enum.h"
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;
} }
__attribute_packed; __attribute_packed;
struct Mach_ppc_thread_state { template <class TMachITypes>
BE32 srr0; /* Instruction address register (PC; entry addr) */ struct Mach_ppc_thread_state
BE32 srr1; /* Machine state register (supervisor) */ {
BE32 r0, r1, r2, r3, r4, r5, r6, r7; typedef typename TMachITypes::Addr Addr;
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;
BE32 cr; /* Condition register */ Addr srr0; /* Instruction address register (PC; entry addr) */
BE32 xer; /* User's integer exception register */ Addr srr1; /* Machine state register (supervisor) */
BE32 lr; /* Link register */ Addr r0, r1, r2, r3, r4, r5, r6, r7;
BE32 ctr; /* Count register */ Addr r8, r9,r10,r11,r12,r13,r14,r15;
BE32 mq; /* MQ register (601 only) */ 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; __attribute_packed;
struct Mach_thread_command { } // namespace N_Mach
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
BE32 cmdsize; /* total size of this command */ namespace N_Mach32 {
BE32 flavor;
enum { template <class TMachITypes>
PPC_THREAD_STATE = 1 struct Mach_i386_thread_state
}; {
BE32 count; /* sizeof(following_thread_state)/4 */ typedef typename TMachITypes::Word Word;
enum {
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4 Word eax, ebx, ecx, edx;
}; Word edi, esi, ebp;
struct Mach_ppc_thread_state state; Word esp, ss;
Word eflags;
Word eip, cs;
Word ds, es, fs, gs;
} }
__attribute_packed; __attribute_packed;
} // namespace N_Mach32
namespace N_Mach64 {
template <class TMachITypes>
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 <class TP>
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<U32, U32, U32, U32> MachITypes;
typedef typename MachITypes::Addr Addr;
// Mach types
typedef N_Mach::Mach_header<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
};
template <class TP>
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<U32, U64, U64, U64> MachITypes;
// Mach types
typedef N_Mach::Mach_header64<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
};
} // namespace N_Mach
typedef N_Mach::MachClass_32<N_BELE_CTP::HostPolicy> MachClass_Host32;
typedef N_Mach::MachClass_64<N_BELE_CTP::HostPolicy> MachClass_Host64;
typedef N_Mach::MachClass_32<N_BELE_CTP::BEPolicy> MachClass_BE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::BEPolicy> MachClass_BE64;
typedef N_Mach::MachClass_32<N_BELE_CTP::LEPolicy> MachClass_LE32;
typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> 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" #include "p_unix.h"
class PackMachPPC32 : public PackUnixBe32 template <class TMachClass>
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: public:
PackMachPPC32(InputFile *f); PackMachBase(InputFile *f, unsigned, unsigned, unsigned);
virtual ~PackMachPPC32(); virtual ~PackMachBase();
virtual int getVersion() const { return 13; } 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() // called by the generic pack()
virtual void pack1(OutputFile *, Filter &); // generate executable header virtual void pack1(OutputFile *, Filter &); // generate executable header
virtual void pack2(OutputFile *, Filter &); // append compressed data virtual void pack2(OutputFile *, Filter &); // append compressed data
virtual void pack3(OutputFile *, Filter &); // append loader virtual void pack3(OutputFile *, Filter &) = 0; // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
virtual bool canPack(); virtual bool canPack();
virtual unsigned find_SEGMENT_gap(unsigned const k); virtual unsigned find_SEGMENT_gap(unsigned const k);
protected: protected:
virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
virtual void patchLoader(); virtual void patchLoader();
virtual void patchLoaderChecksum(); virtual void patchLoaderChecksum();
@ -196,6 +330,12 @@ protected:
virtual void defineSymbols(Filter const *); virtual void defineSymbols(Filter const *);
virtual void addStubEntrySections(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 n_segment;
unsigned sz_segment; unsigned sz_segment;
unsigned sz_mach_headers; unsigned sz_mach_headers;
@ -205,11 +345,44 @@ protected:
Mach_header mhdro; Mach_header mhdro;
Mach_segment_command segcmdo; Mach_segment_command segcmdo;
Mach_thread_command threado;
struct l_info linfo; struct l_info linfo;
}; };
class PackMachPPC32 : public PackMachBase<MachClass_BE32>
{
typedef PackMachBase<MachClass_BE32> 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 */ #endif /* already included */

106
src/p_mach_enum.h Normal file
View File

@ -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
<jreiser@users.sourceforge.net>
*/
/*************************************************************************
// 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
*/