include $(__nmk_dir)msg.mk

CFLAGS			:= $(filter-out -pg $(CFLAGS-GCOV),$(CFLAGS))
CFLAGS			:= $(filter-out -DCONFIG_X86_64,$(CFLAGS))

SYS-PROTO-GENERIC	:= $(obj)/../../include/syscall.h

SYS-CODES-GENERIC	= $(obj)/../../include/syscall-codes.h
SYS-CODES		= $(obj)/../../include/syscall-codes-$(1).h
SYS-PROTO		= $(obj)/../../include/syscall-$(1).h
SYS-DEF			= $(obj)/syscalls/syscall_$(1).tbl
SYS-ASM			= syscalls-$(1).S
SYS-ASM-COMMON		= syscall-common-x86-$(1).S
SYS-EXEC-TBL		= $(obj)/sys-exec-tbl-$(1).c

target			:=
target_32		:= syscalls-32
target_64		:= syscalls-64

SYS-BITS		:= 32

# native x86_64
ifeq ($(ARCH),x86)
	SYS-BITS	+= 64
endif

# targets
define gen-targets
target			+= $(target_$(1))
endef

$(eval $(call map,gen-targets,$(SYS-BITS)))

# AFLAGS, LDFLAGS
asflags-y		+= -Wstrict-prototypes -Wa,--noexecstack
asflags-y		+= -D__ASSEMBLY__ -nostdlib -fomit-frame-pointer
asflags-y		+= -iquote $(obj) -iquote $(obj)/include
asflags-y		+= -iquote $(SRC_DIR)/criu/include

AFLAGS_$(target_32)	+= -fno-pic -m32
AFLAGS_$(target_64)	+= -fpie
LDFLAGS_$(target_32)	+= -m elf_i386

$(target_32)-obj-y		+= syscalls/syscall32.o
$(obj)/syscalls/syscall32.d: $(obj)/../../include/syscall-codes-32.h	\
				$(obj)/../../include/syscall-32.h

CFLAGS_syscall32.o += -fno-pic -m32 -DCR_NOGLIBC -DCONFIG_X86_32
CFLAGS_syscall32.d += -fno-pic -m32 -DCR_NOGLIBC -DCONFIG_X86_32
cleanup-y		+= $(obj)/syscalls/syscall32.o

# Here are rules for 32/64-bit platforms. For compat mode we need both
# 32 and 64 bit syscalls, so generate the rules with SYS-BIT being
# $1 parameter in all gen-rule-*

# awk variable should be escaped twice
AV			:= $$$$

define gen-rule-sys-codes
$(SYS-CODES): $(SYS-DEF)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $$@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H_$(1)__"		>> $$@
	$(Q) echo "#define __ASM_CR_SYSCALL_CODES_H_$(1)__"		>> $$@
	$(Q) cat $$< | awk '/^__NR/{SYSN=$(AV)1;			\
		sub("^__NR", "SYS", SYSN);				\
		print "\n#ifndef ", $(AV)1;				\
		print "#define", $(AV)1, $(AV)2;			\
		print "#endif";						\
		print "\n#ifndef ", SYSN;				\
		print "#define ", SYSN, $(AV)1;				\
		print "#endif";}'					>> $$@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H_$(1)__ */"	>> $$@
mrproper-y		+= $(SYS-CODES)
endef

