PAGE_SIZE varies: Apple M1 uses 16K
modified: p_mach.cpp modified: p_mach.h modified: p_mach_enum.h
This commit is contained in:
committed by
Markus F.X.J. Oberhumer
parent
333a288248
commit
766fe466d6
+18
-42
@@ -103,8 +103,9 @@ static const unsigned lc_routines[2] = {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
|
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
|
||||||
unsigned flavor, unsigned count, unsigned size) :
|
unsigned flavor, unsigned count, unsigned size, unsigned page_shift) :
|
||||||
super(f), my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor),
|
super(f), my_page_size(1ull<<page_shift), my_page_mask(~0ull<<page_shift),
|
||||||
|
my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor),
|
||||||
my_thread_state_word_count(count), my_thread_command_size(size),
|
my_thread_state_word_count(count), my_thread_command_size(size),
|
||||||
n_segment(0), rawmseg(nullptr), msegcmd(nullptr), o__mod_init_func(0),
|
n_segment(0), rawmseg(nullptr), msegcmd(nullptr), o__mod_init_func(0),
|
||||||
prev_mod_init_func(0), pagezero_vmsize(0)
|
prev_mod_init_func(0), pagezero_vmsize(0)
|
||||||
@@ -156,12 +157,12 @@ const int *PackMachARMEL::getCompressionMethods(int method, int level) const
|
|||||||
|
|
||||||
PackMachPPC32::PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
|
PackMachPPC32::PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
|
||||||
Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE,
|
Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE,
|
||||||
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado))
|
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado), 12)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
PackMachPPC64LE::PackMachPPC64LE(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC64LE,
|
PackMachPPC64LE::PackMachPPC64LE(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC64LE,
|
||||||
Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE64,
|
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
|
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,
|
PackMachI386::PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
|
||||||
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE32,
|
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
|
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,
|
PackMachAMD64::PackMachAMD64(InputFile *f) : super(f, Mach_header::CPU_TYPE_X86_64,
|
||||||
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE64,
|
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
|
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,
|
PackMachARMEL::PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM,
|
||||||
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE,
|
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,
|
PackMachARM64EL::PackMachARM64EL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM64,
|
||||||
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE64,
|
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
|
int const *PackMachARMEL::getFilters() const
|
||||||
@@ -468,24 +469,9 @@ PackMachBase<T>::compare_segment_command(void const *const aa, void const *const
|
|||||||
return 0;
|
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
|
// At 2013-02-03 part of the source for codesign was
|
||||||
// http://opensource.apple.com/source/cctools/cctools-836/libstuff/ofile.c
|
// 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
|
unsigned const blankLINK = 16; // size of our empty __LINK segment
|
||||||
// Note: "readelf --segments" ==> "otool -hl" or "otool -hlv" etc. (Xcode on MacOS)
|
// Note: "readelf --segments" ==> "otool -hl" or "otool -hlv" etc. (Xcode on MacOS)
|
||||||
|
|
||||||
@@ -498,9 +484,9 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
|
|
||||||
if (Mach_header::MH_EXECUTE == my_filetype) {
|
if (Mach_header::MH_EXECUTE == my_filetype) {
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned len = fo->getBytesWritten();
|
||||||
char page[~PAGE_MASK]; memset(page, 0, sizeof(page));
|
MemBuffer page(my_page_size); memset(page, 0, my_page_size);
|
||||||
fo->write(page, ~PAGE_MASK & (0u - len));
|
fo->write(page, ~my_page_mask & (0u - len));
|
||||||
len += ~PAGE_MASK & (0u - len) ;
|
len += ~my_page_mask & (0u - len) ;
|
||||||
|
|
||||||
segTEXT.filesize = len;
|
segTEXT.filesize = len;
|
||||||
segTEXT.vmsize = len; // FIXME? utilize GAP + NO_LAP + sz_unc - sz_cpr
|
segTEXT.vmsize = len; // FIXME? utilize GAP + NO_LAP + sz_unc - sz_cpr
|
||||||
@@ -518,7 +504,7 @@ void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
segLINK.fileoff = len; // must be in the file
|
segLINK.fileoff = len; // must be in the file
|
||||||
segLINK.vmaddr = len + segTEXT.vmaddr;
|
segLINK.vmaddr = len + segTEXT.vmaddr;
|
||||||
fo->write(page, blankLINK); len += blankLINK;
|
fo->write(page, blankLINK); len += blankLINK;
|
||||||
segLINK.vmsize = PAGE_SIZE;
|
segLINK.vmsize = my_page_size;
|
||||||
segLINK.filesize = blankLINK;
|
segLINK.filesize = blankLINK;
|
||||||
|
|
||||||
// Get a writeable copy of the stub to make editing easier.
|
// Get a writeable copy of the stub to make editing easier.
|
||||||
@@ -781,7 +767,7 @@ void PackMachBase<T>::pack4dylib( // append PackHeader
|
|||||||
opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff;
|
opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
slide = opos - segcmdtmp.fileoff;
|
||||||
segcmdtmp.fileoff = opos;
|
segcmdtmp.fileoff = opos;
|
||||||
}
|
}
|
||||||
@@ -1208,17 +1194,7 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
segZERO.cmd = lc_seg;
|
segZERO.cmd = lc_seg;
|
||||||
segZERO.cmdsize = sizeof(segZERO);
|
segZERO.cmdsize = sizeof(segZERO);
|
||||||
strncpy((char *)segZERO.segname, "__PAGEZERO", sizeof(segZERO.segname));
|
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;
|
segZERO.vmsize = pagezero_vmsize;
|
||||||
}
|
|
||||||
else {
|
|
||||||
segZERO.vmsize <<= 20; // (1ul<<32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
segTEXT.cmd = lc_seg;
|
segTEXT.cmd = lc_seg;
|
||||||
segTEXT.cmdsize = sizeof(segTEXT) + sizeof(secTEXT);
|
segTEXT.cmdsize = sizeof(segTEXT) + sizeof(secTEXT);
|
||||||
@@ -1262,8 +1238,8 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
|
|||||||
segXHDR = segTEXT;
|
segXHDR = segTEXT;
|
||||||
segXHDR.cmdsize = sizeof(segXHDR) + sizeof(secXHDR);
|
segXHDR.cmdsize = sizeof(segXHDR) + sizeof(secXHDR);
|
||||||
segXHDR.vmaddr = segZERO.vmsize;
|
segXHDR.vmaddr = segZERO.vmsize;
|
||||||
segXHDR.vmsize = PAGE_SIZE;
|
segXHDR.vmsize = my_page_size;
|
||||||
segXHDR.filesize = PAGE_SIZE;
|
segXHDR.filesize = my_page_size;
|
||||||
segXHDR.nsects = 1;
|
segXHDR.nsects = 1;
|
||||||
strncpy((char *)segXHDR.segname, "UPX_DATA", sizeof(segXHDR.segname));
|
strncpy((char *)segXHDR.segname, "UPX_DATA", sizeof(segXHDR.segname));
|
||||||
|
|
||||||
@@ -1903,7 +1879,7 @@ bool PackMachBase<T>::canPack()
|
|||||||
for (unsigned j= 0; j < ncmds; ++j) {
|
for (unsigned j= 0; j < ncmds; ++j) {
|
||||||
if (lc_seg==msegcmd[j].cmd) {
|
if (lc_seg==msegcmd[j].cmd) {
|
||||||
++n_segment;
|
++n_segment;
|
||||||
if (~PAGE_MASK & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
|
if (~my_page_mask & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
upx_uint64_t t = msegcmd[j].vmsize + msegcmd[j].vmaddr;
|
upx_uint64_t t = msegcmd[j].vmsize + msegcmd[j].vmaddr;
|
||||||
@@ -1914,7 +1890,7 @@ bool PackMachBase<T>::canPack()
|
|||||||
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
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
|
// info: currently the header is 36 (32+4) bytes before EOF
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
|
|||||||
+4
-1
@@ -759,7 +759,8 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
|
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 ~PackMachBase();
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
@@ -803,6 +804,8 @@ protected:
|
|||||||
virtual upx_uint64_t threadc_getPC(void /*MachThreadCommand*/ const *) = 0;
|
virtual upx_uint64_t threadc_getPC(void /*MachThreadCommand*/ const *) = 0;
|
||||||
|
|
||||||
upx_uint64_t entryVMA;
|
upx_uint64_t entryVMA;
|
||||||
|
upx_uint64_t my_page_size;
|
||||||
|
upx_uint64_t my_page_mask;
|
||||||
unsigned my_cputype;
|
unsigned my_cputype;
|
||||||
unsigned my_cpusubtype;
|
unsigned my_cpusubtype;
|
||||||
unsigned my_filetype;
|
unsigned my_filetype;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
CPU_SUBTYPE_ARM_V6 = 6
|
CPU_SUBTYPE_ARM_V6 = 6
|
||||||
};
|
};
|
||||||
enum { // filetype
|
enum { // filetype
|
||||||
|
MH_OBJECT = 1, /* relocatable object file */
|
||||||
MH_EXECUTE = 2,
|
MH_EXECUTE = 2,
|
||||||
MH_PRELOAD = 5, /* preloaded executable */
|
MH_PRELOAD = 5, /* preloaded executable */
|
||||||
MH_DYLIB = 6, /* dynamically bound shared library */
|
MH_DYLIB = 6, /* dynamically bound shared library */
|
||||||
|
|||||||
Reference in New Issue
Block a user