1
0
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:
John Reiser
2025-03-02 11:32:49 -08:00
parent fb0f6c6a00
commit 6998449715
7 changed files with 16 additions and 249 deletions

View File

@ -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

View File

@ -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
//

View File

@ -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 *);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);