diff --git a/src/stub/src/arm-linux.elf-entry.S b/src/stub/src/arm-linux.elf-entry.S index 6159db16..75f63e24 100644 --- a/src/stub/src/arm-linux.elf-entry.S +++ b/src/stub/src/arm-linux.elf-entry.S @@ -61,6 +61,10 @@ __NR_mmap64 = 0xc0 + __NR_SYSCALL_BASE __ARM_NR_BASE = 0xf0000 + __NR_SYSCALL_BASE __ARM_NR_cacheflush = 2 + __ARM_NR_BASE +#ifndef DEBUG /*{*/ +#define DEBUG 0 +#endif /*}*/ + //.long sz_pack2 // placed there by ::pack3() section ELFMAINX start_params: @@ -74,6 +78,16 @@ _start: .globl _start the brk() of the _un_compressed program. The address is pre-calculated calculated by PackLinuxElf32arm::addLinkerSymbols(). */ + +#if DEBUG /*{*/ +#define TRACE_REGS r0-r12,r14,r15 +// sp (r13) is not included because the write-back might cause UNDEFINED behavior +// if the write-back register is not first or last. The actual value of sp +// usually does not matter. Just remember that lr (r14) and pc (r15) are stored +// one word closer to the stack pointer because r13 has been omitted. + + stmdb sp!,{TRACE_REGS}; bl trace1 +#endif /*}*/ adr r12,start_params -4 // &sz_pack2 ldmia r12,{r1,r2, r10,r11} // r1= sz_pack2; r2= ADRM; r10= LENF; r11= CPR0; add r10,r10,r12 // end_decompress @@ -96,6 +110,9 @@ D_sz_unc=2*4 // stack displacement to sz_unc swi 0 #else /*}{*/ swi __NR_mmap64 +#endif /*}*/ +#if DEBUG /*{*/ + stmdb sp!,{TRACE_REGS}; bl trace2 #endif /*}*/ cmn r0,#4096 bcs msg_SELinux @@ -133,9 +150,73 @@ D_stm1=2*4 mov r2,lr // dst str r3,[sp,#D_stm1 + D_sz_unc] // sz_unc; lzma needs for EOF add r3, sp,#D_stm1 + D_sz_unc // &sz_unc +#if DEBUG /*{*/ + stmdb sp!,{TRACE_REGS}; bl trace3 +#endif /*}*/ mov lr,pc; mov pc,r5 // decompress folded code [opcode 'bx' not in v4a] ldmia sp!,{r1, pc} // discard 5th param; goto unfolded +#if DEBUG /*{*/ +trace3: + add r0,r0,#1 +trace2: + add r0,r0,#1 +trace1: + add r0,r0,#1 +trace0: + +TRACE_BUFLEN=512 +trace_print: + str lr,[sp,#(-1+ 15)*4] @ return pc; [remember: sp is not stored] + mov r4,sp @ &saved_r0 + ldr r1,[sp] @ saved r0 + sub sp,sp,#TRACE_BUFLEN + mov r2,sp @ output string + + sub r0,r0,r1; mov r1,#'\n'; bl trace_hex @ which trace + mov r1,#'>'; strb r1,[r2],#1 + + mov r5,#3 @ rows to print +L600: @ each row + sub r0,r4,#TRACE_BUFLEN + sub r0,r0,sp + mov r0,r0,lsr #2; mov r1,#'\n'; bl trace_hex @ which block of 8 + + mov r6,#8 @ words per row +L610: @ each word + ldr r0,[r4],#4; mov r1,#' '; bl trace_hex @ next word + subs r6,r6,#1; bgt L610 + + subs r5,r5,#1; bgt L600 + + mov r0,#'\n'; strb r0,[r2],#1 + sub r2,r2,sp @ count + mov r1,sp @ buf + mov r0,#2 @ FD_STDERR +#if defined(ARMEL_EABI4) /*{*/ + mov r7,#__NR_write + swi 0 +#else /*}{*/ + swi __NR_write +#endif /*}*/ + add sp,sp,#TRACE_BUFLEN + ldmia sp!,{TRACE_REGS} + +trace_hex: // In: r0=val, r1=punctuation before, r2=ptr; Uses: r3, ip + strb r1,[r2],#1 @ punctuation + mov r3,#4*(8 -1) @ shift count + adr ip,hex +L620: + mov r1,r0,lsr r3 + and r1,r1,#0xf + ldrb r1,[ip, r1] + strb r1,[r2],#1 + subs r3,r3,#4; bge L620 + ret +hex: + .ascii "0123456789abcdef" +#endif /*}*/ + f_decompress: #define LINUX_ARM_CACHEFLUSH 1 diff --git a/src/stub/src/arm-linux.elf-fold.S b/src/stub/src/arm-linux.elf-fold.S index 46312cbe..45b317d4 100644 --- a/src/stub/src/arm-linux.elf-fold.S +++ b/src/stub/src/arm-linux.elf-fold.S @@ -119,7 +119,7 @@ top_unf: tst_unf: cmp len,#0 bne top_unf - mov pc,lr + ret .unreq ptr .unreq len @@ -179,58 +179,95 @@ mmap: ldr r5,[sp],#4 ret -#if 0 /*{ "gcc-3.4 -fPIC" botches string constants when code moves! */ + +#ifndef DEBUG /*{*/ +#define DEBUG 0 +#endif /*}*/ + +#if DEBUG /*{ "gcc-3.4 -fPIC" botches string constants when code moves! */ + +div10: .globl div10 + mov ip,r0 @ extra copy used at end + sub r1,r1,r1 @ hi + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #3 @ 9*lo + adc r1,r1,r1,lsl #3 @ 9*hi + C + add r1,r1,r2,lsr #(32 - 3) @ bits shifted from lo to hi + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #4 + adc r1,r1,r1,lsl #4 + add r1,r1,r2,lsr #(32 - 4) @ * 0x99 + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #8 + adc r1,r1,r1,lsl #8 + add r1,r1,r2,lsr #(32 - 8) @ * 0x9999 + + mov r2,r0 @ copy lo + adds r0,r0,r0,lsl #16 + adc r1,r1,r1,lsl #16 + add r1,r1,r2,lsr #(32 - 16) @ * 0x99999999 + + subs r0,r0,ip,lsl #(32 - 1) @ - * 0x80000000 + sbc r1,r1,ip,lsr #1 @ * 0x19999999 + + adds r0,r0,r0 + adc r0,r1,#0 @ round and move to result + ret + .globl STR_0x STR_0x: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "0x" .balign 4 .globl STR_hex STR_hex: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "0123456789abcdef" .balign 4 .globl STR_xread STR_xread: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "xread %p(%x %p) %p %x\n" .balign 4 .globl STR_unpackExtent STR_unpackExtent: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "unpackExtent in=%p(%x %p) out=%p(%x %p) %p %p\n" .balign 4 .globl STR_make_hatch_arm STR_make_hatch_arm: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "make_hatch_arm %p %x\n" .balign 4 .globl STR_auxv_up STR_auxv_up: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "auxv_up %p %x %x\n" .balign 4 .globl STR_xfind_pages STR_xfind_pages: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "xfind_pages %x %p %d %p\n" .balign 4 .globl STR_do_xmap STR_do_xmap: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "do_xmap fdi=%x ehdr=%p xi=%p(%x %p) av=%p p_reloc=%p f_unf=%p\n" .balign 4 .globl STR_upx_main STR_upx_main: - mov r0,pc; mov pc,lr + mov r0,pc; ret .asciz "upx_main av=%p szc=%x f_dec=%p f_unf=%p xo=%p(%x %p) xi=%p(%x %p) dynbase=%x\n", .balign 4 #endif /*}*/ diff --git a/src/stub/src/i386-linux.elf-fold.S b/src/stub/src/i386-linux.elf-fold.S index 76b73b8f..117841ea 100644 --- a/src/stub/src/i386-linux.elf-fold.S +++ b/src/stub/src/i386-linux.elf-fold.S @@ -238,5 +238,56 @@ mmap: .globl mmap pop ebx ret +#ifndef DEBUG /*{*/ +#define DEBUG 0 +#endif /*}*/ + +#if DEBUG /*{ truly-PIC string constants for debugging */ + .globl STR_0x +STR_0x: + call 0f; .asciz "0x"; 0: + pop eax; ret + + .globl STR_hex +STR_hex: + call 0f; .asciz "0123456789abcdef"; 0: + pop eax; ret + + .globl STR_xread +STR_xread: + call 0f; .asciz "xread %p(%x %p) %p %x\n"; 0: + pop eax; ret + + .globl STR_unpackExtent +STR_unpackExtent: + call 0f; .asciz "unpackExtent in=%p(%x %p) out=%p(%x %p) %p %p\n"; 0: + pop eax; ret + + .globl STR_make_hatch_arm +STR_make_hatch_arm: + call 0f; .asciz "make_hatch_arm %p %x\n"; 0: + pop eax; ret + + .globl STR_auxv_up +STR_auxv_up: + call 0f; .asciz "auxv_up %p %x %x\n"; 0: + pop eax; ret + + .globl STR_xfind_pages +STR_xfind_pages: + call 0f; .asciz "xfind_pages %x %p %d %p\n"; 0: + pop eax; ret + + .globl STR_do_xmap +STR_do_xmap: + call 0f; .asciz "do_xmap fdi=%x ehdr=%p xi=%p(%x %p) av=%p p_reloc=%p f_unf=%p\n"; 0: + pop eax; ret + + .globl STR_upx_main +STR_upx_main: + call 0f; .asciz "upx_main av=%p szc=%x f_dec=%p f_unf=%p xo=%p(%x %p) xi=%p(%x %p) dynbase=%x\n"; 0: + pop eax; ret +#endif /*}*/ + // vi:ts=8:et:nowrap diff --git a/src/stub/src/i386-linux.elf-main.c b/src/stub/src/i386-linux.elf-main.c index 6f6e68a6..b1ad82b0 100644 --- a/src/stub/src/i386-linux.elf-main.c +++ b/src/stub/src/i386-linux.elf-main.c @@ -43,9 +43,13 @@ ssize_t write(int, void const *, size_t); // it at an address different from it load address: there must be no // static data, and no string constants. -#if 1 /*{*/ +#ifndef DEBUG /*{*/ +#define DEBUG 0 +#endif /*}*/ + +#if !DEBUG || defined(__mips__) /*{*/ #define DPRINTF(a) /* empty: no debug drivel */ -#else /*}{*/ +#else /*}{ DEBUG */ #if 0 #include "stdarg.h" #else @@ -55,12 +59,23 @@ ssize_t write(int, void const *, size_t); #define va_start __builtin_va_start #endif +#ifdef __arm__ /*{*/ +extern unsigned div10(unsigned); +#else /*}{*/ +static unsigned +div10(unsigned x) +{ + return x / 10u; +} +#endif /*}*/ + static int unsimal(unsigned x, char *ptr, int n) { if (10<=x) { - n = unsimal(x/10, ptr, n); - x %= 10; + unsigned const q = div10(x); + n = unsimal(q, ptr, n); + x -= 10 * q; } ptr[n] = '0' + x; return 1+ n; diff --git a/src/stub/src/mipsel.r3000-linux.elf-fold.S b/src/stub/src/mipsel.r3000-linux.elf-fold.S index 97d9db61..e24f808e 100644 --- a/src/stub/src/mipsel.r3000-linux.elf-fold.S +++ b/src/stub/src/mipsel.r3000-linux.elf-fold.S @@ -207,4 +207,65 @@ mmap: .globl mmap addiu sp,sp, sp_frame #endif /*}*/ +#if 0 /*{ truly-PIC string constants for debugging */ +/* UNFORTUNATELY THIS DOES NOT WORK because gcc uses 'jal' instead of 'bal' */ + + .globl STR_0x +ret_at: + jr at + nop +STR_0x: + move at,ra; bal ret_at; move v0,ra + .asciz "0x" + .balign 4 + + .globl STR_hex +STR_hex: + move at,ra; bal ret_at; move v0,ra + .asciz "0123456789abcdef" + .balign 4 + + .globl STR_xread +STR_xread: + move at,ra; bal ret_at; move v0,ra + .asciz "xread %p(%x %p) %p %x\n" + .balign 4 + + .globl STR_unpackExtent +STR_unpackExtent: + move at,ra; bal ret_at; move v0,ra + .asciz "unpackExtent in=%p(%x %p) out=%p(%x %p) %p %p\n" + .balign 4 + + .globl STR_make_hatch_arm +STR_make_hatch_arm: + move at,ra; bal ret_at; move v0,ra + .asciz "make_hatch_arm %p %x\n" + .balign 4 + + .globl STR_auxv_up +STR_auxv_up: + move at,ra; bal ret_at; move v0,ra + .asciz "auxv_up %p %x %x\n" + .balign 4 + + .globl STR_xfind_pages +STR_xfind_pages: + move at,ra; bal ret_at; move v0,ra + .asciz "xfind_pages %x %p %d %p\n" + .balign 4 + + .globl STR_do_xmap +STR_do_xmap: + move at,ra; bal ret_at; move v0,ra + .asciz "do_xmap fdi=%x ehdr=%p xi=%p(%x %p) av=%p p_reloc=%p f_unf=%p\n" + .balign 4 + + .globl STR_upx_main +STR_upx_main: + move at,ra; bal ret_at; move v0,ra + .asciz "upx_main av=%p szc=%x f_dec=%p f_unf=%p xo=%p(%x %p) xi=%p(%x %p) dynbase=%x\n", + .balign 4 +#endif /*}*/ + # vi:ts=8:et:nowrap