1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00
upx/src/stub/src/arm64-linux.elf-so_entry.S
John Reiser 0144f81c28 Cleanup stub for arm64 shared library
modified:   stub/arm64-linux.elf-so_entry.h
	modified:   stub/src/arm64-linux.elf-so_entry.S
2025-02-16 08:41:50 -08:00

204 lines
5.1 KiB
ArmAsm

/* arm64-linux.elf-so_entry.S -- Linux DT_INIT & decompressor (Elf shared lib)
*
* This file is part of the UPX executable compressor.
*
* Copyright (C) 1996-2021 Markus Franz Xaver Johannes Oberhumer
* Copyright (C) 1996-2021 Laszlo Molnar
* Copyright (C) 2000-2025 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>
*/
NBPW= 8
#include "arch/arm64/v8/macros.S"
lr .req x30
#define DEBUG 0
sz_Elf64_Ehdr = 8*NBPW
sz_Elf64_Phdr = 7*NBPW
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
sz_l_info= 12
sz_p_info= 12
PROT_READ= 1
PROT_WRITE= 2
PROT_EXEC= 4
MAP_PRIVATE= 2
MAP_FIXED= 0x10
MAP_ANONYMOUS= 0x20
// /usr/include/asm-generic/unistd.h
__NR_close = 0x39 // 57
__NR_exit = 0x5d // 93
__NR_memfd_create = 0x117 // 279
__NR_mmap = 0xde // 222
__NR_mprotect = 0xe2 // 226
__NR_munmap = 0xd7 // 215
__NR_openat = 0x38 // 56
__NR_read = 0x3f // 63
__NR_write = 0x40 // 64
arg1 .req x0
arg1w .req w0
arg2 .req x1
arg2w .req w1
arg3 .req x2
arg3w .req w2
arg4 .req x3
arg4w .req w3
arg5 .req x4
arg5w .req w4
arg6 .req x5
arg6w .req w5
#define bkpt brk #0
#define call bl
section ELFMAINX
// .long offset(b_info)|(asl_delta>>12) src for f_exp FIXME: really?
//SO_INFO:
// .word offset(.) // detect relocation
// .word offset(user DT_INIT)
// .word offset(escape_hatch) // override with round_up(2, PT_LOAD[0]{.p_memsz + .p_vaddr})
// .word offset(dst for f_exp)
.balign 4
_start: .globl _start
// bkpt // DEBUG
PUSH4 (x0,x1,x2,lr) // MATCH_00
sub sp,sp,#2*NBPW // space for ADRU, LENU
F_ADRU= 0 * NBPW
F_LENU= 1 * NBPW
F_ARGC= 2 * NBPW
adr x30,fold_info // assembler bug: 'lr' not an integer register
foldi .req x30
old_sp .req x14 // busy: lr,x14
mov old_sp,sp
ldr w0,[foldi,#sz_unc]
str x0,[old_sp,#F_LENU]
sub x0,sp,x0 // alloca
and sp,x0,#-2*NBPW // align stack
psa_fd .req w5
aux_end .req x4
page_m .req x7
AT_PAGESZ= 6
O_RDONLY= 0
mov w2,#O_RDONLY
adr x1,str_psa
mov w0,#0
do_sys __NR_openat; mov psa_fd,w0
mov x1,sp // buffer
mov x2,#512 // len
do_sys __NR_read; add aux_end,x1,x0 // end
mov w0,psa_fd; do_sys __NR_close
.unreq psa_fd
0:
ldr x0,[x1,#NBPW] // value
ldr x2,[x1],#2*NBPW // tag
cmp x2,#AT_PAGESZ; beq 1f
cmp x1,aux_end; blo 0b; mov x0,#1<<12 // default 4KiB
.unreq aux_end
1:
sub page_m,xzr,x0 // PAGE_MASK
add arg4,old_sp,#F_LENU // &dstlen
mov arg3,sp // dst for decompress
ldr arg2w,[foldi,#sz_cpr] // srclen
add arg1,foldi,#sz_b_info // src
.unreq foldi // busy: x14
bl f_decompress
mov arg2w,#0
adr arg1,str_upx
mfd .req w15 // busy: x15,x14
do_sys __NR_memfd_create; mov mfd, w0
str page_m, [sp,#0]
mov arg2,sp
ldr arg3,[old_sp,#F_LENU]
do_sys __NR_write
mov sp,old_sp // de-alloca
.unreq old_sp // busy: x15
mov arg6,#0 // beginning of file
mov arg5w,mfd
mov arg4w,#MAP_PRIVATE // modes
mov arg3w,#PROT_READ|PROT_EXEC // prot
ldr arg2,[sp,#F_LENU]
mov arg1,#0 // addr (kernel chooses)
do_sys __NR_mmap; str x0,[sp,#F_ADRU]
u_ptr .req x14 // busy: x15,x14
mov u_ptr,x0
mov arg1w,mfd
.unreq mfd // busy: x14
do_sys __NR_close
adr arg1,_start - 4*4 // &SO_INFO
add arg2,sp,#F_ARGC // &{argc, argv, envp}
add u_ptr,u_ptr,2*NBPW
br u_ptr
.unreq u_ptr
str_upx:
.asciz "upx"
str_psa:
.asciz "/proc/self/auxv"
.balign 4
//%esp:
// MATCH_04 ptr unfolded_code
// MATCH_10 len unfolded_code
// MATCH_00 argc,argv,envp,lr(_start)
f_decompress:
// nrv2b code is hard-wired here
#define NO_METHOD_CHECK 1
// only one de-compressor; build 'eof' return
#undef DAISY_CHAIN
// use of mmap() forces implcit cache sync
#define NO_SYNC_CACHE 1
off .req w5
#include "arch/arm64/v8/nrv2b_d32.S"
// IDENTSTR goes here
section ELFMAINZ
fold_info:
// b_info (sz_unc, sz_cpr, method) of folded code (C-language, etc.)
/* vim:set ts=8 sw=8 et: */