prefix = /usr
datarootdir = ${prefix}/share
datadir = /usr/share

ksplice-script = $(datadir)/ksplice/ksplice-obj.pl

KSPLICE_KID ?= $(error "You must set KSPLICE_KID.")
KSPLICE_VERSION ?= $(error "You must set KSPLICE_VERSION.")
map_printk ?= $(error "You must set map_printk.")

ifneq ($(KSPLICE_STANDALONE),)
    KSPLICE_CFLAGS += -DKSPLICE_STANDALONE
endif
KSPLICE_CFLAGS += -DKSPLICE_KID=$(KSPLICE_KID)
KSPLICE_CFLAGS += -DMAP_PRINTK=0x$(map_printk)L

comma ?= ,
name-fix ?= $(subst $(comma),_,$(subst -,_,$(1)))
target = $(call name-fix,$(mod))
KSPLICE_MID = $(KSPLICE_KID)_$(target)
KSPLICE = ksplice-$(KSPLICE_MID)
KSPLICE_CORE = ksplice-$(KSPLICE_KID)

quiet_cmd_ksplice-collect = COLLECT $@
cmd_ksplice-collect = \
	$(ksplice-script) finalize $< $<.final && \
	$(LD) --script=$(src)/ld-script -r -o $@ $<.final

ksplice-pack-cflags = $(KSPLICE_CFLAGS) \
	"-DKSPLICE_MID=$(KSPLICE_MID)" \
	$(addprefix -DKSPLICE_TARGET=,$(target)) \
	"-DKSPLICE_VERSION=\"$(KSPLICE_VERSION)\""

ksplice-primary-objs = primary-$(target).o collect-primary-$(mod).o
ksplice-helper-objs = helper-$(target).o collect-helper-$(mod).o

ifneq ($(KSPLICE_STANDALONE),)
obj-m += $(KSPLICE_CORE).o
UDIS86 = x86/libudis86
kudis86 += \
	$(UDIS86)/itab.o \
	$(UDIS86)/input.o \
	$(UDIS86)/decode.o \
	$(UDIS86)/syn.o \
	$(UDIS86)/syn-intel.o \
	$(UDIS86)/syn-att.o \
	$(UDIS86)/udis86.o
$(KSPLICE_CORE)-objs = ksplice-rmsyms.o $(kudis86)
endif

define ksplice-pack-vars
obj-m += $(KSPLICE).o $(KSPLICE)-helper.o
$(KSPLICE)-objs = $(ksplice-primary-objs)
$(KSPLICE)-helper-objs = $(ksplice-helper-objs)
CFLAGS_primary-$(target).o = $(ksplice-pack-cflags)
CFLAGS_helper-$(target).o = $(ksplice-pack-cflags)
endef

$(foreach mod,$(KSPLICE_MODULES),$(eval $(ksplice-pack-vars)))

ifneq ($(KSPLICE_MODULES),)
$(foreach mod,$(KSPLICE_MODULES),$(obj)/primary-$(target).o): $(obj)/%.o: $(src)/primary.c FORCE
	$(call if_changed_rule,cc_o_c)
$(foreach mod,$(KSPLICE_MODULES),$(obj)/helper-$(target).o): $(obj)/%.o: $(src)/helper.c FORCE
	$(call if_changed_rule,cc_o_c)
endif

$(obj)/collect-primary-%.o: $(obj)/%.o.KSPLICE_primary FORCE
	$(call if_changed,ksplice-collect)
$(obj)/collect-helper-%.o: $(obj)/%.o.KSPLICE_helper FORCE
	$(call if_changed,ksplice-collect)

CFLAGS_offsets.o += $(KSPLICE_CFLAGS)
extra-y += offsets.o

ifneq ($(KSPLICE_STANDALONE),)
CFLAGS_ksplice.o += $(KSPLICE_CFLAGS)
extra-y += ksplice.o

RMSYMS = \
	apply_paravirt \
	thread_return \
	bust_spinlocks \
	task_curr \
	__kernel_text_address \
	tasklist_lock \
	stop_machine_run \
	module_mutex \
	modules \
	init_mm \
	kallsyms_addresses \
	kallsyms_num_syms \
	kallsyms_names \
	kallsyms_token_table \
	kallsyms_token_index \
	__module_text_address \
	__start___ksymtab \
	__stop___ksymtab \
	__start___ksymtab_gpl \
	__stop___ksymtab_gpl \
	__start___ksymtab_gpl_future \
	__stop___ksymtab_gpl_future \
	__start___ksymtab_unused \
	__stop___ksymtab_unused \
	__start___ksymtab_unused_gpl \
	__stop___ksymtab_unused_gpl \
	__start___ksymtab_gpl_future \
	__stop___ksymtab_gpl_future \
	__start___kcrctab \
	__start___kcrctab_gpl \
	__start___kcrctab_gpl_future \
	__start___kcrctab_unused \
	__start___kcrctab_unused_gpl

quiet_cmd_ksplice-rmsyms = RMSYMS  $@
cmd_ksplice-rmsyms = \
	$(ksplice-script) rmsyms $< $<.rmsyms $(RMSYMS) && \
	$(LD) -r -o $@ $<.rmsyms $(src)/ksplice.lds
$(obj)/ksplice-rmsyms.o: $(obj)/ksplice.o $(obj)/offsets.o FORCE
	$(call if_changed,ksplice-rmsyms)
endif # KSPLICE_STANDALONE
