arm-linux stub interfacing for lzma
This commit is contained in:
+10
-8
@@ -770,6 +770,7 @@ void PackVmlinuxARM::pack(OutputFile *fo)
|
|||||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
|
compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
|
||||||
unsigned const txt_c_len = ph.c_len;
|
unsigned const txt_c_len = ph.c_len;
|
||||||
|
unsigned const txt_u_len = ph.u_len;
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
|
||||||
@@ -777,8 +778,6 @@ void PackVmlinuxARM::pack(OutputFile *fo)
|
|||||||
if (0x40==(0xf0 & ft.id)) {
|
if (0x40==(0xf0 & ft.id)) {
|
||||||
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||||
}
|
}
|
||||||
linker->defineSymbol("BYTE_ADJ", (3& -txt_c_len));
|
|
||||||
linker->defineSymbol("WORD_ADJ", 4);
|
|
||||||
defineDecompressorSymbols();
|
defineDecompressorSymbols();
|
||||||
relocateLoader();
|
relocateLoader();
|
||||||
|
|
||||||
@@ -794,24 +793,27 @@ void PackVmlinuxARM::pack(OutputFile *fo)
|
|||||||
shdro[1].sh_type = Elf32_Shdr::SHT_PROGBITS;
|
shdro[1].sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
shdro[1].sh_flags = Elf32_Shdr::SHF_ALLOC | Elf32_Shdr::SHF_EXECINSTR;
|
shdro[1].sh_flags = Elf32_Shdr::SHF_ALLOC | Elf32_Shdr::SHF_EXECINSTR;
|
||||||
shdro[1].sh_offset = fo_off;
|
shdro[1].sh_offset = fo_off;
|
||||||
shdro[1].sh_size = sizeof(stub_arm_linux_kernel_vmlinux_head) + ph.c_len + lsize;
|
shdro[1].sh_size = sizeof(stub_arm_linux_kernel_vmlinux_head) + txt_c_len + lsize;
|
||||||
shdro[1].sh_addralign = 1;
|
shdro[1].sh_addralign = 1;
|
||||||
|
|
||||||
// This ought to be a linker section (to handle the relocation of 'bl'),
|
// This ought to be a linker section (to handle the relocation of 'bl'),
|
||||||
// but buildLoader gets called from the middle of compressWithFilters
|
// but buildLoader gets called from the middle of compressWithFilters
|
||||||
// so there is a circularity problem.
|
// so there is a circularity problem.
|
||||||
fo->write(&stub_arm_linux_kernel_vmlinux_head[0], sizeof(stub_arm_linux_kernel_vmlinux_head)-2*4);
|
fo->write(&stub_arm_linux_kernel_vmlinux_head[0], sizeof(stub_arm_linux_kernel_vmlinux_head)-9*4);
|
||||||
tmp_le32 = get_le32(&stub_arm_linux_kernel_vmlinux_head[sizeof(stub_arm_linux_kernel_vmlinux_head)-2*4]);
|
tmp_le32 = get_le32(&stub_arm_linux_kernel_vmlinux_head[sizeof(stub_arm_linux_kernel_vmlinux_head)-9*4]);
|
||||||
tmp_le32 = (0xff000000 & tmp_le32) | (0x00ffffff & (-0+ ((3+ txt_c_len)>>2)));
|
tmp_le32 = (0xff000000 & tmp_le32) | (0x00ffffff & (7+ ((3+ txt_c_len)>>2)));
|
||||||
fo->write(&tmp_le32, 4);
|
fo->write(&tmp_le32, 4);
|
||||||
fo->write(&stub_arm_linux_kernel_vmlinux_head[sizeof(stub_arm_linux_kernel_vmlinux_head)-4], 4);
|
fo->write(&stub_arm_linux_kernel_vmlinux_head[sizeof(stub_arm_linux_kernel_vmlinux_head)-8*4], 5*4);
|
||||||
|
tmp_le32 = txt_c_len; fo->write(&tmp_le32, 4);
|
||||||
|
tmp_le32 = txt_u_len; fo->write(&tmp_le32, 4);
|
||||||
|
tmp_le32 = ph.method; fo->write(&tmp_le32, 4);
|
||||||
fo_off += sizeof(stub_arm_linux_kernel_vmlinux_head);
|
fo_off += sizeof(stub_arm_linux_kernel_vmlinux_head);
|
||||||
|
|
||||||
fo->write(obuf, ~3& (3+ txt_c_len)); fo_off += ~3& (3+ txt_c_len);
|
fo->write(obuf, ~3& (3+ txt_c_len)); fo_off += ~3& (3+ txt_c_len);
|
||||||
fo->write(loader, lsize); fo_off += lsize;
|
fo->write(loader, lsize); fo_off += lsize;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: compressed : %8u bytes\n", getName(), ph.c_len);
|
printf("%-13s: compressed : %8u bytes\n", getName(), txt_c_len);
|
||||||
printf("%-13s: decompressor : %8u bytes\n", getName(), lsize);
|
printf("%-13s: decompressor : %8u bytes\n", getName(), lsize);
|
||||||
#endif
|
#endif
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* arm-linux.kernel.vmlinux-head.h
|
/* arm-linux.kernel.vmlinux-head.h
|
||||||
created from arm-linux.kernel.vmlinux-head.bin, 20 (0x14) bytes
|
created from arm-linux.kernel.vmlinux-head.bin, 68 (0x44) bytes
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
@@ -28,11 +28,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_SIZE 20
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_SIZE 68
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_ADLER32 0x621b0b3f
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_ADLER32 0xd30518ac
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_CRC32 0x87e74167
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_HEAD_CRC32 0xa10e8134
|
||||||
|
|
||||||
unsigned char stub_arm_linux_kernel_vmlinux_head[20] = {
|
unsigned char stub_arm_linux_kernel_vmlinux_head[68] = {
|
||||||
112, 0, 32,225, 1, 96, 34,233, 2,208,160,225,254,255,255,235, /* 0x 0 */
|
9, 96, 34,233, 2,208,160,225, 0, 32,160,225, 36, 0,143,226, /* 0x 0 */
|
||||||
2,160,157,232 /* 0x 10 */
|
10, 16,176,232, 4, 48, 45,229, 13, 48,160,225, 4,192, 45,229, /* 0x 10 */
|
||||||
|
254,255,255,235, 0, 0, 80,227, 7, 0, 0, 26, 14,112,157,232, /* 0x 20 */
|
||||||
|
3, 0,130,224, 14,240,160,225, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 30 */
|
||||||
|
0, 0, 0, 0 /* 0x 40 */
|
||||||
};
|
};
|
||||||
|
|||||||
+1033
-1050
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,27 @@
|
|||||||
/* Calling sequence of equivalent code in arch/arm/boot/compressed/misc.c:
|
/* Calling sequence of equivalent code in arch/arm/boot/compressed/misc.c:
|
||||||
decompress_kernel: # (char *out, char *tmp, char *end_tmp, int arch_id)
|
decompress_kernel: # (char *out, char *tmp, char *end_tmp, int arch_id)
|
||||||
*/
|
*/
|
||||||
bkpt
|
stmdb r2!,{r0,r3,sp,lr} // &outdata, arch_id, sp_in, retaddr
|
||||||
stmdb r2!,{r0,sp,lr}
|
mov sp,r2 // switch stacks to end_tmp area (64KB)
|
||||||
mov sp,r2
|
mov r2,r0 // &outdata
|
||||||
// PackVmlinuxARM::pack knows the format of the next instruction.
|
adr r0,.L10
|
||||||
bl COMPRESSED_LENGTH
|
ldmia r0!,{r1,r3,ip} // r0=&indata; r1=insize; r3=outsize; ip=method
|
||||||
ldmia sp,{r1,sp,pc}
|
str r3,[sp,#-4]! // outsize
|
||||||
|
mov r3,sp // &outsize
|
||||||
|
str ip,[sp,#-4]! // method
|
||||||
|
// PackVmlinuxARM::pack knows the layout of the following words.
|
||||||
|
bl LINUX000 // (&indata, insize, &outdata, &outsize, method)
|
||||||
|
spin:
|
||||||
|
cmp r0,#0 // check for success
|
||||||
|
bne spin
|
||||||
|
|
||||||
|
ldmia sp,{r1,r2,r3,ip,sp,lr} // method, outsize, &outdata, arch_id, sp_in, retaddr
|
||||||
|
add r0,r2,r3 // rv= &outdata[outsize]
|
||||||
|
mov pc,lr // return
|
||||||
|
.L10:
|
||||||
|
.long COMPRESSED_LENGTH
|
||||||
|
.long UNCOMPRESSED_LENGTH
|
||||||
|
.long METHOD
|
||||||
|
|
||||||
// Compressed data appears >here<, then decompressor.
|
// Compressed data appears >here<, then decompressor.
|
||||||
|
|
||||||
|
|||||||
@@ -37,29 +37,18 @@
|
|||||||
; ============= ENTRY POINT
|
; ============= ENTRY POINT
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
; In:
|
|
||||||
; r0= outptr; r1= &tmp; r3= arch_id; lr= retaddr, inptr - N
|
|
||||||
|
|
||||||
How to debug: run under qemu (http://fabrice.bellard.free.fr/qemu/)
|
How to debug: run under qemu (http://fabrice.bellard.free.fr/qemu/)
|
||||||
after un-commenting the bkpt opcode below. That opcode forces qemu
|
after un-commenting the bkpt opcode below. That opcode forces qemu
|
||||||
to stop in gdb. You'll have to "set $pc+=4" by hand.
|
to stop in gdb. You'll have to "set $pc+=4" by hand.
|
||||||
*/
|
*/
|
||||||
section LINUX000
|
section LINUX000
|
||||||
bkpt // qemu breakpoint
|
// bkpt // qemu DEBUG only
|
||||||
ldr r1,[lr,#-4] // 'bl' instruction
|
|
||||||
str r3,[sp,$-4]! // push arch_id
|
|
||||||
bic r1,r1,#~0<<24 // word count
|
|
||||||
sub sp,sp,#4 // space for outsize
|
|
||||||
mov r1,r1,lsl #2 // byte count
|
|
||||||
mov r3,sp // &outsize
|
|
||||||
.long 0xe2411000 + BYTE_ADJ // sub r1,r1,#BYTE_ADJ // insize
|
|
||||||
mov r2,r0 // outptr
|
|
||||||
.long 0xe28e0000 + WORD_ADJ // add r0,lr,#WORD_ADJ // inptr
|
|
||||||
/*
|
/*
|
||||||
r0= inptr
|
r0= inptr
|
||||||
r1= insize
|
r1= insize
|
||||||
r2= outptr
|
r2= outptr
|
||||||
r3= &outsize
|
r3= &outsize
|
||||||
|
sp/ method
|
||||||
*/
|
*/
|
||||||
|
|
||||||
section LXCALLT1
|
section LXCALLT1
|
||||||
|
|||||||
Reference in New Issue
Block a user