#For s390x: -pg and -fomit-frame-pointer are incompatible
ifeq ($(ARCH),s390)
ifdef CONFIG_FUNCTION_TRACER
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS))
endif
endif

#Users of GNU ld (BFD) from binutils 2.39+ will observe below warning during
#linking step
#
#ld: missing .note.GNU-stack section implies executable stack
#
#To avoid these warning use -z noexecstack linker option. Based on commit
#ffcf9c5700e49c kernel has also used same option to avoid these warnings
#Also KBUILD_LDFLAGS is available from 4.19 kernel onwards based on commit
#d503ac531a524, so also use this option with LDFLAGS for older kernel
KBUILD_LDFLAGS := $(KBUILD_LDFLAGS) -z noexecstack
LDFLAGS := $(LDFLAGS) -z noexecstack

# %Z%%M% %I% %W% %G% %U%
#It is in the KBuild context when this file is invoked
include $(CONFIGDIR)/kdef.mk
ifneq ($(SUBARCH),$(ARCH))
  ifeq ($(CROSS_COMPILE),)
    CROSS_COMPILE := $(call cc-cross-prefix, $(CROSS_PREFIX))
  endif
endif
MODPATH := /$(GPLDIR)/gpl_kernel.tmp.ver
DUMMY   := $(shell echo $(KERNELRELEASE)> $(MODPATH))

# Only used for Debian, SUBLEVEL is needed to identify
# different Debian minor version
# Examples for Debian SUBLEVEL:
#   LINUX_KERNEL_VERSION of Debian 7.x are all 30200004
#   SUBLEVEL of Debian 7.8 is 65
#   SUBLEVEL of Debian 7.6 is 57
$(KBCFLAGS) += -DSUBLEVEL=$(SUBLEVEL)
# Only used for Debian, DEB7U2 is needed to differentiate
# Debian kernel 3.2.65-1+deb7u2 from 3.2.65-1
ifneq (,$(findstring 3.2.65-1+deb7u2,$(shell uname -v)))
$(KBCFLAGS) += -DDEB7U2
endif

# Linux kernel commit 04e85bbf in Linux kernel 5.16 removed
# the global -isystem flag to gcc. Set the flag here for
# the module compile, since gpfs.h includes stddef.h, and
# that is not found otherwise.
# This is also backported to RHEL 9.1 kernel 5.14.0-85.el9
$(KBCFLAGS) += -isystem $(shell $(CC) -print-file-name=include)

# Commit e732b538 from Linux kernel 5.11 added a check for KBUILD_BUILTIN.
# Also based on Linux commit 6212804f2d78, KBUILD_BUILTIN should be cleared
# for building external modules.
# So clear KBUILD_BUILTIN to handle this correctly for the GPFS module build.
# This change has been backported to SLES 15 SP3 kernel update 5.3.18-150300.59.90
KBUILD_BUILTIN :=

# If find -mabi=elfv1, remove -mabi=elfv1 and -mcall-aixdesc
# from KCFLAGS
ifneq (,$(findstring -mabi=elfv1,$(KCFLAGS)))
$(KBCFLAGS) +=  $(filter-out -mabi=elfv1 -mcall-aixdesc, $(KCFLAGS)) -I$(M)
else
$(KBCFLAGS) +=  $(KCFLAGS) -I$(M)
endif
$(KBLDFLAGS) += $(MMLDFLAGS)
obj-m := tracedev.o mmfs26.o mmfslinux.o
tracedev-y := tracelin.o tracedev-ksyms.o ktrccalls.o relaytrc.o
mmfs26-y := $(MMFSNAME) mmfsmod.o $(KLDGCCNAME)
mmfslinux-y := cfiles_cust.o $(SS_NAME).o $(KLDGCCNAME)

ifeq ($(ARCH),arm64)
$(KBCFLAGS) += -mno-outline-atomics
mmfs26-y += aarch64_auxv.o
mmfslinux-y += aarch64_auxv.o
endif

