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:
parent
78364ac830
commit
8b1cc28783
|
@ -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 <class T>
|
||||
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 [] rawmseg;
|
||||
|
@ -69,8 +74,9 @@ Linker *PackMachPPC32::newLinker() const
|
|||
return new ElfLinkerPpc32;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
PackMachPPC32::addStubEntrySections(Filter const *)
|
||||
PackMachBase<T>::addStubEntrySections(Filter const *)
|
||||
{
|
||||
addLoader("MACOS000", 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
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void
|
||||
PackMachPPC32::buildMachLoader(
|
||||
PackMachBase<T>::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 <class T>
|
||||
void PackMachBase<T>::patchLoader() { }
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::updateLoader(OutputFile *) {}
|
||||
|
||||
template <class T>
|
||||
void PackMachBase<T>::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 <class T>
|
||||
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 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 <class T>
|
||||
unsigned PackMachBase<T>::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 <class T>
|
||||
void PackMachBase<T>::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 <class T>
|
||||
void PackMachBase<T>::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 <class T>
|
||||
void PackMachBase<T>::unpack(OutputFile *fo)
|
||||
{
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
|
@ -414,8 +432,8 @@ PackMachPPC32::unpack(OutputFile *fo)
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
PackMachPPC32::canPack()
|
||||
template <class T>
|
||||
bool PackMachBase<T>::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
@ -462,6 +480,8 @@ PackMachPPC32::canPack()
|
|||
return 0 < n_segment;
|
||||
}
|
||||
|
||||
template class PackMachBase<MachClass_BE32>;
|
||||
template class PackMachBase<MachClass_LE32>;
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
|
401
src/p_mach.h
401
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 <class TWord, class TXword, class TAddr, class TOff>
|
||||
struct MachITypes
|
||||
{
|
||||
typedef TWord Word;
|
||||
typedef TXword Xword;
|
||||
typedef TAddr Addr;
|
||||
typedef TOff Off;
|
||||
};
|
||||
|
||||
template <class TMachITypes>
|
||||
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 <class TMachITypes>
|
||||
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 <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];
|
||||
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 <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 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 <class TMachITypes>
|
||||
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 <class TMachITypes>
|
||||
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 <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"
|
||||
|
||||
|
||||
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:
|
||||
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<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 */
|
||||
|
||||
|
||||
|
|
106
src/p_mach_enum.h
Normal file
106
src/p_mach_enum.h
Normal 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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user