Compare commits
1 Commits
devel
...
jreiser-riscv64
| Author | SHA1 | Date | |
|---|---|---|---|
| 65b3dd7e52 |
+69
-1
@@ -42,6 +42,8 @@ endif
|
|||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
ifndef STUBS
|
ifndef STUBS
|
||||||
|
STUBS += riscv64-linux.elf-entry.h
|
||||||
|
STUBS += riscv64-linux.elf-fold.h
|
||||||
STUBS += amd64-darwin.dylib-entry.h
|
STUBS += amd64-darwin.dylib-entry.h
|
||||||
STUBS += amd64-darwin.macho-entry.h
|
STUBS += amd64-darwin.macho-entry.h
|
||||||
STUBS += amd64-darwin.macho-fold.h
|
STUBS += amd64-darwin.macho-fold.h
|
||||||
@@ -320,7 +322,7 @@ define tc.default.f-embed_objinfo_without_xstrip_keep_dot_text
|
|||||||
chmod a-x $1
|
chmod a-x $1
|
||||||
$(call tc,objcopy) -R .data -R .bss $1
|
$(call tc,objcopy) -R .data -R .bss $1
|
||||||
$(call tc,objcopy) -R .comment -R .note -R .note.GNU-stack -R .reginfo $1
|
$(call tc,objcopy) -R .comment -R .note -R .note.GNU-stack -R .reginfo $1
|
||||||
$(call tc,objcopy) --strip-unneeded --keep-symbol=_start --keep-symbol=upx_so_main $1
|
$(call tc,objcopy) --strip-unneeded --keep-symbol=_start --keep-symbol=upx_so_main --keep-symbol=str_upx $1
|
||||||
#
|
#
|
||||||
# Disassemble for human readability
|
# Disassemble for human readability
|
||||||
# objdump
|
# objdump
|
||||||
@@ -2182,6 +2184,72 @@ powerpc64-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S
|
|||||||
$(call tc,objcopy) --output-target binary --only-section .text tmp/$T.o tmp/$T.bin
|
$(call tc,objcopy) --output-target binary --only-section .text tmp/$T.o tmp/$T.bin
|
||||||
$(call tc,bin2h) tmp/$T.bin $@
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
# =====
|
||||||
|
# /***********************************************************************
|
||||||
|
# // riscv64-linux.elf
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
riscv64-linux.elf%.h : tc_list = riscv64-linux.elf default
|
||||||
|
riscv64-linux.elf%.h : tc_bfdname = elf64-littleriscv64
|
||||||
|
|
||||||
|
tc.riscv64-linux.elf.gcc = /usr/bin/riscv64-linux-gnu-gcc -nostdinc -MMD -MT $@
|
||||||
|
tc.riscv64-linux.elf.gcc += -fno-exceptions -fno-asynchronous-unwind-tables # -fno-stack-protector
|
||||||
|
tc.riscv64-linux.elf.gcc += -Wall -W -Wcast-align -Wcast-qual -Wstrict-prototypes -Wwrite-strings -Werror
|
||||||
|
|
||||||
|
tc.riscv64-linux.elf.objcopy = /usr/bin/riscv64-linux-gnu-objcopy
|
||||||
|
# Override of objcopy is needed because:
|
||||||
|
# multiarch-objcopy-2.17 -F elf64-littleriscv64 --strip-unneeded --keep-symbol=_start --keep-symbol=upx_so_main tmp/riscv64-linux.elf-entry.bin
|
||||||
|
# multiarch-objcopy-2.17: tmp/riscv64-linux.elf-entry.bin: Invalid bfd target
|
||||||
|
|
||||||
|
tc.riscv64-linux.elf.objdump = /usr/bin/riscv64-linux-gnu-objdump
|
||||||
|
# Override of objdump is needed because:
|
||||||
|
# multiarch-objdump-2.17 -b elf64-littleriscv64 -Dr tmp/riscv64-linux.elf-entry.bin | sed -e 's/[ ]*$//' > tmp/riscv64-linux.elf-entry.bin.disasm
|
||||||
|
# multiarch-objdump-2.17: tmp/riscv64-linux.elf-entry.bin: Invalid bfd target
|
||||||
|
# multiarch-objdump-2.17 -b elf64-littleriscv64 -htr -w tmp/riscv64-linux.elf-entry.bin | sed -e 's/[ ]*$//' | cat --squeeze-blank | sed -e '1{/^$/d}' -e '${/^$/d}' | sed -e '1s/^.*: *file format/file format/' -e 's/ / /g' -e 's/ 00*/ 0/g' -e 's/CONTENTS.*/CONTENTS/' > tmp/riscv64-linux.elf-entry.bin.dump
|
||||||
|
# multiarch-objdump-2.17: tmp/riscv64-linux.elf-entry.bin: Invalid bfd target
|
||||||
|
|
||||||
|
|
||||||
|
tc.riscv64-linux.elf.ld = /usr/bin/riscv64-linux-gnu-ld
|
||||||
|
# Override of ld is needed because:
|
||||||
|
# multiarch-objcopy-2.17 -F elf64-littleriscv64 --strip-unneeded --keep-symbol=_start --keep-symbol=upx_so_main tmp/riscv64-linux.elf-entry.bin
|
||||||
|
# multiarch-objcopy-2.17: tmp/riscv64-linux.elf-entry.bin: Invalid bfd target
|
||||||
|
|
||||||
|
riscv64-linux.elf-entry.h : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o tmp/$T.bin
|
||||||
|
$(call tc,f-embed_objinfo,tmp/$T.bin)
|
||||||
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
riscv64-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
|
||||||
|
tmp/$$T.o \
|
||||||
|
tmp/riscv64-linux.elf-help_umf.o \
|
||||||
|
tmp/riscv64-linux.elf-upxfd_linux.o \
|
||||||
|
tmp/riscv64-expand.o \
|
||||||
|
tmp/riscv64-linux.elf-main2.o
|
||||||
|
$(call tc,ld) -r -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin
|
||||||
|
$(call tc,f-embed_objinfo_without_xstrip_keep_dot_text,tmp/$T.bin)
|
||||||
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
tmp/riscv64-linux.elf-fold.o : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o $@
|
||||||
|
$(call tc,f-objstrip,$@)
|
||||||
|
|
||||||
|
tmp/riscv64-linux.elf-main2.o : $(srcdir)/src/$$T.c $(srcdir)/src/i386-linux.elf-main2.c
|
||||||
|
$(call tc,gcc) -c $< -o $@
|
||||||
|
$(call tc,f-objstrip,$@)
|
||||||
|
|
||||||
|
tmp/riscv64-linux.elf-help_umf.o: $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o $@
|
||||||
|
|
||||||
|
tmp/riscv64-linux.elf-upxfd_linux.o : $(srcdir)/src/upxfd_linux.c
|
||||||
|
$(call tc,gcc) -c -O $< -o $@
|
||||||
|
$(call tc,objcopy) --strip-unneeded --rename-section .text=UMF_LINUX \
|
||||||
|
-R .riscv.attributes -R .data -R .bss -R .note.GNU-stack $@
|
||||||
|
$(call tc,objdump) -Dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm
|
||||||
|
|
||||||
|
tmp/riscv64-expand.o: $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o $@
|
||||||
|
|
||||||
|
# =====
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // dependencies
|
# // dependencies
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ def do_file(fn):
|
|||||||
# ELF64 LE
|
# ELF64 LE
|
||||||
eh, idata = idata[:64], idata[64:]
|
eh, idata = idata[:64], idata[64:]
|
||||||
e_shnum, e_shstrndx = struct.unpack("<HH", eh[60:64])
|
e_shnum, e_shstrndx = struct.unpack("<HH", eh[60:64])
|
||||||
assert e_shstrndx + 3 == e_shnum
|
assert e_shstrndx + 3 >= e_shnum
|
||||||
elif idata[4:7] == "\x02\x02\x01":
|
elif idata[4:7] == "\x02\x02\x01":
|
||||||
# ELF64 BE
|
# ELF64 BE
|
||||||
eh, idata = idata[:64], idata[64:]
|
eh, idata = idata[:64], idata[64:]
|
||||||
@@ -178,6 +178,8 @@ def do_file(fn):
|
|||||||
assert pos >= len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
assert pos >= len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
||||||
elif re.search(r"^arm64-", os.path.basename(fn)):
|
elif re.search(r"^arm64-", os.path.basename(fn)):
|
||||||
assert pos >= len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
assert pos >= len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
||||||
|
elif re.search(r"^riscv", os.path.basename(fn)):
|
||||||
|
assert pos >= len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
||||||
else:
|
else:
|
||||||
assert pos == len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
assert pos == len(odata), ("unexpected strip_with_dump", pos, len(odata))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -77,6 +77,16 @@ extern void my_bkpt(void *, ...);
|
|||||||
/*und*/ : "x30"); \
|
/*und*/ : "x30"); \
|
||||||
str; \
|
str; \
|
||||||
})
|
})
|
||||||
|
#elif defined(__riscv) //}{
|
||||||
|
#define ANDROID_FRIEND 0
|
||||||
|
#define addr_string(string) ({ \
|
||||||
|
char const *str; \
|
||||||
|
asm("jal 0f; .string \"" string "\"; .balign 4; 0: mv %0,ra" \
|
||||||
|
/*out*/ : "=r"(str) \
|
||||||
|
/* in*/ : \
|
||||||
|
/*und*/ : "x30"); \
|
||||||
|
str; \
|
||||||
|
})
|
||||||
#else //}{
|
#else //}{
|
||||||
#error;
|
#error;
|
||||||
#endif //}
|
#endif //}
|
||||||
@@ -279,6 +289,36 @@ make_hatch(
|
|||||||
DPRINTF("hatch=%%p\\n", hatch);
|
DPRINTF("hatch=%%p\\n", hatch);
|
||||||
return hatch;
|
return hatch;
|
||||||
}
|
}
|
||||||
|
#elif defined(__riscv) //{
|
||||||
|
static void *
|
||||||
|
make_hatch(
|
||||||
|
ElfW(Phdr) const *const phdr,
|
||||||
|
char *next_unc,
|
||||||
|
unsigned const frag_mask
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned long a = (unsigned long)next_unc;
|
||||||
|
int *hatch = (int *)((3u & -a) + a);
|
||||||
|
int code[3] = {
|
||||||
|
0,0,0 //NYI illegal instruction
|
||||||
|
};
|
||||||
|
DPRINTF("make_hatch %%p %%p %%x\\n", phdr, next_unc, frag_mask);
|
||||||
|
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
|
||||||
|
if (sizeof(code) <= (unsigned)(frag_mask & -(long)hatch)) {
|
||||||
|
hatch[0] = code[0];
|
||||||
|
hatch[1] = code[1];
|
||||||
|
hatch[2] = code[2];
|
||||||
|
}
|
||||||
|
else { // Does not fit at hi end of .text, so must use a new page "permanently"
|
||||||
|
int mfd = upxfd_create(addr_string("upx"), MFD_EXEC); // the directory entry
|
||||||
|
write(mfd, &code, sizeof(code));
|
||||||
|
hatch = mmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
|
||||||
|
close(mfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DPRINTF("hatch=%%p\\n", hatch);
|
||||||
|
return hatch;
|
||||||
|
}
|
||||||
#elif defined(__powerpc64__) //}{
|
#elif defined(__powerpc64__) //}{
|
||||||
static void *
|
static void *
|
||||||
make_hatch(
|
make_hatch(
|
||||||
@@ -660,7 +700,7 @@ upx_main2( // returns entry address
|
|||||||
/*arg4*/ ElfW(auxv_t) *const av
|
/*arg4*/ ElfW(auxv_t) *const av
|
||||||
#if defined(__x86_64) //{
|
#if defined(__x86_64) //{
|
||||||
/*arg5*/ , ElfW(Addr) elfaddr // In: &ElfW(Ehdr) for stub
|
/*arg5*/ , ElfW(Addr) elfaddr // In: &ElfW(Ehdr) for stub
|
||||||
#elif defined(__aarch64__) //}{
|
#elif defined(__aarch64__) || defined(__riscv) //}{
|
||||||
/*arg5*/ , ElfW(Addr) elfaddr
|
/*arg5*/ , ElfW(Addr) elfaddr
|
||||||
#elif defined(__powerpc64__) //}{
|
#elif defined(__powerpc64__) //}{
|
||||||
/*arg5*/ , ElfW(Addr) *p_reloc // In: &ElfW(Ehdr) for stub; Out: 'slide' for PT_INTERP
|
/*arg5*/ , ElfW(Addr) *p_reloc // In: &ElfW(Ehdr) for stub; Out: 'slide' for PT_INTERP
|
||||||
@@ -681,7 +721,7 @@ upx_main2( // returns entry address
|
|||||||
// ehdr = Uncompress Ehdr and Phdrs
|
// ehdr = Uncompress Ehdr and Phdrs
|
||||||
unpackExtent(&xi2, &xo); // never filtered?
|
unpackExtent(&xi2, &xo); // never filtered?
|
||||||
|
|
||||||
#if defined(__x86_64) || defined(__aarch64__) //{
|
#if defined(__x86_64) || defined(__aarch64__) || defined(__riscv) //{
|
||||||
ElfW(Addr) *const p_reloc = &elfaddr;
|
ElfW(Addr) *const p_reloc = &elfaddr;
|
||||||
#endif //}
|
#endif //}
|
||||||
ElfW(Addr) page_mask = get_page_mask(); (void)page_mask;
|
ElfW(Addr) page_mask = get_page_mask(); (void)page_mask;
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
#undef x86_64
|
#undef x86_64
|
||||||
|
|
||||||
//.altmacro // not supported by x86_64-linux-as-2.15
|
//.altmacro // not supported by x86_64-linux-as-2.15
|
||||||
.code64
|
|
||||||
|
|
||||||
.macro section name
|
.macro section name
|
||||||
.section \name
|
.section \name
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# convenience Makefile
|
||||||
|
default %:
|
||||||
|
$(MAKE) -C ../../.. $@
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
MAKEFLAGS += -rR
|
||||||
|
.SUFFIXES:
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
|
||||||
|
ifndef top_srcdir
|
||||||
|
__dir_list = . .. ../.. ../../.. ../../../.. ../../../../..
|
||||||
|
__dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
||||||
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars-global.mk ./Makevars-local.mk)
|
||||||
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
|
STUBS =
|
||||||
|
include $(top_srcdir)/src/stub/src/c/Makevars-lzma.mk
|
||||||
|
ifneq ($(UPX_LZMA_VERSION),)
|
||||||
|
STUBS += lzma_d_cf.S lzma_d_cs.S lzma_d_cn.S
|
||||||
|
endif
|
||||||
|
|
||||||
|
default.targets = all
|
||||||
|
ifeq ($(strip $(STUBS)),)
|
||||||
|
STUBS = NO_STUBS
|
||||||
|
all.targets =
|
||||||
|
endif
|
||||||
|
include $(top_srcdir)/src/stub/Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // method-lzma
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
lzma_d_c%.S : tc_list = method-lzma riscv64-linux.elf default
|
||||||
|
lzma_d_c%.S : tc_bfdname = elf64-riscv64
|
||||||
|
|
||||||
|
c := tc.method-lzma.gcc
|
||||||
|
$c = $(tc.riscv64-linux.elf.gcc)
|
||||||
|
$c += -Os -fomit-frame-pointer
|
||||||
|
$c += -fno-unit-at-a-time
|
||||||
|
$c += -ffunction-sections
|
||||||
|
$c += -fwrapv
|
||||||
|
$c += -DWITH_LZMA=$(UPX_LZMA_VERSION)
|
||||||
|
$c += -I$(UPX_LZMADIR)
|
||||||
|
$c += -I$(top_srcdir)/src
|
||||||
|
|
||||||
|
lzma_d_c%.S : lzma_d_c.c
|
||||||
|
$(call tc,gcc) $(PP_FLAGS) -c $< -o tmp/$T.o
|
||||||
|
$(call tc,f-objstrip,tmp/$T.o)
|
||||||
|
$(call tc,objcopy) -O binary --only-section .text.LzmaDecode tmp/$T.o tmp/$T.bin
|
||||||
|
head -c-1 tmp/$T.bin > tmp/$T.out
|
||||||
|
$(call tc,objdump) -b binary -m i386:x86-64 -D tmp/$T.out | $(RTRIM) > tmp/$T.out.disasm
|
||||||
|
$(call tc,bin2h) --mode=gas tmp/$T.out $@
|
||||||
|
|
||||||
|
lzma_d_cf.% : PP_FLAGS = -DFAST
|
||||||
|
lzma_d_cs.% : PP_FLAGS = -DSMALL
|
||||||
|
lzma_d_cn.% : PP_FLAGS = -DFAST -mno-red-zone
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
; macros.S --
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; Copyright (C) 1996-2025 Laszlo Molnar
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
; <markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro section name
|
||||||
|
.section \name
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro syscall num
|
||||||
|
li a7,\num; ecall
|
||||||
|
.endm
|
||||||
|
|
||||||
|
NBPW= 8
|
||||||
|
|
||||||
|
.macro PUSH4 a,b,c,d
|
||||||
|
addi sp,sp,-4*NBPW
|
||||||
|
sd \a,0*NBPW(sp)
|
||||||
|
sd \b,1*NBPW(sp)
|
||||||
|
sd \c,2*NBPW(sp)
|
||||||
|
sd \d,3*NBPW(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro POP4 a,b,c,d
|
||||||
|
ld \a,0*NBPW(sp)
|
||||||
|
ld \b,1*NBPW(sp)
|
||||||
|
ld \c,2*NBPW(sp)
|
||||||
|
ld \d,3*NBPW(sp)
|
||||||
|
addi sp,sp,4*NBPW
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro PUSH3 a,b,c
|
||||||
|
addi sp,sp,-4*NBPW
|
||||||
|
sd \a,0*NBPW(sp)
|
||||||
|
sd \b,1*NBPW(sp)
|
||||||
|
sd \c,2*NBPW(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro POP3 a,b,c
|
||||||
|
ld \a,0*NBPW(sp)
|
||||||
|
ld \b,1*NBPW(sp)
|
||||||
|
ld \c,2*NBPW(sp)
|
||||||
|
addi sp,sp,4*NBPW
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro PUSH2 a,b
|
||||||
|
addi sp,sp,-2*NBPW
|
||||||
|
sd \a,0*NBPW(sp)
|
||||||
|
sd \b,1*NBPW(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro POP2 a,b,c
|
||||||
|
ld \a,0*NBPW(sp)
|
||||||
|
ld \b,1*NBPW(sp)
|
||||||
|
addi sp,sp,2*NBPW
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro PUSH1 a
|
||||||
|
addi sp,sp,-2*NBPW
|
||||||
|
sd \a,0*NBPW(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro POP1 a
|
||||||
|
ld \a,0*NBPW(sp)
|
||||||
|
addi sp,sp,2*NBPW
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro SUB2 dst,src
|
||||||
|
sub \dst,\dst,\src
|
||||||
|
.endm
|
||||||
|
|
||||||
|
// vi:ts=8:et:nowrap
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/* riscv64 nrv2b_d.S -- RISCV64 decompressor for NRV2B
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2025 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2025 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
#ifndef NO_METHOD_CHECK
|
||||||
|
cmpb $ M_NRV2B_LE32,methb; jne not_n2b
|
||||||
|
#endif
|
||||||
|
li bits,1<<31 // empty; force refill
|
||||||
|
li len,0
|
||||||
|
li disp,-1 // initial displacement
|
||||||
|
j top_n2b
|
||||||
|
|
||||||
|
#undef EOF
|
||||||
|
#define EOF eof_n2b
|
||||||
|
|
||||||
|
lit_n2b:
|
||||||
|
addi src,src,1; sb bytpre,(dst)
|
||||||
|
addi dst,dst,1
|
||||||
|
top_n2b:
|
||||||
|
lbu bytpre,(src) # prefetch: literal, or bottom 8 bits of offset
|
||||||
|
jnextb1yp lit_n2b
|
||||||
|
li off,1
|
||||||
|
offmore_n2b:
|
||||||
|
getnextbp(off)
|
||||||
|
jnextb0np offmore_n2b
|
||||||
|
|
||||||
|
addi off,off,-3; blt off,zero,len_n2b # use previous offset
|
||||||
|
slli off,off,8
|
||||||
|
or off,off,bytpre; addi src,src,1
|
||||||
|
xori disp,off,~0; beq disp,zero,EOF
|
||||||
|
len_n2b:
|
||||||
|
li off,1
|
||||||
|
getnextb(len); getnextb(len) # two bits; cc set on result
|
||||||
|
bne len,zero,gotlen_n2b # raw 1,2,3 ==> 2,3,4
|
||||||
|
mv len,off # len= 1, the msb
|
||||||
|
addi off,off,3-1 # raw 2.. ==> 5..
|
||||||
|
lenmore_n2b:
|
||||||
|
getnextb(len)
|
||||||
|
jnextb0n lenmore_n2b
|
||||||
|
gotlen_n2b:
|
||||||
|
li t0,0x300; lui t0,0xfffff # -0xd00
|
||||||
|
sltu retbit,t0,disp
|
||||||
|
add len,len,off; add len,len,retbit # len += off + (disp < -0xd00)
|
||||||
|
//NYI call copy@plt; .extern copy
|
||||||
|
bot_n2b: # In: 0==len
|
||||||
|
j top_n2b
|
||||||
|
|
||||||
|
#ifndef NO_METHOD_CHECK //{
|
||||||
|
not_n2b:
|
||||||
|
push %rdi; pop %rsi # src = arg1
|
||||||
|
#endif //}
|
||||||
|
|
||||||
|
# fall into daisy chain
|
||||||
|
/*
|
||||||
|
vi:ts=8:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#if 0 //{ pre-defined
|
||||||
|
#define ra x1 /* return address */
|
||||||
|
#define sp x2 /* stack ptr */
|
||||||
|
#define gp x3 /* global ptr */
|
||||||
|
#define tp x4 /* thread ptr */
|
||||||
|
#endif //}
|
||||||
|
#define t0 x5
|
||||||
|
#define t1 x6
|
||||||
|
#define t2 x7
|
||||||
|
|
||||||
|
#define s0 x8
|
||||||
|
#define s1 x9
|
||||||
|
|
||||||
|
#define rv a0 /* return value */
|
||||||
|
|
||||||
|
/* NOTE: THE FIRST ARGUMENT IS arg1, NOT arg0. */
|
||||||
|
#define arg1 x10 /* same as rv */
|
||||||
|
#define arg2 x11
|
||||||
|
#define arg3 x12
|
||||||
|
#define arg4 x13
|
||||||
|
#define arg5 x14
|
||||||
|
#define arg6 x15
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
; riscv64-expand.S -- decompressors for riscv64
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 1996-2021 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; Copyright (C) 1996-2021 Laszlo Molnar
|
||||||
|
; Copyright (C) 2000-2021 John F. Reiser
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
; <markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
;
|
||||||
|
; John F. Reiser
|
||||||
|
; <jreiser@users.sourceforge.net>
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
NBPW = 8
|
||||||
|
#include "arch/riscv/64/macros.S"
|
||||||
|
.macro call subr; jal \subr; .endm
|
||||||
|
|
||||||
|
section EXP_HEAD
|
||||||
|
|
||||||
|
sz_unc= 0
|
||||||
|
sz_cpr= 4
|
||||||
|
b_method= 8
|
||||||
|
b_ftid= 9
|
||||||
|
b_cto8= 10
|
||||||
|
b_extra= 11
|
||||||
|
sz_binfo= 12
|
||||||
|
|
||||||
|
f_expand: .globl f_expand // f_expand(b_info *, dst, &dstlen)
|
||||||
|
// Supervisor for de-compression, un-filter, and sync_cache
|
||||||
|
// Input to supervisor:
|
||||||
|
#define fx_src a0
|
||||||
|
#define fx_dst a1
|
||||||
|
#define fx_dstlen a2
|
||||||
|
PUSH4 fx_src,fx_dst,fx_dstlen,ra // MATCH_95 params to unfilter and sync_cache
|
||||||
|
|
||||||
|
// Input to de-compressor:
|
||||||
|
#define xsrc a0
|
||||||
|
#define xsrclen a1
|
||||||
|
#define xdst a2
|
||||||
|
#define xdstlen a3
|
||||||
|
#define meth a4
|
||||||
|
lbu meth,b_method(fx_src)
|
||||||
|
mv xdstlen,fx_dstlen // arg4
|
||||||
|
mv xdst,fx_dst // arg3
|
||||||
|
lw xsrclen,sz_cpr(xsrc) // arg2
|
||||||
|
addi xsrc,fx_src,sz_binfo // arg1
|
||||||
|
call decompress
|
||||||
|
mv a3,a0 // save retval
|
||||||
|
|
||||||
|
POP4 fx_src,fx_dst,fx_dstlen,ra // MATCH_95 fx_src,fx_dst,fx_dstlen,ra
|
||||||
|
lw fx_dst,(fx_dst) // actual length used by decompressor
|
||||||
|
PUSH3 fx_src,fx_dst,a2 // MATCH_96 params for sync_cache
|
||||||
|
lbu a3,b_ftid(sp)
|
||||||
|
lbu a2,b_cto8(sp)
|
||||||
|
beqz a3,no_unf
|
||||||
|
//NYI #include "arch/arm64/v8/bxx.S" // unfilter code; args in registers, fall-through return
|
||||||
|
no_unf:
|
||||||
|
|
||||||
|
POP2 a0,a1 // MATCH_96 dst, len
|
||||||
|
add a1,a1,a0 // lo, hi
|
||||||
|
//NYI sync_cache // in macros.S
|
||||||
|
POP1 a0 // MATCH_96 retval from decompress
|
||||||
|
ret
|
||||||
|
#undef fx_src
|
||||||
|
#undef fx_dst
|
||||||
|
#undef fx_dstlen
|
||||||
|
#undef xsrc
|
||||||
|
#undef xsrclen
|
||||||
|
#undef xdst
|
||||||
|
#undef xdstlen
|
||||||
|
|
||||||
|
decompress: // (src *, cpr_len, dst *, &dstlen);
|
||||||
|
// sections NRV2B, etc, inserted here by addLoader() from ::buildLinuxLoader()
|
||||||
|
|
||||||
|
section EXP_TAIL
|
||||||
|
// Fall through: daisy chain had no matching method
|
||||||
|
li a0,-1
|
||||||
|
mv a1,meth
|
||||||
|
ebreak // EXP_TAIL daisy chain fail
|
||||||
|
|
||||||
|
#define src a0
|
||||||
|
#define bits a1
|
||||||
|
#define dst a2
|
||||||
|
#define off a3
|
||||||
|
#define len a4
|
||||||
|
#define disp a5
|
||||||
|
#define retbit t0
|
||||||
|
#define bytpre t1
|
||||||
|
|
||||||
|
|
||||||
|
.globl eof
|
||||||
|
|
||||||
|
// sync_cache is done in tail of f_expand, after possible unfilter
|
||||||
|
// NYI: eof_n2b, eof_n2d, eof_n2e should be unified.
|
||||||
|
eof_n2b: // .globl eof_n2b .type eof_n2b,%function
|
||||||
|
eof: // MATCH_90 end of a compressed extent; need sync_cache after unfilter
|
||||||
|
ld a2,0*NBPW(sp) // &input_eof
|
||||||
|
sub a0,src,a3 // src -= eof; // return 0: good; else: bad
|
||||||
|
ld a1,1*NBPW(sp) // original dst
|
||||||
|
sub dst,dst,a1 // dst -= original dst; actual length of output
|
||||||
|
ld a1,2*NBPW(sp) // &dstlen
|
||||||
|
sw dst,(a1) // actual length used at dst XXX: 4GB
|
||||||
|
ld ra,3*NBPW(sp)
|
||||||
|
addi sp,sp,4*NBPW
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
// WINDOWS_BACK compatibility seems to be broken
|
||||||
|
// if POP3 replaces POP2+POP1 (MATCH_92, MATCH_91)
|
||||||
|
#define srclim a7
|
||||||
|
eof_n2d: // .globl eof_n2d
|
||||||
|
eof_n2e: // .globl eof_n2e
|
||||||
|
POP2 a3,a4 // MATCH_92 r3= orig_dst; r4= plen_dst
|
||||||
|
SUB2 src,srclim // 0 if actual src length equals expected length
|
||||||
|
SUB2 dst,a3 // actual dst length
|
||||||
|
sw dst,(a4)
|
||||||
|
POP1 ra // MATCH_91
|
||||||
|
ret
|
||||||
|
|
||||||
|
eof_lzma: .globl eof_lzma
|
||||||
|
POP4 x2,x3, fp,ra // MATCH_94 x2= orig_dst; x3= plen_dst
|
||||||
|
ret
|
||||||
|
|
||||||
|
upx_mmap_and_fd: .globl upx_mmap_and_fd
|
||||||
|
// UMF_LINUX goes here
|
||||||
|
|
||||||
|
#define M_NRV2B_LE32 2
|
||||||
|
#define M_NRV2B_8 3
|
||||||
|
#define M_NRV2D_LE32 5
|
||||||
|
#define M_NRV2D_8 6
|
||||||
|
#define M_NRV2E_LE32 8
|
||||||
|
#define M_NRV2E_8 9
|
||||||
|
#define M_CL1B_LE32 11
|
||||||
|
#define M_LZMA 14
|
||||||
|
|
||||||
|
#define NO_METHOD_CHECK 1 /* subsumed here by daisy chain */
|
||||||
|
|
||||||
|
getbit:
|
||||||
|
srli retbit,bits,63 # hi bit of 64
|
||||||
|
slli bits,bits,1; beq bits,zero,refill
|
||||||
|
ret
|
||||||
|
/* On refill: prefetch next byte, for latency reduction on literals and offsets. */
|
||||||
|
refill:
|
||||||
|
lw bits,(src); addi src,src,4
|
||||||
|
srli retbit,bits,31 # hi bit of 4 bytes fetched
|
||||||
|
slli bits,bits,1; lbu bytpre,(src) # prefetch
|
||||||
|
ori bits,bits,1 # the flag bit
|
||||||
|
slli bits,bits,32 # hi 32 bits in 64-bit register
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* jump on next bit {0,1} with prediction {y==>likely, n==>unlikely} */
|
||||||
|
/* Prediction omitted for now. */
|
||||||
|
|
||||||
|
#define jnextb0np jnextb0yp
|
||||||
|
#define jnextb0yp GETBITp; beq retbit,zero,
|
||||||
|
#define jnextb1np jnextb1yp
|
||||||
|
#define jnextb1yp GETBITp; bne retbit,zero,
|
||||||
|
#define GETBITp \
|
||||||
|
call getbit
|
||||||
|
|
||||||
|
/* Same, but without prefetch (not useful for length of match.) */
|
||||||
|
#define jnextb0n jnextb0y
|
||||||
|
#define jnextb0y GETBIT; beq retbit,zero,
|
||||||
|
#define jnextb1n jnextb1y
|
||||||
|
#define jnextb1y GETBIT; bne retbit,zero,
|
||||||
|
#define GETBIT \
|
||||||
|
call getbit
|
||||||
|
|
||||||
|
/* rotate next bit into bottom bit of reg */
|
||||||
|
#define getnextbp(reg) GETBITp; slli reg,reg,1; or reg,reg,retbit
|
||||||
|
#define getnextb(reg) getnextbp(reg)
|
||||||
|
|
||||||
|
section NRV2E
|
||||||
|
li t0,M_NRV2E_LE32; bne meth,t0,not_nrv2e
|
||||||
|
//NYI #include "arch/arm64/v8/nrv2e_d.S"
|
||||||
|
not_nrv2e:
|
||||||
|
|
||||||
|
section NRV2D
|
||||||
|
li t0,M_NRV2D_LE32; bne meth,t0,not_nrv2d
|
||||||
|
//NYI #include "arch/arm64/v8/nrv2d_d.S"
|
||||||
|
not_nrv2d:
|
||||||
|
|
||||||
|
section NRV2B
|
||||||
|
li t0,M_NRV2B_LE32; bne meth,t0,not_nrv2b
|
||||||
|
#include "arch/riscv/64/nrv2b_d.S"
|
||||||
|
not_nrv2b:
|
||||||
|
|
||||||
|
section LZMA_DAISY
|
||||||
|
li t0,M_LZMA; bne meth,t0,not_lzma
|
||||||
|
//NYI #include "arch/arm64/v8/lzma_d.S"
|
||||||
|
not_lzma:
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/* riscv64-linux.elf-entry.S -- Linux program entry point & decompressor (Elf binary)
|
||||||
|
*
|
||||||
|
* This file is part of the UPX executable compressor.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
* Copyright (C) 1996-2025 Laszlo Molnar
|
||||||
|
* Copyright (C) 2000-2025 John F. Reiser
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* UPX and the UCL library are free software; you can redistribute them
|
||||||
|
* and/or modify them under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING.
|
||||||
|
* If not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
* <markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
*
|
||||||
|
* John F. Reiser
|
||||||
|
* <jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/riscv/64/macros.S"
|
||||||
|
#include "arch/riscv/64/regs.h"
|
||||||
|
NBPW= 8
|
||||||
|
|
||||||
|
/* These from /usr/include/unistd_64.h */
|
||||||
|
__NR_close= 57
|
||||||
|
__NR_exit= 93
|
||||||
|
__NR_ftruncate= 64
|
||||||
|
__NR_memfd_create= 279
|
||||||
|
__NR_mmap= 222
|
||||||
|
__NR_mprotect= 226
|
||||||
|
__NR_msync= 227
|
||||||
|
__NR_openat= 56
|
||||||
|
__NR_write= 64
|
||||||
|
|
||||||
|
sz_Ehdr= 64
|
||||||
|
e_phnum= 56
|
||||||
|
sz_Phdr= 56
|
||||||
|
|
||||||
|
sz_l_info= 12
|
||||||
|
l_lsize= 8
|
||||||
|
|
||||||
|
sz_p_info= 12
|
||||||
|
|
||||||
|
sz_b_info= 12
|
||||||
|
sz_unc= 0
|
||||||
|
sz_cpr= 4
|
||||||
|
b_method= 8
|
||||||
|
|
||||||
|
AT_PAGESZ= 6
|
||||||
|
|
||||||
|
PROT_READ= 1
|
||||||
|
PROT_WRITE= 2
|
||||||
|
PROT_EXEC= 4
|
||||||
|
|
||||||
|
MAP_SHARED= 1
|
||||||
|
MAP_PRIVATE= 2
|
||||||
|
MAP_FIXED= 0x10
|
||||||
|
MAP_ANONYMOUS= 0x20
|
||||||
|
|
||||||
|
MFD_EXEC= 0x0010
|
||||||
|
|
||||||
|
SYS_mmap= 9 // 64-bit mode only!
|
||||||
|
|
||||||
|
FD_stderr= 2
|
||||||
|
|
||||||
|
M_NRV2B_LE32=2 // ../conf.h
|
||||||
|
M_NRV2D_LE32=5
|
||||||
|
M_NRV2E_LE32=8
|
||||||
|
|
||||||
|
|
||||||
|
// https://www.uclibc.org/docs/psABI-x86_64.pdf
|
||||||
|
section ELFMAINX
|
||||||
|
sz_pack2= .-4
|
||||||
|
_start: .globl _start
|
||||||
|
//// nop; int3 # uncomment for debugging
|
||||||
|
|
||||||
|
ld s0,0(sp) // argc
|
||||||
|
addi s1,sp,NBPW // argv
|
||||||
|
//NYI lea cancel_dummy(%rip),%r15
|
||||||
|
|
||||||
|
section ELFMAINX2
|
||||||
|
|
||||||
|
// same as in riscv64-linux.elf-fold.S
|
||||||
|
F_FRAME= 8*NBPW
|
||||||
|
F_EOF= 7*NBPW
|
||||||
|
F_ENTR= 6*NBPW; F_PMASK= F_ENTR
|
||||||
|
F_RDX= 5*NBPW
|
||||||
|
F_LENU= 4*NBPW
|
||||||
|
F_ADRU= 3*NBPW
|
||||||
|
F_ELFA= 2*NBPW
|
||||||
|
F_LENX= 1*NBPW
|
||||||
|
F_ADRX= 0*NBPW
|
||||||
|
|
||||||
|
D_FOLD= 2*NBPW // .data space at start of unfold
|
||||||
|
D_PMASK= 0*NBPW
|
||||||
|
D_XSIGSEGV= 1*NBPW
|
||||||
|
|
||||||
|
// find auxv
|
||||||
|
slli t0,s0,3 // NBPW * argc
|
||||||
|
add t0,t0,a1 // end argv
|
||||||
|
0: // find end of env
|
||||||
|
addi t0,t0,NBPW // &env[k]
|
||||||
|
ld t1,(t0); bnez t1,0b
|
||||||
|
|
||||||
|
// find AT_PAGESZ in auxv
|
||||||
|
addi t0,t0,NBPW // &auxv
|
||||||
|
li a7,AT_PAGESZ // desired key
|
||||||
|
0:
|
||||||
|
ld t1,(t0); ld t2,NBPW(t0); addi t0,t0,2*NBPW
|
||||||
|
beq t1,a7,1f // found it
|
||||||
|
bne t1,zero,0b // keep searching
|
||||||
|
li t2,0x1000 // default PAGE_SIZE
|
||||||
|
1:
|
||||||
|
sub a7,zero,t2 // PAGE_MASK
|
||||||
|
2:
|
||||||
|
// Create anonymous temporary file on mfd; like upxfd_create
|
||||||
|
jal arg1,0f
|
||||||
|
str_upx:
|
||||||
|
.asciz "upx"
|
||||||
|
0:
|
||||||
|
// lla arg1,str_upx
|
||||||
|
li arg2,MFD_EXEC // flags
|
||||||
|
syscall __NR_memfd_create
|
||||||
|
bne a0,zero,ok_memfd // success
|
||||||
|
no_memfd: // so try /dev/shm
|
||||||
|
|
||||||
|
O_RDWR= 2
|
||||||
|
O_DIRECTORY= 0200000 // 0x010000
|
||||||
|
O_TMPFILE= 020000000 // 0x400000
|
||||||
|
# lla arg1,str_devmem
|
||||||
|
jal arg1,0f
|
||||||
|
str_devmem:
|
||||||
|
.asciz "/dev/mem"
|
||||||
|
.balign 4
|
||||||
|
0:
|
||||||
|
li arg2,0700 // mode
|
||||||
|
li arg3,O_RDWR | O_TMPFILE | O_DIRECTORY
|
||||||
|
syscall __NR_openat
|
||||||
|
ok_memfd:
|
||||||
|
#define mfd s2
|
||||||
|
mv mfd,rv
|
||||||
|
|
||||||
|
lla t0,sz_pack2
|
||||||
|
#define elfa s3
|
||||||
|
lw t1,(t0); sub elfa,t0,t1
|
||||||
|
#define binf s4
|
||||||
|
lla binf,4+o_binfo
|
||||||
|
#define lenu s5
|
||||||
|
lw lenu,sz_unc(binf)
|
||||||
|
#define szp2 s6
|
||||||
|
#define lenx s7
|
||||||
|
sub lenx,szp2,binf
|
||||||
|
#define adrx s8
|
||||||
|
add adrx,elfa,binf
|
||||||
|
|
||||||
|
#define old_sp s9
|
||||||
|
mv old_sp,sp
|
||||||
|
// alloca()
|
||||||
|
sub sp,sp,lenu; andi sp,sp,-2*NBPW
|
||||||
|
|
||||||
|
// Decompress the rest of this loader, and jump to it.
|
||||||
|
|
||||||
|
#define dst a2
|
||||||
|
#define src a0
|
||||||
|
#define lsrc a1
|
||||||
|
mv dst,sp
|
||||||
|
lw lsrc,sz_cpr(binf)
|
||||||
|
lbu t0,b_method(binf); li t1,M_NRV2B_LE32|(0<<8); beq t0,t1,0f; ebreak
|
||||||
|
0:
|
||||||
|
add t0,lsrc,src; sw t0,F_EOF(old_sp)
|
||||||
|
|
||||||
|
//%rsp:
|
||||||
|
// MATCH_10 old_sp
|
||||||
|
// MATCH_11 &input_eof
|
||||||
|
|
||||||
|
//%rbp === old_sp: array of F_FRAME
|
||||||
|
|
||||||
|
#define src a0
|
||||||
|
#define bits a1
|
||||||
|
#define dst a2
|
||||||
|
#define off a3
|
||||||
|
#define len a4
|
||||||
|
#define disp a5
|
||||||
|
#define retbit t0
|
||||||
|
#define bytpre t1
|
||||||
|
|
||||||
|
/* jump on next bit {0,1} with prediction {y==>likely, n==>unlikely} */
|
||||||
|
/* Prediction omitted for now. */
|
||||||
|
|
||||||
|
#define jnextb0np jnextb0yp
|
||||||
|
#define jnextb0yp GETBITp; beq retbit,zero,
|
||||||
|
#define jnextb1np jnextb1yp
|
||||||
|
#define jnextb1yp GETBITp; bne retbit,zero,
|
||||||
|
#define GETBITp \
|
||||||
|
call getbit
|
||||||
|
|
||||||
|
/* Same, but without prefetch (not useful for length of match.) */
|
||||||
|
#define jnextb0n jnextb0y
|
||||||
|
#define jnextb0y GETBIT; beq retbit,zero,
|
||||||
|
#define jnextb1n jnextb1y
|
||||||
|
#define jnextb1y GETBIT; bne retbit,zero,
|
||||||
|
#define GETBIT \
|
||||||
|
call getbit
|
||||||
|
|
||||||
|
/* rotate next bit into bottom bit of reg */
|
||||||
|
#define getnextbp(reg) GETBITp; slli reg,reg,1; or reg,reg,retbit
|
||||||
|
#define getnextb(reg) getnextbp(reg)
|
||||||
|
|
||||||
|
// We already checked the method and no filter.
|
||||||
|
#define NO_METHOD_CHECK 1
|
||||||
|
#include "arch/riscv/64/nrv2b_d.S"
|
||||||
|
|
||||||
|
getbit:
|
||||||
|
srli retbit,bits,63 # hi bit of 64
|
||||||
|
slli bits,bits,1; beq bits,zero,refill
|
||||||
|
ret
|
||||||
|
/* On refill: prefetch next byte, for latency reduction on literals and offsets. */
|
||||||
|
refill:
|
||||||
|
lw bits,(src); addi src,src,4
|
||||||
|
srli retbit,bits,31 # hi bit of 4 bytes fetched
|
||||||
|
slli bits,bits,1; lbu bytpre,(src) # prefetch
|
||||||
|
ori bits,bits,1 # the flag bit
|
||||||
|
slli bits,bits,32 # hi 32 bits in 64-bit register
|
||||||
|
ret
|
||||||
|
|
||||||
|
n2b_EOFbad:
|
||||||
|
ebreak
|
||||||
|
eof_n2b:
|
||||||
|
lw t0,F_EOF(old_sp)
|
||||||
|
bne t0,src,n2b_EOFbad
|
||||||
|
|
||||||
|
// Write de-compressed 'fold' to file
|
||||||
|
lw t0,F_PMASK(old_sp); sw t0,D_PMASK(sp) // propagate PAGE_MASK
|
||||||
|
lwu arg3,F_LENU(old_sp)
|
||||||
|
mv arg2,sp
|
||||||
|
mv arg1,mfd
|
||||||
|
mv s2,arg3 // LENU
|
||||||
|
0: // /dev/shm might be restricted to 8KiB at a time!
|
||||||
|
syscall __NR_write
|
||||||
|
add arg2,arg2,rv // ptr += count
|
||||||
|
sub arg3,arg3,rv // decrement count
|
||||||
|
bnez arg3,0b // not finished
|
||||||
|
// de-alloca()
|
||||||
|
mv sp,old_sp
|
||||||
|
|
||||||
|
// Map unfolded code the SELinux way
|
||||||
|
li arg6,0 // offset
|
||||||
|
mv arg5,mfd
|
||||||
|
li arg4,MAP_SHARED
|
||||||
|
li arg3,PROT_READ|PROT_EXEC // FIXME: add PROT_WRITE for DEBUG only
|
||||||
|
mv arg2,s2 // LENU
|
||||||
|
li arg1,0 // (%arg1)dst = 0; // kernel chooses addr
|
||||||
|
syscall __NR_mmap
|
||||||
|
sw rv,F_ADRU(old_sp)
|
||||||
|
|
||||||
|
mv arg1,mfd
|
||||||
|
syscall __NR_close
|
||||||
|
|
||||||
|
// Use the copy.
|
||||||
|
ld a0,F_ADRU(sp) //
|
||||||
|
addi a0,a0,D_FOLD // beyond .data
|
||||||
|
jr a0 // goto unfolded stub
|
||||||
|
|
||||||
|
// IDENTSTR goes here
|
||||||
|
|
||||||
|
section ELFMAINZ
|
||||||
|
.balign 4
|
||||||
|
o_binfo:
|
||||||
|
.long O_BINFO // offset of b_info for .text | is_ptinerp | unmap_all_pages
|
||||||
|
FOLD:
|
||||||
|
// { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
|
||||||
|
|
||||||
|
/*__XTHEENDX__*/
|
||||||
|
|
||||||
|
/* vim:set ts=8 sw=8 et: */
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
/* riscv64-linux.elf-fold.S -- linkage to C code to process Elf binary
|
||||||
|
*
|
||||||
|
* This file is part of the UPX executable compressor.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2025 John F. Reiser
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* UPX and the UCL library are free software; you can redistribute them
|
||||||
|
* and/or modify them under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING.
|
||||||
|
* If not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
* <markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
*
|
||||||
|
* John F. Reiser
|
||||||
|
* <jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
NBPW= 8
|
||||||
|
#include "arch/riscv/64/macros.S"
|
||||||
|
#include "arch/riscv/64/regs.h"
|
||||||
|
|
||||||
|
PATH_MAX= 4096 // /usr/include/linux/limits.h
|
||||||
|
|
||||||
|
sz_b_info= 12
|
||||||
|
sz_unc= 0
|
||||||
|
sz_cpr= 4
|
||||||
|
|
||||||
|
sz_l_info= 12
|
||||||
|
sz_p_info= 12
|
||||||
|
|
||||||
|
MAP_PRIVATE= 0x02
|
||||||
|
MAP_FIXED= 0x10
|
||||||
|
|
||||||
|
PROT_READ= 0x1
|
||||||
|
|
||||||
|
O_RDONLY= 0
|
||||||
|
FD_CWD= -100
|
||||||
|
|
||||||
|
OVERHEAD=2048
|
||||||
|
|
||||||
|
/* 64-bit mode only! */
|
||||||
|
__NR_read= 0
|
||||||
|
__NR_write= 1
|
||||||
|
__NR_openat= 2 //NYI
|
||||||
|
__NR_close= 3
|
||||||
|
|
||||||
|
__NR_mmap= 9
|
||||||
|
__NR_mprotect= 10
|
||||||
|
__NR_munmap= 11
|
||||||
|
__NR_msync= 26 // 0x1a
|
||||||
|
MS_SYNC= 4
|
||||||
|
__NR_brk= 12
|
||||||
|
__NR_memfd_create= 0x13f // 319
|
||||||
|
__NR_ftruncate= 0x4d // 77
|
||||||
|
|
||||||
|
__NR_exit= 60
|
||||||
|
__NR_readlink= 89
|
||||||
|
|
||||||
|
unmap_all_pages= (1<<1)
|
||||||
|
is_ptinterp= (1<<0)
|
||||||
|
|
||||||
|
// same as in riscv64-linux.elf-entry.S
|
||||||
|
F_FRAME= 8*NBPW
|
||||||
|
F_EOF= 7*NBPW // sometimes omitted from FRAME
|
||||||
|
F_ENTR= 6*NBPW; F_PMASK= F_ENTR
|
||||||
|
F_RDX= 5*NBPW
|
||||||
|
F_LENU= 4*NBPW
|
||||||
|
F_ADRU= 3*NBPW
|
||||||
|
F_ELFA= 2*NBPW
|
||||||
|
F_LENX= 1*NBPW
|
||||||
|
F_ADRX= 0*NBPW
|
||||||
|
|
||||||
|
D_FOLD= 2*NBPW // .data space at start of unfold
|
||||||
|
D_PMASK= 0*NBPW
|
||||||
|
D_XSIGSEGV= 1*NBPW
|
||||||
|
|
||||||
|
#define rsp sp /* x2 */
|
||||||
|
#define rax a0 /* x10 */
|
||||||
|
#define rbx s1 /* x9 */
|
||||||
|
#define rbp s0 /* x8 */
|
||||||
|
#define rcx t2 /* x7 */
|
||||||
|
#define rdx t1 /* x6 */
|
||||||
|
#define r12 t0 /* x5 */
|
||||||
|
|
||||||
|
#define rdi a5 /* x15 */
|
||||||
|
#define rsi a4 /* x14 */
|
||||||
|
#define r15 a3 /* x13 */
|
||||||
|
#define r14 a2 /* x12 */
|
||||||
|
#define r13 a1 /* x11 */
|
||||||
|
|
||||||
|
#define rfd rbp /* file descriptor for /proc/self/exe */
|
||||||
|
|
||||||
|
.balign 8
|
||||||
|
PAGE_MASK: .quad -1<<12 // default
|
||||||
|
cancel_sigsegv: .quad 0 // subroutine that cancels sigaction(SIGSEGV,)
|
||||||
|
|
||||||
|
// IN: [ADRX,+LENX): compressed data; [ADRU,+LENU): expanded fold (w/ upx_main2)
|
||||||
|
// %rsp= %rbp= &F_ADRX; %r13= O_BINFO | is_ptinterp | unmap_all_pages
|
||||||
|
|
||||||
|
// no 'section', thus '.text'; also loaded first in riscv64-linux.elf-fold.bin.
|
||||||
|
// Code from riscv64-linux2.elf-main.c is also .text, and is next.
|
||||||
|
fold_begin:
|
||||||
|
//// ebreak # DEBUG
|
||||||
|
// copy is_interp bit from r13 to F_ELFA(rbp)
|
||||||
|
ld t0,F_ELFA(rbp); andi t1,r13,is_ptinterp; or t0,t0,t1;
|
||||||
|
sd t0,F_ELFA(rbp)
|
||||||
|
// if !unmap_all_pages then need space on stack for result of readlink("/proc/self/exe",...)
|
||||||
|
mv rsi,rsp
|
||||||
|
andi t0,r13,unmap_all_pages
|
||||||
|
bnez t0,5f; li t0,PATH_MAX; sub rsp,rsp,t0; 0:
|
||||||
|
mv rdi,rsp
|
||||||
|
li rcx,8
|
||||||
|
0: // copy down ADRX,LDRX,ELFA,ADRU,LENU,rdx,%entry,argc
|
||||||
|
ld t0,(rsi); addi rsi,rsi,NBPW; addi rcx,rcx,-1
|
||||||
|
sd t0,(rdi); addi rdi,rdi,NBPW; bnez rcx,0b
|
||||||
|
|
||||||
|
5:
|
||||||
|
0: // copy down argv
|
||||||
|
ld t0,(rsi); addi rsi,rsi,NBPW
|
||||||
|
sd t0,(rdi); addi rdi,rdi,NBPW
|
||||||
|
bnez t0,0b
|
||||||
|
mv r14,rdi // remember &new_env[0]
|
||||||
|
|
||||||
|
andi t0,r13,unmap_all_pages; bnez t0,0f
|
||||||
|
sd zero,(rdi); addi rdi,rdi,NBPW // space for new_env[0]
|
||||||
|
0: // find old Elf64_auxv
|
||||||
|
ld t0,(rsi); sd t0,(rdi); bnez t0,0b
|
||||||
|
mv t2,rdi # &old Elf64_auxv
|
||||||
|
|
||||||
|
0: // find &strings (beyond auxv)
|
||||||
|
ld t0,(rsi); ld t1,NBPW(rsi); addi rsi,rsi,2*NBPW
|
||||||
|
sd t0,(rdi); sd t1,NBPW(rdi); addi rdi,rdi,2*NBPW
|
||||||
|
bnez t0,0b
|
||||||
|
mv r15,rdi # beyond auxv
|
||||||
|
mv r13,rsi # beginning of strings
|
||||||
|
sub rdi,rdi,t2 # -length of auxv
|
||||||
|
|
||||||
|
andi t0,r13,unmap_all_pages; beqz t0,env_pse
|
||||||
|
ori rfd,rfd,~0; mv r14,rdi; j no_env_pse # no fd; beyond auxv
|
||||||
|
env_pse:
|
||||||
|
li arg3,0 # O_RdONLY
|
||||||
|
lla arg2,proc_self_exe
|
||||||
|
li arg1,FD_CWD
|
||||||
|
call openat; mv rfd,rv # fd
|
||||||
|
|
||||||
|
li arg3,-1+ PATH_MAX # buflen
|
||||||
|
mv arg2,sp # buffer
|
||||||
|
lla arg1,proc_self_exe
|
||||||
|
syscall __NR_readlink; bgez rv,0f
|
||||||
|
// readlink() failed. Set the result equal to the argument.
|
||||||
|
lla arg2,proc_self_exe # failure result= "/proc/self/exe"
|
||||||
|
li rcx,15 # sizeof "/proc/self/exe"
|
||||||
|
0:
|
||||||
|
// std
|
||||||
|
addi rdi,r13,-1 # dst last byte
|
||||||
|
sb zero,(rdi) # terminate
|
||||||
|
addi rsi,arg2,-1
|
||||||
|
add rsi,rsi,rcx # src last byte
|
||||||
|
0: // slide up (hi end goes first)
|
||||||
|
lbu t0,(rsi); addi rsi,rsi,-1; addi rcx,rcx,-1
|
||||||
|
sb t0,(rdi); addi rdi,rdi,-1; bnez rcx,0b
|
||||||
|
// add new env " =..."
|
||||||
|
li t0,' '; sb t0,-3(rdi); sb t0,-2(rdi); sb t0,-1(rdi); addi rdi,rdi,-3
|
||||||
|
sd rdi,(r14) # new_env[0]
|
||||||
|
andi rdi,rdi,-NBPW # align
|
||||||
|
mv rcx,r15
|
||||||
|
sub rsp,rsp,rcx # byte count
|
||||||
|
|
||||||
|
addi rdi,rdi,-NBPW # &last qword of new auxv
|
||||||
|
addi rsi,r15,-NBPW # &last qword of old auxv
|
||||||
|
|
||||||
|
// end of auxv must move by even number of NBPW
|
||||||
|
mv t0,rdi
|
||||||
|
xor t0,t0,rsi
|
||||||
|
andi t0,t0,NBPW
|
||||||
|
sub rdi,rdi,t0
|
||||||
|
mv r14,rdi # &last qword of new auxv
|
||||||
|
|
||||||
|
srl rcx,rcx,3
|
||||||
|
0:
|
||||||
|
ld t0,(rsi); addi rsi,rsi,-NBPW; addi rcx,rcx,-1
|
||||||
|
sd t0,(rdi); addi rdi,rdi,-NBPW; bnez rcx,0b
|
||||||
|
addi rsp,rdi,NBPW
|
||||||
|
// cld
|
||||||
|
|
||||||
|
add arg4,r14,r12; addi arg4,arg4,NBPW # &new Elf64_auxv %r12 dead
|
||||||
|
no_env_pse:
|
||||||
|
ld arg1,F_ADRX(rbp)
|
||||||
|
ld arg2,F_LENX(rbp)
|
||||||
|
andi arg1,arg1,~(is_ptinterp | unmap_all_pages)
|
||||||
|
|
||||||
|
ld arg5,F_ELFA(rbp) # ELFA | is_ptinterp
|
||||||
|
andi t0,arg5,is_ptinterp; or arg4,arg4,t0 # transfer is_ptinterp to &new_ELF64_auxv
|
||||||
|
sub arg5,arg5,t0 # and clear from ELFA
|
||||||
|
mv r13,arg5 # save ELFA
|
||||||
|
addi rsp,rsp,-OVERHEAD
|
||||||
|
mv arg3,rsp # &ELf64_Ehdr temporary space
|
||||||
|
call upx_main2 # Out: rv= entry
|
||||||
|
|
||||||
|
// entry= upx_main2(
|
||||||
|
// b_info *arg1, {%rdi}
|
||||||
|
// total_size arg2, {%rsi}
|
||||||
|
// Elf64_Ehdr *arg3, {%rdx}
|
||||||
|
// Elf32_Auxv_t *arg4, {%rcx}
|
||||||
|
// Elf64_Addr elfaddr {%r8}
|
||||||
|
// )
|
||||||
|
|
||||||
|
// rsp/ {OVERHEAD},ADRU,LENU,rdx,%entry, argc,argv,0,envp,0,auxv,0,strings
|
||||||
|
li t0,OVERHEAD
|
||||||
|
add rsp,rsp,t0 # remove Elf64_Ehdr temporary space
|
||||||
|
#define r_fd ebx
|
||||||
|
ld rfd,(rbp) //NYI
|
||||||
|
sd rv,3*NBPW(rsp) # entry
|
||||||
|
|
||||||
|
//NYI call *cancel_sigsegv(%rip)
|
||||||
|
|
||||||
|
sz_Ehdr= 8*NBPW
|
||||||
|
e_type= 16
|
||||||
|
ET_EXEC= 2
|
||||||
|
sz_Phdr= 7*NBPW
|
||||||
|
p_memsz= 5*NBPW
|
||||||
|
// Discard pages of compressed data (includes [ADRX,+LENX) )
|
||||||
|
addi arg2,r13,p_memsz+sz_Phdr+sz_Ehdr # Phdr[C_TEXT= 1].p_memsz
|
||||||
|
//cmpw $ET_EXEC, e_type(%r13); jne 1f
|
||||||
|
mv arg1,r13; call brk // also sets the brk
|
||||||
|
1:
|
||||||
|
mv arg1,r13; call munmap # discard C_TEXT compressed data
|
||||||
|
|
||||||
|
// Map 1 page of /proc/self/exe so that the symlink does not disappear.
|
||||||
|
bltz rfd,no_pse_map
|
||||||
|
li arg6,0 # 0 offset
|
||||||
|
mv arg5,rfd
|
||||||
|
li arg4,MAP_PRIVATE
|
||||||
|
li arg3,PROT_READ
|
||||||
|
li arg2,1<<12
|
||||||
|
li arg1,0
|
||||||
|
call mmap
|
||||||
|
|
||||||
|
mv arg1,rfd
|
||||||
|
call close
|
||||||
|
|
||||||
|
no_pse_map:
|
||||||
|
ld arg1,F_ADRU(rbp) # ADRU: unfolded upx_main2 etc.
|
||||||
|
ld arg2,F_LENU(rbp)
|
||||||
|
li a7,__NR_munmap
|
||||||
|
jr r14 # goto: syscall; pop %rdx; ret
|
||||||
|
|
||||||
|
get_page_mask: .globl get_page_mask
|
||||||
|
ld rv,PAGE_MASK
|
||||||
|
ret
|
||||||
|
|
||||||
|
section SYSCALLS
|
||||||
|
my_bkpt: .globl my_bkpt
|
||||||
|
ebreak // my_bkpt
|
||||||
|
ret
|
||||||
|
|
||||||
|
proc_self_exe:
|
||||||
|
.asciz "/proc/self/exe"
|
||||||
|
.balign 4
|
||||||
|
|
||||||
|
upxfd_create: .globl upxfd_create // (char *tag, unsigned flags)
|
||||||
|
0: // try memfd_create
|
||||||
|
syscall __NR_memfd_create; j ok_memfd //NYI
|
||||||
|
O_RDWR= 2
|
||||||
|
O_DIRECTORY= 0200000 // 0x010000
|
||||||
|
O_TMPFILE= 020000000 // 0x400000
|
||||||
|
li arg4,0700 # mode
|
||||||
|
li arg3,O_RDWR|O_DIRECTORY|O_TMPFILE
|
||||||
|
la arg3,dev_shm
|
||||||
|
li arg1,FD_CWD
|
||||||
|
syscall __NR_openat
|
||||||
|
ok_memfd:
|
||||||
|
ret
|
||||||
|
|
||||||
|
Pmap: .globl Pmap // page-align the lo end
|
||||||
|
ld t0,PAGE_MASK; xori t0,t0,~0 // frag mask
|
||||||
|
and arg1,arg1,t0 // frag
|
||||||
|
sub arg1,arg1,t0
|
||||||
|
add arg2,arg2,t0
|
||||||
|
mmap: .globl mmap
|
||||||
|
li a7,__NR_mmap
|
||||||
|
sysgo:
|
||||||
|
sys_check:
|
||||||
|
ebreak // sys_check
|
||||||
|
syscall 0 //NYI
|
||||||
|
//NYI syscall error checking
|
||||||
|
ret
|
||||||
|
|
||||||
|
Psync: .globl Psync
|
||||||
|
li a7,__NR_msync
|
||||||
|
j 5f
|
||||||
|
|
||||||
|
Pprotect: .globl Pprotect
|
||||||
|
li a7,__NR_mprotect
|
||||||
|
j 5f
|
||||||
|
|
||||||
|
Punmap: .globl Punmap // page-align the lo end
|
||||||
|
li a7,__NR_munmap
|
||||||
|
5:
|
||||||
|
ld t0,PAGE_MASK; xori t0,t0,~0 // frag mask
|
||||||
|
and t0,t0,arg1 // frag
|
||||||
|
sub arg1,arg1,t0
|
||||||
|
add arg2,arg2,t0
|
||||||
|
j sysgo
|
||||||
|
|
||||||
|
munmap: .globl munmap
|
||||||
|
li a7,__NR_munmap; 5: j 5f
|
||||||
|
exit: .globl exit
|
||||||
|
li a7,__NR_exit; 5: j 5f
|
||||||
|
brk: .globl brk
|
||||||
|
li a7,__NR_brk; 5: j 5f
|
||||||
|
close: .globl close
|
||||||
|
li a7,__NR_close; 5: j 5f
|
||||||
|
ftruncate: .globl ftruncate
|
||||||
|
li a7,__NR_ftruncate; 5: j 5f
|
||||||
|
open: .globl openat
|
||||||
|
li a7,__NR_openat; 5: j 5f
|
||||||
|
mprotect: .globl mprotect
|
||||||
|
li a7,__NR_mprotect; 5: j 5f
|
||||||
|
msync: .globl msync
|
||||||
|
li a7,__NR_msync; 5: j 5f
|
||||||
|
Pwrite: .globl Pwrite
|
||||||
|
write: .globl write
|
||||||
|
li a7,__NR_write; 5: j 5f
|
||||||
|
read: .globl read
|
||||||
|
li a7,__NR_read; 5: j sysgo
|
||||||
|
|
||||||
|
// vim:set ts=8 sw=8 et:
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* riscv64-linux.elf-fold.lds -- static linker script to build riscv64-linux.elf-fold.bin
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 2000-2025 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf64-littleriscv64", "elf64-littleriscv64", "elf64-littleriscv64")
|
||||||
|
OUTPUT_ARCH(riscv64)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = SIZEOF_HEADERS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
.section HUMF_A, "ax"
|
||||||
|
j upx_mmap_and_fd_android
|
||||||
|
|
||||||
|
.section HUMF_L, "ax"
|
||||||
|
j upx_mmap_and_fd_linux
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#include "amd64-linux.elf-main2.c"
|
||||||
@@ -74,6 +74,16 @@ extern void my_bkpt(void const *, ...);
|
|||||||
/*und*/ : "x30"); \
|
/*und*/ : "x30"); \
|
||||||
str; \
|
str; \
|
||||||
})
|
})
|
||||||
|
#elif defined(__riscv) //}{
|
||||||
|
#define ANDROID_FRIEND 0
|
||||||
|
#define addr_string(string) ({ \
|
||||||
|
char const *str; \
|
||||||
|
asm("jal 0f; .string \"" string "\"; .balign 4; 0: mv %0,ra" \
|
||||||
|
/*out*/ : "=r"(str) \
|
||||||
|
/* in*/ : \
|
||||||
|
/*und*/ : "x30"); \
|
||||||
|
str; \
|
||||||
|
})
|
||||||
#else //}{
|
#else //}{
|
||||||
#define ANDROID_FRIEND 0
|
#define ANDROID_FRIEND 0
|
||||||
#error addr_string
|
#error addr_string
|
||||||
|
|||||||
Reference in New Issue
Block a user