From a5d8e575bd9c9a843d8f13a2227921e80b816660 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Thu, 25 Mar 2004 06:08:27 +0000 Subject: [PATCH] Building the Linux stub is now completely freestanding of any libc/kernel headers. committer: mfx 1080194907 +0000 --- src/stub/Makefile | 22 +-- src/stub/l_lx_elf.c | 4 +- src/stub/l_lx_exec.c | 4 +- src/stub/linux.hh | 345 +++++++++++++++++++++++++++++++------------ 4 files changed, 265 insertions(+), 110 deletions(-) diff --git a/src/stub/Makefile b/src/stub/Makefile index c0eab35d..6c85e812 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -85,6 +85,7 @@ STRIPELF = ./util/sstrip/sstrip # gcc 3.4 (20040118 experimental) seems to produce the smallest code ifeq (1,2) CC_LINUX_I386 = gcc-2.72 -m386 -O2 +## CC_LINUX_I386 = gcc-1.41 -O -Mcxx else ifeq (1,2) # gcc 2.95 @@ -95,20 +96,22 @@ ifeq (1,2) CC_LINUX_I386 += -malign-functions=0 -malign-jumps=0 -malign-loops=0 CC_LINUX_I386 += -Werror else - # gcc 3.4 20040118 (fold_*.bin: 1552 / 1043 / 1320) + # gcc 3.4 20040118 (fold_*.bin: 1525 / 1043 / 1300) # info: -mcpu=k6 procduces the smallest code CC_LINUX_I386 = gcc-3.4 -march=i386 -mtune=k6 -Os -fno-omit-frame-pointer -fno-exceptions CC_LINUX_I386 += -fno-align-functions -fno-align-jumps -fno-align-labels -fno-align-loops CC_LINUX_I386 += -fweb + CC_LINUX_I386 += -momit-leaf-frame-pointer CC_LINUX_I386 += -Werror endif endif +CC_LINUX_I386 += -nostdinc CC_LINUX_I386 += -Wall -W -Wcast-align -Wcast-qual -Wwrite-strings CC_LINUX_I386 += -funsigned-char ###CC_LINUX_I386 += -fwritable-strings -save-temps # Motorola 68000 -CPP_M68K = gcc-2.72 -I$(UCL_UPX) -I$(srcdir) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional +CPP_M68K = gcc-2.72 -nostdinc -I$(UCL_UPX) -I$(srcdir) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional APP_M68K = perl -w $(srcdir)/scripts/app_m68k.pl ifeq (1,1) # a68k 68000-assembler @@ -121,7 +124,7 @@ else endif # MIPS R3000 -CPP_MR3K = gcc-2.72 -I$(UCL_UPX) -I$(srcdir) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional +CPP_MR3K = gcc-2.72 -nostdinc -I$(UCL_UPX) -I$(srcdir) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional APP_MR3K = perl -w $(srcdir)/scripts/app_mr3k.pl ASM_MR3K = asm5900 --nologo -q @@ -321,16 +324,16 @@ l_lx_sh86.h: l_lx_sh86.asx $(NASM) -f bin -o $T.bin $< $(BIN2H) $T.bin linux_i386sh_loader $@ -l_lx_elf.o: l_lx_elf.c +l_lx_elf.o: l_lx_elf.c linux.hh $(CC_LINUX_I386) -c $< -l_lx_exec.o: l_lx_exec.c +l_lx_exec.o: l_lx_exec.c linux.hh $(CC_LINUX_I386) -c $< -l_lx_sep.o: l_lx_sep.c +l_lx_sep.o: l_lx_sep.c linux.hh $(CC_LINUX_I386) -c $< -l_lx_sh.o: l_lx_sh.c +l_lx_sh.o: l_lx_sh.c linux.hh $(CC_LINUX_I386) -c $< fold_elf86.o: fold_elf86.asm @@ -399,6 +402,7 @@ l_t_n2ds.h: n2d_d.ash bits.ash $(DEPS1) l_t_n2e.h: n2e_d.ash bits.ash $(DEPS1) l_t_n2es.h: n2e_d.ash bits.ash $(DEPS1) l_tmt.h: $(DEPS2) $(DEPS3) +l_vmlinz.h: $(DEPS2) $(DEPS3) l_vxd.h: $(DEPS2) $(DEPS3) l_wcle.h: $(DEPS2) $(DEPS3) l_w32pe.h: $(DEPS2) $(DEPS3) @@ -406,10 +410,6 @@ l_w32pe.h: $(DEPS2) $(DEPS3) l_lx_elf86.h: l_lx_elf86.asm macros.ash macros.asy $(DEPS3) l_lx_exec86.h: l_lx_exec86.asm macros.ash macros.asy $(DEPS3) l_lx_sh86.h: l_lx_sh86.asm macros.ash macros.asy $(DEPS3) -l_vmlinz.h: l_vmlinz.asm macros.ash macros.asy $(DEPS3) - -upxb: linux.hh -upxd: linux.hh .NOEXPORT: diff --git a/src/stub/l_lx_elf.c b/src/stub/l_lx_elf.c index b4389cce..ec126cd7 100644 --- a/src/stub/l_lx_elf.c +++ b/src/stub/l_lx_elf.c @@ -208,7 +208,7 @@ make_hatch(Elf32_Phdr const *const phdr) } static void -__attribute__ ((regparm(2), stdcall)) +__attribute__((regparm(2), stdcall)) upx_bzero(char *p, size_t len) { if (len) do { @@ -219,7 +219,7 @@ upx_bzero(char *p, size_t len) static void -__attribute__ ((regparm(3), stdcall)) +__attribute__((regparm(3), stdcall)) auxv_up(Elf32_auxv_t *av, int const type, unsigned const value) { if (av && 0==(1&(int)av)) /* PT_INTERP usually inhibits, except for hatch */ diff --git a/src/stub/l_lx_exec.c b/src/stub/l_lx_exec.c index 69ed25ed..513a7dff 100644 --- a/src/stub/l_lx_exec.c +++ b/src/stub/l_lx_exec.c @@ -79,7 +79,7 @@ static __inline__ int xwrite(int fd, const void *buf, int count) #if 1 extern char * -__attribute__ ((regparm(2), stdcall)) // be ruthless +__attribute__((regparm(2), stdcall)) // be ruthless upx_itoa(unsigned long v, char *buf); #else @@ -131,7 +131,7 @@ static char * do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { (void)len; (void)prot; (void)flags; (void)fd; (void)offset; - return mmap((void *)&addr); + return (char *) mmap((void *)&addr); } diff --git a/src/stub/linux.hh b/src/stub/linux.hh index 2fb545b8..5e18f1ca 100644 --- a/src/stub/linux.hh +++ b/src/stub/linux.hh @@ -26,100 +26,118 @@ */ -#if !defined(__linux__) || !defined(__i386__) -# error "this stub must be compiled under linux/i386" +// NOTE: +// to avoid endless problems with moving libc and kernel headers, this +// section is now completly freestanding + + +/************************************************************************* +// +**************************************************************************/ + +// +typedef long ptrdiff_t; +typedef unsigned long size_t; +// +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +#if defined(_WIN32) && !defined(__GNUC__) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +typedef long long int64_t; +typedef unsigned long long uint64_t; #endif +typedef size_t uintptr_t; +// +typedef long off_t; +//typedef int64_t off64_t; +//typedef size_t caddr_t; +typedef void* caddr_t; +typedef unsigned pid_t; -/************************************************************************* -// includes -**************************************************************************/ - +struct rusage; struct timex; - -#define __need_timeval -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -#include - - -#define CONST_CAST(type, var) \ - ((type) ((unsigned long) (var))) - - -/************************************************************************* -// constants and types -**************************************************************************/ - -// !!! must be the same as in p_unix.h !!! -#define OVERHEAD 2048 - -#define UPX_MAGIC_LE32 0x21585055 // "UPX!" - -// patch constants for our loader (le32 format) -#define UPX1 0x31585055 // "UPX1" -#define UPX2 0x32585055 // "UPX2" -#define UPX3 0x33585055 // "UPX4" -#define UPX4 0x34585055 // "UPX4" -#define UPX5 0x35585055 // "UPX5" - - -#undef int32_t -#undef uint32_t -#define int32_t int -#define uint32_t unsigned int - - -typedef int nrv_int; -typedef int nrv_int32; -typedef unsigned int nrv_uint; -typedef unsigned int nrv_uint32; -#define nrv_byte unsigned char -#define nrv_bytep unsigned char * -#define nrv_voidp void * - - -// From ../p_unix.h -struct b_info { // 12-byte header before each compressed block - unsigned sz_unc; // uncompressed_size - unsigned sz_cpr; // compressed_size - unsigned char b_method; // compression algorithm - unsigned char b_ftid; // filter id - unsigned char b_cto8; // filter parameter - unsigned char b_unused; +struct timeval { + unsigned tv_sec; + unsigned tv_usec; }; - -struct l_info // 12-byte trailer in header for loader (offset 116) -{ - uint32_t l_checksum; - uint32_t l_magic; - uint16_t l_lsize; - uint8_t l_version; - uint8_t l_format; -}; - -struct p_info // 12-byte packed program header follows stub loader -{ - uint32_t p_progid; - uint32_t p_filesize; - uint32_t p_blocksize; +struct timespec { + unsigned tv_sec; + long tv_nsec; }; -#define SEEK_SET 0 -#define SEEK_CUR 1 +// misc constants -#define PAGE_MASK (~0u<<12) // discards the offset, keeps the page -#define PAGE_SIZE ( 1u<<12) +#define SEEK_SET 0 +#define SEEK_CUR 1 + +#define PAGE_MASK (~0u<<12) // discards the offset, keeps the page +#define PAGE_SIZE ( 1u<<12) + +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 +#define O_EXCL 0200 + +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#define F_OK 0 + +#define F_GETFD 1 +#define F_SETFD 2 +#define FD_CLOEXEC 1 + + +// +#define ENOENT 2 +#define EINTR 4 + + +// +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define PROT_EXEC 0x4 +#define PROT_NONE 0x0 + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 + + +// +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_access 33 +#define __NR_brk 45 +#define __NR_fcntl 55 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_ftruncate 93 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_personality 136 +#define __NR_msync 144 +#define __NR_nanosleep 162 +#define __NR_getcwd 183 /************************************************************************* @@ -187,7 +205,7 @@ type name(type1 arg1) \ return (type) __res; \ } -// special for mmap; somehow Z0(arg1) and Z1(arg1) don't work +// special for mmap; somehow Z0(arg1) and Z1(arg1) do not work #define _syscall1m(type,name,type1,arg1) \ type name(type1 arg1) \ { \ @@ -274,15 +292,9 @@ type name(type1 arg1,type2 arg2,type3 arg3) \ return (type) __res; \ } -#define access syscall_access + #define _exit syscall_exit -#define fcntl syscall_fcntl -#define getcwd syscall_getcwd -#define getrusage syscall_getrusage -#define gettimeofday syscall_gettimeofday -#define nanosleep syscall_nanosleep -#define open syscall_open -#define personality syscall_personality +#define exit syscall_exit static inline _syscall2(int,access,const char *,file,int,mode) static inline _syscall1(int,adjtimex,struct timex *,ntx) @@ -309,12 +321,155 @@ static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) static inline _syscall1(int,unlink,const char *,file) -#define exit _exit + #undef Z0 #undef Z1 +/************************************************************************* +// +**************************************************************************/ + +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +#define EI_NIDENT 16 + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +typedef struct +{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +typedef struct +{ + int a_type; + union { + long a_val; + void *a_ptr; + void (*a_fcn) (void); + } a_un; +} Elf32_auxv_t; + + +#define AT_NULL 0 +#define AT_IGNORE 1 +#define AT_PHDR 3 +#define AT_PHENT 4 +#define AT_PHNUM 5 +#define AT_PAGESZ 6 +#define AT_ENTRY 9 + +#define ET_DYN 3 + +#define PF_X 1 +#define PF_W 2 +#define PF_R 4 + +#define PT_LOAD 1 +#define PT_INTERP 3 +#define PT_PHDR 6 + + +/************************************************************************* +// UPX stuff +**************************************************************************/ + +// !!! must be the same as in p_unix.h !!! +#define OVERHEAD 2048 + +#define UPX_MAGIC_LE32 0x21585055 // "UPX!" + +// patch constants for our loader (le32 format) +#define UPX1 0x31585055 // "UPX1" +#define UPX2 0x32585055 // "UPX2" +#define UPX3 0x33585055 // "UPX4" +#define UPX4 0x34585055 // "UPX4" +#define UPX5 0x35585055 // "UPX5" + + +typedef int nrv_int; +typedef int nrv_int32; +typedef unsigned int nrv_uint; +typedef unsigned int nrv_uint32; +#define nrv_byte unsigned char +#define nrv_bytep unsigned char * +#define nrv_voidp void * + + +// From ../p_unix.h +struct b_info { // 12-byte header before each compressed block + unsigned sz_unc; // uncompressed_size + unsigned sz_cpr; // compressed_size + unsigned char b_method; // compression algorithm + unsigned char b_ftid; // filter id + unsigned char b_cto8; // filter parameter + unsigned char b_unused; +}; + +struct l_info // 12-byte trailer in header for loader (offset 116) +{ + uint32_t l_checksum; + uint32_t l_magic; + uint16_t l_lsize; + uint8_t l_version; + uint8_t l_format; +}; + +struct p_info // 12-byte packed program header follows stub loader +{ + uint32_t p_progid; + uint32_t p_filesize; + uint32_t p_blocksize; +}; + + +#define CONST_CAST(type, var) \ + ((type) ((uintptr_t) (var))) + + /* vi:ts=4:et:nowrap */