1/* arm.v4t-wince.pe.S -- ARM/PE decompressor assembly startup (thumb mode)
2
3   This file is part of the UPX executable compressor.
4
5   Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
6   Copyright (C) 1996-2020 Laszlo Molnar
7   Copyright (C) 2000-2020 John F. Reiser
8   All Rights Reserved.
9
10   UPX and the UCL library are free software; you can redistribute them
11   and/or modify them under the terms of the GNU General Public License as
12   published by the Free Software Foundation; either version 2 of
13   the License, or (at your option) any later version.
14
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License for more details.
19
20   You should have received a copy of the GNU General Public License
21   along with this program; see the file COPYING.
22   If not, write to the Free Software Foundation, Inc.,
23   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25   Markus F.X.J. Oberhumer              Laszlo Molnar
26   <markus@oberhumer.com>               <ezerotven+github@gmail.com>
27
28   John F. Reiser
29   <jreiser@users.sourceforge.net>
30*/
31
32#include "arch/arm/v4t/macros.S"
33
34// p_armpe.cpp uses some symbols, so they should be global
35
36        .globl SRC0
37        .globl DST0
38        .globl IATT
39        .globl ENTR
40
41        .arm
42
43        dst0    .req r8                 @ global register
44
45section DllStart
46        cmp     r1, #1
47        bne     .Lstart_orig
48
49section ExeStart
50        stmfd   sp!, {r0 - r11, lr}
51
52        @ access all pages in ARM mode - this seems to be required
53        @ otherwise the THUMB mode stuff fails
54
55        adr     r3, SRC0
56        ldmia   r3, {r5, r6, r7, r8, r9, r10, r11}  @ r7=dst0
57        add     r5, pc, #4096           @ r3=addr src0, r11=LoadLibraryW
58.L01:                                   @ r10=GetProcAddressA, r9=CacheSync
59        ldr     r6, [r7]
60        add     r7, r7, #4096
61        cmp     r7, r5
62        bls     .L01
63
64        adr     r4, ProcessAll + 1
65        mov     lr, pc
66        bx      r4
67
68        ldmfd   sp!, {r0 - r11, lr}
69.Lstart_orig:
70        ldr     ip, ENTR
71        bx      ip
72
73SRC0:   .long   start_of_compressed
74SRCL:   .long   compressed_length
75DST0:   .long   start_of_uncompressed
76DSTL:   .long   uncompressed_length
77IATT:   .long   0, 0, 0, 0
78ENTR:   .long   original_entry
79
80        .thumb
81
82ProcessAll:
83        ldmia   r3!, {r0, r1, r2}       @ r0=src0, r1=slen, r2=dst0, r3=addr dstl
84        mov     dst0, r2
85        mov     r4, r9                  @ CacheSync
86        push    {r4, lr}
87
88        @@ uncompress/unfilter/imports/relocs are copied here by the upx linker
89
90@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
91
92section Unfilter_0x50
93        buffer  .req r0
94        addval  .req r2
95        bufend  .req r4
96
97        ldr     buffer, .LFIBS
98        mov     addval, #0
99        ldr     bufend, .LFIBE
100        mov     r5, #0x0f
101        mov     r6, #0xff
102        lsl     r6, #24
103        mvn     r7, r6
104.Luf50_0:
105        cmp     buffer, bufend
106        beq     .Luf50_ret
107
108        ldr     r3, [buffer]
109        lsr     r1, r3, #24
110        and     r1, r5
111        cmp     r1, #0x0b
112        bne     .Luf50_1
113        mov     r1, r3
114        and     r1, r6
115        sub     r3, addval
116        and     r3, r7
117        orr     r3, r1
118        str     r3, [buffer]
119
120.Luf50_1:
121        add     buffer, #4
122        add     addval, #1
123        b       .Luf50_0
124
125        .unreq  buffer
126        .unreq  addval
127        .unreq  bufend
128
129        .align  2
130S(FIBS):.long   filter_buffer_start
131S(FIBE):.long   filter_buffer_end
132
133.Luf50_ret:
134
135@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
136
137section Relocs
138        buffer  .req r0
139        dest    .req r1
140        addval  .req r2
141
142        ldr     buffer, .LBREL
143        mov     addval, dst0
144        sub     dest, addval, #4
145
146.Lreloc_loop:
147        ldrb    r3, [buffer]
148        add     buffer, #1
149        cmp     r3, #0
150        beq     .Lreloc_end
151        cmp     r3, #0xf0
152        blo     .Lreloc_add
153
154        mov     r4, #0x0f
155        and     r4, r3
156        ldrb    r3, [buffer, #1]        @ get_le16
157        lsl     r4, #8
158        add     r4, r3
159        ldrb    r3, [buffer]
160        add     buffer, #2
161        lsl     r4, #8
162        add     r3, r4
163
164.Lreloc_add:
165        add     dest, r3
166        mov     r5, #0
167
168.Lread_be32:
169        ldrb    r3, [dest, r5]
170        lsl     r4, #8
171        add     r4, r3
172        add     r5, #1
173        cmp     r5, #4
174        bne     .Lread_be32
175
176        add     r4, addval
177        str     r4, [dest]
178        b       .Lreloc_loop
179
180        .align  2
181S(BREL):.long   start_of_relocs
182
183.Lreloc_end:
184
185@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
186
187section Imports
188        imp     .req r4
189        iat     .req r5
190        dll     .req r6
191
192.real_start_ofImports:          // suppress silly warnings
193        mov     r7, sp
194        sub     sp, #508
195        sub     sp, #508
196        sub     sp, #508
197        sub     sp, #508
198        ldr     imp, .LBIMP
199.Lhi_loop1:
200        mov     r0, imp
201        bl      get_le32
202        beq     .Lhi_end
203
204        ldr     r1, .LONAM
205        add     r0, r1
206        mov     r1, sp
207.Lhi_copyname:
208        ldrb    r2, [r0]
209        add     r0, #1
210        strh    r2, [r1]
211        add     r1, #2
212        cmp     r2, #0
213        bne     .Lhi_copyname
214
215        mov     r0, sp
216        bl      LoadLibraryW
217        mov     dll, r0
218        add     r0, imp, #4
219        bl      get_le32
220        mov     iat, dst0
221        add     iat, r0
222        add     imp, #8
223
224.Lhi_gpa_loop:
225        ldrb    r0, [imp]
226        add     imp, #1
227        cmp     r0, #1
228        bmi     .Lhi_loop1
229        bne     .Lhi_by_ord
230
231        mov     r1, imp
232.Lhi_by_name:
233        ldrb    r0, [imp]
234        add     imp, #1
235        cmp     r0, #0
236        bne     .Lhi_by_name
237        b       .Lhi_call_gpa
238
239.Lhi_by_ord:
240        ldrb    r0, [imp]
241        ldrb    r1, [imp, #1]
242        add     imp, #2
243        lsl     r1, #8
244        add     r1, r0
245
246.Lhi_call_gpa:
247        mov     r0, dll
248        bl      GetProcAddressA
249        stmia   iat!, {r0}
250        b       .Lhi_gpa_loop
251
252        .unreq  iat
253        .unreq  imp
254        .unreq  dll
255
256get_le32:                               @ optimized for size
257        mov     r1, #3
258.Lg0:
259        ldrb    r3, [r0, r1]
260        lsl     r2, r2, #8
261        add     r2, r2, r3
262        sub     r1, #1
263        bpl     .Lg0
264        mov     r0, r2                  @ sets the Z flag if zero
265        bx      lr
266
267LoadLibraryW:
268        bx      r11
269
270GetProcAddressA:
271        bx      r10
272
273S(BIMP):.long   start_of_imports
274S(ONAM):.long   start_of_dll_names
275
276.Lhi_end:
277        mov     sp, r7
278
279@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
280
281section ProcessEnd
282        pop     {r1, r2}                @ r1=CacheSync, r2=lr
283        mov     r0, #4                  @ parameter of CacheSync
284        mov     lr, r2
285        bx      r1
286
287@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
288
289#include "include/header.S"
290
291#define PURE_THUMB 1
292
293section .ucl_nrv2b_decompress_8
294#include "arch/arm/v4t/nrv2b_d8.S"
295#undef GETBIT
296#undef wrnk
297
298section Call2B
299        bl      .thumb_nrv2b_d8
300
301
302section .ucl_nrv2e_decompress_8
303#include "arch/arm/v4t/nrv2e_d8.S"
304#undef GETBIT
305#undef wrnk
306
307section Call2E
308        bl      .thumb_nrv2e_d8
309
310
311#if 0
312section .ucl_nrv2b_decompress_32
313#include "arch/arm/v4t/nrv2b_d32.S"
314#undef GETBIT
315#undef wrnk
316#endif
317
318
319#if 0
320section .ucl_nrv2e_decompress_32
321#include "arch/arm/v4t/nrv2e_d32.S"
322#undef GETBIT
323#undef wrnk
324#endif
325
326////////////////////////////////////////
327
328section CallLZMA
329        // r0=src0, r1=slen, r2=dst0, r3=addr dstl
330
331        parb    .req r3
332        para    .req r4
333        parc    .req r5
334        pard    .req r6
335
336        adr     r7, .LzmaParams
337        ldmia   r7!, {parb, para, parc, pard}    // load params
338
339        mov     r7, sp                  // save stack
340        add     para, sp
341        mov     r1, #0
342.Lclearstack:
343        push    {r1}
344        cmp     sp, para
345        bne     .Lclearstack
346
347        push    {r2, parb, para}        // out, outSize, &outSizeProcessed
348        add     r3, para, #4            // &inSizeProcessed
349        mov     r2, parc                // inSize
350        add     r1, r0, #2              // in
351        add     r0, r3, #4              // &CLzmaDecoderState
352        str     pard, [r0]              // lc, lp, pb, dummy
353        bl      LZMA_DECODE
354        mov     sp, r7
355        b       .LLZMA_end
356
357        .align  2
358.LzmaParams:
359        .long   lzma_u_len, lzma_stack_adjust, lzma_c_len, lzma_properties
360
361.LLZMA_end:
362
363section LZMA_DECODE
364.real_start_ofLZMA_DECODE:              // suppress silly warnings
365
366section LZMA_DEC10
367#include "arch/arm/v4t/lzma_d_cs.S"
368
369/* vim:set ts=8 sw=8 et: */
370