Added support for FreeMiNT.
committer: mfx <mfx> 969522282 +0000
This commit is contained in:
+26
-9
@@ -101,12 +101,17 @@ int PackTos::getLoaderSize() const
|
|||||||
#define F_FASTLOAD 0x01 // don't zero heap
|
#define F_FASTLOAD 0x01 // don't zero heap
|
||||||
#define F_ALTLOAD 0x02 // OK to load in alternate ram
|
#define F_ALTLOAD 0x02 // OK to load in alternate ram
|
||||||
#define F_ALTALLOC 0x04 // OK to malloc from alt. ram
|
#define F_ALTALLOC 0x04 // OK to malloc from alt. ram
|
||||||
#define F_RESERVED 0x08 // reserved for future use
|
#define F_SMALLTPA 0x08 // used in MagiC: TPA can be allocated
|
||||||
|
// as specified in the program header
|
||||||
|
// rather than the biggest free memory
|
||||||
|
// block
|
||||||
#define F_MEMFLAGS 0xf0 // reserved for future use
|
#define F_MEMFLAGS 0xf0 // reserved for future use
|
||||||
#define F_SHTEXT 0x800 // program's text may be shared
|
#define F_SHTEXT 0x800 // program's text may be shared
|
||||||
|
|
||||||
#define F_MINALT 0xf0000000 // used to decide which type of RAM to load in
|
#define F_MINALT 0xf0000000 // used to decide which type of RAM to load in
|
||||||
|
|
||||||
|
#define F_ALLOCZERO 0x2000 // zero mem, for bugged (GEM...) programs
|
||||||
|
|
||||||
/* Bit in Mxalloc's arg for "don't auto-free this memory" */
|
/* Bit in Mxalloc's arg for "don't auto-free this memory" */
|
||||||
#define F_KEEP 0x4000
|
#define F_KEEP 0x4000
|
||||||
|
|
||||||
@@ -148,10 +153,10 @@ bool PackTos::checkFileHeader()
|
|||||||
throwCantPack("I won't pack F_OS_SPECIAL programs");
|
throwCantPack("I won't pack F_OS_SPECIAL programs");
|
||||||
if ((f & F_PROTMODE) > F_PROT_I)
|
if ((f & F_PROTMODE) > F_PROT_I)
|
||||||
throwCantPack("invalid protection mode");
|
throwCantPack("invalid protection mode");
|
||||||
if (ih.fh_reserved != 0)
|
if (f & F_MEMFLAGS)
|
||||||
{
|
{
|
||||||
if (opt->force < 1)
|
if (opt->force < 1)
|
||||||
throwCantPack("reserved header field set; use option `-f' to force packing");
|
throwCantPack("invalid memory flags; use option `-f' to force packing");
|
||||||
}
|
}
|
||||||
if ((f & F_PROTMODE) != F_PROT_P)
|
if ((f & F_PROTMODE) != F_PROT_P)
|
||||||
{
|
{
|
||||||
@@ -163,6 +168,14 @@ bool PackTos::checkFileHeader()
|
|||||||
if (opt->force < 1)
|
if (opt->force < 1)
|
||||||
throwCantPack("shared text segment; use option `-f' to force packing");
|
throwCantPack("shared text segment; use option `-f' to force packing");
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
// fh_reserved seems to be unused
|
||||||
|
if (ih.fh_reserved != 0)
|
||||||
|
{
|
||||||
|
if (opt->force < 1)
|
||||||
|
throwCantPack("reserved header field set; use option `-f' to force packing");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +203,7 @@ void PackTos::patch_d0_subq(void *l, int llen,
|
|||||||
|
|
||||||
// Check relocation for errors to make sure our loader can handle it.
|
// Check relocation for errors to make sure our loader can handle it.
|
||||||
static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
||||||
unsigned *relocsize, unsigned *overlay)
|
unsigned *nrelocs, unsigned *relocsize, unsigned *overlay)
|
||||||
{
|
{
|
||||||
unsigned fixup = get_be32(relocs);
|
unsigned fixup = get_be32(relocs);
|
||||||
unsigned last_fixup = fixup;
|
unsigned last_fixup = fixup;
|
||||||
@@ -199,6 +212,7 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
|||||||
assert(isize >= 4);
|
assert(isize >= 4);
|
||||||
assert(fixup > 0);
|
assert(fixup > 0);
|
||||||
|
|
||||||
|
*nrelocs = 1;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (fixup & 1) // must be word-aligned
|
if (fixup & 1) // must be word-aligned
|
||||||
@@ -220,6 +234,7 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
|||||||
if (fixup - last_fixup < 4) // overlapping relocation
|
if (fixup - last_fixup < 4) // overlapping relocation
|
||||||
return -1;
|
return -1;
|
||||||
last_fixup = fixup;
|
last_fixup = fixup;
|
||||||
|
*nrelocs += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +284,7 @@ void PackTos::fileInfo()
|
|||||||
void PackTos::pack(OutputFile *fo)
|
void PackTos::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
unsigned t;
|
unsigned t;
|
||||||
|
unsigned nrelocs = 0;
|
||||||
unsigned relocsize = 0;
|
unsigned relocsize = 0;
|
||||||
unsigned overlay = 0;
|
unsigned overlay = 0;
|
||||||
|
|
||||||
@@ -321,10 +337,10 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
else if (ih.fh_reloc != 0)
|
else if (ih.fh_reloc != 0)
|
||||||
relocsize = 0;
|
relocsize = 0;
|
||||||
else
|
else
|
||||||
r = check_relocs(ibuf+t, overlay, t, &relocsize, &overlay);
|
r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay);
|
||||||
|
|
||||||
#if 0 || defined(TESTING)
|
#if 0 || defined(TESTING)
|
||||||
printf("xx2 reloc: %d, overlay: %d, t: %d\n", relocsize, overlay, t);
|
printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
@@ -410,9 +426,9 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
memcpy(loader,getLoader(),o_text);
|
memcpy(loader,getLoader(),o_text);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
// patch "subq.l #1,d0" or "subq.w #1,d0" - see "up41" below
|
|
||||||
if (!opt->small)
|
if (!opt->small)
|
||||||
patchVersion(loader,o_text);
|
patchVersion(loader,o_text);
|
||||||
|
// patch "subq.l #1,d0" or "subq.w #1,d0" - see "up41" below
|
||||||
patch_be16(loader,o_text,"u4",
|
patch_be16(loader,o_text,"u4",
|
||||||
dirty_bss / dirty_bss_align > 65535 ? 0x5380 : 0x5340);
|
dirty_bss / dirty_bss_align > 65535 ? 0x5380 : 0x5340);
|
||||||
patch_be32(loader,o_text,"up31",d_off + offset);
|
patch_be32(loader,o_text,"up31",d_off + offset);
|
||||||
@@ -441,8 +457,9 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
|
|
||||||
// patch decompressor
|
// patch decompressor
|
||||||
upx_byte *p = obuf + d_off;
|
upx_byte *p = obuf + d_off;
|
||||||
|
// patch "moveq.l #1,d3" or "jmp (a5)"
|
||||||
|
patch_be16(p,d_len,"u3", (relocsize > 4) ? 0x7601 : 0x4ed5);
|
||||||
patch_be32(p,d_len,"up41", dirty_bss / dirty_bss_align);
|
patch_be32(p,d_len,"up41", dirty_bss / dirty_bss_align);
|
||||||
patch_be16(p,d_len,"u3", 0x7600 + (relocsize > 4)); // moveq.l #X,d3
|
|
||||||
|
|
||||||
// set new file_hdr
|
// set new file_hdr
|
||||||
memcpy(&oh, &ih, FH_SIZE);
|
memcpy(&oh, &ih, FH_SIZE);
|
||||||
@@ -461,7 +478,7 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
oh.fh_sym = 0;
|
oh.fh_sym = 0;
|
||||||
oh.fh_reserved = 0;
|
oh.fh_reserved = 0;
|
||||||
// only keep the following flags:
|
// only keep the following flags:
|
||||||
oh.fh_flag = ih.fh_flag & (F_FASTLOAD | F_ALTALLOC | F_KEEP);
|
oh.fh_flag = ih.fh_flag & (F_FASTLOAD | F_ALTALLOC | F_SMALLTPA | F_ALLOCZERO | F_KEEP);
|
||||||
// add an empty relocation fixup to workaround a bug in some TOS versions
|
// add an empty relocation fixup to workaround a bug in some TOS versions
|
||||||
oh.fh_reloc = 0;
|
oh.fh_reloc = 0;
|
||||||
|
|
||||||
|
|||||||
+19
-13
@@ -291,18 +291,29 @@ cutpoint:
|
|||||||
# error
|
# error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
; note: d1 and d2 are 0 from decompressor above
|
||||||
|
|
||||||
|
|
||||||
|
; ------------- prepare d0 for clearing the dirty bss
|
||||||
|
|
||||||
|
#if defined(SMALL)
|
||||||
|
move.l #'up41',d0 ; dirty_bss / 4
|
||||||
|
#else
|
||||||
|
move.l #'up41',d0 ; dirty_bss / 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
; ------------- test if we need to reloc
|
||||||
|
|
||||||
|
dc.b 'u3' ; jmp (a5) / moveq.l #1,d3
|
||||||
|
|
||||||
|
|
||||||
; ------------- reloc
|
; ------------- reloc
|
||||||
|
|
||||||
; The decompressed relocations now are just after the decompressed
|
; The decompressed relocations now are just after the decompressed
|
||||||
; data segment, i.e. at the beginning of the (dirty) bss.
|
; data segment, i.e. at the beginning of the (dirty) bss.
|
||||||
|
|
||||||
; note: d1 and d2 are 0 from decompressor above
|
; note: d1 and d2 are still 0
|
||||||
|
|
||||||
reloc:
|
|
||||||
;;move.w #'u3',d3 ; #0 or #1
|
|
||||||
dc.b 'u3' ; moveq.l #0,d3 / moveq.l #1,d3
|
|
||||||
beq reloc_end ; don't reloc
|
|
||||||
|
|
||||||
move.l a6,a0 ; a0 = start of relocations
|
move.l a6,a0 ; a0 = start of relocations
|
||||||
|
|
||||||
@@ -320,23 +331,18 @@ L(loop2): move.b (a0)+,d1
|
|||||||
|
|
||||||
reloc_end:
|
reloc_end:
|
||||||
|
|
||||||
; note: d1 and d2 are still 0
|
|
||||||
|
|
||||||
|
|
||||||
; ------------- clear dirty bss & start program
|
; ------------- clear dirty bss & start program
|
||||||
|
|
||||||
; We are currently running in the dirty bss.
|
; We are currently running in the dirty bss.
|
||||||
; Jump to the code we copied below the stack.
|
; Jump to the code we copied below the stack.
|
||||||
|
|
||||||
#if defined(SMALL)
|
; note: d1 and d2 are still 0
|
||||||
move.l #'up41',d0 ; dirty_bss / 4
|
|
||||||
#else
|
|
||||||
move.l #'up41',d0 ; dirty_bss / 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jmp (a5) ; jmp clear_bss (on stack)
|
jmp (a5) ; jmp clear_bss (on stack)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
dc.w cutpoint-start ; size of entry
|
dc.w cutpoint-start ; size of entry
|
||||||
dc.w eof-cutpoint ; size of decompressor
|
dc.w eof-cutpoint ; size of decompressor
|
||||||
|
|||||||
Reference in New Issue
Block a user