summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@canonical.com>2020-10-08 16:49:21 -0700
committerAliaksey Kandratsenka <alkondratenko@gmail.com>2020-12-19 18:16:39 -0800
commit313495587598fb1a69b94c44a83735f6056f6049 (patch)
tree3b07236e48dd04ee0e2be354395c2f530a2197a6
parentf0e289bdbb2fbbb7fa71496d846988c1bac0e310 (diff)
downloadgperftools-313495587598fb1a69b94c44a83735f6056f6049.tar.gz
Additional porting for riscv64.
Adds handling for the PC register, malloc_hook_mmap, and syscalls. Successfully built in Ubuntu with these changes.
-rw-r--r--m4/pc_from_ucontext.m41
-rw-r--r--src/base/linux_syscall_support.h112
-rw-r--r--src/malloc_hook_mmap_linux.h2
3 files changed, 110 insertions, 5 deletions
diff --git a/m4/pc_from_ucontext.m4 b/m4/pc_from_ucontext.m4
index 9d76f4c..88c8abf 100644
--- a/m4/pc_from_ucontext.m4
+++ b/m4/pc_from_ucontext.m4
@@ -28,6 +28,7 @@ AC_DEFUN([AC_PC_FROM_UCONTEXT],
pc_fields="$pc_fields uc_mcontext.sc_ip" # Linux (ia64)
pc_fields="$pc_fields uc_mcontext.pc" # Linux (mips)
pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
+ pc_fields="$pc_fields uc_mcontext.__gregs[[REG_PC]]" # Linux (riscv64)
pc_fields="$pc_fields uc_mcontext.psw.addr" # Linux (s390)
pc_fields="$pc_fields uc_mcontext.gregs[[R15]]" # Linux (arm old [untested])
pc_fields="$pc_fields uc_mcontext.arm_pc" # Linux (arm arch 5)
diff --git a/src/base/linux_syscall_support.h b/src/base/linux_syscall_support.h
index 085da1a..b32383f 100644
--- a/src/base/linux_syscall_support.h
+++ b/src/base/linux_syscall_support.h
@@ -130,13 +130,13 @@
#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
#define SYS_LINUX_SYSCALL_SUPPORT_H
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64, s390 and s390x
- * on Linux.
+/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64,
+ * s390, s390x, and riscv64 on Linux.
* Porting to other related platforms should not be difficult.
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
defined(__mips__) || defined(__mips64) || defined(__mips64el__) || defined(__PPC__) || \
- defined(__aarch64__) || defined(__s390__)) \
+ defined(__aarch64__) || defined(__s390__) || defined(__riscv)) \
&& (defined(__linux))
#ifndef SYS_CPLUSPLUS
@@ -938,6 +938,22 @@ struct kernel_stat {
# endif
#endif /* __s390__ */
/* End of s390/s390x definitions */
+#elif defined(__riscv)
+# ifndef __NR_gettid
+# define __NR_gettid 178
+# endif
+# ifndef __NR_futex
+# define __NR_futex 422
+# endif
+# ifndef __NR_getdents64
+# define __NR_getdents64 61
+# endif
+# ifndef __NR_openat
+# define __NR_openat 56
+# endif
+# ifndef __NR_fstatat
+# define __NR_fstatat 79
+# endif
#endif
@@ -1001,7 +1017,7 @@ struct kernel_stat {
#undef LSS_RETURN
#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
- defined(__aarch64__) || defined(__s390__))
+ defined(__aarch64__) || defined(__s390__) || defined(__riscv))
/* Failing system calls return a negative result in the range of
* -1..-4095. These are "errno" values with the sign inverted.
*/
@@ -2460,6 +2476,94 @@ struct kernel_stat {
}
LSS_RETURN(int, __ret);
}
+ #elif defined(__riscv)
+ #undef LSS_REG
+ #define LSS_REG(r,a) register long __a##r __asm__("a"#r) = \
+ (long)(a)
+
+ #undef LSS_BODY
+ #define LSS_BODY(type, name, args...) \
+ register long __a7 __asm__("a7") = __NR_##name; \
+ long __res; \
+ __asm__ __volatile__ ( \
+ "scall\n\t" \
+ : "+r" (__a0) \
+ : "r" (__a7), ##args \
+ : "memory"); \
+ __res = __a0; \
+ LSS_RETURN(type, __res)
+ #undef _syscall0
+ #define _syscall0(type,name) \
+ type LSS_NAME(name)() { \
+ register long __a7 __asm__("a7") = __NR_##name; \
+ register long __a0 __asm__("a0"); \
+ long __res; \
+ __asm__ __volatile__ ( \
+ "scall\n\t" \
+ : "=r" (__a0) \
+ : "r" (__a7) \
+ : "memory"); \
+ __res = __a0; \
+ LSS_RETURN(type, __res); \
+ }
+ #undef _syscall1
+ #define _syscall1(type, name, type1, arg1) \
+ type LSS_NAME(name)(type1 arg1) { \
+ /* There is no need for using a volatile temp. */ \
+ LSS_REG(0, arg1); \
+ LSS_BODY(type, name); \
+ }
+ #undef _syscall2
+ #define _syscall2(type, name, type1, arg1, type2, arg2) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \
+ LSS_REG(0, arg1); \
+ LSS_REG(1, arg2); \
+ LSS_BODY(type, name, "r"(__a1)); \
+ }
+ #undef _syscall3
+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
+ LSS_REG(0, arg1); \
+ LSS_REG(1, arg2); \
+ LSS_REG(2, arg3); \
+ LSS_BODY(type, name, "r"(__a1), "r"(__a2)); \
+ }
+ #undef _syscall4
+ #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ LSS_REG(0, arg1); \
+ LSS_REG(1, arg2); \
+ LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); \
+ LSS_BODY(type, name, "r"(__a1), "r"(__a2), "r"(__a3)); \
+ }
+ #undef _syscall5
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ LSS_REG(0, arg1); \
+ LSS_REG(1, arg2); \
+ LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); \
+ LSS_REG(4, arg5); \
+ LSS_BODY(type, name, "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4)); \
+ }
+ #undef _syscall6
+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ LSS_REG(0, arg1); \
+ LSS_REG(1, arg2); \
+ LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); \
+ LSS_REG(4, arg5); \
+ LSS_REG(5, arg6); \
+ LSS_BODY(type, name, "r"(__a1), "r"(__a2), "r"(__a3), "r"(__a4), \
+ "r"(__a5)); \
+ }
#endif
#define __NR__exit __NR_exit
#define __NR__gettid __NR_gettid
diff --git a/src/malloc_hook_mmap_linux.h b/src/malloc_hook_mmap_linux.h
index e2efb05..fb93b8a 100644
--- a/src/malloc_hook_mmap_linux.h
+++ b/src/malloc_hook_mmap_linux.h
@@ -56,7 +56,7 @@
|| defined(__PPC64__) \
|| defined(__aarch64__) \
|| (defined(_MIPS_SIM) && (_MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32)) \
- || defined(__s390__)
+ || defined(__s390__) || (defined(__riscv) && __riscv_xlen == 64)
static inline void* do_mmap64(void *start, size_t length,
int prot, int flags,