diff --git a/src/conf.h b/src/conf.h index cb83c5b4..cb9f8581 100644 --- a/src/conf.h +++ b/src/conf.h @@ -460,6 +460,7 @@ private: #define UPX_F_MACH_i386 29 #define UPX_F_LINUX_ELF32_MIPSEL 30 #define UPX_F_VMLINUZ_ARMEL 31 +#define UPX_F_MACH_ARMEL 32 #define UPX_F_PLAIN_TEXT 127 diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 6dd774a3..8f073ca1 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -44,6 +44,11 @@ static const static const #include "stub/i386-darwin.macho-fold.h" +static const +#include "stub/arm-darwin.macho-entry.h" +static const +#include "stub/arm-darwin.macho-fold.h" + template PackMachBase::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor, unsigned count, unsigned size) : @@ -69,6 +74,11 @@ const int *PackMachBase::getCompressionMethods(int method, int level) const return Packer::getDefaultCompressionMethods_le32(method, level); } +const int *PackMachARMEL::getCompressionMethods(int method, int level) const +{ + return Packer::getDefaultCompressionMethods_8(method, level); +} + const int *PackMachPPC32::getFilters() const { @@ -82,6 +92,12 @@ int const *PackMachI386::getFilters() const return filters; } +int const *PackMachARMEL::getFilters() const +{ + static const int filters[] = { 0x50, FT_END }; + return filters; +} + Linker *PackMachPPC32::newLinker() const { return new ElfLinkerPpc32; @@ -92,6 +108,11 @@ Linker *PackMachI386::newLinker() const return new ElfLinkerX86; } +Linker *PackMachARMEL::newLinker() const +{ + return new ElfLinkerArmLE; +} + template void PackMachBase::addStubEntrySections(Filter const *) @@ -171,6 +192,21 @@ void PackMachI386::addStubEntrySections(Filter const *ft) addLoader("FOLDEXEC", NULL); } +void PackMachARMEL::addStubEntrySections(Filter const */*ft*/) +{ + addLoader("MACHMAINX", NULL); + //addLoader(getDecompressorSections(), NULL); + addLoader( + ( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL" + : M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL" + : M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL" + : M_IS_LZMA(ph.method) ? "LZMA_ELF00,+80C,LZMA_DEC20,LZMA_DEC30" + : NULL), NULL); + if (hasLoaderSection("CFLUSH")) + addLoader("CFLUSH"); + addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL); +} + template void PackMachBase::defineSymbols(Filter const *) @@ -217,7 +253,8 @@ PackMachBase::buildMachLoader( delete [] cprLoader; int const GAP = 128; // must match stub/l_mac_ppc.S - segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64; + int const NO_LAP = 64; // must match stub/src/*darwin*.S + segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + NO_LAP; addStubEntrySections(ft); @@ -241,6 +278,14 @@ PackMachI386::buildLoader(const Filter *ft) stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft ); } +void +PackMachARMEL::buildLoader(const Filter *ft) +{ + buildMachLoader( + stub_arm_darwin_macho_entry, sizeof(stub_arm_darwin_macho_entry), + stub_arm_darwin_macho_fold, sizeof(stub_arm_darwin_macho_fold), ft ); +} + template void PackMachBase::patchLoader() { } @@ -305,6 +350,20 @@ void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader fo->rewrite(&linfo, sizeof(linfo)); } +void PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader +{ + // offset of p_info in compressed file + overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo); + + super::pack4(fo, ft); + segcmdo.filesize = fo->getBytesWritten(); + segcmdo.vmsize += segcmdo.filesize; + fo->seek(sizeof(mhdro), SEEK_SET); + fo->rewrite(&segcmdo, sizeof(segcmdo)); + fo->rewrite(&threado, sizeof(threado)); + fo->rewrite(&linfo, sizeof(linfo)); +} + void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader { BE32 disp; @@ -333,6 +392,20 @@ void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader super::pack3(fo, ft); } +void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader +{ + LE32 disp; + unsigned const zero = 0; + unsigned len = fo->getBytesWritten(); + fo->write(&zero, 3& (0u-len)); + len += (3& (0u-len)); + disp = len - sz_mach_headers; + fo->write(&disp, sizeof(disp)); + + threado.state.pc = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */ + super::pack3(fo, ft); +} + // Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD // 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. @@ -480,6 +553,16 @@ void PackMachI386::pack1_setup_threado(OutputFile *const fo) fo->write(&threado, sizeof(threado)); } +void PackMachARMEL::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 { diff --git a/src/p_mach.h b/src/p_mach.h index d75f5224..842702f0 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -197,6 +197,19 @@ struct Mach_i386_new_thread_state } __attribute_packed; +template +struct Mach_ARM_thread_state +{ + typedef typename TMachITypes::Word Word; + + Word r[13]; // r0-r12 + Word sp; // r13 + Word lr; // r14 + Word pc; // r15 + Word cpsr; +} +__attribute_packed; + } // namespace N_Mach namespace N_Mach32 { @@ -253,6 +266,7 @@ struct MachClass_32 typedef N_Mach::Mach_section_command Mach_section_command; typedef N_Mach::Mach_ppc_thread_state Mach_ppc_thread_state; typedef N_Mach::Mach_i386_thread_state Mach_i386_thread_state; + typedef N_Mach::Mach_ARM_thread_state Mach_ARM_thread_state; static void compileTimeAssertions() { BeLePolicy::compileTimeAssertions(); @@ -311,6 +325,7 @@ typedef MachClass_LE64::Mach_section_command MachLE64_section_command; typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state; typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state; +typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state; #include "p_unix.h" @@ -491,6 +506,43 @@ protected: Mach_thread_command threado; }; +class PackMachARMEL : public PackMachBase +{ + typedef PackMachBase super; + +public: + PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM, + (unsigned)Mach_thread_command::ARM_THREAD_STATE, + sizeof(Mach_ARM_thread_state)>>2, sizeof(threado)) { } + + virtual int getFormat() const { return UPX_F_MACH_ARMEL; } + virtual const char *getName() const { return "Mach/ARMEL"; } + virtual const char *getFullName(const options_t *) const { return "ARMEL-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); + virtual void addStubEntrySections(Filter const *); + + struct Mach_thread_command + { + LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ + LE32 cmdsize; /* total size of this command */ + LE32 flavor; + LE32 count; /* sizeof(following_thread_state)/4 */ + Mach_ARM_thread_state state; + #define WANT_MACH_THREAD_ENUM + #include "p_mach_enum.h" + } + __attribute_packed; + Mach_thread_command threado; +}; + class PackMachFat : public Packer { typedef Packer super; diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h index cb2120b6..54ee8fc9 100644 --- a/src/p_mach_enum.h +++ b/src/p_mach_enum.h @@ -40,9 +40,15 @@ }; enum { // cputype CPU_TYPE_I386 = 7, + CPU_TYPE_ARM = 12, CPU_TYPE_POWERPC = 0x00000012, CPU_TYPE_POWERPC64 = 0x01000012 }; + enum { // cpusubtype + CPU_SUBTYPE_ARM_ALL = 0, + CPU_SUBTYPE_ARM_V4T = 5, + CPU_SUBTYPE_ARM_V6 = 6 + }; enum { // filetype MH_EXECUTE = 2 }; @@ -98,7 +104,8 @@ enum { // thread flavor PPC_THREAD_STATE = 1, i386_THREAD_STATE = 1, - i386_OLD_THREAD_STATE = -1 + i386_OLD_THREAD_STATE = -1, + ARM_THREAD_STATE = 1 }; #endif /*}*/ diff --git a/src/packmast.cpp b/src/packmast.cpp index f78ef1e0..8e717d9d 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -278,6 +278,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio return p; if ((p = func(new PackMachI386(f), user)) != NULL) return p; + if ((p = func(new PackMachARMEL(f), user)) != NULL) + return p; return NULL; } diff --git a/src/stub/Makefile b/src/stub/Makefile index c0a3a522..5785e929 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -52,6 +52,8 @@ STUBS += amd64-linux.kernel.vmlinux.h STUBS += amd64-linux.kernel.vmlinux-head.h STUBS += armel-eabi-linux.elf-entry.h STUBS += armel-eabi-linux.elf-fold.h +STUBS += arm-darwin.macho-entry.h +STUBS += arm-darwin.macho-fold.h STUBS += arm-linux.elf-entry.h STUBS += arm-linux.elf-fold.h STUBS += arm-linux.kernel.vmlinux.h @@ -327,6 +329,35 @@ tmp/armel-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,f-objstrip,$@) $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm +# /*********************************************************************** +# // arm-darwin.macho +# ************************************************************************/ + +# info: we use the tc settings from arm-linux.elf, but override v4 with v5 +arm-darwin.macho%.h : tc_list = arm-linux.elf default +arm-darwin.macho%.h : tc_bfdname = elf32-littlearm +tc.arm-darwin.macho-entry.gcc = arm-linux-gcc-4.1.0 -march=armv5 -nostdinc -MMD -MT $@ +tc.arm-darwin.macho-fold.gcc = arm-linux-gcc-4.1.0 -march=armv5 -nostdinc -MMD -MT $@ + +arm-darwin.macho-entry.h : $(srcdir)/src/$$T.S + $(call tc,gcc) -c $< -o tmp/$T.bin + $(call tc,f-embed_objinfo,tmp/$T.bin) + $(call tc,bin2h) tmp/$T.bin $@ + +arm-darwin.macho-fold.h : tmp/$$T.o tmp/arm-darwin.macho-main.o + $(call tc,ld) --no-warn-mismatch --strip-all --oformat binary -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin + chmod a-x tmp/$T.bin + $(call tc,bin2h) tmp/$T.bin $@ + +tmp/arm-darwin.macho-fold.o : $(srcdir)/src/$$T.S + $(call tc,gcc) -c $< -o $@ + $(call tc,f-objstrip,$@) + +tmp/arm-darwin.macho-main.o : $(srcdir)/src/$$T.c + $(call tc,gcc) -c -Os $< -o $@ + $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm + # /*********************************************************************** # // arm-linux.elf # ************************************************************************/ diff --git a/src/stub/i386-darwin.macho-fold.h b/src/stub/i386-darwin.macho-fold.h index 8b301589..0783ba62 100644 --- a/src/stub/i386-darwin.macho-fold.h +++ b/src/stub/i386-darwin.macho-fold.h @@ -1,5 +1,5 @@ /* i386-darwin.macho-fold.h - created from i386-darwin.macho-fold.bin, 1105 (0x451) bytes + created from i386-darwin.macho-fold.bin, 1096 (0x448) bytes This file is part of the UPX executable compressor. @@ -31,13 +31,13 @@ */ -#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1105 -#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x5ad106a1 -#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x01a4878b +#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1096 +#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0xee0f0416 +#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0xa5096bf9 -unsigned char stub_i386_darwin_macho_fold[1105] = { +unsigned char stub_i386_darwin_macho_fold[1096] = { /* 0x0000 */ 106, 0,137,231,141,117, 2,139, 19,137,217, 41,209,139, 89, 24, -/* 0x0010 */ 184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 6, +/* 0x0010 */ 184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 1, /* 0x0020 */ 3, 0, 0,139, 76, 36, 16,141,100, 12, 32,255, 96, 40,139, 68, /* 0x0030 */ 36, 4,139, 76, 36, 8,139, 16, 15,202,137, 16,131,233, 4,141, /* 0x0040 */ 64, 4,115,242,195, 90, 15, 52,176, 1,235, 2,176, 74,235, 2, @@ -64,46 +64,45 @@ unsigned char stub_i386_darwin_macho_fold[1105] = { /* 0x0190 */ 228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, 69,224,139, 69, /* 0x01a0 */ 20,137, 85,220,139, 85, 24,137, 69,216,139, 93,232,139, 69,232, /* 0x01b0 */ 137, 85,212, 49,210,131,195, 28,199, 69,204, 0, 0, 0, 0, 59, -/* 0x01c0 */ 80, 16, 15,131, 86, 1, 0, 0,139, 3,131,248, 1, 15,133, 29, +/* 0x01c0 */ 80, 16, 15,131, 81, 1, 0, 0,139, 3,131,248, 1, 15,133, 24, /* 0x01d0 */ 1, 0, 0,139, 83, 24,139, 67, 28,139, 75, 36,137,214, 1,208, /* 0x01e0 */ 137, 85,240,137, 69,200,137,208, 37,255, 15, 0, 0,137,207, 41, -/* 0x01f0 */ 198, 1,199,137, 77,236,116, 69,139, 69,228, 49,210, 3, 67, 32, -/* 0x0200 */ 82,133,201, 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, -/* 0x0210 */ 80,117, 9,133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, -/* 0x0220 */ 0,131,125,224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, -/* 0x0230 */ 86,232, 42,254,255,255,131,196, 28, 57,198,117, 94,131,125,224, -/* 0x0240 */ 0,116, 42,131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131, -/* 0x0250 */ 125, 16, 0,116, 5,139, 85, 16,137, 50,255,117,212,255,117,216, -/* 0x0260 */ 141, 85,236,139, 69,224,232, 65,254,255,255, 88, 90,137,248,141, -/* 0x0270 */ 20, 62,247,216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193, -/* 0x0280 */ 198, 2, 0, 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232, -/* 0x0290 */ 184,253,255,255,131,196, 12,133,192,116, 7,106,127,232,166,253, -/* 0x02a0 */ 255,255,139, 85,196,141, 4, 23, 1,198, 59,117,200,115, 35,106, -/* 0x02b0 */ 0,106, 0,106,255,104, 18, 16, 0, 0,255,115, 44, 41,117,200, -/* 0x02c0 */ 255,117,200, 86,232,151,253,255,255,131,196, 28, 57,198,116, 58, -/* 0x02d0 */ 235,201,131,125,224, 0,116, 50,141, 71, 3, 37,255, 15, 0, 0, -/* 0x02e0 */ 131,248, 3,119, 37, 80, 86,232,100,253,255,255, 89, 94,235, 26, -/* 0x02f0 */ 131,232, 4,131,248, 1,119, 18,131,123, 8, 1,117, 12,131,123, -/* 0x0300 */ 12, 16,117, 6,141, 67, 16,137, 69,208,255, 69,204,139, 85,232, -/* 0x0310 */ 139, 69,204, 3, 91, 4, 59, 66, 16,233,164,254,255,255,139, 69, -/* 0x0320 */ 208,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83,131, -/* 0x0330 */ 236, 32,199, 69,212, 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, -/* 0x0340 */ 93, 16,137, 69,216,139,117, 20,141, 66, 24,137,117,232,137, 69, -/* 0x0350 */ 240,139, 69, 28,131,232, 24,137, 69,236,139, 66, 24,139, 85,240, -/* 0x0360 */ 106, 0,137, 69,228,139, 69,236,137, 85,224,137, 69,220,141, 85, -/* 0x0370 */ 228,141, 69,236, 83,232, 50,253,255,255,255,117, 12, 83, 49,210, -/* 0x0380 */ 255,117, 8,141, 69,220,106,255, 80,137,240,232,239,253,255,255, -/* 0x0390 */ 49,210,137,195,141, 70, 28,131,196, 28,139, 78, 16, 57,202, 15, -/* 0x03a0 */ 131,162, 0, 0, 0,131, 56, 14, 15,133,144, 0, 0, 0, 3, 64, -/* 0x03b0 */ 8,106, 0,106, 0, 80,232,161,252,255,255,131,196, 12,133,192, -/* 0x03c0 */ 137,199,120, 25, 49,210,139, 69,212, 82, 80,255,117,216, 86, 87, -/* 0x03d0 */ 232,127,252,255,255,131,196, 20, 57, 69,216,116, 15,106,127,232, -/* 0x03e0 */ 100,252,255,255,139, 91, 8,137, 93,212,235,216,129, 62,202,254, -/* 0x03f0 */ 186,190,117, 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, -/* 0x0400 */ 8, 80, 86,232, 38,252,255,255, 89, 90, 49,192,139, 86, 4, 57, -/* 0x0410 */ 208,115, 11,131, 59, 7,116,204, 64,131,195, 20,235,241,106, 0, -/* 0x0420 */ 139, 85,212,106, 0,137,240,106, 0, 87,106, 0,232, 78,253,255, -/* 0x0430 */ 255, 87,137,195,232, 31,252,255,255,131,196, 24,235, 9, 3, 64, -/* 0x0440 */ 4, 66,233, 86,255,255,255,141,101,244,137,216, 91, 94, 95,201, -/* 0x0450 */ 195 +/* 0x01f0 */ 198, 1,199,137, 77,236,116, 66,139, 69,228, 3, 67, 32,133,201, +/* 0x0200 */ 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, 80,117, 9, +/* 0x0210 */ 133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, 0,131,125, +/* 0x0220 */ 224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, 86,232, 45, +/* 0x0230 */ 254,255,255,131,196, 24, 57,198,117, 94,131,125,224, 0,116, 42, +/* 0x0240 */ 131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131,125, 16, 0, +/* 0x0250 */ 116, 5,139, 85, 16,137, 50,255,117,212,255,117,216,141, 85,236, +/* 0x0260 */ 139, 69,224,232, 68,254,255,255, 88, 90,137,248,141, 20, 62,247, +/* 0x0270 */ 216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193,198, 2, 0, +/* 0x0280 */ 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232,187,253,255, +/* 0x0290 */ 255,131,196, 12,133,192,116, 7,106,127,232,169,253,255,255,139, +/* 0x02a0 */ 85,196,141, 4, 23, 1,198, 59,117,200,115, 33,106, 0,106,255, +/* 0x02b0 */ 104, 18, 16, 0, 0,255,115, 44, 41,117,200,255,117,200, 86,232, +/* 0x02c0 */ 156,253,255,255,131,196, 24, 57,198,116, 58,235,203,131,125,224, +/* 0x02d0 */ 0,116, 50,141, 71, 3, 37,255, 15, 0, 0,131,248, 3,119, 37, +/* 0x02e0 */ 80, 86,232,105,253,255,255, 89, 94,235, 26,131,232, 4,131,248, +/* 0x02f0 */ 1,119, 18,131,123, 8, 1,117, 12,131,123, 12, 16,117, 6,141, +/* 0x0300 */ 67, 16,137, 69,208,255, 69,204,139, 85,232,139, 69,204, 3, 91, +/* 0x0310 */ 4, 59, 66, 16,233,169,254,255,255,139, 69,208,141,101,244, 91, +/* 0x0320 */ 94, 95,201,195, 85,137,229, 87, 86, 83,131,236, 32,199, 69,212, +/* 0x0330 */ 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, 93, 16,137, 69,216, +/* 0x0340 */ 139,117, 20,141, 66, 24,137,117,232,137, 69,240,139, 69, 28,131, +/* 0x0350 */ 232, 24,137, 69,236,139, 66, 24,139, 85,240,106, 0,137, 69,228, +/* 0x0360 */ 139, 69,236,137, 85,224,137, 69,220,141, 85,228,141, 69,236, 83, +/* 0x0370 */ 232, 55,253,255,255,255,117, 12, 83, 49,210,255,117, 8,141, 69, +/* 0x0380 */ 220,106,255, 80,137,240,232,244,253,255,255, 49,210,137,195,141, +/* 0x0390 */ 70, 28,131,196, 28,139, 78, 16, 57,202, 15,131,158, 0, 0, 0, +/* 0x03a0 */ 131, 56, 14, 15,133,140, 0, 0, 0, 3, 64, 8,106, 0,106, 0, +/* 0x03b0 */ 80,232,166,252,255,255,131,196, 12,133,192,137,199,120, 21,255, +/* 0x03c0 */ 117,212,255,117,216, 86, 87,232,136,252,255,255,131,196, 16, 57, +/* 0x03d0 */ 69,216,116, 15,106,127,232,109,252,255,255,139, 91, 8,137, 93, +/* 0x03e0 */ 212,235,220,129, 62,202,254,186,190,117, 42, 15,182, 70, 7,141, +/* 0x03f0 */ 94, 8,107,192, 20,131,192, 8, 80, 86,232, 47,252,255,255, 89, +/* 0x0400 */ 90, 49,192,139, 86, 4, 57,208,115, 11,131, 59, 7,116,204, 64, +/* 0x0410 */ 131,195, 20,235,241,106, 0,139, 85,212,106, 0,137,240,106, 0, +/* 0x0420 */ 87,106, 0,232, 87,253,255,255, 87,137,195,232, 40,252,255,255, +/* 0x0430 */ 131,196, 24,235, 9, 3, 64, 4, 66,233, 90,255,255,255,141,101, +/* 0x0440 */ 244,137,216, 91, 94, 95,201,195 }; diff --git a/src/stub/src/arch/arm/v4a/lzma_d.S b/src/stub/src/arch/arm/v4a/lzma_d.S index 8f970754..335421a5 100644 --- a/src/stub/src/arch/arm/v4a/lzma_d.S +++ b/src/stub/src/arch/arm/v4a/lzma_d.S @@ -45,7 +45,7 @@ #define M_LZMA 14 ldrb ip,meth; cmp ip,#M_LZMA; bne not_lzma -#if defined(LINUX_ARM_CACHEFLUSH) /*{*/ +#if defined(LINUX_ARM_CACHEFLUSH)||defined(DARWIN_ARM_CACHEFLUSH) /*{*/ PUSH {dst,ldst, fp,lr} // dst,ldst for cache flush #else /*}{*/ PUSH { fp,lr} @@ -116,6 +116,14 @@ do_sys2 __ARM_NR_cacheflush // decompressed region mov r0,r3 // result value #endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov r4,r0 // save result value + POP {r0,r1} // dst, ldst + ldr r1,[r1] // ldst by reference + PUSH {r0,r1}; do_dcache_flush + POP {r0,r1}; do_icache_invalidate + mov r0,r4 // result value +#endif /*}*/ POP {fp,pc} 1: diff --git a/src/stub/src/arch/arm/v4a/macros.S b/src/stub/src/arch/arm/v4a/macros.S index 1e5f0594..9f3d6b38 100644 --- a/src/stub/src/arch/arm/v4a/macros.S +++ b/src/stub/src/arch/arm/v4a/macros.S @@ -34,7 +34,16 @@ .section \name .endm -#if defined(ARMEL_EABI4) /*{*/ +#if defined(ARMEL_DARWIN) /*{*/ +__NR_SYSCALL_BASE = 0 +.macro do_sys N + mov ip,#\N + swi 0x80 // returns Carry iff error + orrcs r0,r0,#(1<<31) // force negative on error; FIXME: needed? + ret +.endm + +#elif defined(ARMEL_EABI4) /*}{*/ __NR_SYSCALL_BASE = 0 .macro do_sys N @@ -51,7 +60,7 @@ __NR_SYSCALL_BASE = 0 mov r7,r12 // restore r7 from ip .endm -#else /*}{*/ +#elif defined(ARM_OLDABI) /*}{*/ __NR_SYSCALL_BASE = 0x900000 .macro do_sys N @@ -61,10 +70,17 @@ __NR_SYSCALL_BASE = 0x900000 swi \N .endm +#else /*}{*/ +.macro do_sys N + error ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm +.macro do_sys2 N + error ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm #endif /*}*/ .macro ret - mov pc,lr /* armv4 fails for thumb interworking */ + mov pc,lr /* armv4 lacks 'bx'; fails for thumb interworking */ .endm // vi:ts=8:et:nowrap diff --git a/src/stub/src/arch/arm/v4a/nrv2b_d8.S b/src/stub/src/arch/arm/v4a/nrv2b_d8.S index 3448e6d6..e45d2223 100644 --- a/src/stub/src/arch/arm/v4a/nrv2b_d8.S +++ b/src/stub/src/arch/arm/v4a/nrv2b_d8.S @@ -78,6 +78,14 @@ eof_n2b: do_sys2 __ARM_NR_cacheflush // decompressed region mov r0,r4 // result value #endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov r4,r0 // save result value + mov r0,r3 // orig_dst + mov r1,dst // dst_len + PUSH {r0,r1}; do_dcache_flush + POP {r0,r1}; do_icache_invalidate + mov r0,r4 // result value +#endif /*}*/ POP {r4,r5, pc} // return diff --git a/src/stub/src/arch/arm/v4a/nrv2d_d8.S b/src/stub/src/arch/arm/v4a/nrv2d_d8.S index 9eb048d2..d75d035c 100644 --- a/src/stub/src/arch/arm/v4a/nrv2d_d8.S +++ b/src/stub/src/arch/arm/v4a/nrv2d_d8.S @@ -118,6 +118,14 @@ eof_n2d: do_sys2 __ARM_NR_cacheflush // decompressed region mov r0,r4 // result value #endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov r4,r0 // save result value + mov r0,r3 // orig_dst + mov r1,dst // dst_len + PUSH {r0,r1}; do_dcache_flush + POP {r0,r1}; do_icache_invalidate + mov r0,r4 // result value +#endif /*}*/ POP {r4,r5,r6,r7 ,pc} diff --git a/src/stub/src/arch/arm/v4a/nrv2e_d8.S b/src/stub/src/arch/arm/v4a/nrv2e_d8.S index f1c834b3..6aaa824d 100644 --- a/src/stub/src/arch/arm/v4a/nrv2e_d8.S +++ b/src/stub/src/arch/arm/v4a/nrv2e_d8.S @@ -118,6 +118,14 @@ eof_n2e: do_sys2 __ARM_NR_cacheflush // decompressed region mov r0,r4 // result value #endif /*}*/ +#if defined(DARWIN_ARM_CACHEFLUSH) /*{*/ + mov r4,r0 // save result value + mov r0,r3 // orig_dst + mov r1,dst // dst_len + PUSH {r0,r1}; do_dcache_flush + POP {r0,r1}; do_icache_invalidate + mov r0,r4 // result value +#endif /*}*/ POP {r4,r5,r6,r7 ,pc} diff --git a/src/stub/src/arch/arm/v5a/macros.S b/src/stub/src/arch/arm/v5a/macros.S index 3ef210ed..e4228493 100644 --- a/src/stub/src/arch/arm/v5a/macros.S +++ b/src/stub/src/arch/arm/v5a/macros.S @@ -34,7 +34,27 @@ .section \name .endm -#if defined(ARMEL_EABI4) /*{*/ +#if defined(ARMEL_DARWIN) /*{*/ +__NR_SYSCALL_BASE = 0 +.macro do_sys N + mov ip,#\N + swi 0x80 // sets Carry iff error + orrcs r0,r0,#(1<<31) // force negative on error; FIXME: needed? + ret +.endm + +.macro do_dcache_flush // In: r0=addr; r1=len + mov r3,#1 // _sys_dcache_flush + mov ip,#(1<<31) // syscall number? + swi 0x80 +.endm + +.macro do_icache_invalidate // In: r0=addr; r1=len + mov r3,#0 // _sys_icache_invalidate + mov ip,#(1<<31) // syscall number? + swi 0x80 +.endm +#elif defined(ARMEL_EABI4) /*}{*/ __NR_SYSCALL_BASE = 0 .macro do_sys N @@ -51,7 +71,7 @@ __NR_SYSCALL_BASE = 0 mov r7,r12 // restore r7 from ip .endm -#else /*}{*/ +#elif defined(ARM_OLDABI) /*}{*/ __NR_SYSCALL_BASE = 0x900000 .macro do_sys N @@ -61,6 +81,13 @@ __NR_SYSCALL_BASE = 0x900000 swi \N .endm +#else /*}{*/ +.macro do_sys N + error \N // ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm +.macro do_sys2 N + error \N // ARM_OLDABI, ARMEL_EABI4, ARMEL_DARWIN ? +.endm #endif /*}*/ .macro ret diff --git a/src/stub/src/arm-linux.elf-entry.S b/src/stub/src/arm-linux.elf-entry.S index be39a047..89e48706 100644 --- a/src/stub/src/arm-linux.elf-entry.S +++ b/src/stub/src/arm-linux.elf-entry.S @@ -29,6 +29,7 @@ * */ +#define ARM_OLDABI 1 #include "arch/arm/v4a/macros.S" #define bkpt .long 0xe1200070 diff --git a/src/stub/src/arm-linux.elf-fold.S b/src/stub/src/arm-linux.elf-fold.S index 06774beb..8c5540c6 100644 --- a/src/stub/src/arm-linux.elf-fold.S +++ b/src/stub/src/arm-linux.elf-fold.S @@ -27,6 +27,7 @@ @ @ +#define ARM_OLDABI 1 #include "arch/arm/v4a/macros.S" sz_Elf32_Ehdr = 13*4 diff --git a/src/stub/src/armeb-linux.elf-entry.S b/src/stub/src/armeb-linux.elf-entry.S index 8f9b7d4a..35fe9eee 100644 --- a/src/stub/src/armeb-linux.elf-entry.S +++ b/src/stub/src/armeb-linux.elf-entry.S @@ -29,7 +29,7 @@ * */ - +#define ARM_OLDABI 1 #include "arm-linux.elf-entry.S" diff --git a/src/stub/src/armeb-linux.elf-fold.S b/src/stub/src/armeb-linux.elf-fold.S index 35c861df..f1d515d2 100644 --- a/src/stub/src/armeb-linux.elf-fold.S +++ b/src/stub/src/armeb-linux.elf-fold.S @@ -27,6 +27,7 @@ @ @ +#define ARM_OLDABI 1 #define FILTER_ID 0x51 /* big-endian */ #include "arm-linux.elf-fold.S" #undef FILTER_ID diff --git a/src/stub/src/i386-darwin.macho-main.c b/src/stub/src/i386-darwin.macho-main.c index 79f1d4af..3e2d00af 100644 --- a/src/stub/src/i386-darwin.macho-main.c +++ b/src/stub/src/i386-darwin.macho-main.c @@ -304,7 +304,6 @@ typedef union { #define PROT_WRITE 2 #define PROT_EXEC 4 -typedef long long off_t; extern char *mmap(char *, size_t, unsigned, unsigned, int, off_t); extern ssize_t pread(int, void *, size_t, off_t); extern void bswap(void *, unsigned); @@ -312,7 +311,7 @@ extern void bswap(void *, unsigned); static Mach_i386_thread_state const * do_xmap( Mach_header const *const mhdr, - unsigned const fat_offset, + off_t fat_offset, Extent *const xi, int const fdi, Mach_header **mhdrpp, @@ -398,7 +397,7 @@ upx_main( ) { Mach_i386_thread_state const *entry; - unsigned fat_offset = 0; + off_t fat_offset = 0; Extent xi, xo, xi0; xi.buf = CONST_CAST(char *, 1+ (struct p_info const *)(1+ li)); // &b_info xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info)); diff --git a/src/stub/src/include/darwin.h b/src/stub/src/include/darwin.h index 1d434162..6a564b53 100644 --- a/src/stub/src/include/darwin.h +++ b/src/stub/src/include/darwin.h @@ -69,6 +69,11 @@ typedef unsigned long long uint64_t; #endif typedef size_t uintptr_t; +// XXX: restrict ourselves to 4GB for off_t. Some versions of gcc +// have bugs in handling 64-bit integers (such as passing as argument +// the wrong registers) and it takes more code anyway. +// Adjust in system call wrappers, particularly mmap() and pread(). +typedef unsigned off_t; // misc constants diff --git a/src/stub/src/powerpc-darwin.macho-main.c b/src/stub/src/powerpc-darwin.macho-main.c index ca049f2e..fe097c7a 100644 --- a/src/stub/src/powerpc-darwin.macho-main.c +++ b/src/stub/src/powerpc-darwin.macho-main.c @@ -313,15 +313,15 @@ typedef union { /* bug in crosstool/powerpc-750-linux-gnu/gcc-3.4.1-glibc-20040827: unsigned long long off_t goes into registers (9,10) instead of (8,9). - Adjust in mmap(). + Adjust in mmap(), pread(), and include/darwin.h . */ -extern char *mmap(char *, size_t, unsigned, unsigned, int, /*off_t*/size_t); -ssize_t pread(int, void *, size_t, /*off_t*/unsigned); // FIXME? +extern char *mmap(char *, size_t, unsigned, unsigned, int, off_t); +ssize_t pread(int, void *, size_t, off_t); static Mach_ppc_thread_state const * do_xmap( Mach_header const *const mhdr, - unsigned const fat_offset, + off_t const fat_offset, Extent *const xi, int const fdi, Mach_header **mhdrpp, @@ -399,7 +399,7 @@ upx_main( ) { Mach_ppc_thread_state const *entry; - unsigned fat_offset = 0; + off_t fat_offset = 0; Extent xi, xo, xi0; xi.buf = CONST_CAST(char *, 1+ (struct p_info const *)(1+ li)); // &b_info xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info));