1/*
2;  i386-darwin.macho-upxsubr.S -- system calls, bswap, bzero (i386 Mach-o)
3;
4;  This file is part of the UPX executable compressor.
5;
6;  Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
7;  Copyright (C) 1996-2020 Laszlo Molnar
8;  Copyright (C) 2000-2020 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// Prepend one underscore
34#define GLOBAL(sym) _##sym: .globl _##sym
35
36GLOBAL(bswap)
37        mov 1*4(%esp),%edx  // ptr
38        mov 2*4(%esp),%ecx  // len
390:
40        mov (%edx),%eax  // value
41        .byte 0x0f,0xc8  // bswap eax
42        mov %eax,(%edx)
43        sub $4,%ecx
44        lea 4(%edx),%edx
45        ja 0b
46        ret
47
48GLOBAL(bzero)
49GLOBAL(__bzero)
50        pop %edx  // retaddr
51        pop %eax  // ptr
52        pop %ecx  // len
53        push %ecx
54        push %eax
55        push %edx
56
57        push %edi
58        xchg %eax,%edi  // ptr
59        xor %eax,%eax  // the value
60        rep; stosb  // *edi++ = %al
61        pop %edi
62
63        ret
64
65SYS_exit  =1
66SYS_read  =3
67SYS_write =4
68SYS_open  =5
69SYS_close =6
70
71SYS_pread    =0x99
72SYS_mmap     =0xc5
73SYS_munmap   =0x49
74SYS_mprotect =0x4a
75
76sysgo:
77        pop %edx  // return address for sysenter
78        .byte 0x0f,0x34  // sysenter
79
80// lazy jmps enable compression of this code
81GLOBAL(write)
82        mov $SYS_write,%al;  .word 0x02eb
83GLOBAL(exit)
84        mov $SYS_exit,%al;  .word 0x02eb
85GLOBAL(mprotect)
86        mov $SYS_mprotect,%al; .word 0x02eb
87GLOBAL(munmap)
88        mov $SYS_munmap,%al; .word 0x02eb
89GLOBAL(pread)
90        mov $SYS_pread,%al; .word 0x02eb
91GLOBAL(close)
92        mov $SYS_close,%al; .word 0x02eb
93GLOBAL(open)
94        mov $SYS_open,%al;  .word 0x02eb
95GLOBAL(mmap)
96        mov $SYS_mmap,%al;  .word 0x02eb
97GLOBAL(read)
98        mov $SYS_read,%al
99
100        movzbl %al,%eax
101        mov %esp,%ecx  // &{user_ra, arg1, arg2, ...}
102        or $0xC0000,%eax
103        call sysgo; jnc 0f
104        or $~0,%eax  // mov %eax,errno
1050:
106        ret
107