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:
parent
59dd33a461
commit
31b629a19c
26
doc/upx.pod
26
doc/upx.pod
|
@ -699,19 +699,19 @@ nostalgic feelings of one of the authors.
|
|||
Packed programs will be byte-identical to the original after uncompression,
|
||||
until further notice.
|
||||
|
||||
Maximum uncompressed size: ~1998848 bytes.
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||
|
||||
Notes:
|
||||
|
||||
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable.
|
||||
For transfer between client/target use options below.
|
||||
- UPX creates as default a console transfer compatible executable.
|
||||
For CD-Mastering use option "--boot-only" as descriped below.
|
||||
|
||||
- Normally the packed files use the same memory areas like the uncompressed
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
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
|
||||
offset for the packed file, but this isn't a real problem if it is a
|
||||
single or boot-only executable.
|
||||
error. With the "--force" option UPX will relocate the loading address
|
||||
for the packed file, but this isn't a real problem if it is a single or
|
||||
the main executable.
|
||||
|
||||
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 default method gives the best results anyway.
|
||||
|
||||
--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 !
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||
|
||||
--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
|
||||
alignment. May slightly improves the compression ratio,
|
||||
but the compressed executable will not boot from a CD.
|
||||
Use it for client/target transfer only !
|
||||
Use it for console transfer only !
|
||||
|
||||
|
||||
|
||||
|
|
349
src/p_ps1.cpp
349
src/p_ps1.cpp
|
@ -40,24 +40,26 @@
|
|||
static const
|
||||
#include "stub/mipsel.r3000-ps1.h"
|
||||
|
||||
#define CD_SEC 2048
|
||||
#define PS_HDR_SIZE CD_SEC
|
||||
#define PS_RAM_SIZE ram_size
|
||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||
#define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100)
|
||||
#define CD_SEC 2048
|
||||
#define PS_HDR_SIZE CD_SEC
|
||||
#define PS_RAM_SIZE ram_size
|
||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||
#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 HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||
|
||||
#define K0_BS (0x80000000)
|
||||
#define K1_BS (0xa0000000)
|
||||
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||
#define K0_BS (0x80000000)
|
||||
#define K1_BS (0xa0000000)
|
||||
#define EXE_BS (ih.epc & K0_BS)
|
||||
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||
|
||||
// lui / addiu
|
||||
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||
#define MIPS_LO(a) ((a) & 0xffff)
|
||||
#define MIPS_PC16(a) ((a) >> 2)
|
||||
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||
#define MIPS_LO(a) ((a) & 0xffff)
|
||||
#define MIPS_PC16(a) ((a) >> 2)
|
||||
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||
|
||||
/*************************************************************************
|
||||
// ps1 exe looks like this:
|
||||
|
@ -76,7 +78,8 @@ static const
|
|||
PackPs1::PackPs1(InputFile *f) :
|
||||
super(f),
|
||||
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_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)];
|
||||
|
||||
memset(cpr_bh, 0, sizeof(bh));
|
||||
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||
|
||||
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);
|
||||
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||
delete [] cpr_bh;
|
||||
delete [] cpr_bh;
|
||||
}
|
||||
else
|
||||
throwInternalError("failed to create backup header");
|
||||
throwInternalError("header compression failed");
|
||||
}
|
||||
|
||||
#define ADLER16_HI(a,b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||
#define ADLER16_LO(a,b) (((a) >> 16) ^ (b))
|
||||
#define RE_ADLER16(a,b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||
#define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||
#define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
|
||||
#define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||
|
||||
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
|
||||
{
|
||||
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 sz_bh = SZ_IH_BKUP;
|
||||
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
|
||||
unc_bh, &sz_bh, M_NRV2E_8, NULL );
|
||||
|
@ -245,10 +249,12 @@ bool PackPs1::checkFileHeader()
|
|||
infoWarning("unsupported header field entry");
|
||||
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");
|
||||
return false;
|
||||
if (!opt->force)
|
||||
return false;
|
||||
else
|
||||
infoWarning("%s: stack pointer offset low", fi->getName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -293,117 +299,183 @@ bool PackPs1::canPack()
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackPs1::buildPS1Loader(const Filter *)
|
||||
int PackPs1::buildLoader(const Filter *)
|
||||
{
|
||||
const char *p = NULL;
|
||||
unsigned gap = 0;
|
||||
const char *method = NULL;
|
||||
|
||||
if (ph.method == M_NRV2B_8)
|
||||
p = isCon ? "nrv2b.small,gb.8bit.sub,nrv.small.done" :
|
||||
"nrv2b.8bit";
|
||||
method = isCon ? "nrv2b.small,gb.8bit.sub,nrv.done" :
|
||||
"nrv2b.8bit,nrv.done";
|
||||
else if (ph.method == M_NRV2D_8)
|
||||
p = isCon ? "nrv2d.small,gb.8bit.sub,nrv.small.done" :
|
||||
"nrv2d.8bit";
|
||||
method = isCon ? "nrv2d.small,gb.8bit.sub,nrv.done" :
|
||||
"nrv2d.8bit,nrv.done";
|
||||
else if (ph.method == M_NRV2E_8)
|
||||
p = isCon ? "nrv2e.small,gb.8bit.sub,nrv.small.done" :
|
||||
"nrv2e.8bit";
|
||||
method = isCon ? "nrv2e.small,gb.8bit.sub,nrv.done" :
|
||||
"nrv2e.8bit,nrv.done";
|
||||
else if (ph.method == M_NRV2B_LE32)
|
||||
p = isCon ? "nrv2b.small,gb.32bit.sub,nrv.small.done" :
|
||||
"nrv2b.32bit";
|
||||
method = isCon ? "nrv2b.small,gb.32bit.sub,nrv.done" :
|
||||
"nrv2b.32bit,nrv.done";
|
||||
else if (ph.method == M_NRV2D_LE32)
|
||||
p = isCon ? "nrv2d.small,gb.32bit.sub,nrv.small.done" :
|
||||
"nrv2d.32bit";
|
||||
method = isCon ? "nrv2d.small,gb.32bit.sub,nrv.done" :
|
||||
"nrv2d.32bit,nrv.done";
|
||||
else if (ph.method == M_NRV2E_LE32)
|
||||
p = isCon ? "nrv2e.small,gb.32bit.sub,nrv.small.done" :
|
||||
"nrv2e.32bit";
|
||||
method = isCon ? "nrv2e.small,gb.32bit.sub,nrv.done" :
|
||||
"nrv2e.32bit,nrv.done";
|
||||
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
|
||||
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;
|
||||
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)");
|
||||
}
|
||||
else
|
||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead-sa_tmp),4);
|
||||
infoWarning("not in-place decompressible");
|
||||
throwCantPack("packed data overlap (try --force)");
|
||||
}
|
||||
if (ph.method == M_LZMA && !build_Loader)
|
||||
{
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
addLoader(isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||
"con.exit", NULL);
|
||||
}
|
||||
else if (ph.method == M_LZMA && build_Loader)
|
||||
else
|
||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
|
||||
}
|
||||
|
||||
foundBss = findBssSection();
|
||||
|
||||
if (ph.method == M_LZMA && !buildPart2)
|
||||
{
|
||||
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)];
|
||||
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
|
||||
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||
throwInternalError("loader compression failed");
|
||||
initLoader(nrv_loader,sizeof(nrv_loader), 0,
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
initLoader(nrv_loader, sizeof(nrv_loader), 0,
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||
delete [] cprLoader;
|
||||
buildPS1Loader();
|
||||
}
|
||||
else
|
||||
{
|
||||
initLoader(nrv_loader,sizeof(nrv_loader), 0,
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
buildPS1Loader();
|
||||
initLoader(nrv_loader, sizeof(nrv_loader), 0,
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
|
||||
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();
|
||||
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);
|
||||
obuf.allocForCompression(fdata_size);
|
||||
const upx_byte *p_scan = ibuf+fdata_size;
|
||||
const upx_byte *p_scan = ibuf + fdata_size;
|
||||
|
||||
// read file
|
||||
fi->seek(PS_HDR_SIZE,SEEK_SET);
|
||||
|
@ -421,9 +493,9 @@ 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++ > (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);
|
||||
else
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt,4);
|
||||
|
@ -442,10 +514,15 @@ void PackPs1::pack(OutputFile *fo)
|
|||
if (overlap)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
if (bss_start && bss_end && !foundBss)
|
||||
infoWarning("%s: .bss section too small - use stack", fi->getName());
|
||||
*/
|
||||
|
||||
unsigned lzma_init = 0;
|
||||
|
||||
if (ph.method == M_LZMA)
|
||||
|
@ -454,23 +531,22 @@ void PackPs1::pack(OutputFile *fo)
|
|||
|
||||
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
|
||||
defineDecompressorSymbols();
|
||||
linker->defineSymbol("lzma_decoder", linker->getSymbolOffset(isCon ? "LZMA_DEC20" : "LZMA_DEC10"));
|
||||
linker->defineSymbol("entry", ih.epc);
|
||||
linker->defineSymbol("SC",
|
||||
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||
linker->relocate();
|
||||
|
||||
build_Loader = 1;
|
||||
buildPart2 = true;
|
||||
buildLoader(&ft);
|
||||
}
|
||||
|
||||
memcpy(&oh, &ih, sizeof(ih));
|
||||
|
||||
|
||||
unsigned sz_cbh;
|
||||
putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);
|
||||
|
||||
if (ih.is_ptr == 0)
|
||||
oh.is_ptr = PS_RAM_SIZE-0x10;
|
||||
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||
oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));
|
||||
|
||||
if (ih.da_ptr != 0 || ih.da_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("SC", MIPS_LO(sa_cnt > (0x10000 << 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;
|
||||
oh.epc = oh.tx_ptr = entry;
|
||||
|
@ -537,9 +620,6 @@ void PackPs1::pack(OutputFile *fo)
|
|||
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||
else
|
||||
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||
linker->relocate();
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -548,12 +628,12 @@ void PackPs1::pack(OutputFile *fo)
|
|||
if (ph.method == M_LZMA)
|
||||
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
||||
- 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
|
||||
fo->write(&oh, sizeof(oh));
|
||||
fo->write(&bh, sz_cbh);
|
||||
|
@ -572,18 +652,25 @@ 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: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||
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: eof in mem OF: %08X bytes\n", getName(), (unsigned int) oh.tx_ptr+oh.tx_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: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);
|
||||
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||
printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
|
||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||
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);
|
||||
printf("%-13s: compressor : %s\n", getName(), method_name);
|
||||
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
|
13
src/p_ps1.h
13
src/p_ps1.h
|
@ -59,8 +59,8 @@ protected:
|
|||
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
|
||||
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||
virtual bool readBkupHeader();
|
||||
virtual void buildPS1Loader(const Filter *ft=0);
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual bool findBssSection();
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual int readFileHeader();
|
||||
|
@ -111,16 +111,25 @@ protected:
|
|||
}
|
||||
__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_hb_t bh;
|
||||
|
||||
bool isCon;
|
||||
bool is32Bit;
|
||||
bool build_Loader;
|
||||
bool buildPart2;
|
||||
bool foundBss;
|
||||
unsigned ram_size;
|
||||
unsigned sa_cnt, overlap;
|
||||
unsigned sz_lunc, sz_lcpr;
|
||||
unsigned pad_code;
|
||||
unsigned bss_start, bss_end;
|
||||
// filesize-PS_HDR_SIZE
|
||||
unsigned fdata_size;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,11 +21,15 @@
|
|||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Jens Medoch
|
||||
; <markus@oberhumer.com> <jssg@users.sourceforge.net>
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <mfx@users.sourceforge.net>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
*/
|
||||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MR3K_STD_CONF_
|
||||
#define _MR3K_STD_CONF_
|
||||
|
@ -195,12 +199,11 @@
|
|||
.ifnb label
|
||||
\label:
|
||||
.endif
|
||||
\type done
|
||||
\type decomp_done
|
||||
.if (UCL_SMALL == 1)
|
||||
1:
|
||||
GBIT
|
||||
.endif
|
||||
done:
|
||||
.else
|
||||
.ifc "\option", "sub_only"
|
||||
sub_size = .
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
John F. Reiser Jens Medoch
|
||||
<jreiser@users.sourceforge.net> <jssg@users.sourceforge.net>
|
||||
*/
|
||||
*/
|
||||
|
||||
section lzma.init
|
||||
li tmp,%lo(UPXa-lzma_args_sz)
|
||||
|
|
|
@ -21,15 +21,18 @@
|
|||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Jens Medoch
|
||||
; <markus@oberhumer.com> <jssg@users.sourceforge.net>
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <mfx@users.sourceforge.net>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
*/
|
||||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
.macro section name
|
||||
.section \name
|
||||
.align 0
|
||||
.section \name
|
||||
.align 0
|
||||
.endm
|
||||
|
||||
#define zero $0
|
||||
|
|
|
@ -21,11 +21,14 @@
|
|||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Jens Medoch
|
||||
; <markus@oberhumer.com> <jssg@users.sourceforge.net>
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <mfx@users.sourceforge.net>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
*/
|
||||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,11 +21,14 @@
|
|||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Jens Medoch
|
||||
; <markus@oberhumer.com> <jssg@users.sourceforge.net>
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <mfx@users.sourceforge.net>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
*/
|
||||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,11 +21,14 @@
|
|||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Jens Medoch
|
||||
; <markus@oberhumer.com> <jssg@users.sourceforge.net>
|
||||
; http$://www.oberhumer.com/opensource/ucl/
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <mfx@users.sourceforge.net>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
*/
|
||||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -29,12 +29,12 @@
|
|||
; Jens Medoch
|
||||
; <jssg@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
*/
|
||||
|
||||
.set mips1
|
||||
.altmacro
|
||||
.set noreorder
|
||||
.set noat
|
||||
.altmacro
|
||||
|
||||
|
||||
#include "arch/mips/mipsel.r3000/macros.ash"
|
||||
|
@ -62,32 +62,32 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
.macro regs _w, ok
|
||||
\_w pc,SZ_REG*0(sp)
|
||||
\_w src,SZ_REG*1(sp)
|
||||
\_w cnt,SZ_REG*2(sp)
|
||||
\_w a3,SZ_REG*3(sp)
|
||||
\_w ra,SZ_REG*4(sp)
|
||||
.macro regs _w, sz, reg
|
||||
\_w pc,SZ_REG*0(\reg)
|
||||
\_w src,SZ_REG*1(\reg)
|
||||
\_w cnt,SZ_REG*2(\reg)
|
||||
\_w a3,SZ_REG*3(\reg)
|
||||
\_w ra,SZ_REG*4(\reg)
|
||||
REG_SZ = (5*SZ_REG)
|
||||
.if (\ok == 1)
|
||||
\_w tmp,SZ_REG*5(sp)
|
||||
.if (\sz == 1)
|
||||
\_w tmp,SZ_REG*5(\reg)
|
||||
REG_SZ = (6*SZ_REG)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro push ok = 0
|
||||
.macro push sz = 0, reg = sp
|
||||
.if (PS1)
|
||||
regs sw,\ok
|
||||
regs sw,\sz,\reg
|
||||
.else
|
||||
regs sd,\ok
|
||||
regs sd,\sz,\reg
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pop ok = 0
|
||||
.macro pop ok = 0, reg = sp
|
||||
.if (PS1)
|
||||
regs lw,\ok
|
||||
regs lw,\ok,\reg
|
||||
.else
|
||||
regs ld,\ok
|
||||
regs ld,\ok,\reg
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
@ -105,11 +105,23 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
.macro EnterCriticalSection
|
||||
li a0, 1
|
||||
syscall
|
||||
.endm
|
||||
|
||||
|
||||
.macro ExitCriticalSection
|
||||
li a0, 2
|
||||
syscall
|
||||
.endm
|
||||
*/
|
||||
|
||||
#define CLzmaDecoderState a0 /* CLzmaDecoderState */
|
||||
#define inStream a1
|
||||
#define inSize a2
|
||||
#define pinSizeprocessed a3 /* inSizeprocessed */
|
||||
#define pinSizeprocessed a3 /* *inSizeprocessed */
|
||||
|
||||
#define outStream t0
|
||||
#define outSize t1
|
||||
|
@ -141,7 +153,7 @@ section cdb.entry
|
|||
section cdb.start.lzma
|
||||
la t0,PSVR // prepare to compute value
|
||||
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
|
||||
subu sp,tmp // adjust the stack with this size
|
||||
|
||||
|
@ -175,16 +187,16 @@ section cdb.exit
|
|||
mCDBOOT 0
|
||||
|
||||
section con.start
|
||||
li tmp,%lo(LS+REG_SZ) // size of decomp. routine
|
||||
subu sp,tmp // adjust the stack with this size
|
||||
push 1 // push used regs
|
||||
subiu cnt,tmp,REG_SZ // cnt = counter copyloop
|
||||
addiu pc,sp,REG_SZ // get offset for decomp. routine
|
||||
li tmp,%lo(ldr_sz+REG_SZ) // size of decomp. routine
|
||||
subu sp,tmp // adjust the stack with this size
|
||||
push 1 // push used regs
|
||||
addiu pc,sp,REG_SZ // get offset for decomp. routine
|
||||
move dst,pc
|
||||
la src,DCRT // load decompression routine's offset
|
||||
la src,DCRT // load decompression routine's offset
|
||||
|
||||
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
|
||||
sw var,0(dst)
|
||||
addiu src,4
|
||||
|
@ -215,17 +227,53 @@ section con.exit
|
|||
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
|
||||
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)
|
||||
subiu cnt,1
|
||||
bnez cnt,1b
|
||||
addiu dst,4
|
||||
|
||||
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)
|
||||
1: sw zero,0(dst)
|
||||
subiu cnt,1
|
||||
|
@ -279,9 +327,12 @@ section nrv2d.small
|
|||
section nrv2e.small
|
||||
build without_sub, nrv2e
|
||||
|
||||
section nrv.small.done
|
||||
section nrv.done
|
||||
decomp_done:
|
||||
|
||||
section decompressor.start
|
||||
decompressor:
|
||||
|
||||
#include "arch/mips/mipsel.r3000/lzma_d.S"
|
||||
|
||||
#include "include/header2.ash"
|
||||
|
|
Loading…
Reference in New Issue
Block a user