aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-user/strace.c88
-rw-r--r--linux-user/strace.list3
2 files changed, 90 insertions, 1 deletions
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 5218e3fc33..e08bd53afb 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -3866,6 +3866,94 @@ print_futex(CPUArchState *cpu_env, const struct syscallname *name,
}
#endif
+#ifdef TARGET_NR_prlimit64
+static const char *target_ressource_string(abi_ulong r)
+{
+ #define RET_RES_ENTRY(res) case TARGET_##res: return #res;
+ switch (r) {
+ RET_RES_ENTRY(RLIMIT_AS);
+ RET_RES_ENTRY(RLIMIT_CORE);
+ RET_RES_ENTRY(RLIMIT_CPU);
+ RET_RES_ENTRY(RLIMIT_DATA);
+ RET_RES_ENTRY(RLIMIT_FSIZE);
+ RET_RES_ENTRY(RLIMIT_LOCKS);
+ RET_RES_ENTRY(RLIMIT_MEMLOCK);
+ RET_RES_ENTRY(RLIMIT_MSGQUEUE);
+ RET_RES_ENTRY(RLIMIT_NICE);
+ RET_RES_ENTRY(RLIMIT_NOFILE);
+ RET_RES_ENTRY(RLIMIT_NPROC);
+ RET_RES_ENTRY(RLIMIT_RSS);
+ RET_RES_ENTRY(RLIMIT_RTPRIO);
+#ifdef RLIMIT_RTTIME
+ RET_RES_ENTRY(RLIMIT_RTTIME);
+#endif
+ RET_RES_ENTRY(RLIMIT_SIGPENDING);
+ RET_RES_ENTRY(RLIMIT_STACK);
+ default:
+ return NULL;
+ }
+ #undef RET_RES_ENTRY
+}
+
+static void
+print_rlimit64(abi_ulong rlim_addr, int last)
+{
+ if (rlim_addr) {
+ struct target_rlimit64 *rl;
+
+ rl = lock_user(VERIFY_READ, rlim_addr, sizeof(*rl), 1);
+ if (!rl) {
+ print_pointer(rlim_addr, last);
+ return;
+ }
+ print_raw_param64("{rlim_cur=%" PRId64, tswap64(rl->rlim_cur), 0);
+ print_raw_param64("rlim_max=%" PRId64 "}", tswap64(rl->rlim_max),
+ last);
+ unlock_user(rl, rlim_addr, 0);
+ } else {
+ qemu_log("NULL%s", get_comma(last));
+ }
+}
+
+static void
+print_prlimit64(CPUArchState *cpu_env, const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ const char *rlim_name;
+
+ print_syscall_prologue(name);
+ print_raw_param("%d", arg0, 0);
+ rlim_name = target_ressource_string(arg1);
+ if (rlim_name) {
+ qemu_log("%s,", rlim_name);
+ } else {
+ print_raw_param("%d", arg1, 0);
+ }
+ print_rlimit64(arg2, 0);
+ print_pointer(arg3, 1);
+ print_syscall_epilogue(name);
+}
+
+static void
+print_syscall_ret_prlimit64(CPUArchState *cpu_env,
+ const struct syscallname *name,
+ abi_long ret, abi_long arg0, abi_long arg1,
+ abi_long arg2, abi_long arg3, abi_long arg4,
+ abi_long arg5)
+{
+ if (!print_syscall_err(ret)) {
+ qemu_log(TARGET_ABI_FMT_ld, ret);
+ if (arg3) {
+ qemu_log(" (");
+ print_rlimit64(arg3, 1);
+ qemu_log(")");
+ }
+ }
+ qemu_log("\n");
+}
+#endif
+
#ifdef TARGET_NR_kill
static void
print_kill(CPUArchState *cpu_env, const struct syscallname *name,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d8acbeec60..f776c73fa0 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1074,7 +1074,8 @@
{ TARGET_NR_preadv, "preadv" , NULL, NULL, NULL },
#endif
#ifdef TARGET_NR_prlimit64
-{ TARGET_NR_prlimit64, "prlimit64" , NULL, NULL, NULL },
+{ TARGET_NR_prlimit64, "prlimit64" , NULL, print_prlimit64,
+ print_syscall_ret_prlimit64 },
#endif
#ifdef TARGET_NR_process_vm_readv
{ TARGET_NR_process_vm_readv, "process_vm_readv" , NULL, NULL, NULL },