diff --git a/doc/Makefile b/doc/Makefile index 21dae4d1..213abb5a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -3,7 +3,7 @@ SHELL = /bin/sh top_srcdir = .. PACKAGE = upx -VERSION_DATE = 21 Jul 2004 +VERSION_DATE = 01 Oct 2004 VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h) TRIMSPACE = cat diff --git a/doc/upx.pod b/doc/upx.pod index 79a7b5cb..b61f7c1b 100644 --- a/doc/upx.pod +++ b/doc/upx.pod @@ -692,10 +692,10 @@ Extra options available for this executable format: This is the executable format used by the Sony PlayStation (PSone), a Mips R3000 based gaming console which is popular since the late '90s. Support of this format is very similar to the Atari one, because of -nostalgic feelings of one of the authors, but this format maybe serves -a practical purpose ;-). +nostalgic feelings of one of the authors. -Packed programs will be byte-identical to the original after uncompression. +Packed programs will be byte-identical to the original after uncompression, +until further notice. Maximum uncompressed size: ~1998848 bytes. @@ -718,17 +718,15 @@ Extra options available for this executable format: the compression ratio in some cases, but usually the default method gives the best results anyway. - --console-run This enables client/target transfer compatibility. - This format also run from a CD, except the "--no-align" - option is used. Upto 2024 bytes larger files - than [default] will be the result, also a - slower decompression speed can be expected. + --boot-only The format will only run from a CD and may slightly + improves the compression ratio. The decompression + routines are faster than default ones. + But it cannot be used for host/client transfer ! --no-align This option disables CD mode 2 data sector format - alignment, and enables "--console-run". - This will slightly improve the compression ratio, + alignment. May slightly improves the compression ratio, but the compressed executable will not boot from a CD. - So use it for client/target transfer only!. + Use it for client/target transfer only ! diff --git a/src/main.cpp b/src/main.cpp index f878e84a..24de94f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -706,11 +706,11 @@ static int do_option(int optc, const char *arg) opt->o_unix.ptinterp = true; break; case 670: - opt->ps1_exe.console_run = true; + opt->ps1_exe.boot_only = true; break; case 671: opt->ps1_exe.no_align = true; - opt->ps1_exe.console_run = true; + opt->ps1_exe.boot_only = false; break; case 672: opt->ps1_exe.do_8bit = true; @@ -833,7 +833,7 @@ static const struct mfx_option longopts[] = {"strip-loadconf", 0x12, 0, 633}, {"strip-relocs", 0x12, 0, 634}, // ps1/exe - {"console-run", 0x10, 0, 670}, + {"boot-only", 0x10, 0, 670}, {"no-align", 0x10, 0, 671}, {"8-bit", 0x10, 0, 672}, diff --git a/src/options.h b/src/options.h index 8ebbe0c6..69cbac14 100644 --- a/src/options.h +++ b/src/options.h @@ -109,7 +109,7 @@ struct options_t { bool no_reloc; } dos_exe; struct { - bool console_run; + bool boot_only; bool no_align; bool do_8bit; } ps1_exe; diff --git a/src/p_ps1.cpp b/src/p_ps1.cpp index 87f229ec..b800361f 100644 --- a/src/p_ps1.cpp +++ b/src/p_ps1.cpp @@ -49,6 +49,8 @@ static const #define CD_SEC 2048 #define PS_HDR_SIZE CD_SEC +#define PS_RAM_SIZE 0x200000 +#define PS_MIN_SIZE (PS_HDR_SIZE*3) #define PS_MAX_SIZE 0x1e8000 #define SZ_IH_BKUP (10 * sizeof(LE32)) @@ -75,17 +77,17 @@ static const PackPs1::PackPs1(InputFile *f) : super(f), - isCon(false^opt->ps1_exe.console_run), is32Bit(true^opt->ps1_exe.do_8bit), - overlap(0), sa_cnt(0), cfile_size(0) + isCon(true^opt->ps1_exe.boot_only), is32Bit(true^opt->ps1_exe.do_8bit), + overlap(0), sa_cnt(0) { COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188); COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t)); COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40); #if 1 || defined(WITH_NRV) COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3918); - COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0xb1939f02); + COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0xdf0cbd9e); COMPILE_TIME_ASSERT(sizeof(nrv_con_loader) == 2810); - COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0xaf39f37f); + COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x31747f8b); #endif fdata_size = file_size - PS_HDR_SIZE; } @@ -127,23 +129,30 @@ int PackPs1::readFileHeader() bool PackPs1::checkFileHeader() { - if (fdata_size != ih.tx_len || (ih.tx_len & 3) && !opt->force ) + if (fdata_size != ih.tx_len || (ih.tx_len & 3)) { - infoWarning("check header for file size"); + if (!opt->force) + throwCantPack("file size entry damaged (try --force)"); + else + { + opt->info_mode += !opt->info_mode ? 1 : 0; + infoWarning("fixing damaged header, keeping backup file"); + opt->backup = 1; + ih.tx_len = fdata_size; + } + } + if (!opt->force && + (ih.da_ptr != 0 || ih.da_len != 0 || + ih.bs_ptr != 0 || ih.bs_len != 0)) + { + infoWarning("unsupported header field entry"); return false; } - cfile_size = fdata_size; - if (ih.da_ptr != 0 || ih.da_len != 0 || - ih.bs_ptr != 0 || ih.bs_len != 0 && !opt->force) + if (!opt->force && ih.is_ptr == 0) { + infoWarning("stack pointer field empty"); return false; } - if (ih.is_ptr == 0 && !opt->force) - { - infoWarning("check header for stack pointer"); - return false; - } - cfile_size = ih.tx_len; return true; } @@ -189,20 +198,30 @@ void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_) bool PackPs1::canPack() { + unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS]; + if (!readFileHeader()) return false; - unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS]; fi->readx(buf, sizeof(buf)); - for (unsigned i = 0; i < sizeof(buf); i++) - if (buf[i] != 0 && !opt->force) - throwCantPack("unknown data in header (try --force)"); checkAlreadyPacked(buf, sizeof(buf)); + + for (unsigned i = 0; i < sizeof(buf); i++) + if (buf[i] != 0) + if (!opt->force) + throwCantPack("unknown data in header (try --force)"); + else + { + opt->info_mode += !opt->info_mode ? 1 : 0; + infoWarning("clearing header, keeping backup file"); + opt->backup = 1; + break; + } if (!checkFileHeader()) throwCantPack("unsupported header flags (try --force)"); - if (file_size <= (PS_HDR_SIZE*3) && !opt->force) + if (!opt->force && file_size < PS_MIN_SIZE) throwCantPack("file is too small (try --force)"); - if (file_size > PS_MAX_SIZE && !opt->force) + if (!opt->force && file_size > PS_MAX_SIZE) throwCantPack("file is too big (try --force)"); return true; } @@ -223,8 +242,7 @@ int PackPs1::buildLoader(const Filter *) isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY", ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI", isCon ? "PS1ENTRY" : "", - NULL - ); + NULL); if (ph.method == M_NRV2B_8) addLoader("PS1N2B08", NULL); @@ -242,14 +260,14 @@ int PackPs1::buildLoader(const Filter *) throwInternalError("unknown compression method"); if (sa_cnt) - addLoader(sa_cnt > 0xfffc ? "PS1MSETB" : "PS1MSETS", // set small/big memset - ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA", // un/aligned memset - NULL - ); + addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS", + ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA", + NULL); + addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR", isCon ? "PS1SREGS" : "", - NULL - ); + NULL); + return getLoaderSize(); } @@ -262,7 +280,7 @@ void PackPs1::pack(OutputFile *fo) { ibuf.alloc(fdata_size); obuf.allocForCompression(fdata_size); - const upx_byte *p_scan = ibuf+(fdata_size-1); + const upx_byte *p_scan = ibuf+fdata_size; // read file fi->seek(PS_HDR_SIZE,SEEK_SET); @@ -270,10 +288,10 @@ void PackPs1::pack(OutputFile *fo) // scan EOF for 2048 bytes sector alignment // the removed space will secure in-place decompression - while (!(*p_scan--)) { if (sa_cnt++ > (0xfffc<<3)) break; } + while (!(*--p_scan)) { if (sa_cnt++ > (0x10000<<5) || sa_cnt >= fdata_size-1024) break; } - if (sa_cnt > 0xfffc) - sa_cnt = ALIGN_DOWN(sa_cnt,8); + if (sa_cnt > (0x10000<<2)) + sa_cnt = ALIGN_DOWN(sa_cnt,32); else sa_cnt = ALIGN_DOWN(sa_cnt,4); @@ -304,6 +322,14 @@ void PackPs1::pack(OutputFile *fo) memcpy(&oh.ih_bkup, &ih.epc, SZ_IH_BKUP); oh.ih_csum = upx_adler32(&ih.epc, SZ_IH_BKUP); + if (ih.is_ptr == 0) + oh.is_ptr = PS_RAM_SIZE-0x10; + + if (ih.da_ptr != 0 || ih.da_len != 0 || + ih.bs_ptr != 0 || ih.bs_len != 0) + oh.da_ptr = oh.da_len = + oh.bs_ptr = oh.bs_len = 0; + const int lsize = getLoaderSize(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); @@ -311,7 +337,7 @@ void PackPs1::pack(OutputFile *fo) patchPackHeader(loader,lsize); unsigned pad = 0; - unsigned filelen = ALIGN_UP((cfile_size ? cfile_size : (unsigned) ih.tx_len), 4); + unsigned filelen = ALIGN_UP(ih.tx_len, 4); unsigned pad_code = TIL_ALIGNED(ph.c_len, 4); const unsigned decomp_data_start = ih.tx_ptr; @@ -335,7 +361,8 @@ void PackPs1::pack(OutputFile *fo) patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc)); if (sa_cnt) - patch_mips_le(loader,c_len,"SC",MIPS_LO(sa_cnt > 0xfffc ? sa_cnt >> 3 : sa_cnt)); + patch_mips_le(loader,c_len,"SC", + MIPS_LO(sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2)); if (ih.tx_ptr & 0xffff) patch_mips_le(loader,c_len,"DECO",decomp_data_start); else @@ -401,6 +428,7 @@ void PackPs1::pack(OutputFile *fo) throwNotCompressible(); #if 0 + printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len); printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len); printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len); printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc); @@ -448,7 +476,7 @@ void PackPs1::unpack(OutputFile *fo) assert(oh.tx_len >= ph.u_len); const unsigned pad = oh.tx_len - ph.u_len; - ibuf.alloc(fdata_size); + ibuf.alloc(fdata_size > PS_HDR_SIZE ? fdata_size : PS_HDR_SIZE); obuf.allocForUncompression(ph.u_len, pad); fi->seek(PS_HDR_SIZE, SEEK_SET); @@ -466,7 +494,7 @@ void PackPs1::unpack(OutputFile *fo) // write header fo->write(&oh, sizeof(oh)); // align the ps exe header (mode 2 sector data size) - ibuf.clear(0, PS_HDR_SIZE - sizeof(oh)); + ibuf.clear(); // write uncompressed data + pad fo->write(ibuf, PS_HDR_SIZE - sizeof(oh)); obuf.clear(ph.u_len, pad); diff --git a/src/p_ps1.h b/src/p_ps1.h index 6f320417..f981e93d 100644 --- a/src/p_ps1.h +++ b/src/p_ps1.h @@ -104,8 +104,6 @@ protected: // filesize-PS_HDR_SIZE unsigned fdata_size; - // calculated filesize - unsigned cfile_size; }; diff --git a/src/stub/l_ps1.asm b/src/stub/l_ps1.asm index bb39f937..ccf8c6a6 100644 --- a/src/stub/l_ps1.asm +++ b/src/stub/l_ps1.asm @@ -179,22 +179,22 @@ cutpoint: ; ============= -; __PS1MSETB__ - ori a0,zero,'SC' ; amount of removed zero's at eof - sll a0,3 ; (cd mode 2 data sector alignment) ; __PS1MSETS__ - ori a0,zero,'SC' ; amount of removed zero's at eof + ori a0,zero,'SC' ; amount of removed zeros at eof +; __PS1MSETB__ + ori a0,zero,'SC' ; amount of removed zeros at eof + sll a0,3 ; (cd mode 2 data sector alignment) ; __PS1MSETA__ memset_aligned: sw zero,0(a2) - addiu a0,-4 + addiu a0,-1 bnez a0,memset_aligned addiu a2,4 ; __PS1MSETU__ memset_unaligned: swl zero,3(a2) swr zero,0(a2) - addiu a0,-4 + addiu a0,-1 bnez a0,memset_unaligned addiu a2,4 diff --git a/src/version.h b/src/version.h index 38749eff..cfc6a6c5 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ #define UPX_VERSION_HEX 0x019300 /* 01.93.00 */ #define UPX_VERSION_STRING "1.93 beta" #define UPX_VERSION_STRING4 "1.93" -#define UPX_VERSION_DATE "Jul 21st 2004" +#define UPX_VERSION_DATE "Oct 1st 2004"