/proc/self/auxv for AT_PAGESZ because musl calls _init with no args
https://github.com/upx/upx/issues/473 modified: mipsel.r3000-linux.shlib-init.S
This commit is contained in:
committed by
Markus F.X.J. Oberhumer
parent
c5cc83d424
commit
ad6d73c875
@@ -71,7 +71,10 @@ AT_PAGESZ= 6
|
|||||||
|
|
||||||
__NR_Linux = 4000
|
__NR_Linux = 4000
|
||||||
__NR_exit = 1+ __NR_Linux
|
__NR_exit = 1+ __NR_Linux
|
||||||
|
__NR_read = 3+ __NR_Linux
|
||||||
__NR_write = 4+ __NR_Linux
|
__NR_write = 4+ __NR_Linux
|
||||||
|
__NR_open = 5+ __NR_Linux
|
||||||
|
__NR_close = 6+ __NR_Linux
|
||||||
__NR_mmap64 = 90+ __NR_Linux
|
__NR_mmap64 = 90+ __NR_Linux
|
||||||
__NR_munmap = 91+ __NR_Linux
|
__NR_munmap = 91+ __NR_Linux
|
||||||
__NR_mprotect = 125+ __NR_Linux
|
__NR_mprotect = 125+ __NR_Linux
|
||||||
@@ -104,7 +107,7 @@ DCACHE= 1<<1
|
|||||||
#define UNFILTER 0 /* no unfilter for MIPS */
|
#define UNFILTER 0 /* no unfilter for MIPS */
|
||||||
|
|
||||||
N_SLOTS= 0
|
N_SLOTS= 0
|
||||||
sp_frame = 24 * NBPW
|
sp_frame = 26 * NBPW
|
||||||
.macro slot symbol, n
|
.macro slot symbol, n
|
||||||
.ifnb n
|
.ifnb n
|
||||||
N_SLOTS = \n + N_SLOTS
|
N_SLOTS = \n + N_SLOTS
|
||||||
@@ -126,34 +129,67 @@ pb_info= . - 1*NBPW // .long offset({p_info; b_info; compressed data})
|
|||||||
slot f_envp
|
slot f_envp
|
||||||
slot f_argv
|
slot f_argv
|
||||||
slot f_argc
|
slot f_argc
|
||||||
|
slot f_main
|
||||||
|
slot f_fd
|
||||||
|
|
||||||
_start: .globl _start // IN: jp= &_start; arg1= argc; arg2= argv; arg3= envp
|
_start: .globl _start // IN: jp= &_start
|
||||||
|
// If glibc: arg1= argc; arg2= argv; arg3= envp
|
||||||
|
// But musl: no args!
|
||||||
//// break // for debugging
|
//// break // for debugging
|
||||||
addiu sp,sp,-sp_frame
|
addiu sp,sp,-sp_frame
|
||||||
sw ra,f_my_ra(sp)
|
sw ra,f_my_ra(sp)
|
||||||
sw arg3,f_envp(sp)
|
sw arg3,f_envp(sp)
|
||||||
sw arg2,f_argv(sp)
|
sw arg2,f_argv(sp)
|
||||||
sw arg1,f_argc(sp)
|
sw arg1,f_argc(sp)
|
||||||
|
sw fp,f_fp(sp)
|
||||||
|
|
||||||
// Calculate PAGE_MASK
|
li v0,%lo(_start)
|
||||||
0: // Advance envp to auxp
|
subu jp,jp,v0
|
||||||
lw v0,(arg3)
|
addiu jp,jp,%lo(main) // jp= &main
|
||||||
bnez v0,0b
|
sw jp,f_main(sp)
|
||||||
addiu arg3,arg3,NBPW
|
|
||||||
|
// Determine PAGE_MASK
|
||||||
|
bal 0f
|
||||||
|
move a0,ra
|
||||||
|
.asciz "/proc/self/auxv"
|
||||||
|
bad_open:
|
||||||
|
bad_read:
|
||||||
|
li v1,1<<PAGE_SHIFT // default
|
||||||
|
b 9f
|
||||||
|
negu fp,v1 // PAGE_MASK
|
||||||
|
|
||||||
|
BUFLEN= 40*2*NBPW
|
||||||
|
0:
|
||||||
|
move a1,zero // O_RDONLY
|
||||||
|
do_sys __NR_open
|
||||||
|
bnez a3,bad_open
|
||||||
|
sw v0,f_fd(sp) // fd
|
||||||
|
|
||||||
|
addiu sp,sp,-BUFLEN
|
||||||
|
li a2,BUFLEN // buflen
|
||||||
|
move a1,sp // buffer
|
||||||
|
move a0,v0 // fd
|
||||||
|
do_sys __NR_read
|
||||||
|
bltz a3,bad_read
|
||||||
|
addu a2,sp,v0 // end-of-buffer
|
||||||
|
|
||||||
|
move a3,sp // buffer
|
||||||
0: // Find AT_PAGESZ
|
0: // Find AT_PAGESZ
|
||||||
lw v0,a_type(arg3)
|
beq a3,a2,5f // not found
|
||||||
li v1,1<<PAGE_SHIFT // default value
|
li v1,1<<PAGE_SHIFT // default value
|
||||||
|
lw v0,a_type(arg3)
|
||||||
beqz v0,5f // AT_NULL
|
beqz v0,5f // AT_NULL
|
||||||
addiu v0,v0,-AT_PAGESZ
|
addiu v0,v0,-AT_PAGESZ
|
||||||
bnez v0,0b
|
bnez v0,0b
|
||||||
addiu arg3,arg3,2*NBPW
|
addiu arg3,arg3,2*NBPW
|
||||||
lw v1,-2*NBPW + a_val(arg3)
|
lw v1,-2*NBPW + a_val(arg3) // non-default value
|
||||||
5: // v1= PAGE_SIZE
|
5: // v1= PAGE_SIZE
|
||||||
li v0,%lo(_start)
|
addiu sp,sp,BUFLEN
|
||||||
sw fp,f_fp(sp)
|
|
||||||
subu jp,jp,v0
|
|
||||||
negu fp,v1 // PAGE_MASK
|
negu fp,v1 // PAGE_MASK
|
||||||
addiu jp,jp,%lo(main) // jp= &main
|
lw a0,f_fd(sp)
|
||||||
|
do_sys __NR_close
|
||||||
|
9:
|
||||||
|
lw jp,f_main(sp)
|
||||||
jalr jp // ra= &f_decompress
|
jalr jp // ra= &f_decompress
|
||||||
nop
|
nop
|
||||||
e_start:
|
e_start:
|
||||||
@@ -256,7 +292,7 @@ lxlzma_retval = lxlzma_srcdone
|
|||||||
lw a0,lxlzma_dst(sp)
|
lw a0,lxlzma_dst(sp)
|
||||||
lw a1,lxlzma_dstdone(sp)
|
lw a1,lxlzma_dstdone(sp)
|
||||||
li a2,ICACHE|DCACHE
|
li a2,ICACHE|DCACHE
|
||||||
li v0,__NR_cacheflush; syscall
|
do_sys __NR_cacheflush
|
||||||
|
|
||||||
lw v0,lxlzma_retval(sp) # return value from decompression
|
lw v0,lxlzma_retval(sp) # return value from decompression
|
||||||
|
|
||||||
@@ -305,7 +341,7 @@ eof:
|
|||||||
subu a1,lxdst,v1 // actual length generated
|
subu a1,lxdst,v1 // actual length generated
|
||||||
sw a1,(lxdstlen)
|
sw a1,(lxdstlen)
|
||||||
li a2,ICACHE|DCACHE
|
li a2,ICACHE|DCACHE
|
||||||
li v0,__NR_cacheflush; syscall
|
do_sys __NR_cacheflush
|
||||||
|
|
||||||
lw v0,0(sp)
|
lw v0,0(sp)
|
||||||
jr ra
|
jr ra
|
||||||
|
|||||||
Reference in New Issue
Block a user