mirror of
https://github.com/upx/upx.git
synced 2025-08-07 22:46:51 +08:00
Remove inline syscalls from MIPS stubs
They were a maintenance headache, especially for error handling. modified: stub/src/i386-linux.elf-entry.S modified: stub/src/i386-linux.elf-main2.c modified: stub/src/include/linux.h modified: stub/src/mips.r3000-expand.S modified: stub/src/mipsel.r3000-linux.elf-entry.S modified: stub/src/mipsel.r3000-linux.elf-fold.S modified: stub/src/upxfd_android.c
This commit is contained in:
@ -201,7 +201,7 @@ AT_PAGESZ= 6 // /usr/include/elf.h
|
||||
pop %edx // MATCH_33 restore &getbit
|
||||
mov %eax,%ecx
|
||||
shr $12,%eax; shl $12,%eax; mov %eax,F_ADRU(old_sp)
|
||||
sub %eax,%ecx; sub $1,%ecx; mov %ecx,F_MFD (old_sp)
|
||||
sub %eax,%ecx; dec %ecx; mov %ecx,F_MFD (old_sp)
|
||||
#undef r_unc
|
||||
#undef u_len
|
||||
|
||||
|
@ -33,19 +33,6 @@
|
||||
#define DEBUG 0
|
||||
#endif //}
|
||||
|
||||
#ifdef __mips__ //{
|
||||
// We want to supersede in *.elf-fold.S, not use include/linux.h
|
||||
#define NO_WANT_CLOSE 1
|
||||
#define NO_WANT_EXIT 1
|
||||
#define NO_WANT_MMAP 1
|
||||
#define NO_WANT_MPROTECT 1
|
||||
#define NO_WANT_MSYNC 1
|
||||
#define NO_WANT_OPEN 1
|
||||
#define NO_WANT_READ 1
|
||||
#define NO_WANT_WRITE 1
|
||||
extern int open(char const *pathname, int flags, unsigned mode);
|
||||
extern int read(int fd, void *buf, unsigned count);
|
||||
#endif //}
|
||||
#include "include/linux.h"
|
||||
|
||||
#define MFD_EXEC 0x0010
|
||||
@ -757,6 +744,9 @@ ERR_LAB
|
||||
}
|
||||
|
||||
|
||||
int open(char const *, int, int);
|
||||
ssize_t read(int, void *, size_t);
|
||||
|
||||
/*************************************************************************
|
||||
// upx_main - called by our entry code
|
||||
//
|
||||
|
@ -380,215 +380,8 @@ static inline _syscall2(int,link,const char *,src, const char *,dst)
|
||||
#undef Z1
|
||||
|
||||
#elif defined(__mips__) /*}{*/
|
||||
|
||||
#undef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS 0x800
|
||||
|
||||
/* Cannot write an inline assembler constraint for a specific register.
|
||||
http://gcc.gnu.org/ml/gcc-help/2007-02/msg00068.html
|
||||
Workaround:
|
||||
const register int num asm("v0") = 4;
|
||||
const register char *const str asm("a0") = string;
|
||||
asm volatile("syscall" : : "r"(num), "r"(str));
|
||||
*/
|
||||
#ifndef NO_WANT_MMAP /*{*/
|
||||
static void *mmap(
|
||||
void *addr, size_t len,
|
||||
int prot, int flags,
|
||||
int fd, off_t offset
|
||||
)
|
||||
{
|
||||
#define __NR_mmap (90+ 4000)
|
||||
register void * const a0 asm("a0") = addr;
|
||||
register size_t const a1 asm("a1") = len;
|
||||
register int const a2 asm("a2") = prot;
|
||||
register int a3 asm("a3") = flags;
|
||||
register int const t0 asm("t0") = fd;
|
||||
register off_t const t1 asm("t1") = offset;
|
||||
register int v0 asm("v0") = __NR_mmap;
|
||||
__asm__ __volatile__(
|
||||
/*"break\n"*/ /* debug only */
|
||||
"addiu $29,$29,-0x20\n"
|
||||
"\tsw $8,0x10($29)\n"
|
||||
"\tsw $9,0x14($29)\n"
|
||||
"\tsyscall\n"
|
||||
".set noreorder\n"
|
||||
"\tb sysret_incl\n"
|
||||
"\t addiu $29,$29, 0x20\n"
|
||||
".set reorder\n"
|
||||
"sysgo_incl:"
|
||||
/*"break\n"*/ /* debug only */
|
||||
"\tsyscall\n"
|
||||
"sysret_incl: .set noat\n"
|
||||
"\tsltiu $1,$7,1\n" /* 1: no error; 0: error; $7 == a3 */
|
||||
"\taddiu $1,$1,-1\n" /* 0: no error; -1: error */
|
||||
"\tor $2,$2,$1\n" /* $2 == v0; good result, else -1 for error */
|
||||
/*".set at\n"*/
|
||||
: "+r"(v0), "+r"(a3) /* "+r" ==> both read and write */
|
||||
: "r"(a0), "r"(a1), "r"(a2), "r"(t0), "r"(t1)
|
||||
);
|
||||
return (void *)v0;
|
||||
}
|
||||
#endif /* NO_WANT_MMAP }*/
|
||||
|
||||
#ifndef NO_WANT_READ /*{*/
|
||||
static ssize_t read(int fd, void *buf, size_t len)
|
||||
{
|
||||
#define __NR_read (3+ 4000)
|
||||
register int const a0 asm("a0") = fd;
|
||||
register void * const a1 asm("a1") = buf;
|
||||
register size_t const a2 asm("a2") = len;
|
||||
register size_t v0 asm("v0") = __NR_read;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1), "r"(a2)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /* NO_WANT_READ }*/
|
||||
|
||||
#if 0 //{ UNUSED
|
||||
static void *brk(void *addr)
|
||||
{
|
||||
#define __NR_brk (45+ 4000)
|
||||
register void *const a0 asm("a0") = addr;
|
||||
register void * v0 asm("v0") = (void *)__NR_brk;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif //}
|
||||
|
||||
#ifndef NO_WANT_CLOSE /*{*/
|
||||
static int close(int fd)
|
||||
{
|
||||
#define __NR_close (6+ 4000)
|
||||
register int const a0 asm("a0") = fd;
|
||||
register int v0 asm("v0") = __NR_close;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /* NO_WANT_CLOSE }*/
|
||||
|
||||
#ifndef NO_WANT_EXIT /*{*/
|
||||
static void exit(int code) __attribute__ ((__noreturn__));
|
||||
static void exit(int code)
|
||||
{
|
||||
#define __NR_exit (1+ 4000)
|
||||
register int const a0 asm("a0") = code;
|
||||
register int v0 asm("v0") = __NR_exit;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
:
|
||||
: "r"(v0), "r"(a0)
|
||||
: "a3", "ra"
|
||||
);
|
||||
for (;;) {}
|
||||
}
|
||||
#endif /* NO_WANT_EXIT }*/
|
||||
|
||||
#if 0 //{ unused?
|
||||
static int munmap(void *addr, size_t len)
|
||||
{
|
||||
#define __NR_munmap (91+ 4000)
|
||||
register void *const a0 asm("a0") = addr;
|
||||
register size_t const a1 asm("a1") = len;
|
||||
register size_t v0 asm("v0") = __NR_munmap;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif //}
|
||||
|
||||
#ifndef NO_WANT_MPROTECT /*{*/
|
||||
static int mprotect(void const *addr, size_t len, int prot)
|
||||
{
|
||||
#define __NR_mprotect (125+ 4000)
|
||||
register void const *const a0 asm("a0") = addr;
|
||||
register size_t const a1 asm("a1") = len;
|
||||
register int const a2 asm("a2") = prot;
|
||||
register size_t v0 asm("v0") = __NR_mprotect;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1), "r"(a2)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /*} NO_WANT_MPROTECT */
|
||||
|
||||
#ifndef NO_WANT_MSYNC /*{*/
|
||||
static int msync(void const *addr, size_t len, int prot)
|
||||
{
|
||||
#define __NR_msync (144+ 4000)
|
||||
register void const *const a0 asm("a0") = addr;
|
||||
register size_t const a1 asm("a1") = len;
|
||||
register int const a2 asm("a2") = prot;
|
||||
register size_t v0 asm("v0") = __NR_msync;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1), "r"(a2)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /*} NO_WANT_MSYNC */
|
||||
|
||||
#ifndef NO_WANT_OPEN /*{*/
|
||||
static ssize_t open(char const *path, int kind, int mode)
|
||||
{
|
||||
#define __NR_open (5+ 4000)
|
||||
register char const *const a0 asm("a0") = path;
|
||||
register int const a1 asm("a1") = kind;
|
||||
register int const a2 asm("a2") = mode;
|
||||
register size_t v0 asm("v0") = __NR_open;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1), "r"(a2)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /* NO_WANT_OPEN }*/
|
||||
|
||||
#if DEBUG /*{*/
|
||||
#ifndef NO_WANT_WRITE /*{*/
|
||||
static ssize_t write(int fd, void const *buf, size_t len)
|
||||
{
|
||||
#define __NR_write (4+ 4000)
|
||||
register int const a0 asm("a0") = fd;
|
||||
register void const * const a1 asm("a1") = buf;
|
||||
register size_t const a2 asm("a2") = len;
|
||||
register size_t v0 asm("v0") = __NR_write;
|
||||
__asm__ __volatile__(
|
||||
"bal sysgo_incl"
|
||||
: "+r"(v0)
|
||||
: "r"(a0), "r"(a1), "r"(a2)
|
||||
: "a3", "ra"
|
||||
);
|
||||
return v0;
|
||||
}
|
||||
#endif /*}*/
|
||||
#endif /*}*/
|
||||
|
||||
#undef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS 0x800
|
||||
#else /*}{ generic */
|
||||
|
||||
void *brk(void *);
|
||||
|
@ -42,7 +42,6 @@ SZ_DLINE= 128 # size of data cache line in Apple G5
|
||||
|
||||
#include "arch/mips/r3000/macros.ash"
|
||||
#include "arch/mips/r3000/bits.ash"
|
||||
#define NO_WANT_MMAP 1
|
||||
|
||||
/* These from /usr/include/asm/unistd.h */
|
||||
__NR_cacheflush = 147+ __NR_Linux
|
||||
|
@ -192,13 +192,6 @@ eof_n2b:
|
||||
// // section UMF_LINUX or UMF_ANDROID goes here
|
||||
|
||||
section ELFMAINZ; .set noreorder
|
||||
L72:
|
||||
li a0,2 # fd stderr
|
||||
li v0,__NR_write; syscall
|
||||
die:
|
||||
li a0,127
|
||||
li v0,__NR_exit; syscall
|
||||
|
||||
unfold: # IN: $r_fexp,$r_auxv,$r_PMASK,$r_FOLD
|
||||
addiu sp,sp,-sp_frame
|
||||
sw $r_PMASK,F_PMASK(sp)
|
||||
|
@ -31,12 +31,6 @@ NBPW= 4
|
||||
#include "arch/mips/r3000/macros.ash"
|
||||
#include "arch/mips/r3000/bits.ash"
|
||||
|
||||
#define NO_WANT_MMAP 1
|
||||
#define NO_WANT_CLOSE 1
|
||||
#define NO_WANT_EXIT 1
|
||||
#define NO_WANT_MPROTECT 1
|
||||
#define NO_WANT_WRITE 1
|
||||
|
||||
.set mips1
|
||||
.set noreorder
|
||||
.set noat
|
||||
@ -415,6 +409,15 @@ sysOK:
|
||||
jr ra
|
||||
nop
|
||||
|
||||
sysgo_incl: .globl sysgo_incl
|
||||
syscall
|
||||
sysret_incl: .globl sysret_incl
|
||||
.set noat
|
||||
sltiu at,a3,1 /* 1: no error; 0: error */
|
||||
addiu at,at,-1 /* 0: no error; -1: error */
|
||||
or v0,v0,at /* good result, else -1 for error */
|
||||
.set at
|
||||
|
||||
exit: .globl exit
|
||||
b sysgo; li v0,__NR_exit
|
||||
brk: .globl brk
|
||||
|
@ -127,18 +127,7 @@ struct stat { // __NR_stat = 106 + NR_SYSCALL_BASE
|
||||
#define S_IRWXU 00700
|
||||
#define AT_FDCWD -100
|
||||
#define restrict /**/
|
||||
//
|
||||
#ifdef __mips__ //{
|
||||
// We want to supersede in *.elf-fold.S, not use include/linux.h
|
||||
#define NO_WANT_CLOSE 1
|
||||
#define NO_WANT_EXIT 1
|
||||
#define NO_WANT_MMAP 1
|
||||
#define NO_WANT_MPROTECT 1
|
||||
#define NO_WANT_MSYNC 1
|
||||
#define NO_WANT_OPEN 1
|
||||
#define NO_WANT_READ 1
|
||||
#define NO_WANT_WRITE 1
|
||||
#endif //}
|
||||
|
||||
#include "include/linux.h" // syscalls; i386 inlines via "int 0x80"
|
||||
extern int open(char const *, int, int);
|
||||
|
||||
|
Reference in New Issue
Block a user