Implement getrandom syscall decoding

* getrandom.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* linux/dummy.h (sys_getrandom): Remove.
* linux/syscall.h (sys_getrandom): New prototype.
* xlat/getrandom_flags.in: New file.
* tests/getrandom.c: New file.
* tests/getrandom.awk: New file.
* tests/getrandom.test: New test.
* tests/Makefile.am (check_PROGRAMS): Add getrandom.
(TESTS): Add getrandom.test.
(EXTRA_DIST): Add getrandom.awk.
* tests/.gitignore: Add getrandom.
diff --git a/Makefile.am b/Makefile.am
index a00aad2..bb2cae2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@
 	get_robust_list.c \
 	getcpu.c	\
 	getcwd.c	\
+	getrandom.c	\
 	hostname.c	\
 	inotify.c	\
 	io.c		\
diff --git a/getrandom.c b/getrandom.c
new file mode 100644
index 0000000..068b2e6
--- /dev/null
+++ b/getrandom.c
@@ -0,0 +1,16 @@
+#include "defs.h"
+#include "xlat/getrandom_flags.h"
+
+int
+sys_getrandom(struct tcb *tcp)
+{
+	if (exiting(tcp)) {
+		if (syserror(tcp))
+			tprintf("%#lx", tcp->u_arg[0]);
+		else
+			printstr(tcp, tcp->u_arg[0], tcp->u_rval);
+		tprintf(", %lu, ", tcp->u_arg[1]);
+		printflags(getrandom_flags, tcp->u_arg[2], "GRND_???");
+	}
+	return 0;
+}
diff --git a/linux/dummy.h b/linux/dummy.h
index 576fede..85dd060 100644
--- a/linux/dummy.h
+++ b/linux/dummy.h
@@ -34,7 +34,6 @@
 /* still unfinished */
 #define	sys_bpf			printargs
 #define	sys_execveat		printargs
-#define	sys_getrandom		printargs
 #define	sys_ioperm		printargs
 #define	sys_iopl		printargs
 #define	sys_kcmp		printargs
diff --git a/linux/syscall.h b/linux/syscall.h
index d353f74..ba585b3 100644
--- a/linux/syscall.h
+++ b/linux/syscall.h
@@ -104,6 +104,7 @@
 int sys_getitimer();
 int sys_getpmsg(); /* TODO: non-Linux, remove? */
 int sys_getpriority();
+int sys_getrandom();
 int sys_getresuid();
 int sys_getrlimit();
 int sys_getrusage();
diff --git a/tests/.gitignore b/tests/.gitignore
index f276b9b..debbda8 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,5 +1,6 @@
 caps
 fanotify_mark
+getrandom
 inet-accept-connect-send-recv
 ioctl
 ipc_msg
diff --git a/tests/Makefile.am b/tests/Makefile.am
index db3561e..f394d81 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,13 +3,14 @@
 AM_CFLAGS = $(WARN_CFLAGS)
 
 check_PROGRAMS = \
+	caps \
+	fanotify_mark \
+	getrandom \
 	inet-accept-connect-send-recv \
 	ioctl \
 	ipc_msg \
-	ipc_shm \
 	ipc_sem \
-	caps \
-	fanotify_mark \
+	ipc_shm \
 	mmsg \
 	net-accept-connect \
 	netlink_inet_diag \
@@ -42,6 +43,7 @@
 	dumpio.test \
 	fanotify_mark.test \
 	getdents.test \
+	getrandom.test \
 	ioctl.test \
 	ipc_msg.test \
 	ipc_shm.test \
diff --git a/tests/getrandom.awk b/tests/getrandom.awk
new file mode 100644
index 0000000..4c5f6fc
--- /dev/null
+++ b/tests/getrandom.awk
@@ -0,0 +1,26 @@
+BEGIN {
+	r[1] = "^getrandom\\(\"(\\\\x[0-9a-f][0-9a-f]){3}\", 3, 0\\) += 3$"
+	r[2] = "^getrandom\\(\"(\\\\x[0-9a-f][0-9a-f]){3}\"\\.\\.\\., 4, GRND_NONBLOCK\\) += 4$"
+	r[3] = "^getrandom\\(0x[[0-9a-f]+, 4, GRND_NONBLOCK\\|GRND_RANDOM\\|0x3000\\) += -1 "
+	r[4] = "^\\+\\+\\+ exited with 0 \\+\\+\\+$"
+	lines = 4
+	fail = 0
+}
+
+NR > lines { exit 1 }
+
+{
+	if (match($0, r[NR]))
+		next
+
+	print "Line " NR " does not match."
+	fail = 1
+}
+
+END {
+	if (fail == 0 && NR != lines) {
+		fail = 1
+		print "Expected " lines " lines, found " NR " line(s)."
+	}
+	exit fail
+}
diff --git a/tests/getrandom.c b/tests/getrandom.c
new file mode 100644
index 0000000..4620f9f
--- /dev/null
+++ b/tests/getrandom.c
@@ -0,0 +1,21 @@
+#include <unistd.h>
+#include <sys/syscall.h>
+
+int
+main(void)
+{
+#ifdef __NR_getrandom
+	char buf[4];
+
+	if (syscall(__NR_getrandom, buf, sizeof(buf) - 1, 0) != sizeof(buf) - 1)
+		return 77;
+	if (syscall(__NR_getrandom, buf, sizeof(buf), 1) != sizeof(buf))
+		return 77;
+	if (syscall(__NR_getrandom, buf, sizeof(buf), 0x3003) != -1)
+		return 77;
+
+	return 0;
+#else
+	return 77;
+#endif
+}
diff --git a/tests/getrandom.test b/tests/getrandom.test
new file mode 100755
index 0000000..9117038
--- /dev/null
+++ b/tests/getrandom.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Check getrandom syscall decoding.
+
+. "${srcdir=.}/init.sh"
+
+check_prog awk
+
+./getrandom ||
+	framework_skip_ 'getrandom is not available'
+
+args="-e getrandom -xx -s3 ./getrandom"
+$STRACE -o "$LOG" $args || {
+	cat "$LOG"
+	fail_ "$STRACE $args failed"
+}
+
+awk -f "$srcdir"/getrandom.awk "$LOG" || {
+	cat "$LOG"
+	fail_ 'unexpected output'
+}
+
+exit 0
diff --git a/xlat/getrandom_flags.in b/xlat/getrandom_flags.in
new file mode 100644
index 0000000..7b77c5a
--- /dev/null
+++ b/xlat/getrandom_flags.in
@@ -0,0 +1,12 @@
+#unconditional
+
+#ifndef GRND_NONBLOCK
+# define GRND_NONBLOCK 1
+#endif
+
+#ifndef GRND_RANDOM
+# define GRND_RANDOM 2
+#endif
+
+GRND_NONBLOCK
+GRND_RANDOM