Blame | Last modification | View Log | RSS feed
/* arm_nrv2e_d8.S -- ARM decompressor for NRV2EThis file is part of the UPX executable compressor.Copyright (C) 1996-2008 Markus Franz Xaver Johannes OberhumerCopyright (C) 1996-2008 Laszlo MolnarCopyright (C) 2000-2008 John F. ReiserAll Rights Reserved.UPX and the UCL library are free software; you can redistribute themand/or modify them under the terms of the GNU General Public License aspublished by the Free Software Foundation; either version 2 ofthe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong 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> <ml1050@users.sourceforge.net>John F. Reiser<jreiser@users.sourceforge.net>*/#define src r0#define len r1 /* overlaps 'cnt' */#define dst r2#define tmp r3#define bits r4#define off r5#define wrnk r6 /* 0x500 M2_MAX_OFFSET before "wrinkle" */#define srclim r7#define cnt r1 /* overlaps 'len' while reading an offset *//* "mov lr,pc; bxx ..." implements conditional subroutine call */#define GETBIT add bits,bits; mov lr,pc; beq get1_n2e#define getnextb(reg) GETBIT; adc reg,reg#define jnextb0 GETBIT; bcc#define jnextb1 GETBIT; bcs/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)Actual decompressed length is stored through plen_dst.*/.code 16 @ THUMB mode.thumb_func.byte 0.byte 0.thumb_nrv2e_d8:push {r2,r3,r4,r5,r6,r7,lr}add srclim,len,src @ srclim= eof_src;mov bits,#1; neg off,bits @ off= -1 initial conditionlsl bits,#31 @ 1<<31: refill next timemov wrnk,#5lsl wrnk,#8 @ 0x500 @ nrv2e M2_MAX_OFFSETb top_n2eeof_n2e:pop {r3,r4} @ r3= orig_dst; r4= plen_dstsub src,srclim @ 0 if actual src length equals expected lengthsub dst,r3 @ actual dst lengthstr dst,[r4]pop {r4,r5,r6,r7}pop {r1}bx r1get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]ldrb bits,[src] @ zero-extend next byteadc bits,bits @ double and insert CarryIn as low bitadd src,#1lsl bits,#24 @ move to top byte, and set CarryOut from old bit 8mov pc,lr @ return, stay in current (THUMB) modelit_n2e:ldrb tmp,[src]; add src,#1strb tmp,[dst]; add dst,#1top_n2e:jnextb1 lit_n2emov cnt,#1; b getoff_n2eoff_n2e:sub cnt,#1getnextb(cnt)getoff_n2e:getnextb(cnt)jnextb0 off_n2esub tmp,cnt,#3 @ set Carrymov len,#0 @ Carry unaffectedblo offprev_n2e @ cnt was 2; tests Carry onlylsl tmp,#8ldrb off,[src]; add src,#1 @ low 7+1 bitsorr off,tmpmvn off,off; beq eof_n2e @ off= ~offasr off,#1; bcs lenlast_n2eb lenmore_n2eoffprev_n2e:jnextb1 lenlast_n2elenmore_n2e:mov len,#1jnextb1 lenlast_n2elen_n2e:getnextb(len)jnextb0 len_n2eadd len,#6-2b gotlen_n2elenlast_n2e:getnextb(len) @ 0,1,2,3add len,#2gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sumcmn wrnk,off; bcs near_n2e @ within M2_MAX_OFFSETadd len,#1 @ too far away, so minimum match length is 3near_n2e:ldrb tmp,[dst] @ force cacheline allocatecopy_n2e:ldrb tmp,[dst,off]strb tmp,[dst]; add dst,#1sub len,#1; bne copy_n2eb top_n2e.code 32.global _start_start:msr cpsr_c, #0xd3mrc p15, 0, r0,c1,c0bic r0, r0, #5mcr p15, 0, r0,c1,c0mov r2, #0x22000000add sp, r2, #0x2c000sub r3, r2, #4adr r11, .thumb_nrv2e_d8+1sub r0, pc, #0xec0mov lr, pcbx r11mov r0, #0x22000000add r0, r0, #1bx r0