1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

New PS1 version from Jens.

committer: mfx <mfx> 1096637259 +0000
This commit is contained in:
Markus F.X.J. Oberhumer 2004-10-01 13:27:39 +00:00
parent ec25835525
commit ac724c7e6c
8 changed files with 86 additions and 62 deletions

View File

@ -3,7 +3,7 @@ SHELL = /bin/sh
top_srcdir = .. top_srcdir = ..
PACKAGE = upx 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) VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
TRIMSPACE = cat TRIMSPACE = cat

View File

@ -692,10 +692,10 @@ Extra options available for this executable format:
This is the executable format used by the Sony PlayStation (PSone), This is the executable format used by the Sony PlayStation (PSone),
a Mips R3000 based gaming console which is popular since the late '90s. 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 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 nostalgic feelings of one of the authors.
a practical purpose ;-).
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. 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 compression ratio in some cases, but usually
the default method gives the best results anyway. the default method gives the best results anyway.
--console-run This enables client/target transfer compatibility. --boot-only The format will only run from a CD and may slightly
This format also run from a CD, except the "--no-align" improves the compression ratio. The decompression
option is used. Upto 2024 bytes larger files routines are faster than default ones.
than [default] will be the result, also a But it cannot be used for host/client transfer !
slower decompression speed can be expected.
--no-align This option disables CD mode 2 data sector format --no-align This option disables CD mode 2 data sector format
alignment, and enables "--console-run". alignment. May slightly improves the compression ratio,
This will slightly improve the compression ratio,
but the compressed executable will not boot from a CD. 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 !

View File

@ -706,11 +706,11 @@ static int do_option(int optc, const char *arg)
opt->o_unix.ptinterp = true; opt->o_unix.ptinterp = true;
break; break;
case 670: case 670:
opt->ps1_exe.console_run = true; opt->ps1_exe.boot_only = true;
break; break;
case 671: case 671:
opt->ps1_exe.no_align = true; opt->ps1_exe.no_align = true;
opt->ps1_exe.console_run = true; opt->ps1_exe.boot_only = false;
break; break;
case 672: case 672:
opt->ps1_exe.do_8bit = true; opt->ps1_exe.do_8bit = true;
@ -833,7 +833,7 @@ static const struct mfx_option longopts[] =
{"strip-loadconf", 0x12, 0, 633}, {"strip-loadconf", 0x12, 0, 633},
{"strip-relocs", 0x12, 0, 634}, {"strip-relocs", 0x12, 0, 634},
// ps1/exe // ps1/exe
{"console-run", 0x10, 0, 670}, {"boot-only", 0x10, 0, 670},
{"no-align", 0x10, 0, 671}, {"no-align", 0x10, 0, 671},
{"8-bit", 0x10, 0, 672}, {"8-bit", 0x10, 0, 672},

View File

@ -109,7 +109,7 @@ struct options_t {
bool no_reloc; bool no_reloc;
} dos_exe; } dos_exe;
struct { struct {
bool console_run; bool boot_only;
bool no_align; bool no_align;
bool do_8bit; bool do_8bit;
} ps1_exe; } ps1_exe;

View File

