~ubuntu-branches/debian/sid/upx-ucl/sid

« back to all changes in this revision

Viewing changes to src/stub/src/i386-darwin.dylib-entry.S

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2009-10-16 12:56:47 UTC
  • mfrom: (1.2.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20091016125647-vity1npel2qsmr9c
Tags: 3.04-1
* New upstream release:
  + FTBFS with gcc 4.4 fixed by upstream (closes: #548566).
* p_mach.cpp: Fix from upstream vcs: mach/fat needs seek() 
  after set_extent().

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
;  i386-darwin.dylib-entry.S -- program entry point & decompressor (i386 Mach-o)
 
3
;
 
4
;  This file is part of the UPX executable compressor.
 
5
;
 
6
;  Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
 
7
;  Copyright (C) 1996-2009 Laszlo Molnar
 
8
;  Copyright (C) 2000-2009 John F. Reiser
 
9
;  All Rights Reserved.
 
10
;
 
11
;  UPX and the UCL library are free software; you can redistribute them
 
12
;  and/or modify them under the terms of the GNU General Public License as
 
13
;  published by the Free Software Foundation; either version 2 of
 
14
;  the License, or (at your option) any later version.
 
15
;
 
16
;  This program is distributed in the hope that it will be useful,
 
17
;  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
;  GNU General Public License for more details.
 
20
;
 
21
;  You should have received a copy of the GNU General Public License
 
22
;  along with this program; see the file COPYING.
 
23
;  If not, write to the Free Software Foundation, Inc.,
 
24
;  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
25
;
 
26
;  Markus F.X.J. Oberhumer              Laszlo Molnar
 
27
;  <markus@oberhumer.com>               <ml1050@users.sourceforge.net>
 
28
;
 
29
;  John F. Reiser
 
30
;  <jreiser@users.sourceforge.net>
 
31
;
 
32
*/
 
33
 
 
34
#include "arch/i386/macros.S"
 
35
 
 
36
 
 
37
/*************************************************************************
 
38
// We have been CALLed as a subroutine from dyld; C-language rules apply.
 
39
// -4*4+_start: .long offset(user_init_function)
 
40
// -3*4+_start: .long offset(&b_info of compressed Mach_headers)
 
41
// -2*4+_start: .long length(compressed __TEXT)
 
42
// -1*4+_start: .long total_length  # of preceding bytes in file
 
43
**************************************************************************/
 
44
 
 
45
section LEXEC000
 
46
_start: .globl _start
 
47
////    int3  # for debug only
 
48
        push eax  # space for &user_init_function
 
49
        pusha
 
50
        call main  // push address of decompress subroutine
 
51
decompress:
 
52
 
 
53
// /*************************************************************************
 
54
// // C callable decompressor
 
55
// **************************************************************************/
 
56
 
 
57
// /* Offsets to parameters, allowing for {pusha + call} */
 
58
#define         O_INP   (8*4 +1*4)
 
59
#define         O_INS   (8*4 +2*4)
 
60
#define         O_OUTP  (8*4 +3*4)
 
61
#define         O_OUTS  (8*4 +4*4)
 
62
#define         O_PARAM (8*4 +5*4)
 
63
 
 
64
#define         INP     dword ptr [esp+O_INP]
 
65
#define         INS     dword ptr [esp+O_INS]
 
66
#define         OUTP    dword ptr [esp+O_OUTP]
 
67
#define         OUTS    dword ptr [esp+O_OUTS]
 
68
#define         PARM    dword ptr [esp+O_PARAM]
 
69
 
 
70
section LEXEC009
 
71
        //;  empty section for commonality with l_lx_exec86.asm
 
72
section LEXEC010
 
73
                pusha
 
74
                // cld
 
75
 
 
76
                mov     esi, INP
 
77
                mov     edi, OUTP
 
78
 
 
79
                or      ebp, -1
 
80
//;;              align   8
 
81
 
 
82
#include "arch/i386/nrv2b_d32.S"
 
83
#include "arch/i386/nrv2d_d32.S"
 
84
#include "arch/i386/nrv2e_d32.S"
 
85
#include "arch/i386/lzma_d.S"
 
86
 
 
87
section LEXEC015
 
88
                // eax is 0 from decompressor code
 
89
                //xor     eax, eax               ; return code
 
90
 
 
91
// check compressed size
 
92
                mov     edx, INP
 
93
                add     edx, INS
 
94
                cmp     esi, edx
 
95
                jz      .ok
 
96
                dec     eax
 
97
.ok:
 
98
 
 
99
// write back the uncompressed size
 
100
                sub     edi, OUTP
 
101
                mov     edx, OUTS
 
102
                mov     [edx], edi
 
103
 
 
104
                mov [7*4 + esp], eax
 
105
                popa
 
106
                ret
 
107
 
 
108
                ctojr32
 
109
                ctok32  edi, dl
 
110
                cit32   edi
 
111
section LEXEC017
 
112
                popa
 
113
                ret
 
114
 
 
115
section LEXEC020
 
116
 
 
117
#define PAGE_SIZE ( 1<<12)
 
118
 
 
119
sz_Mach_header= 7*4
 
120
mh_sizeofcmds=5*4
 
121
 
 
122
seg_vmaddr=2*4+16
 
123
seg_vmsize=4+seg_vmaddr
 
124
seg_filesize=2*4+seg_vmsize
 
125
 
 
126
sz_l_info=3*4
 
127
sz_p_info=3*4
 
128
sz_b_info=3*4
 
129
  sz_unc= 0
 
130
  sz_cpr= 4
 
131
  b_method= 8
 
132
 
 
133
#define MAP_FIXED     0x10
 
134
#define MAP_PRIVATE   0x02
 
135
#define MAP_ANON    0x1000
 
136
#define PROT_READ      1
 
137
#define PROT_WRITE     2
 
138
#define PROT_EXEC      4
 
139
 
 
140
 
 
141
main:
 
142
        pop ebp  # &decompress
 
143
        lea ebx,[-4+ _start - decompress + ebp]  # &total_length
 
144
        mov eax,[-1*4 + ebx]  # length(compressed __TEXT)
 
145
        add eax,offset(dy_top)
 
146
        sub eax,offset(decompress)
 
147
 
 
148
        push eax  # length for eventual munmap
 
149
 
 
150
        push 0  # hi32(offset)
 
151
        push 0  # lo32(offset)
 
152
        push -1  # fd
 
153
        push MAP_ANON|MAP_PRIVATE
 
154
        push PROT_READ|PROT_WRITE
 
155
        push eax  # length
 
156
        push 0  # addr
 
157
        call mmap
 
158
        add esp,7*4
 
159
 
 
160
        push eax  # addr for eventual munmap
 
161
 
 
162
        // Copy interval [decompress, dy_top).
 
163
        mov esi,ebp  # decompressor
 
164
        mov ebp,eax  # new location
 
165
        mov edi,eax  # dst for decompressor
 
166
        mov ecx,offset(dy_top)
 
167
        sub ecx,offset(decompress)
 
168
        cld; rep movsb
 
169
 
 
170
        // Goto the copied dy_reloc.
 
171
        lea eax,[-offset(dy_top - dy_reloc) + edi]
 
172
        jmp %eax
 
173
dy_reloc:
 
174
 
 
175
        // Copy compressed __TEXT.
 
176
        push edi  # remember start of compressed __TEXT
 
177
        mov edx,ebx  # &total_length
 
178
          mov eax,[-3*4+ebx]  # offset(user_init_function)
 
179
        sub edx,[ebx]  # runtime base address
 
180
          add eax,edx; mov [(1+2+8)*4 + esp],eax  # relocate &user_init_function
 
181
        mov esi,[-2*4 + ebx]; add esi,edx
 
182
        mov ecx,[-1*4 + ebx]
 
183
        rep movsb
 
184
        pop esi  # &b_info for Mach_header
 
185
        mov edi,edx  # runtime base address
 
186
 
 
187
        // Decompress __TEXT, but do not overwrite Mach_headers
 
188
        // in order to maintain consistency with dyld partial caching of them.
 
189
        // So, skip the first compressed block.
 
190
        lodsd; add edi,eax  # sz_unc
 
191
        lodsd; add esi,eax  # sz_cpr
 
192
        lodsd  # b_method
 
193
dy_uncpr:
 
194
        push esi; push edi  # save in case unfilter
 
195
 
 
196
        lodsd; test eax,eax; jz dy_done
 
197
        push eax  // sz_uncompressed  (maximum dstlen for lzma)
 
198
        mov ecx,esp  // save &dstlen
 
199
        push eax  // space for 5th param b_info.misc
 
200
        push ecx  // &dstlen
 
201
        push edi  // dst
 
202
        add edi,eax  // next dst
 
203
        lodsd; push eax  // sz_compressed  (srclen)
 
204
        mov ecx,eax
 
205
        lodsd; mov [3*4 + esp],eax // last 4 bytes of b_info
 
206
        push esi  // &compressed __TEXT
 
207
        add esi,ecx  // next src
 
208
        call ebp  // decompress(src, srclen, dst, &dstlen, b_info.misc)
 
209
        add esp, (5+1)*4  // (5+1) args to decompress
 
210
 
 
211
        pop edx; pop eax  # edx= old dst; eax= old &b_info
 
212
        movzbl ecx,[1+ b_method + eax]; jecxz dy_uncpr; push ecx  # ftid
 
213
        movzbl ecx,[2+ b_method + eax];                 push ecx  # cto8
 
214
        push [sz_unc + eax]
 
215
        push edx    # dst
 
216
        lea eax,[2+ ebp]; call eax  # f_unfilter(dst, dstlen, cto8, ftid)
 
217
        add esp,4*4
 
218
        jmp dy_uncpr
 
219
 
 
220
SYS_mmap    =197
 
221
mmap:
 
222
        mov eax,SYS_mmap
 
223
        call sysgo; jncs 0f; or eax,~0
 
224
0:
 
225
        ret
 
226
 
 
227
SYS_munmap=73
 
228
dy_done:
 
229
        pop eax  # discard, leaving 1 junk word below the regs for POPA
 
230
        lea edx,[-5+ edi]  # steal some space at high end of __TEXT
 
231
        mov  byte ptr [   edx],      0x58  # pop eax
 
232
        mov dword ptr [1+ edx],0xc3615858  # pop eax; pop eax; popa; ret
 
233
        mov eax,SYS_munmap
 
234
        push edx  # retaddr
 
235
sysgo:
 
236
        pop edx  # return address for sysenter
 
237
        mov ecx,esp  # &{user_ret, arg1, arg2, ...}
 
238
        .byte 0x0f, 0x34  # sysenter
 
239
 
 
240
dy_top:
 
241
 
 
242
// vi:ts=8:et:nowrap