diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 8f62a3e5..ccd0b98c 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -103,8 +103,9 @@ static const unsigned lc_routines[2] = { template PackMachBase::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype, - unsigned flavor, unsigned count, unsigned size) : - super(f), my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor), + unsigned flavor, unsigned count, unsigned size, unsigned page_shift) : + super(f), my_page_size(1ull<>2, sizeof(threado)) + sizeof(Mach_ppc_thread_state)>>2, sizeof(threado), 12) { } PackMachPPC64LE::PackMachPPC64LE(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC64LE, Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE64, - sizeof(Mach_ppcle_thread_state64)>>2, sizeof(threado)) + sizeof(Mach_ppcle_thread_state64)>>2, sizeof(threado), 16) { } const int *PackMachPPC32::getFilters() const @@ -178,7 +179,7 @@ const int *PackMachPPC64LE::getFilters() const PackMachI386::PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE32, - sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) + sizeof(Mach_i386_thread_state)>>2, sizeof(threado), 12) { } int const *PackMachI386::getFilters() const @@ -189,7 +190,7 @@ int const *PackMachI386::getFilters() const PackMachAMD64::PackMachAMD64(InputFile *f) : super(f, Mach_header::CPU_TYPE_X86_64, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE64, - sizeof(Mach_AMD64_thread_state)>>2, sizeof(threado)) + sizeof(Mach_AMD64_thread_state)>>2, sizeof(threado), 12) { } int const *PackMachAMD64::getFilters() const @@ -200,12 +201,12 @@ int const *PackMachAMD64::getFilters() const PackMachARMEL::PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE, - sizeof(Mach_ARM_thread_state)>>2, sizeof(threado)) + sizeof(Mach_ARM_thread_state)>>2, sizeof(threado), 12) { } PackMachARM64EL::PackMachARM64EL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM64, Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE64, - sizeof(Mach_ARM64_thread_state)>>2, sizeof(threado)) + sizeof(Mach_ARM64_thread_state)>>2, sizeof(threado), 14) { } int const *PackMachARMEL::getFilters() const @@ -468,24 +469,9 @@ PackMachBase::compare_segment_command(void const *const aa, void const *const return 0; } -#undef PAGE_MASK -#undef PAGE_SIZE -#define PAGE_MASK (~0u<<12) -#define PAGE_SIZE (0u-PAGE_MASK) - -#undef PAGE_MASK64 -#undef PAGE_SIZE64 -#define PAGE_MASK64 (~(upx_uint64_t)0<<16) -#define PAGE_SIZE64 ((upx_uint64_t)0-PAGE_MASK64) - // At 2013-02-03 part of the source for codesign was // http://opensource.apple.com/source/cctools/cctools-836/libstuff/ofile.c -#undef PAGE_MASK64 -#undef PAGE_SIZE64 -#define PAGE_MASK64 (~(upx_uint64_t)0<<12) -#define PAGE_SIZE64 ((upx_uint64_t)0-PAGE_MASK64) - unsigned const blankLINK = 16; // size of our empty __LINK segment // Note: "readelf --segments" ==> "otool -hl" or "otool -hlv" etc. (Xcode on MacOS) @@ -498,9 +484,9 @@ void PackMachBase::pack4(OutputFile *fo, Filter &ft) // append PackHeader if (Mach_header::MH_EXECUTE == my_filetype) { unsigned len = fo->getBytesWritten(); - char page[~PAGE_MASK]; memset(page, 0, sizeof(page)); - fo->write(page, ~PAGE_MASK & (0u - len)); - len += ~PAGE_MASK & (0u - len) ; + MemBuffer page(my_page_size); memset(page, 0, my_page_size); + fo->write(page, ~my_page_mask & (0u - len)); + len += ~my_page_mask & (0u - len) ; segTEXT.filesize = len; segTEXT.vmsize = len; // FIXME? utilize GAP + NO_LAP + sz_unc - sz_cpr @@ -518,7 +504,7 @@ void PackMachBase::pack4(OutputFile *fo, Filter &ft) // append PackHeader segLINK.fileoff = len; // must be in the file segLINK.vmaddr = len + segTEXT.vmaddr; fo->write(page, blankLINK); len += blankLINK; - segLINK.vmsize = PAGE_SIZE; + segLINK.vmsize = my_page_size; segLINK.filesize = blankLINK; // Get a writeable copy of the stub to make editing easier. @@ -781,7 +767,7 @@ void PackMachBase::pack4dylib( // append PackHeader opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff; } else { - opos += ~PAGE_MASK & (0u - opos); // advance to PAGE_SIZE boundary + opos += ~my_page_mask & (0u - opos); // advance to my_page_size boundary slide = opos - segcmdtmp.fileoff; segcmdtmp.fileoff = opos; } @@ -1208,17 +1194,7 @@ void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e segZERO.cmd = lc_seg; segZERO.cmdsize = sizeof(segZERO); strncpy((char *)segZERO.segname, "__PAGEZERO", sizeof(segZERO.segname)); - segZERO.vmsize = PAGE_SIZE; - if __acc_cte(sizeof(segZERO.vmsize) == 8 - && mhdro.filetype == Mach_header::MH_EXECUTE - && mhdro.cputype == Mach_header::CPU_TYPE_X86_64) { - if (pagezero_vmsize < 0xF0000000ull) { - segZERO.vmsize = pagezero_vmsize; - } - else { - segZERO.vmsize <<= 20; // (1ul<<32) - } - } + segZERO.vmsize = pagezero_vmsize; segTEXT.cmd = lc_seg; segTEXT.cmdsize = sizeof(segTEXT) + sizeof(secTEXT); @@ -1262,8 +1238,8 @@ void PackMachBase::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e segXHDR = segTEXT; segXHDR.cmdsize = sizeof(segXHDR) + sizeof(secXHDR); segXHDR.vmaddr = segZERO.vmsize; - segXHDR.vmsize = PAGE_SIZE; - segXHDR.filesize = PAGE_SIZE; + segXHDR.vmsize = my_page_size; + segXHDR.filesize = my_page_size; segXHDR.nsects = 1; strncpy((char *)segXHDR.segname, "UPX_DATA", sizeof(segXHDR.segname)); @@ -1552,7 +1528,7 @@ int PackMachBase::canUnpack() if (2048 < headway) { infoWarning("Mach_header.sizeofcmds(%d) > 2048", headway); } - if(!headway){ + if (!headway) { throwCantPack("Mach_header.sizeofcmds == 0"); } rawmseg_buf.alloc(mhdri.sizeofcmds); @@ -1903,7 +1879,7 @@ bool PackMachBase::canPack() for (unsigned j= 0; j < ncmds; ++j) { if (lc_seg==msegcmd[j].cmd) { ++n_segment; - if (~PAGE_MASK & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) { + if (~my_page_mask & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) { return false; } upx_uint64_t t = msegcmd[j].vmsize + msegcmd[j].vmaddr; @@ -1914,7 +1890,7 @@ bool PackMachBase::canPack() sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff; } } - vma_max = PAGE_MASK & (~PAGE_MASK + vma_max); + vma_max = my_page_mask & (~my_page_mask + vma_max); // info: currently the header is 36 (32+4) bytes before EOF unsigned char buf[256]; diff --git a/src/p_mach.h b/src/p_mach.h index 5ba68e14..52b3f86f 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -759,7 +759,8 @@ protected: public: PackMachBase(InputFile *, unsigned cpuid, unsigned filetype, - unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size); + unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size, + unsigned page_shift); virtual ~PackMachBase(); virtual int getVersion() const { return 13; } virtual const int *getCompressionMethods(int method, int level) const; @@ -803,6 +804,8 @@ protected: virtual upx_uint64_t threadc_getPC(void /*MachThreadCommand*/ const *) = 0; upx_uint64_t entryVMA; + upx_uint64_t my_page_size; + upx_uint64_t my_page_mask; unsigned my_cputype; unsigned my_cpusubtype; unsigned my_filetype; diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h index 02ac171c..b23787d8 100644 --- a/src/p_mach_enum.h +++ b/src/p_mach_enum.h @@ -53,6 +53,7 @@ CPU_SUBTYPE_ARM_V6 = 6 }; enum { // filetype + MH_OBJECT = 1, /* relocatable object file */ MH_EXECUTE = 2, MH_PRELOAD = 5, /* preloaded executable */ MH_DYLIB = 6, /* dynamically bound shared library */