define gen-rule-sys-proto
$(SYS-PROTO): $(SYS-DEF)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $$@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H_$(1)__"		>> $$@
	$(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H_$(1)__"		>> $$@
	$(Q) echo "#ifndef CR_NOGLIBC"					>> $$@
	$(Q) echo "# error This file should only be used in the parasite code"	\
									>> $$@
	$(Q) echo "#endif"						>> $$@
	$(Q) echo '#include "syscall-codes-$(1).h"'			>> $$@
	$(Q) echo '#include "syscall-types.h"'				>> $$@
ifeq ($(1),32)
	$(Q) echo '#include "asm/syscall32.h"'				>> $$@
endif
	$(Q) cat $$< | awk '/^__NR/{print "extern long", $(AV)3,	\
			substr($(AV)0, index($(AV)0,$(AV)4)), ";"}'	>> $$@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H_$(1)__ */"	>> $$@
mrproper-y		+= $(SYS-PROTO)
endef

define gen-rule-sys-asm
$(obj)/$(SYS-ASM): $(SYS-DEF) $(obj)/syscalls/$(SYS-ASM-COMMON) \
					$(SYS-CODES) $(SYS-PROTO)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $$@
	$(Q) echo '#include "syscall-codes-$(1).h"'			>> $$@
	$(Q) echo '#include "syscalls/$(SYS-ASM-COMMON)"'		>> $$@
	$(Q) cat $$< | awk '/^__NR/{print "SYSCALL(", $(AV)3, ",", $(AV)2, ")"}'\
									>> $$@
mrproper-y		+= $(obj)/$(SYS-ASM)
$(target_$(1))-obj-y	+= $(SYS-ASM:.S=).o
endef

# for 32-bit $(SYS-ASM)
AFLAGS_syscalls-32.o	+= -fno-pic -m32

define gen-rule-sys-exec-tbl
$(SYS-EXEC-TBL): $(SYS-DEF) $(SYS-CODES) $(SYS-PROTO) $(SYS-PROTO-GENERIC)
	$(call msg-gen, $$@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $$@
	$(Q) cat $$< | awk '/^__NR/{print				\
		"SYSCALL(", substr($(AV)3, 5), ",", $(AV)2, ")"}'	>> $$@
mrproper-y		+= $(SYS-EXEC-TBL)
all-y			+= $(SYS-EXEC-TBL)
endef

# Some parts of criu need SYS_memfd_create and other ifndef/define syscalls
# Use 64-bit, native syscalls as-is, add __NR32_*/SYS32_* defines
# to generic file
$(SYS-CODES-GENERIC): $(obj)/syscalls/syscall_32.tbl
	$(call msg-gen, $@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_CODES_H__"			>> $@
	$(Q) echo "#define __ASM_CR_SYSCALL_CODES_H__"			>> $@
	$(Q) echo '#include "syscall-codes-64.h"'			>> $@
	$(Q) cat $< | awk '/^__NR/{NR32=$$1;				\
		sub("^__NR", "__NR32", NR32);				\
		print "\n#ifndef ", NR32;				\
		print "#define ", NR32, $$2;				\
		print "#endif";}'					>> $@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_CODES_H__ */"		>> $@
mrproper-y		+= $(SYS-CODES-GENERIC)
all-y			+= $(SYS-CODES-GENERIC)

$(SYS-PROTO-GENERIC): $(strip $(call map,SYS-PROTO,$(SYS-BITS)))
	$(call msg-gen, $@)
	$(Q) echo "/* Autogenerated, don't edit */"			>  $@
	$(Q) echo "#ifndef __ASM_CR_SYSCALL_PROTO_H__"			>> $@
	$(Q) echo "#define __ASM_CR_SYSCALL_PROTO_H__"			>> $@
	$(Q) echo ""							>> $@
	$(Q) echo "#ifdef CONFIG_X86_32"				>> $@
	$(Q) echo '#include "syscall-32.h"'				>> $@
	$(Q) echo "#else"						>> $@
	$(Q) echo '#include "syscall-64.h"'				>> $@
	$(Q) echo "#endif /* CONFIG_X86_32 */"				>> $@
	$(Q) echo ""							>> $@
	$(Q) echo "#endif /* __ASM_CR_SYSCALL_PROTO_H__ */"		>> $@
mrproper-y		+= $(SYS-PROTO-GENERIC)

$(eval $(call map,gen-rule-sys-codes,$(SYS-BITS)))
$(eval $(call map,gen-rule-sys-proto,$(SYS-BITS)))
$(eval $(call map,gen-rule-sys-asm,$(SYS-BITS)))
$(eval $(call map,gen-rule-sys-exec-tbl,$(SYS-BITS)))
