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

ps1/exe updated from jens

This commit is contained in:
László Molnár 2006-08-29 16:25:59 +02:00
parent 59dd33a461
commit 31b629a19c
11 changed files with 1954 additions and 1576 deletions

View File

@ -699,19 +699,19 @@ 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. until further notice.
Maximum uncompressed size: ~1998848 bytes. Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
Notes: Notes:
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable. - UPX creates as default a console transfer compatible executable.
For transfer between client/target use options below. For CD-Mastering use option "--boot-only" as descriped below.
- Normally the packed files use the same memory areas like the uncompressed - Normally the packed files use the same memory areas like the uncompressed
versions, so they will not override other memory areas while unpacking. versions, so they will not override other memory areas while unpacking.
If this isn't possible UPX will abort showing a 'packed data overlap' If this isn't possible UPX will abort showing a 'packed data overlap'
error. With the "--force" option UPX will set a few 'bytes higher' loading error. With the "--force" option UPX will relocate the loading address
offset for the packed file, but this isn't a real problem if it is a for the packed file, but this isn't a real problem if it is a single or
single or boot-only executable. the main executable.
Extra options available for this executable format: Extra options available for this executable format:
@ -720,15 +720,19 @@ 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.
--boot-only The format will only run from a CD and may slightly --8-bit Uses 8 bit size compression [default: 32 bit]
improves the compression ratio. The decompression
routines are faster than default ones. --8mb-ram PSone has 8 MB ram available [default: 2 MB]
But it cannot be used for host/client transfer !
--boot-only This format is for main exes and CD-Mastering only !
It may slightly improve the compression ratio,
decompression routines are faster than default ones.
But it cannot be used for console transfer !
--no-align This option disables CD mode 2 data sector format --no-align This option disables CD mode 2 data sector format
alignment. May slightly improves the compression ratio, alignment. May slightly improves the compression ratio,
but the compressed executable will not boot from a CD. but the compressed executable will not boot from a CD.
Use it for client/target transfer only ! Use it for console transfer only !

View File

