1include $(XEN_ROOT)/Config.mk
2
3ifeq ($(XEN_TARGET_ARCH),x86_64)
4OBJCOPY_MAGIC := -I binary -O elf64-x86-64 -B i386:x86-64
5endif
6ifeq ($(XEN_TARGET_ARCH),arm64)
7OBJCOPY_MAGIC := -I binary -O elf64-littleaarch64 -B aarch64
8endif
9ifeq ($(XEN_TARGET_ARCH),arm32)
10OBJCOPY_MAGIC := -I binary -O elf32-littlearm -B arm
11endif
12
13CODE_ADDR=$(shell nm --defined $(1) | grep $(2) | awk '{print "0x"$$1}')
14CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}')
15
16.PHONY: default
17
18LIVEPATCH := xen_hello_world.livepatch
19LIVEPATCH_BYE := xen_bye_world.livepatch
20LIVEPATCH_REPLACE := xen_replace_world.livepatch
21LIVEPATCH_NOP := xen_nop.livepatch
22
23LIVEPATCHES += $(LIVEPATCH)
24LIVEPATCHES += $(LIVEPATCH_BYE)
25LIVEPATCHES += $(LIVEPATCH_REPLACE)
26LIVEPATCHES += $(LIVEPATCH_NOP)
27
28LIVEPATCH_DEBUG_DIR ?= $(DEBUG_DIR)/xen-livepatch
29
30build default: livepatch
31
32install: livepatch
33	$(INSTALL_DIR) $(DESTDIR)$(LIVEPATCH_DEBUG_DIR)
34	$(INSTALL_DATA) $(LIVEPATCHES) $(DESTDIR)$(LIVEPATCH_DEBUG_DIR)
35
36uninstall:
37	cd $(DESTDIR)$(LIVEPATCH_DEBUG_DIR) && rm -f $(LIVEPATCHES)
38
39.PHONY: clean
40clean::
41	rm -f *.o .*.o.d *.livepatch config.h
42
43#
44# To compute these values we need the binary files: xen-syms
45# and xen_hello_world_func.o to be already compiled.
46#
47.PHONY: config.h
48config.h: OLD_CODE_SZ=$(call CODE_SZ,$(BASEDIR)/xen-syms,xen_extra_version)
49config.h: NEW_CODE_SZ=$(call CODE_SZ,$<,xen_hello_world)
50config.h: MINOR_VERSION_SZ=$(call CODE_SZ,$(BASEDIR)/xen-syms,xen_minor_version)
51config.h: MINOR_VERSION_ADDR=$(call CODE_ADDR,$(BASEDIR)/xen-syms,xen_minor_version)
52config.h: xen_hello_world_func.o
53	(set -e; \
54	 echo "#define NEW_CODE_SZ $(NEW_CODE_SZ)"; \
55	 echo "#define MINOR_VERSION_SZ $(MINOR_VERSION_SZ)"; \
56	 echo "#define MINOR_VERSION_ADDR $(MINOR_VERSION_ADDR)"; \
57	 echo "#define OLD_CODE_SZ $(OLD_CODE_SZ)") > $@
58
59xen_hello_world.o: config.h
60
61.PHONY: $(LIVEPATCH)
62$(LIVEPATCH): xen_hello_world_func.o xen_hello_world.o note.o
63	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH) $^
64
65#
66# This target is only accessible if CONFIG_LIVEPATCH is defined, which
67# depends on $(build_id_linker) being available. Hence we do not
68# need any checks.
69#
70# N.B. The reason we don't use arch/x86/note.o is that it may
71# not be built (it is for EFI builds), and that we do not have
72# the note.o.bin to muck with (as it gets deleted)
73#
74.PHONY: note.o
75note.o:
76	$(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(BASEDIR)/xen-syms $@.bin
77	$(OBJCOPY) $(OBJCOPY_MAGIC) \
78		   --rename-section=.data=.livepatch.depends,alloc,load,readonly,data,contents -S $@.bin $@
79	rm -f $@.bin
80
81#
82# Extract the build-id of the xen_hello_world.livepatch
83# (which xen_bye_world will depend on).
84#
85.PHONY: hello_world_note.o
86hello_world_note.o: $(LIVEPATCH)
87	$(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(LIVEPATCH) $@.bin
88	$(OBJCOPY) $(OBJCOPY_MAGIC) \
89		   --rename-section=.data=.livepatch.depends,alloc,load,readonly,data,contents -S $@.bin $@
90	rm -f $@.bin
91
92xen_bye_world.o: config.h
93
94.PHONY: $(LIVEPATCH_BYE)
95$(LIVEPATCH_BYE): xen_bye_world_func.o xen_bye_world.o hello_world_note.o
96	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_BYE) $^
97
98xen_replace_world.o: config.h
99
100.PHONY: $(LIVEPATCH_REPLACE)
101$(LIVEPATCH_REPLACE): xen_replace_world_func.o xen_replace_world.o note.o
102	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_REPLACE) $^
103
104xen_nop.o: config.h
105
106.PHONY: $(LIVEPATCH_NOP)
107$(LIVEPATCH_NOP): xen_nop.o note.o
108	$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH_NOP) $^
109
110.PHONY: livepatch
111livepatch: $(LIVEPATCH) $(LIVEPATCH_BYE) $(LIVEPATCH_REPLACE) $(LIVEPATCH_NOP)
112