all : minijail0 libminijail.so libminijailpreload.so
-minijail0 : libminijail.o minijail0.c
+minijail0 : libsyscalls.gen.o libminijail.o minijail0.c
$(CC) $(CFLAGS) -o $@ $^ -lcap
-libminijail.so : libminijail.o
+libminijail.so : libminijail.o libsyscalls.gen.o
$(CC) $(CFLAGS) -shared -o $@ $^ -lcap
-libminijailpreload.so : libminijailpreload.c libminijail.o
+libminijailpreload.so : libminijailpreload.c libsyscalls.gen.o libminijail.o
$(CC) $(CFLAGS) -shared -o $@ $^ -ldl -lcap
libminijail.o : libminijail.c libminijail.h
+
+libsyscalls.gen.o : libsyscalls.gen.c libsyscalls.h
+
+# sed expression which extracts system calls that are
+# defined via asm/unistd.h. It converts them from:
+# #define __NR_read
+# to:
+# #ifdef __NR_read
+# { "read", __NR_read },
+# #endif
+# All other lines will not be emitted. The sed expression lives in its
+# own macro to allow clean line wrapping.
+define sed-multiline
+ 's/#define \(__NR_\)\([a-z0-9_]*\)$$/#ifdef \1\2\n\
+ { "\2", \1\2 },\n#endif/g p;'
+endef
+
+# Generates a header file with a system call table made up of "name",
+# syscall_nr entries by including the build target <asm/unistd.h> and
+# emitting the list of defines. Use of the compiler is needed to
+# dereference the actual provider of syscall definitions.
+# E.g., asm/unistd_32.h or asm/unistd_64.h, etc.
+define gen_syscalls
+ (set -e; \
+ echo '/* GENERATED BY MAKEFILE */'; \
+ echo '#include <stddef.h>'; \
+ echo '#include <asm/unistd.h>'; \
+ echo '#include "libsyscalls.h"'; \
+ echo "const struct syscall_entry syscall_table[] = {"; \
+ echo "#include <asm/unistd.h>" | \
+ $(CC) $(CFLAGS) -dN - -E | sed -ne $(sed-multiline); \
+ echo " { NULL, -1 },"; \
+ echo "};" ) > $1
+endef
+
+# Only regenerate libsyscalls.gen.c if the Makefile or header changes.
+# NOTE! This will not detect if the file is not appropriate for the target.
+libsyscalls.gen.c : Makefile libsyscalls.h
+ @printf "Generating target-arch specific $@ . . . "
+ @$(call gen_syscalls,$@)
+ @printf "done.\n"
+
+clean :
+ @rm -f libminijail.o libminijailpreload.so minijail0
+ @rm -f libsyscalls.gen.c libsyscalls.gen.o