@ -40,24 +40,26 @@
static const static const
#include "stub/mipsel.r3000-ps1.h" #include "stub/mipsel.r3000-ps1.h"
#define CD_SEC 2048 #define CD_SEC 2048
#define PS_HDR_SIZE CD_SEC #define PS_HDR_SIZE CD_SEC
#define PS_RAM_SIZE ram_size #define PS_RAM_SIZE ram_size
#define PS_MIN_SIZE (PS_HDR_SIZE*3) #define PS_MIN_SIZE (PS_HDR_SIZE*3)
#define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100) #define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100)
#define PS_STACK_SIZE (PS_RAM_SIZE / 256)
#define SZ_IH_BKUP (10 * sizeof(LE32)) #define SZ_IH_BKUP (10 * sizeof(LE32))
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh) #define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
#define K0_BS (0x80000000) #define K0_BS (0x80000000)
#define K1_BS (0xa0000000) #define K1_BS (0xa0000000)
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS) #define EXE_BS (ih.epc & K0_BS)
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
// lui / addiu // lui / addiu
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
#define MIPS_LO(a) ((a) & 0xffff) #define MIPS_LO(a) ((a) & 0xffff)
#define MIPS_PC16(a) ((a) >> 2) #define MIPS_PC16(a) ((a) >> 2)
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) #define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
/************************************************************************* /*************************************************************************
// ps1 exe looks like this: // ps1 exe looks like this:
@ -76,7 +78,8 @@ static const
PackPs1::PackPs1(InputFile *f) : PackPs1::PackPs1(InputFile *f) :
super(f), super(f),
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit), isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
build_Loader(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0), pad_code(0) buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
pad_code(0), bss_start(0), bss_end(0)
{ {
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136); COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44); COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
@ -179,6 +182,7 @@ void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsign
{ {
unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)]; unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)];
memset(cpr_bh, 0, sizeof(bh));
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh; ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
int r = upx_compress(src, SZ_IH_BKUP, int r = upx_compress(src, SZ_IH_BKUP,
@ -189,24 +193,24 @@ void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsign
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4); *len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP)); p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
memcpy(dst, cpr_bh, SZ_IH_BKUP); memcpy(dst, cpr_bh, SZ_IH_BKUP);
delete [] cpr_bh; delete [] cpr_bh;
} }
else else
throwInternalError("failed to create backup header"); throwInternalError("header compression failed");
} }
#define ADLER16_HI(a,b) ((((a) & 0xffff) ^ (b)) << 16) #define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
#define ADLER16_LO(a,b) (((a) >> 16) ^ (b)) #define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
#define RE_ADLER16(a,b) (ADLER16_HI(a,b) | ADLER16_LO(a,b)) #define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst) bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
{ {
ps1_exe_chb_t *src = (ps1_exe_chb_t*)p; ps1_exe_chb_t *src = (ps1_exe_chb_t*)p;
if (src && src->id == '1' && dst) if (src && (src->id == '1' && src->len < SZ_IH_BKUP) && dst)
{ {
unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)]; unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)];
unsigned sz_bh = SZ_IH_BKUP; unsigned sz_bh = SZ_IH_BKUP;
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len, int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
unc_bh, &sz_bh, M_NRV2E_8, NULL ); unc_bh, &sz_bh, M_NRV2E_8, NULL );
@ -245,10 +249,12 @@ bool PackPs1::checkFileHeader()
infoWarning("unsupported header field entry"); infoWarning("unsupported header field entry");
return false; return false;
} }
if (!opt->force && ih.is_ptr == 0) if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
{ {
infoWarning("stack pointer field empty"); if (!opt->force)
return false; return false;
else
infoWarning("%s: stack pointer offset low", fi->getName());
} }
return true; return true;
} }
@ -293,117 +299,183 @@ bool PackPs1::canPack()
// //
**************************************************************************/ **************************************************************************/
void PackPs1::buildPS1Loader(const Filter *) int PackPs1::buildLoader(const Filter *)
{ {
const char *p = NULL; const char *method = NULL;
unsigned gap = 0;
if (ph.method == M_NRV2B_8) if (ph.method == M_NRV2B_8)
p = isCon ? "nrv2b.small,gb.8bit.sub,nrv.small.done" : method = isCon ? "nrv2b.small,gb.8bit.sub,nrv.done" :
"nrv2b.8bit"; "nrv2b.8bit,nrv.done";
else if (ph.method == M_NRV2D_8) else if (ph.method == M_NRV2D_8)
p = isCon ? "nrv2d.small,gb.8bit.sub,nrv.small.done" : method = isCon ? "nrv2d.small,gb.8bit.sub,nrv.done" :
"nrv2d.8bit"; "nrv2d.8bit,nrv.done";
else if (ph.method == M_NRV2E_8) else if (ph.method == M_NRV2E_8)
p = isCon ? "nrv2e.small,gb.8bit.sub,nrv.small.done" : method = isCon ? "nrv2e.small,gb.8bit.sub,nrv.done" :
"nrv2e.8bit"; "nrv2e.8bit,nrv.done";
else if (ph.method == M_NRV2B_LE32) else if (ph.method == M_NRV2B_LE32)
p = isCon ? "nrv2b.small,gb.32bit.sub,nrv.small.done" : method = isCon ? "nrv2b.small,gb.32bit.sub,nrv.done" :
"nrv2b.32bit"; "nrv2b.32bit,nrv.done";
else if (ph.method == M_NRV2D_LE32) else if (ph.method == M_NRV2D_LE32)
p = isCon ? "nrv2d.small,gb.32bit.sub,nrv.small.done" : method = isCon ? "nrv2d.small,gb.32bit.sub,nrv.done" :
"nrv2d.32bit"; "nrv2d.32bit,nrv.done";
else if (ph.method == M_NRV2E_LE32) else if (ph.method == M_NRV2E_LE32)
p = isCon ? "nrv2e.small,gb.32bit.sub,nrv.small.done" : method = isCon ? "nrv2e.small,gb.32bit.sub,nrv.done" :
"nrv2e.32bit"; "nrv2e.32bit,nrv.done";
else if (ph.method == M_LZMA) else if (ph.method == M_LZMA)
p = "nrv2b.small,gb.8bit.sub,nrv.small.done,lzma.prep"; method = "nrv2b.small,gb.8bit.sub,nrv.done,lzma.prep";
else else
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
if ((gap = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)),4)))
pad_code = gap;
else
pad_code = 0;
linker->addSection("pad.code", &pad_code, gap, 0);
if (isCon)
if (ph.method == M_LZMA)
addLoader("con.start", p,
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"con.entry", "pad.code", "lzma.exec", NULL);
else
addLoader("con.start", "con.mcpy",
ph.c_len & 3 ? "con.padcd" : "",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"con.entry", p,
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
"con.exit", "pad.code", NULL);
else
if (ph.method == M_LZMA)
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", p, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL);
else
addLoader("cdb.start", "pad.code", "cdb.entry",
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
p,
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
"cdb.exit", "pad.code", NULL);
addLoader("UPX1HEAD", "IDENTSTR", NULL);
}
int PackPs1::buildLoader(const Filter *)
{
unsigned sa_tmp = sa_cnt; unsigned sa_tmp = sa_cnt;
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method) || ph.method == M_LZMA) if (ph.overlap_overhead > sa_cnt)
{ {
if (ph.overlap_overhead > sa_cnt) if (!opt->force)
{ {
if (!opt->force) infoWarning("not in-place decompressible");
{ throwCantPack("packed data overlap (try --force)");
infoWarning("not in-place decompressible");
throwCantPack("packed data overlap (try --force)");
}
else
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead-sa_tmp),4);
} }
if (ph.method == M_LZMA && !build_Loader) else
{ sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
initLoader(nrv_loader,sizeof(nrv_loader)); }
addLoader(isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short", foundBss = findBssSection();
"con.exit", NULL);
} if (ph.method == M_LZMA && !buildPart2)
else if (ph.method == M_LZMA && build_Loader) {
initLoader(nrv_loader, sizeof(nrv_loader));
addLoader("decompressor.start",
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
!foundBss ? "con.exit" : "bss.exit", NULL);
}
else
{
if (ph.method == M_LZMA && buildPart2)
{ {
unsigned char *cprLoader = new unsigned char[MemBuffer::getSizeForCompression(sz_lunc)]; unsigned char *cprLoader = new unsigned char[MemBuffer::getSizeForCompression(sz_lunc)];
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr, int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
NULL, M_NRV2B_8, 10, NULL, NULL ); NULL, M_NRV2B_8, 10, NULL, NULL );
if (r != UPX_E_OK || sz_lcpr >= sz_lunc) if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
throwInternalError("loader compression failed"); throwInternalError("loader compression failed");
initLoader(nrv_loader,sizeof(nrv_loader), 0, initLoader(nrv_loader, sizeof(nrv_loader), 0,
(ph.method != M_LZMA || isCon) ? 0 : 1); (ph.method != M_LZMA || isCon) ? 0 : 1);
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0); linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
delete [] cprLoader; delete [] cprLoader;
buildPS1Loader();
} }
else else
{ {
initLoader(nrv_loader,sizeof(nrv_loader), 0, initLoader(nrv_loader, sizeof(nrv_loader), 0,
(ph.method != M_LZMA || isCon) ? 0 : 1); (ph.method != M_LZMA || isCon) ? 0 : 1);
buildPS1Loader();
} }
}
else pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
throwInternalError("unknown compression method"); linker->addSection("pad.code", &pad_code, pad_code, 0);
if (isCon)
{
if (ph.method == M_LZMA)
addLoader(!foundBss ? "con.start" : "bss.con.start",
method,
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"con.entry", "pad.code", "lzma.exec", NULL);
else
addLoader(!foundBss ? "con.start" : "bss.con.start", "con.mcpy",
ph.c_len & 3 ? "con.padcd" : "",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"con.entry", method,
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
!foundBss ? "con.exit" : "bss.exit",
"pad.code", NULL);
}
else
{
if (ph.method == M_LZMA)
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL);
else
addLoader("cdb.start", "pad.code", "cdb.entry",
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
method,
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
!foundBss ? "cdb.exit" : "bss.exit",
"pad.code", NULL);
}
addLoader("UPX1HEAD", "IDENTSTR", NULL);
}
freezeLoader(); freezeLoader();
return getLoaderSize(); return getLoaderSize();
} }
#define OPTYPE(x) (((x) >> 13) & 0x7)
#define OPCODE(x) (((x) >> 10) & 0x7)
#define REG1(x) (((x) >> 5) & 0x1f)
#define REG2(x) ((x) & 0x1f)
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
// Type
#define REGIMM 1
#define STORE 5
// Op
#define LUI 7
#define ADDIU 1
#define SW 3
#define IS_LUI(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))
#define IS_ADDIU(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))
#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)
bool PackPs1::findBssSection()
{
unsigned char reg;
LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));
// check 18 opcodes for sw zero,0(x)
for (signed i = 18; i >= 0; i--)
{
unsigned short op = p1[i] >> 16;
if (IS_SW_ZERO(op))
{
// found! get reg (x) for bss_start
reg = REG1(op);
for (; i >= 0; i--)
{
bss_nfo *p = (bss_nfo *)&p1[i];
unsigned short op1 = p->op1, op2 = p->op2;
// check for la (x),bss_start
if ((IS_LUI(op1) && REG2(op1) == reg) &&
(IS_ADDIU(op2) && REG1(op2) == reg))
{
op1 = p->op3, op2 = p->op4;
// check for la (y),bss_end
if (IS_LUI(op1) && IS_ADDIU(op2))
{
// bss section info found!
bss_start = MIPS_IMM(p->hi1, p->lo1);
bss_end = MIPS_IMM(p->hi2, p->lo2);
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
{
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
if (bss_end > (end_offs + wkmem_sz))
return (isCon || (!isCon && (ph.method == M_LZMA)));
else
return false;
}
}
else
return false;
}
}
}
}
return false;
}
/************************************************************************* /*************************************************************************
// //
@ -413,7 +485,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; 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);
@ -421,9 +493,9 @@ 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++ > (0x10000<<5) || sa_cnt >= fdata_size-1024) break; } while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }
if (sa_cnt > (0x10000<<2)) if (sa_cnt > (0x10000 << 2))
sa_cnt = ALIGN_DOWN(sa_cnt,32); sa_cnt = ALIGN_DOWN(sa_cnt,32);
else else
sa_cnt = ALIGN_DOWN(sa_cnt,4); sa_cnt = ALIGN_DOWN(sa_cnt,4);
@ -442,10 +514,15 @@ void PackPs1::pack(OutputFile *fo)
if (overlap) if (overlap)
{ {
opt->info_mode += !opt->info_mode ? 1 : 0; opt->info_mode += !opt->info_mode ? 1 : 0;
infoWarning("%s: memory overlap %d bytes", fi->getName(), overlap); infoWarning("overlap - relocating load address (+%d bytes)", overlap);
sa_cnt += overlap; sa_cnt += overlap;
} }
/*
if (bss_start && bss_end && !foundBss)
infoWarning("%s: .bss section too small - use stack", fi->getName());
*/
unsigned lzma_init = 0; unsigned lzma_init = 0;
if (ph.method == M_LZMA) if (ph.method == M_LZMA)
@ -454,23 +531,22 @@ void PackPs1::pack(OutputFile *fo)
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init")); lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
defineDecompressorSymbols(); defineDecompressorSymbols();
linker->defineSymbol("lzma_decoder", linker->getSymbolOffset(isCon ? "LZMA_DEC20" : "LZMA_DEC10"));
linker->defineSymbol("entry", ih.epc); linker->defineSymbol("entry", ih.epc);
linker->defineSymbol("SC", linker->defineSymbol("SC",
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2); sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
linker->relocate(); linker->relocate();
build_Loader = 1; buildPart2 = true;
buildLoader(&ft); buildLoader(&ft);
} }
memcpy(&oh, &ih, sizeof(ih)); memcpy(&oh, &ih, sizeof(ih));
unsigned sz_cbh; unsigned sz_cbh;
putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh); putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);
if (ih.is_ptr == 0) if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
oh.is_ptr = PS_RAM_SIZE-0x10; oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));
if (ih.da_ptr != 0 || ih.da_len != 0 || if (ih.da_ptr != 0 || ih.da_len != 0 ||
ih.bs_ptr != 0 || ih.bs_len != 0) ih.bs_ptr != 0 || ih.bs_len != 0)
@ -504,9 +580,16 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("entry", ih.epc); linker->defineSymbol("entry", ih.epc);
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ? linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
sa_cnt >> 5 : sa_cnt >> 2)); sa_cnt >> 5 : sa_cnt >> 2));
linker->defineSymbol("DECO",decomp_data_start); linker->defineSymbol("DECO", decomp_data_start);
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
if (foundBss)
if (ph.method == M_LZMA)
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
- (sz_lunc + 16));
else
linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));
linker->defineSymbol("LS", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
const unsigned entry = comp_data_start - e_len; const unsigned entry = comp_data_start - e_len;
oh.epc = oh.tx_ptr = entry; oh.epc = oh.tx_ptr = entry;
@ -537,9 +620,6 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec"))); linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
else else
linker->defineSymbol("DCRT", (entry + (e_len - d_len))); linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
linker->relocate();
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
} }
else else
{ {
@ -548,12 +628,12 @@ void PackPs1::pack(OutputFile *fo)
if (ph.method == M_LZMA) if (ph.method == M_LZMA)
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
- getLoaderSectionStart("cdb.entry.lzma")); - getLoaderSectionStart("cdb.entry.lzma"));
linker->relocate();
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader,lsize);
} }
linker->relocate();
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
// ps1_exe_t structure // ps1_exe_t structure
fo->write(&oh, sizeof(oh)); fo->write(&oh, sizeof(oh));
fo->write(&bh, sz_cbh); fo->write(&bh, sz_cbh);
@ -572,18 +652,25 @@ void PackPs1::pack(OutputFile *fo)
throwNotCompressible(); throwNotCompressible();
#if 0 #if 0
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len); 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 - pad_code);
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh); printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc); printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr); printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
printf("%-13s: eof in mem IF: %08X bytes\n", getName(), (unsigned int) ih.tx_ptr+ih.tx_len); printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
printf("%-13s: eof in mem OF: %08X bytes\n", getName(), (unsigned int) oh.tx_ptr+oh.tx_len); printf("%-13s: bbs start : %08X bytes\n", getName(), (unsigned int) bss_start);
printf("%-13s: bbs end : %08X bytes\n", getName(), (unsigned int) bss_end);
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
unsigned char i = 0;
if (isCon) { if (foundBss) i = 1; }
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level); char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
printf("%-13s: compressor : %s\n", getName(), method_name); printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
#endif #endif
} }
/************************************************************************* /*************************************************************************

View File

@ -59,8 +59,8 @@ protected:
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len); virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst); virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
virtual bool readBkupHeader(); virtual bool readBkupHeader();
virtual void buildPS1Loader(const Filter *ft=0);
virtual int buildLoader(const Filter *ft); virtual int buildLoader(const Filter *ft);
virtual bool findBssSection();
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
virtual int readFileHeader(); virtual int readFileHeader();
@ -111,16 +111,25 @@ protected:
} }
__attribute_packed; __attribute_packed;
typedef struct bss_nfo
{
LE16 hi1, op1, lo1, op2;
LE16 hi2, op3, lo2, op4;
}
__attribute_packed;
ps1_exe_t ih, oh; ps1_exe_t ih, oh;
ps1_exe_hb_t bh; ps1_exe_hb_t bh;
bool isCon; bool isCon;
bool is32Bit; bool is32Bit;
bool build_Loader; bool buildPart2;
bool foundBss;
unsigned ram_size; unsigned ram_size;
unsigned sa_cnt, overlap; unsigned sa_cnt, overlap;
unsigned sz_lunc, sz_lcpr; unsigned sz_lunc, sz_lcpr;
unsigned pad_code; unsigned pad_code;
unsigned bss_start, bss_end;
// filesize-PS_HDR_SIZE // filesize-PS_HDR_SIZE
unsigned fdata_size; unsigned fdata_size;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -21,11 +21,15 @@
; If not, write to the Free Software Foundation, Inc., ; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ;
; Markus F.X.J. Oberhumer Jens Medoch ; Markus F.X.J. Oberhumer
; <markus@oberhumer.com> <jssg@users.sourceforge.net> ; <mfx@users.sourceforge.net>
; http://www.oberhumer.com/opensource/ucl/ ; http://www.oberhumer.com/opensource/ucl/
; ;
*/ ; Jens Medoch
; <jssg@users.sourceforge.net>
;
*/
#ifndef _MR3K_STD_CONF_ #ifndef _MR3K_STD_CONF_
#define _MR3K_STD_CONF_ #define _MR3K_STD_CONF_
@ -195,12 +199,11 @@
.ifnb label .ifnb label
\label: \label:
.endif .endif
\type done \type decomp_done
.if (UCL_SMALL == 1) .if (UCL_SMALL == 1)
1: 1:
GBIT GBIT
.endif .endif
done:
.else .else
.ifc "\option", "sub_only" .ifc "\option", "sub_only"
sub_size = . sub_size = .