@ -49,6 +49,8 @@ static const
#define CD_SEC 2048 #define CD_SEC 2048
#define PS_HDR_SIZE CD_SEC #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 PS_MAX_SIZE 0x1e8000
#define SZ_IH_BKUP (10 * sizeof(LE32)) #define SZ_IH_BKUP (10 * sizeof(LE32))
@ -75,17 +77,17 @@ static const
PackPs1::PackPs1(InputFile *f) : PackPs1::PackPs1(InputFile *f) :
super(f), super(f),
isCon(false^opt->ps1_exe.console_run), is32Bit(true^opt->ps1_exe.do_8bit), isCon(true^opt->ps1_exe.boot_only), is32Bit(true^opt->ps1_exe.do_8bit),
overlap(0), sa_cnt(0), cfile_size(0) overlap(0), sa_cnt(0)
{ {
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188); COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t)); COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40); COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
#if 1 || defined(WITH_NRV) #if 1 || defined(WITH_NRV)
COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3918); 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(sizeof(nrv_con_loader) == 2810);
COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0xaf39f37f); COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x31747f8b);
#endif #endif
fdata_size = file_size - PS_HDR_SIZE; fdata_size = file_size - PS_HDR_SIZE;
} }
@ -127,23 +129,30 @@ int PackPs1::readFileHeader()
bool PackPs1::checkFileHeader() 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; return false;
} }
cfile_size = fdata_size; if (!opt->force && ih.is_ptr == 0)
if (ih.da_ptr != 0 || ih.da_len != 0 ||
ih.bs_ptr != 0 || ih.bs_len != 0 && !opt->force)
{ {
infoWarning("stack pointer field empty");
return false; return false;
} }
if (ih.is_ptr == 0 && !opt->force)
{
infoWarning("check header for stack pointer");
return false;
}
cfile_size = ih.tx_len;
return true; return true;
} }
@ -189,20 +198,30 @@ void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_)
bool PackPs1::canPack() bool PackPs1::canPack()
{ {
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
fi->readx(buf, sizeof(buf)); 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)); 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()) if (!checkFileHeader())
throwCantPack("unsupported header flags (try --force)"); 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)"); 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)"); throwCantPack("file is too big (try --force)");
return true; return true;
} }
@ -223,8 +242,7 @@ int PackPs1::buildLoader(const Filter *)
isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY", isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY",
ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI", ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI",
isCon ? "PS1ENTRY" : "", isCon ? "PS1ENTRY" : "",
NULL NULL);
);
if (ph.method == M_NRV2B_8) if (ph.method == M_NRV2B_8)
addLoader("PS1N2B08", NULL); addLoader("PS1N2B08", NULL);
@ -242,14 +260,14 @@ int PackPs1::buildLoader(const Filter *)
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
if (sa_cnt) if (sa_cnt)
addLoader(sa_cnt > 0xfffc ? "PS1MSETB" : "PS1MSETS", // set small/big memset addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS",
ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA", // un/aligned memset ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA",
NULL NULL);
);
addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR", addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR",
isCon ? "PS1SREGS" : "", isCon ? "PS1SREGS" : "",
NULL NULL);
);
return getLoaderSize(); return getLoaderSize();
} }
@ -262,7 +280,7 @@ void PackPs1::pack(OutputFile *fo)
{ {
ibuf.alloc(fdata_size); ibuf.alloc(fdata_size);
obuf.allocForCompression(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 // read file
fi->seek(PS_HDR_SIZE,SEEK_SET); fi->seek(PS_HDR_SIZE,SEEK_SET);
@ -270,10 +288,10 @@ void PackPs1::pack(OutputFile *fo)
// scan EOF for 2048 bytes sector alignment // scan EOF for 2048 bytes sector alignment
// the removed space will secure in-place decompression // 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) if (sa_cnt > (0x10000<<2))
sa_cnt = ALIGN_DOWN(sa_cnt,8); sa_cnt = ALIGN_DOWN(sa_cnt,32);
else else
sa_cnt = ALIGN_DOWN(sa_cnt,4); 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); memcpy(&oh.ih_bkup, &ih.epc, SZ_IH_BKUP);
oh.ih_csum = upx_adler32(&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(); const int lsize = getLoaderSize();
MemBuffer loader(lsize); MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize); memcpy(loader, getLoader(), lsize);
@ -311,7 +337,7 @@ void PackPs1::pack(OutputFile *fo)
patchPackHeader(loader,lsize); patchPackHeader(loader,lsize);
unsigned pad = 0; 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); unsigned pad_code = TIL_ALIGNED(ph.c_len, 4);
const unsigned decomp_data_start = ih.tx_ptr; 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)); patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc));
if (sa_cnt) 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) if (ih.tx_ptr & 0xffff)
patch_mips_le(loader,c_len,"DECO",decomp_data_start); patch_mips_le(loader,c_len,"DECO",decomp_data_start);
else else
@ -401,6 +428,7 @@ void PackPs1::pack(OutputFile *fo)
throwNotCompressible(); throwNotCompressible();
#if 0 #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: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len); printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len);
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc); 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); assert(oh.tx_len >= ph.u_len);
const unsigned pad = 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); obuf.allocForUncompression(ph.u_len, pad);
fi->seek(PS_HDR_SIZE, SEEK_SET); fi->seek(PS_HDR_SIZE, SEEK_SET);
@ -466,7 +494,7 @@ void PackPs1::unpack(OutputFile *fo)
// write header // write header
fo->write(&oh, sizeof(oh)); fo->write(&oh, sizeof(oh));
// align the ps exe header (mode 2 sector data size) // align the ps exe header (mode 2 sector data size)
ibuf.clear(0, PS_HDR_SIZE - sizeof(oh)); ibuf.clear();
// write uncompressed data + pad // write uncompressed data + pad
fo->write(ibuf, PS_HDR_SIZE - sizeof(oh)); fo->write(ibuf, PS_HDR_SIZE - sizeof(oh));
obuf.clear(ph.u_len, pad); obuf.clear(ph.u_len, pad);

View File

@ -104,8 +104,6 @@ protected:
// filesize-PS_HDR_SIZE // filesize-PS_HDR_SIZE
unsigned fdata_size; unsigned fdata_size;
// calculated filesize
unsigned cfile_size;
}; };

View File

@ -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__ ; __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__ ; __PS1MSETA__
memset_aligned: memset_aligned:
sw zero,0(a2) sw zero,0(a2)
addiu a0,-4 addiu a0,-1
bnez a0,memset_aligned bnez a0,memset_aligned
addiu a2,4 addiu a2,4
; __PS1MSETU__ ; __PS1MSETU__
memset_unaligned: memset_unaligned:
swl zero,3(a2) swl zero,3(a2)
swr zero,0(a2) swr zero,0(a2)
addiu a0,-4 addiu a0,-1
bnez a0,memset_unaligned bnez a0,memset_unaligned
addiu a2,4 addiu a2,4

View File

@ -1,4 +1,4 @@
#define UPX_VERSION_HEX 0x019300 /* 01.93.00 */ #define UPX_VERSION_HEX 0x019300 /* 01.93.00 */
#define UPX_VERSION_STRING "1.93 beta" #define UPX_VERSION_STRING "1.93 beta"
#define UPX_VERSION_STRING4 "1.93" #define UPX_VERSION_STRING4 "1.93"
#define UPX_VERSION_DATE "Jul 21st 2004" #define UPX_VERSION_DATE "Oct 1st 2004"