diff --git a/src/stub/src/powerpc-linux.elf-entry.S b/src/stub/src/powerpc-linux.elf-entry.S index 3e31ed87..af765d97 100644 --- a/src/stub/src/powerpc-linux.elf-entry.S +++ b/src/stub/src/powerpc-linux.elf-entry.S @@ -146,80 +146,56 @@ die: li a0,127 li 0,__NR_exit; sc +zfind: + lwz t0,0(a0); addi a0,a0,4 + cmpi cr7,t0,0; bne+ cr7,zfind + ret + /* Decompress the rest of this loader, and jump to it. */ unfold: mflr r30 // &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} + la a0,32*4(sp) + call zfind // a0= envp + call zfind // a0= &Elf32_auxv + mr r28,a0 // save for folded code + +// set a1= actual page size in Elf32_auxv_t +AT_NULL= 0 // +AT_PAGESZ= 6 +a_type= 0 +a_val= 4 +sz_auxv= 2*4 +1: + lwz t0,a_type(a0) + lwz a1,a_val(a0); addi a0,a0,sz_auxv + cmpi cr0,t0,AT_PAGESZ; beq- 2f + cmpi cr0,t0,AT_NULL; bne+ 1b + li a1,PAGE_SIZE // not found; use default +2: + mr r27,a1 // save for folded code + li a5,0 // off_t li a4,-1 // fd; cater to *BSD for MAP_ANON li a3,MAP_PRIVATE | MAP_ANONYMOUS li a2,PROT_READ | PROT_WRITE - li a1,PAGE_SIZE - add a1,a1,a1 // allocate twice 4K - lwz a0,sz_cpr(r30) - add a0,a0,r30 - addi a0,a0,sz_b_info+PAGE_SIZE-1 - rlwinm a0,a0,0,0,31-PAGE_SHIFT // next page boundary after fold - mr 23,a1 // save PAGE_SIZE value - mr 14,a0 // save address being allocated - li 0,__NR_mmap + lwz a0,sz_cpr(r30) // sizeof(folded_loader) + addi a0,a0,sz_b_info + addi t0,a1,-1 // ~page_mask + add a0,a0,r30 // beyond folded_loader + add a0,a0,t0 // + page_size -1 + and t0,t0,a0 // fragment above page boundary + sub a0,a0,t0 // next page boundary after folded code + li r0,__NR_mmap + mr t4,a0 // save address being allocated sc - cmp 0,0,a0,14 - beq alloc4 - b alloc64 - /* try to allocate a 4k page - if failure then allocate 64k page */ -alloc4: - /* deallocate stub allocation */ - mr a1,23 - li 0,__NR_munmap - sc - /* allocate 4k page */ - li a5,0 // off_t - li a4,-1 // fd; cater to *BSD for MAP_ANON - li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS - li a2,PROT_READ | PROT_WRITE | PROT_EXEC - li a1,PAGE_SIZE - lwz a0,sz_cpr(r30) - add a0,a0,r30 - addi a0,a0,sz_b_info+PAGE_SIZE-1 - rlwinm a0,a0,0,0,31-PAGE_SHIFT // next page boundary after fold - li 0,__NR_mmap - mr 23,a1 // save PAGE_SIZE value - mr 14,a0 // save address being allocated - sc - cmpi 0,0,a0,14 // - bne decomp - b msg_SELinux // Branch if SummaryOverflow (failure) - /* 64k page */ -alloc64: - /* deallocate stub allocation */ - mr a1,23 - li 0,__NR_munmap - sc - /* allocate 64k page */ - li a5,0 // off_t - li a4,-1 // fd; cater to *BSD for MAP_ANON - li a3,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS - li a2,PROT_READ | PROT_WRITE | PROT_EXEC - lis a1,1 // 64K - lwz a0,sz_cpr(r30) - add a0,a0,r30 - addi a0,a0,sz_b_info-1 - add a0,a0,a1 - rlwinm a0,a0,0,0,31-PAGE_SHIFT64 // next page boundary after fold - li 0,__NR_mmap - mr 23,a1 // save PAGE_SIZE value - sc - cmpi 0,0,a0,22 // return code - beq msg_SELinux -decomp: -0: + cmp cr0,t4,a0; bne msg_SELinux + mtctr r31 lwz r0,sz_unc(r30) lbz meth,b_method(r30) la ldst,31*4(sp) // &slot on stack stw r0,31*4(sp) // lzma uses for EOF - stw 23,23*4(sp) // save pag shift value mr dst,a0 mtlr a0 // &continuation lwz lsrc,sz_cpr(r30) diff --git a/src/stub/src/powerpc-linux.elf-fold.S b/src/stub/src/powerpc-linux.elf-fold.S index 66abc8ef..60949903 100644 --- a/src/stub/src/powerpc-linux.elf-fold.S +++ b/src/stub/src/powerpc-linux.elf-fold.S @@ -46,32 +46,17 @@ OVERHEAD= 2048 LINKAREA= 6*4 // (sp,pc,cr, xx,yy.zz) save area per calling convention /* In: r31= &decompress; also 8+ (char *)&(#bytes which preceed &-8(r31) + r28= &Elf32_auxv_t + r27= actual page size */ fold_begin: +//// teq r0,r0 // debugging call L90 #include "arch/powerpc/32/bxx.S" - -/* The SysV convention for argument registers after execve is nice: - a0= argc - a1= argv - a2= envp - a3= auxvp - a4= fini - sp= ~0xf & (-2*4 + (void *)&argc) // 0(sp): old_sp, pc - Instead, Linux gives only - sp= &{argc,argv...,0,env...,0,auxv...,strings} // 16-byte aligned? - We must figure out the rest, particularly auxvp. -*/ -zfind: - lwz t0,0(a6); addi a6,a6,4 - cmpi cr7,t0,0; bne+ cr7,zfind - ret L90: la sp,6*4(sp) // trim save area used by decompressor mflr a5 // &ppcbxx: f_unfilter - lwz a6,0(sp) // sp at execve - call zfind // a6= &env - call zfind // a6= &Elf32_auxv + mr a6,r28 // a6= &Elf32_auxv lwz a1,-8(r31) // #bytes which preceed -8(r31) rlwinm r30,a5,0,0,31-12 // r30= &this_page mr a4,r31 // &decompress: f_expand @@ -80,7 +65,7 @@ L90: addi r29,r29,-8 // &our_Elf32_Ehdr addi a1,a1,-(szElf32_Ehdr + 2*szElf32_Phdr) addi a0,r29,(szElf32_Ehdr + 2*szElf32_Phdr) // &{l_info; p_info; b_info} - lwz a7,23*4(sp) // pagesize + mr a7,r27 // pagesize addi sp,sp,-(LINKAREA+OVERHEAD) lwz a3,sz_unc+sz_p_info+sz_l_info(a0) // sz_elf_headers call upx_main // Out: a0= entry @@ -111,8 +96,9 @@ SYS_munmap= 91 SYS_mprotect= 125 mmap: .globl mmap - li 0,SYS_mmap + li r0,SYS_mmap sysgo: + teq r0,r0 // debugging sc bns+ no_fail // 'bns': branch if No Summary[Overflow] li a0,-1 // failure; IGNORE errno @@ -120,18 +106,18 @@ no_fail: ret exit: .globl exit - li 0,SYS_exit; b sysgo + li r0,SYS_exit; b 5f read: .globl read - li 0,SYS_read; b sysgo + li r0,SYS_read; 5: b 5f open: .globl open - li 0,SYS_open; b sysgo + li r0,SYS_open; 5: b 5f close: .globl close - li 0,SYS_close; b sysgo + li r0,SYS_close; 5: b 5f mprotect: .globl mprotect - li 0,SYS_mprotect; b sysgo + li r0,SYS_mprotect; 5: b 5f munmap: .globl munmap - li 0,SYS_munmap; b sysgo + li r0,SYS_munmap; 5: b 5f brk: .globl brk - li 0,SYS_brk; b sysgo + li r0,SYS_brk; 5: b sysgo /* vim:set ts=8 sw=8 et: */