Files
upx/src/stub/src/powerpc-linux.elf-entry.S
T
Thierry Fauck 9b86e68268 POWERPC: Allocate 4K / 64K pages depending on processor type.
Powerpc: ppc64le processor - Fix nrv2x-d.S compression routines
xstrip - disallow assert at line 178

Signed-off-by: Thierry Fauck <tfauck@free.fr>

	modified:   powerpc-darwin.dylib-entry.h
	modified:   powerpc-darwin.macho-entry.h
	modified:   powerpc-darwin.macho-fold.h
	modified:   powerpc-linux.elf-entry.h
	modified:   powerpc-linux.elf-fold.h
	modified:   powerpc-linux.kernel.vmlinux.h
	modified:   powerpc64le-darwin.dylib-entry.h
	modified:   powerpc64le-darwin.macho-entry.h
	modified:   powerpc64le-darwin.macho-fold.h
	modified:   powerpc64le-linux.elf-entry.h
	modified:   powerpc64le-linux.elf-fold.h
	modified:   powerpc64le-linux.kernel.vmlinux.h
	modified:   scripts/xstrip.py
	modified:   src/arch/powerpc/64le/nrv2b_d.S
	modified:   src/arch/powerpc/64le/nrv2d_d.S
	modified:   src/arch/powerpc/64le/nrv2e_d.S
	modified:   src/powerpc-linux.elf-entry.S
	modified:   src/powerpc-linux.elf-fold.S
	modified:   src/powerpc-linux.elf-main.c
	modified:   tmp/powerpc-linux.elf-entry.bin.dump
	modified:   tmp/powerpc64le-darwin.dylib-entry.bin.dump
	modified:   tmp/powerpc64le-darwin.macho-entry.bin.dump
	modified:   tmp/powerpc64le-linux.elf-entry.bin.dump
	modified:   tmp/powerpc64le-linux.kernel.vmlinux.bin.dump
2016-10-11 09:52:40 -04:00

251 lines
7.9 KiB
ArmAsm

/* powerpc-linux.elf-entry.S -- Linux program entry point & decompressor (Elf binary)
*
* This file is part of the UPX executable compressor.
*
* Copyright (C) 1996-2016 Markus Franz Xaver Johannes Oberhumer
* Copyright (C) 1996-2016 Laszlo Molnar
* Copyright (C) 2000-2016 John F. Reiser
* All Rights Reserved.
*
* UPX and the UCL library are free software; you can redistribute them
* and/or modify them under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING.
* If not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Markus F.X.J. Oberhumer Laszlo Molnar
* <markus@oberhumer.com> <ezerotven+github@gmail.com>
*
* John F. Reiser
* <jreiser@users.sourceforge.net>
*/
#include "arch/powerpc/32/macros.S"
#include "arch/powerpc/32/ppc_regs.h"
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
PROT_READ= 1
PROT_WRITE= 2
PROT_EXEC= 4
MAP_PRIVATE= 2
MAP_FIXED= 0x10
MAP_ANONYMOUS= 0x20
PAGE_SHIFT= 12
PAGE_SIZE = -(~0<<PAGE_SHIFT)
PAGE_SHIFT64= 16
PAGE_SIZE64 = -(~0<<PAGE_SHIFT64)
/* /usr/include/asm-ppc/unistd.h */
__NR_write = 4
__NR_exit = 1
__NR_mmap = 90
__NR_munmap = 91
section ELFMAINX
_start: .globl _start
call main // must be exactly 1 instruction; link_register= &decompress
/* Returns 0 on success; non-zero on failure. */
decompress: // (uchar const *src, size_t lsrc, uchar *dst, size_t &ldst, uint method)
section NRV_HEAD
SZ_DLINE=128 # size of data cache line in Apple G5
/* PowerPC has no 'cmplis': compare logical [unsigned] immediate shifted [by 16] */
#define hibit r0 /* holds 0x80000000 during decompress */
#define src a0
#define lsrc a1
#define dst a2
#define ldst a3 /* Out: actually a reference: &len_dst */
#define meth a4
#define off a4
#define len a5
#define bits a6
#define disp a7
section NRV2E
#include "arch/powerpc/32/nrv2e_d.S"
section NRV2D
#include "arch/powerpc/32/nrv2d_d.S"
section NRV2B
#include "arch/powerpc/32/nrv2b_d.S"
#include "arch/powerpc/32/lzma_d.S"
section NRV_TAIL
eof_nrv:
#define dst0 a4
#define tmp a1
lwz dst0,0(ldst) // original dst
mtlr t3 // return address
subf a0,lsrc,src
subf tmp,dst0,dst // -1+ dst length
addi a0,a0,1 // return 0: good; else: bad [+1: correct for lbzu]
addi tmp,tmp,1 // dst length
stw tmp,0(ldst)
#undef tmp
// CACHELINE=32 is the observed minimum line size of any cache.
// Some caches may have larger lines, but it is cumbersome to lookup
// {AT_DCACHEBSIZE, AT_ICACHEBSIZE, AT_UCACHEBSIZE: /usr/include/elf.h},
// then save the correct size in a variable {where to put it?}, or to modify
// the two instructions here. If a cache has larger lines, then we expect
// that the second dcbst (or icbi) on a the same line will be fast.
// If not, then too bad.
section CFLUSH // In: a2=dst= &highest stored byte; a4=dst0= &lowest stored byte
CACHELINE=32
ori dst0,dst0,-1+ CACHELINE // highest addr on cache line
cfl_nrv:
dcbst 0,dst0 // initiate store (modified) cacheline to memory
cmpl cr0,dst0,dst // did we cover the highest-addressed byte?
icbi 0,dst0 // discard instructions from cacheline
addi dst0,dst0,CACHELINE // highest addr on next line
blt cr0,cfl_nrv // not done yet
#undef dst0
sync // wait for all memory operations to finish
isync // discard prefetched instructions (if any)
cfl_ret:
ret
section ELFMAINY
msg_SELinux:
call L72
L70:
.asciz "PROT_EXEC|PROT_WRITE failed.\n"
L71:
// IDENTSTR goes here
section ELFMAINZ
L72:
li a2,L71 - L70 // length
mflr a1 // message text
li a0,2 // fd stderr
li 0,__NR_write; sc
die:
li a0,127
li 0,__NR_exit; sc
/* Decompress the rest of this loader, and jump to it. */
unfold:
mflr r30 // &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
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
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:
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)
addi src,r30,sz_b_info
la sp,-6*4(sp) // (sp,pc,cr, xx,yy,zz) save area per calling convention
bctr // goto decomrpess; return to link register (mmap'ed page)
// Example code at entrypoint of C-language subroutine:
// mflr r0 # r0= return address
// stwu sp,-96(sp) # allocate local frame; chain to previous frame
// stmw r14,24(sp) # save 18 regs r14,r15,...,r31; 4*18 == (96 - 24)
// stw r0,100(sp) # save return address into caller's frame (100 >= 96)
// Example code at exit:
// lwz r0,100(sp) # r0= return address
// lmw r14,24(sp) # restore 18 regs r14,r15,...,r31
// mtlr r0 # prepare for indirect jump
// addi sp,sp,96 # de-allocate local frame
// blr # goto return address
main:
//// teq r0,r0 // debugging
stwu r1,-32*4(sp) // allocate space (keeping 0 mod 16), save r1
stmw r2,4(sp) // save registers r2 thru r31
mflr r31 // &decompress
call unfold
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
/* vim:set ts=8 sw=8 et: */