View File

@ -28,7 +28,7 @@
John F. Reiser Jens Medoch John F. Reiser Jens Medoch
<jreiser@users.sourceforge.net> <jssg@users.sourceforge.net> <jreiser@users.sourceforge.net> <jssg@users.sourceforge.net>
*/ */
section lzma.init section lzma.init
li tmp,%lo(UPXa-lzma_args_sz) li tmp,%lo(UPXa-lzma_args_sz)

View File

@ -21,15 +21,18 @@
; If not, write to the Free Software Foundation, Inc., ; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ;
; Markus F.X.J. Oberhumer Jens Medoch ; Markus F.X.J. Oberhumer
; <markus@oberhumer.com> <jssg@users.sourceforge.net> ; <mfx@users.sourceforge.net>
; http://www.oberhumer.com/opensource/ucl/ ; http://www.oberhumer.com/opensource/ucl/
; ;
*/ ; Jens Medoch
; <jssg@users.sourceforge.net>
;
*/
.macro section name .macro section name
.section \name .section \name
.align 0 .align 0
.endm .endm
#define zero $0 #define zero $0

View File

@ -21,11 +21,14 @@
; If not, write to the Free Software Foundation, Inc., ; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ;
; Markus F.X.J. Oberhumer Jens Medoch ; Markus F.X.J. Oberhumer
; <markus@oberhumer.com> <jssg@users.sourceforge.net> ; <mfx@users.sourceforge.net>
; http://www.oberhumer.com/opensource/ucl/ ; http://www.oberhumer.com/opensource/ucl/
; ;
*/ ; Jens Medoch
; <jssg@users.sourceforge.net>
;
*/
/* /*

View File

@ -21,11 +21,14 @@
; If not, write to the Free Software Foundation, Inc., ; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ;
; Markus F.X.J. Oberhumer Jens Medoch ; Markus F.X.J. Oberhumer
; <markus@oberhumer.com> <jssg@users.sourceforge.net> ; <mfx@users.sourceforge.net>
; http://www.oberhumer.com/opensource/ucl/ ; http://www.oberhumer.com/opensource/ucl/
; ;
*/ ; Jens Medoch
; <jssg@users.sourceforge.net>
;
*/
/* /*

View File

@ -21,11 +21,14 @@
; If not, write to the Free Software Foundation, Inc., ; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
; ;
; Markus F.X.J. Oberhumer Jens Medoch ; Markus F.X.J. Oberhumer
; <markus@oberhumer.com> <jssg@users.sourceforge.net> ; <mfx@users.sourceforge.net>
; http$://www.oberhumer.com/opensource/ucl/ ; http://www.oberhumer.com/opensource/ucl/
; ;
*/ ; Jens Medoch
; <jssg@users.sourceforge.net>
;
*/
/* /*

View File

@ -29,12 +29,12 @@
; Jens Medoch ; Jens Medoch
; <jssg@users.sourceforge.net> ; <jssg@users.sourceforge.net>
; ;
*/ */
.set mips1 .set mips1
.altmacro
.set noreorder .set noreorder
.set noat .set noat
.altmacro
#include "arch/mips/mipsel.r3000/macros.ash" #include "arch/mips/mipsel.r3000/macros.ash"
@ -62,32 +62,32 @@
.endif .endif
.endm .endm
.macro regs _w, ok .macro regs _w, sz, reg
\_w pc,SZ_REG*0(sp) \_w pc,SZ_REG*0(\reg)
\_w src,SZ_REG*1(sp) \_w src,SZ_REG*1(\reg)
\_w cnt,SZ_REG*2(sp) \_w cnt,SZ_REG*2(\reg)
\_w a3,SZ_REG*3(sp) \_w a3,SZ_REG*3(\reg)
\_w ra,SZ_REG*4(sp) \_w ra,SZ_REG*4(\reg)
REG_SZ = (5*SZ_REG) REG_SZ = (5*SZ_REG)
.if (\ok == 1) .if (\sz == 1)
\_w tmp,SZ_REG*5(sp) \_w tmp,SZ_REG*5(\reg)
REG_SZ = (6*SZ_REG) REG_SZ = (6*SZ_REG)
.endif .endif
.endm .endm
.macro push ok = 0 .macro push sz = 0, reg = sp
.if (PS1) .if (PS1)
regs sw,\ok regs sw,\sz,\reg
.else .else
regs sd,\ok regs sd,\sz,\reg
.endif .endif
.endm .endm
.macro pop ok = 0 .macro pop ok = 0, reg = sp
.if (PS1) .if (PS1)
regs lw,\ok regs lw,\ok,\reg
.else .else
regs ld,\ok regs ld,\ok,\reg
.endif .endif
.endm .endm
@ -105,11 +105,23 @@
.endif .endif
.endm .endm
/*
.macro EnterCriticalSection
li a0, 1
syscall
.endm
.macro ExitCriticalSection
li a0, 2
syscall
.endm
*/
#define CLzmaDecoderState a0 /* CLzmaDecoderState */ #define CLzmaDecoderState a0 /* CLzmaDecoderState */
#define inStream a1 #define inStream a1
#define inSize a2 #define inSize a2
#define pinSizeprocessed a3 /* inSizeprocessed */ #define pinSizeprocessed a3 /* *inSizeprocessed */
#define outStream t0 #define outStream t0
#define outSize t1 #define outSize t1
@ -141,7 +153,7 @@ section cdb.entry
section cdb.start.lzma section cdb.start.lzma
la t0,PSVR // prepare to compute value la t0,PSVR // prepare to compute value
subu t0,s0,t0 // get stored header offset in mem subu t0,s0,t0 // get stored header offset in mem
li tmp,%lo(LS+REG_SZ) // size of decomp. routine ori tmp,zero,%lo(ldr_sz+REG_SZ) // size of decomp. routine
jr t0 jr t0
subu sp,tmp // adjust the stack with this size subu sp,tmp // adjust the stack with this size
@ -175,16 +187,16 @@ section cdb.exit
mCDBOOT 0 mCDBOOT 0
section con.start section con.start
li tmp,%lo(LS+REG_SZ) // size of decomp. routine li tmp,%lo(ldr_sz+REG_SZ) // size of decomp. routine
subu sp,tmp // adjust the stack with this size subu sp,tmp // adjust the stack with this size
push 1 // push used regs push 1 // push used regs
subiu cnt,tmp,REG_SZ // cnt = counter copyloop addiu pc,sp,REG_SZ // get offset for decomp. routine
addiu pc,sp,REG_SZ // get offset for decomp. routine
move dst,pc move dst,pc
la src,DCRT // load decompression routine's offset la src,DCRT // load decompression routine's offset
section con.mcpy section con.mcpy
1: lw var,0(src) // memcpy ori cnt,zero,%lo(ldr_sz) // amount of removed zero's at eof
1: lw var,0(src) // memcpy
subiu cnt,4 subiu cnt,4
sw var,0(dst) sw var,0(dst)
addiu src,4 addiu src,4
@ -215,17 +227,53 @@ section con.exit
addu sp,tmp addu sp,tmp
/*
=============
============= ENTRY POINT bss
=============
*/
mCDBOOT 0
section bss.cdb.start.lzma
la t0,PSVR // prepare to compute value
subu t0,s0,t0 // get stored header offset in mem
lui var,%hi(wrkmem-REG_SZ) // size of decomp. routine
jr t0
addiu var,%lo(wrkmem-REG_SZ) // adjust the stack with this size
section bss.cdb.entry.lzma
move tmp,sp
push 1,var // push used regs
addiu src,t0,lzma_cpr // compressed lzma decoder offset
addiu dst,sp,REG_SZ
section bss.con.start
la var,wrkmem-REG_SZ
move tmp,sp
push 1,var // push used regs
move sp,var
addiu pc,sp,REG_SZ // get offset for decomp. routine
move dst,pc
la src,DCRT // load decompression routine's offset
section bss.exit
SysFlushCache
pop 1 // pop used regs with marker for entry
j entry
move sp,tmp
// ============= // =============
section memset.short section memset.short
li cnt,%lo(SC) // amount of removed zero's at eof ori cnt,zero,%lo(SC) // amount of removed zero's at eof
1: sw zero,0(dst) 1: sw zero,0(dst)
subiu cnt,1 subiu cnt,1
bnez cnt,1b bnez cnt,1b
addiu dst,4 addiu dst,4
section memset.long section memset.long
li cnt,%lo(SC) // amount of removed zero's at eof ori cnt,zero,%lo(SC) // amount of removed zero's at eof
sll cnt,3 // (cd mode 2 data sector alignment) sll cnt,3 // (cd mode 2 data sector alignment)
1: sw zero,0(dst) 1: sw zero,0(dst)
subiu cnt,1 subiu cnt,1
@ -279,9 +327,12 @@ section nrv2d.small
section nrv2e.small section nrv2e.small
build without_sub, nrv2e build without_sub, nrv2e
section nrv.small.done section nrv.done
decomp_done: decomp_done:
section decompressor.start
decompressor:
#include "arch/mips/mipsel.r3000/lzma_d.S" #include "arch/mips/mipsel.r3000/lzma_d.S"
#include "include/header2.ash" #include "include/header2.ash"