$(KBHOSTPROGS) := lxtrace
HOSTCFLAGS := $(CDEBUGFLAGS)
# For ASAN builds, STD_LDFLAGS will contain -lasan, which we do not want here
ifneq (,$(findstring -lasan,$(STD_LDFLAGS)))
HOSTLDFLAGS += $(IMAKE_LDFLAGS) $(ALL_LIBPATHS)
else
HOSTLDFLAGS += $(STD_LDFLAGS) $(IMAKE_LDFLAGS) $(ALL_LIBPATHS)
endif
ifeq ($(LOADLIBSVAR),HOSTLDLIBS)
HOSTLDLIBS_lxtrace += -lrt -ldl $(PTHREADS)
else
HOSTLOADLIBES_lxtrace += -lrt -ldl $(PTHREADS)
endif
HOSTCFLAGS_lxtrace.o := ${GPFSKCFLAGS} ${SITE_DEFINES} $(LXTRACECFLAGS) -I$(M)
HOSTCFLAGS_lxtrace_rl.o := ${GPFSKCFLAGS} ${SITE_DEFINES} $(LXTRACECFLAGS) -I$(M)
HOSTCFLAGS_overwrite.o := ${GPFSKCFLAGS} ${SITE_DEFINES} $(LXTRACECFLAGS) -I$(M)
lxtrace-objs := lxtrace.o lxtrace_rl.o overwrite.o

# commit 5f2fb52fac in kernel 5.6 introduced "hostprogs" and "always-y" as new
#    syntax, but kept the old. available.
# commit faabed295c in kernel 5.9 introduced "hostprogs-always-y"
# commit b97652bf10 in kernel 5.12 removed "always" and "hostprogs-y/m"
# Set the new "hostprogs-always-y" and the old "always" to allow compiling
#    across all supported kernels.
hostprogs-always-y := $($(KBHOSTPROGS))
always := $($(KBHOSTPROGS))

# The vmf_insert_pfn_pud function was introduced in kernel 4.10. In 4.18rc6,
# the return value changed from int to vm_fault_t.  Then in kernel version
# 5.2rc1, the arguments changed to take struct vm_fault instead of struct
# vm_area_struct, address and pmd_t.  Normally, we could simply test the kernel
# version to decide which variant to use, but some of the distros back-ported
# parts of these incompatible changes without changing any version numbers,
# making it impossible to determine the signature by looking at the kernel or
# distro version.  To work around this, we try here to determine the signature
# dynamically.
#
# Variants we detect are:
#  <function doesn't exist>
#  int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
#                           pud_t *pud, pfn_t pfn, bool write);
#  vm_fault_t vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
#                           pud_t *pud, pfn_t pfn, bool write);
#  int vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write);
#  vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, pfn_t pfn, bool write);
#  static inline vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, pfn_t pfn,
#                                            bool write)
#
# The sed expression removes punctuation and duplicate spacing, turning the
# line into a list of positional arguments we can easily compare against.
#
VMF_INSERT_PFN_PUD_SIG := $(strip $(shell sed -n -e '/vmf_insert_pfn_pud.struct/s/[^a-z_][^a-z_]*/ /gp' $(srctree)/include/linux/huge_mm.h))
ifneq (,$(VMF_INSERT_PFN_PUD_SIG))
ccflags-y += -DHAVE_VMF_INSERT_PFN_PUD
endif
ifeq (vm_fault_t,$(word 1,$(VMF_INSERT_PFN_PUD_SIG)))
ccflags-y += -DHAVE_VM_FAULT_T
endif
ifeq (vm_fault_t,$(word 3,$(VMF_INSERT_PFN_PUD_SIG)))
ccflags-y += -DHAVE_VM_FAULT_T
endif
ifeq (vm_area_struct,$(word 4,$(VMF_INSERT_PFN_PUD_SIG)))
ccflags-y += -DVMF_INSERT_PFN_X_TAKES_VMA
endif

# Same magic for the detection of the two variants
# vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, pfn_t pfn)
# vs.
# vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr, pfn_t pfn)
VMF_INSERT_MIXED_SIG := $(strip $(shell sed -n -e '/vmf_insert_mixed.struct/s/[^a-z_][^a-z_]*/ /gp' $(srctree)/include/linux/mm.h))
ifneq (,$(VMF_INSERT_MIXED_SIG))
ccflags-y += -DHAVE_VMF_INSERT_MIXED
endif

# Handle variants in the arguments to the vm fault operation.
FAULT_SIG := $(strip $(shell sed -n -e '/(\*fault)(.*)/s/[^a-z_][^a-z_]*/ /gp' $(srctree)/include/linux/mm.h))
ifeq (vm_area_struct,$(word 4,$(FAULT_SIG)))
ccflags-y += -DFAULT_TAKES_VMA_VMF
endif
