From 46c8c6b9f8c8b60c67deae62f48323ca4ecf85bc Mon Sep 17 00:00:00 2001 From: hoytluo Date: Wed, 23 Oct 2024 13:50:19 +0800 Subject: [PATCH 1/3] add support for loongarch64 --- src/linux/elf.c | 6 +++++ src/linux/injector_internal.h | 3 +++ src/linux/ptrace.c | 2 +- src/linux/remote_call.c | 41 +++++++++++++++++++++++++++++++++++ src/linux/util.c | 2 ++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/linux/elf.c b/src/linux/elf.c index 88c30d5..10e9ec0 100644 --- a/src/linux/elf.c +++ b/src/linux/elf.c @@ -275,6 +275,12 @@ int injector__collect_libc_information(injector_t *injector) injector->sys_munmap = 215; break; #endif + case EM_LOONGARCH: + injector->arch = ARCH_LOONGARCH_64; + injector->sys_mmap = 222; + injector->sys_mprotect = 226; + injector->sys_munmap = 215; + break; default: injector__set_errmsg("Unknown target process architecture: 0x%04x", ehdr.e_machine); rv = INJERR_UNSUPPORTED_TARGET; diff --git a/src/linux/injector_internal.h b/src/linux/injector_internal.h index 993cc51..6aebd69 100644 --- a/src/linux/injector_internal.h +++ b/src/linux/injector_internal.h @@ -91,6 +91,7 @@ typedef enum { ARCH_POWERPC, ARCH_RISCV_64, ARCH_RISCV_32, + ARCH_LOONGARCH_64, } arch_t; typedef union { @@ -105,6 +106,8 @@ typedef union { uint32_t u32[2]; #elif defined(__riscv) uint32_t u32[2]; +#elif defined(__loongarch64) + uint32_t u32[2]; #endif long dummy; } code_t; diff --git a/src/linux/ptrace.c b/src/linux/ptrace.c index 43b5083..b5e463f 100644 --- a/src/linux/ptrace.c +++ b/src/linux/ptrace.c @@ -24,7 +24,7 @@ */ #include "injector_internal.h" -#if defined(__aarch64__) || defined(__riscv) +#if defined(__aarch64__) || defined(__riscv) || defined(__loongarch64) #define USE_REGSET #include /* for NT_PRSTATUS */ #include /* for struct iovec */ diff --git a/src/linux/remote_call.c b/src/linux/remote_call.c index 3afeb83..63ff8cf 100644 --- a/src/linux/remote_call.c +++ b/src/linux/remote_call.c @@ -190,6 +190,8 @@ static void print_regs(const injector_t *injector, const struct user_regs_struct typedef uint64_t user_reg_t; #elif defined(__riscv) typedef unsigned long user_reg_t; +#elif defined(__loongarch64) +typedef uint64_t user_reg_t; #elif defined(__LP64__) && !defined(MUSL_LIBC) typedef unsigned long long user_reg_t; #elif defined(__i386__) @@ -425,6 +427,23 @@ int injector__call_syscall(const injector_t *injector, intptr_t *retval, long sy reg_return = ®s.a0; break; #endif + +#if defined(__loongarch64) + case ARCH_LOONGARCH_64: + code.u32[0] = 0x002b0000; /* syscall */ + code.u32[1] = 0x002a0000; /* break */ + code_size = 2 * 4; + regs.pc = injector->code_addr; + regs.gpr[4+0] = arg1; + regs.gpr[4+1] = arg2; + regs.gpr[4+2] = arg3; + regs.gpr[4+3] = arg4; + regs.gpr[4+4] = arg5; + regs.gpr[4+5] = arg6; + regs.gpr[4+7] = syscall_number; + reg_return = ®s.gpr[4]; + break; +#endif default: injector__set_errmsg("Unexpected architecture: %s", injector__arch2name(injector->arch)); return INJERR_UNSUPPORTED_TARGET; @@ -712,6 +731,28 @@ int injector__call_function_va_list(const injector_t *injector, intptr_t *retval reg_return = ®s.a0; break; #endif +#if defined(__loongarch64) + case ARCH_LOONGARCH_64: + { + unsigned int offset = function_addr - injector->code_addr; + + offset = (offset & 0x3FFFFFF) >> 2; + code.u32[0] = 0x54000000 | ((offset & 0xFFFF) << 10)| ((offset & 0xFF0000) >> 16); + } + code.u32[1] = 0x002a0000; /* break */ + code_size = 2 * 4; + regs.pc = injector->code_addr; + regs.gpr[22] = injector->stack + injector->stack_size - 32; // SP + regs.gpr[4+0] = arg1; + regs.gpr[4+1] = arg2; + regs.gpr[4+2] = arg3; + regs.gpr[4+3] = arg4; + regs.gpr[4+4] = arg5; + regs.gpr[4+5] = arg6; + reg_return = ®s.gpr[4]; + break; +#endif + default: injector__set_errmsg("Unexpected architecture: %s", injector__arch2name(injector->arch)); return -1; diff --git a/src/linux/util.c b/src/linux/util.c index 3146743..20b32ed 100644 --- a/src/linux/util.c +++ b/src/linux/util.c @@ -77,6 +77,8 @@ const char *injector__arch2name(arch_t arch) return "RISC-V 64"; case ARCH_RISCV_32: return "RISC-V 32"; + case ARCH_LOONGARCH_64: + return "LOONGARCH 64"; } return "?"; } From 9458508945c5b39954124ace78aa21084726af77 Mon Sep 17 00:00:00 2001 From: hoytluo Date: Wed, 23 Oct 2024 13:53:37 +0800 Subject: [PATCH 2/3] add notes --- README.luo | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 README.luo diff --git a/README.luo b/README.luo new file mode 100644 index 0000000..e045989 --- /dev/null +++ b/README.luo @@ -0,0 +1,5 @@ +# Loongarch64 + +指令参考 https://www.kernel.org/doc/html/latest/translations/zh_CN/arch/loongarch/introduction.html + +我使用了bl指令,没有使用jirl指令 计算offset的时候花了点时间,需要注意先移位然后高低位互换的情况 From 1a7db90d3d36fec344bb035c6b311e1ba9ae8aeb Mon Sep 17 00:00:00 2001 From: hoytluo Date: Wed, 23 Oct 2024 14:15:02 +0800 Subject: [PATCH 3/3] Update README.luo --- README.luo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.luo b/README.luo index e045989..190407b 100644 --- a/README.luo +++ b/README.luo @@ -2,4 +2,4 @@ 指令参考 https://www.kernel.org/doc/html/latest/translations/zh_CN/arch/loongarch/introduction.html -我使用了bl指令,没有使用jirl指令 计算offset的时候花了点时间,需要注意先移位然后高低位互换的情况 +我使用了bl指令,没有使用jirl指令 计算offset的时候花了点时间,需要注意先移位然后高低位互换的情况,主要是我使用的编译器8.3,提示我很多指令不支持,导致无法很好的研究指令特性