mirror of https://github.com/upx/upx.git
New PS1 version from Jens.
committer: mfx <mfx> 1096637259 +0000
This commit is contained in:
parent
ec25835525
commit
ac724c7e6c
|
@ -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
|
||||
|
|
20
doc/upx.pod
20
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 !
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
102
src/p_ps1.cpp
102
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);
|
||||
|
|
|
@ -104,8 +104,6 @@ protected:
|
|||
|
||||
// filesize-PS_HDR_SIZE
|
||||
unsigned fdata_size;
|
||||
// calculated filesize
|
||||
unsigned cfile_size;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue