From 6998449715fb8eb2bf138a880179e0931c8aa855 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 2 Mar 2025 11:32:49 -0800 Subject: [PATCH] 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 --- src/stub/src/i386-linux.elf-entry.S | 2 +- src/stub/src/i386-linux.elf-main2.c | 16 +- src/stub/src/include/linux.h | 211 +------------------- src/stub/src/mips.r3000-expand.S | 1 - src/stub/src/mipsel.r3000-linux.elf-entry.S | 7 - src/stub/src/mipsel.r3000-linux.elf-fold.S | 15 +- src/stub/src/upxfd_android.c | 13 +- 7 files changed, 16 insertions(+), 249 deletions(-) diff --git a/src/stub/src/i386-linux.elf-entry.S b/src/stub/src/i386-linux.elf-entry.S index b95a5fd7..497ab35e 100644 --- a/src/stub/src/i386-linux.elf-entry.S +++ b/src/stub/src/i386-linux.elf-entry.S @@ -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 diff --git a/src/stub/src/i386-linux.elf-main2.c b/src/stub/src/i386-linux.elf-main2.c index 2185889c..a761a0b9 100644 --- a/src/stub/src/i386-linux.elf-main2.c +++ b/src/stub/src/i386-linux.elf-main2.c @@ -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 // diff --git a/src/stub/src/include/linux.h b/src/stub/src/include/linux.h index 2773b67f..c8054abb 100644 --- a/src/stub/src/include/linux.h +++ b/src/stub/src/include/linux.h @@ -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 *); diff --git a/src/stub/src/mips.r3000-expand.S b/src/stub/src/mips.r3000-expand.S index 53a7455e..269720c5 100644 --- a/src/stub/src/mips.r3000-expand.S +++ b/src/stub/src/mips.r3000-expand.S @@ -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 diff --git a/src/stub/src/mipsel.r3000-linux.elf-entry.S b/src/stub/src/mipsel.r3000-linux.elf-entry.S index b47e7eb3..5695907b 100644 --- a/src/stub/src/mipsel.r3000-linux.elf-entry.S +++ b/src/stub/src/mipsel.r3000-linux.elf-entry.S @@ -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) diff --git a/src/stub/src/mipsel.r3000-linux.elf-fold.S b/src/stub/src/mipsel.r3000-linux.elf-fold.S index 3712383f..fd2f0522 100644 --- a/src/stub/src/mipsel.r3000-linux.elf-fold.S +++ b/src/stub/src/mipsel.r3000-linux.elf-fold.S @@ -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 diff --git a/src/stub/src/upxfd_android.c b/src/stub/src/upxfd_android.c index 2e55813d..3ca02d91 100644 --- a/src/stub/src/upxfd_android.c +++ b/src/stub/src/upxfd_android.c @@ -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);