diff --git a/repos/libports/include/libc-genode/sys/syscall.h b/repos/libports/include/libc-genode/sys/syscall.h
index 03445b17d2..fe11f3b4aa 100644
--- a/repos/libports/include/libc-genode/sys/syscall.h
+++ b/repos/libports/include/libc-genode/sys/syscall.h
@@ -1,4 +1,19 @@
/*
- * This file is just here to prevent a compiler warning about the missing include file.
- * On Genode, we do not support calling syscalls directly via a libc mechanism.
+ * \brief Minimal support for FreeBSD-specific syscalls
+ * \author Christian Helmuth
+ * \date 2018-05-16
*/
+
+/*
+ * Copyright (C) 2018 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#ifndef _INCLUDE__LIBC_GENODE__SYS__SYSCALL_H_
+#define _INCLUDE__LIBC_GENODE__SYS__SYSCALL_H_
+
+#define SYS_thr_self 432 /* pid_t gettid() */
+
+#endif /* _INCLUDE__LIBC_GENODE__SYS__SYSCALL_H_ */
diff --git a/repos/libports/lib/mk/libc.mk b/repos/libports/lib/mk/libc.mk
index b14e3694ed..7e95a3aa85 100644
--- a/repos/libports/lib/mk/libc.mk
+++ b/repos/libports/lib/mk/libc.mk
@@ -16,7 +16,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
pread_pwrite.cc readv_writev.cc poll.cc \
libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc signal.cc \
- socket_operations.cc task.cc socket_fs_plugin.cc
+ socket_operations.cc task.cc socket_fs_plugin.cc syscall.cc
CC_OPT_sysctl += -Wno-write-strings
diff --git a/repos/libports/lib/symbols/libc b/repos/libports/lib/symbols/libc
index 1bd3de1c18..05e3db033a 100644
--- a/repos/libports/lib/symbols/libc
+++ b/repos/libports/lib/symbols/libc
@@ -755,6 +755,7 @@ sys_nerr R 4
sys_nsig R 4
sys_siglist D 256
sys_signame D 256
+syscall T
sysconf T
sysctl T
sysctlbyname T
diff --git a/repos/libports/src/lib/libc/syscall.cc b/repos/libports/src/lib/libc/syscall.cc
new file mode 100644
index 0000000000..37dfbf92d5
--- /dev/null
+++ b/repos/libports/src/lib/libc/syscall.cc
@@ -0,0 +1,44 @@
+/*
+ * \brief Minimal support for FreeBSD-specific syscalls
+ * \author Christian Helmuth
+ * \date 2018-05-16
+ */
+
+/*
+ * Copyright (C) 2018 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+/* Genode includes */
+#include
+
+/* libc includes */
+#include
+#include
+#include
+
+
+static int sys_thr_self()
+{
+ using Genode::addr_t;
+
+ addr_t const base = Genode::Thread::stack_area_virtual_base();
+ addr_t const size = Genode::Thread::stack_virtual_size();
+ addr_t const stack = (addr_t)Genode::Thread::myself()->stack_base();
+
+ return int((stack - base) / size + 1);
+}
+
+
+extern "C" int syscall(int nr, ...)
+{
+ switch (nr) {
+ case SYS_thr_self: return sys_thr_self();
+
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+}
diff --git a/repos/libports/src/test/libc/main.cc b/repos/libports/src/test/libc/main.cc
index 40f583a13c..81a548213c 100644
--- a/repos/libports/src/test/libc/main.cc
+++ b/repos/libports/src/test/libc/main.cc
@@ -24,6 +24,9 @@
#include
#include
#include
+#include
+#include
+#include
int main(int argc, char **argv)
@@ -117,5 +120,22 @@ int main(int argc, char **argv)
}
}
+ {
+ pid_t const tid = syscall(SYS_thr_self);
+ if (tid == -1) {
+ printf("syscall(SYS_thr_self) returned %d (%s) - ERROR\n", tid, strerror(errno));
+ ++error_count;
+ } else {
+ printf("syscall(SYS_thr_self) returned %d\n", tid);
+ }
+ int const ret = syscall(0xffff);
+ if (ret != -1) {
+ printf("syscall(unknown) returned %d - ERROR\n", ret);
+ ++error_count;
+ } else {
+ printf("syscall(unknown) returned %d (%s)\n", ret, strerror(errno));
+ }
+ }
+
exit(error_count);
}