1VERSION		= 0.9
2RELEASE		:= ""
3ifneq ($(RELEASE),"")
4	RELEASE="-$(RELEASE)"
5endif
6
7CC		= $(CROSS_COMPILE)gcc
8LD		= $(CROSS_COMPILE)ld
9OBJCOPY		= $(CROSS_COMPILE)objcopy
10
11ARCH		= $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,)
12
13ifeq ($(ARCH),amd64)
14	override ARCH := x86_64
15endif
16ifeq ($(ARCH),i386)
17	override ARCH := ia32
18endif
19
20OBJCOPY_GTE224  = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.* //g' | cut -f1-2 -d.` \>= 2.24)
21
22SUBDIRS		= Cryptlib lib
23
24LIB_PATH	= /usr/lib -L$(LOCALBASE)/lib
25
26EFI_INCLUDE	:= $(LOCALBASE)/include/efi
27EFI_INCLUDES	= -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -I$(shell pwd)/include -I/usr/include
28EFI_PATH	:= $(LOCALBASE)/lib
29
30LIB_GCC		= $(shell $(CC) -print-libgcc-file-name)
31EFI_LIBS	= -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC)
32
33EFI_CRT_OBJS 	= $(EFI_PATH)/crt0-efi-$(ARCH).o
34EFI_LDS		= elf_$(ARCH)_efi.lds
35
36DEFAULT_LOADER	:= \\\\grub.efi
37CFLAGS		= -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
38		  -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
39		  -Werror=sign-compare -ffreestanding \
40		  -I$(shell $(CC) -print-file-name=include) \
41		  "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
42		  "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
43		  $(EFI_INCLUDES)
44
45ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
46	CFLAGS	+= -DOVERRIDE_SECURITY_POLICY
47endif
48
49ifeq ($(ARCH),x86_64)
50	CFLAGS	+= -mno-mmx -mno-sse -mno-red-zone -nostdinc \
51		-maccumulate-outgoing-args \
52		-DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \
53		"-DEFI_ARCH=L\"x64\"" \
54		"-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/x64-$(VERSION)$(RELEASE)/\""
55endif
56ifeq ($(ARCH),ia32)
57	CFLAGS	+= -mno-mmx -mno-sse -mno-red-zone -nostdinc \
58		-maccumulate-outgoing-args -m32 \
59		"-DEFI_ARCH=L\"ia32\"" \
60		"-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/ia32-$(VERSION)$(RELEASE)/\""
61endif
62ifeq ($(ARCH),aarch64)
63	CFLAGS += "-DEFI_ARCH=L\"aa64\""
64		"-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/aa64-$(VERSION)$(RELEASE)/\""
65endif
66
67ifneq ($(origin VENDOR_CERT_FILE), undefined)
68	CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
69endif
70ifneq ($(origin VENDOR_DBX_FILE), undefined)
71	CFLAGS += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\"
72endif
73
74LDFLAGS		= --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) --build-id=sha1
75
76TARGET	= shim.efi MokManager.efi fallback.efi
77OBJS	= shim.o netboot.o cert.o replacements.o version.o
78KEYS	= shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
79SOURCES	= shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h version.c version.h
80MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o
81MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h
82FALLBACK_OBJS = fallback.o
83FALLBACK_SRCS = fallback.c
84
85all: $(TARGET)
86
87shim.crt:
88	./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 </dev/null
89
90shim.cer: shim.crt
91	openssl x509 -outform der -in $< -out $@
92
93shim_cert.h: shim.cer
94	echo "static UINT8 shim_cert[] = {" > $@
95	hexdump -v -e '1/1 "0x%02x, "' $< >> $@
96	echo "};" >> $@
97
98version.c : version.c.in
99	sed	-e "s,@@VERSION@@,$(VERSION)," \
100		-e "s,@@UNAME@@,$(shell uname -a)," \
101		-e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \
102		< version.c.in > version.c
103
104certdb/secmod.db: shim.crt
105	-mkdir certdb
106	pk12util -d certdb/ -i shim.p12 -W "" -K ""
107	certutil -d certdb/ -A -i shim.crt -n shim -t u
108
109shim.o: $(SOURCES) shim_cert.h
110
111cert.o : cert.S
112	$(CC) $(CFLAGS) -c -o $@ $<
113
114shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
115	$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
116
117fallback.o: $(FALLBACK_SRCS)
118
119fallback.so: $(FALLBACK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
120	$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
121
122MokManager.o: $(MOK_SOURCES)
123
124MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
125	$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
126
127Cryptlib/libcryptlib.a:
128	$(MAKE) -C Cryptlib
129
130Cryptlib/OpenSSL/libopenssl.a:
131	$(MAKE) -C Cryptlib/OpenSSL
132
133lib/lib.a:
134	$(MAKE) CFLAGS="$(CFLAGS)" -C lib
135
136ifeq ($(ARCH),aarch64)
137FORMAT		:= -O binary
138SUBSYSTEM	:= 0xa
139LDFLAGS		+= --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
140endif
141
142ifeq ($(ARCH),arm)
143FORMAT		:= -O binary
144SUBSYSTEM	:= 0xa
145LDFLAGS		+= --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
146endif
147
148FORMAT		?= --target efi-app-$(ARCH)
149
150%.efi: %.so
151ifneq ($(OBJCOPY_GTE224),1)
152	$(error objcopy >= 2.24 is required)
153endif
154	$(OBJCOPY) -j .text -j .sdata -j .data \
155		-j .dynamic -j .dynsym  -j .rel* \
156		-j .rela* -j .reloc -j .eh_frame \
157		-j .vendor_cert \
158		$(FORMAT)  $^ $@
159	$(OBJCOPY) -j .text -j .sdata -j .data \
160		-j .dynamic -j .dynsym  -j .rel* \
161		-j .rela* -j .reloc -j .eh_frame \
162		-j .debug_info -j .debug_abbrev -j .debug_aranges \
163		-j .debug_line -j .debug_str -j .debug_ranges \
164		-j .note.gnu.build-id \
165		$(FORMAT) $^ $@.debug
166
167clean:
168	$(MAKE) -C Cryptlib clean
169	$(MAKE) -C Cryptlib/OpenSSL clean
170	$(MAKE) -C lib clean
171	rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb
172	rm -f *.debug *.so *.efi *.tar.* version.c
173
174GITTAG = $(VERSION)
175
176test-archive:
177	@rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
178	@mkdir -p /tmp/shim-$(VERSION)-tmp
179	@git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
180	@git diff | ( cd /tmp/shim-$(VERSION)-tmp/ ; patch -s -p1 -b -z .gitdiff )
181	@mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
182	@git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
183	@dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
184	@rm -rf /tmp/shim-$(VERSION)
185	@echo "The archive is in shim-$(VERSION).tar.bz2"
186
187tag:
188	git tag --sign $(GITTAG) refs/heads/master
189
190archive: tag
191	@rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
192	@mkdir -p /tmp/shim-$(VERSION)-tmp
193	@git archive --format=tar $(GITTAG) | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
194	@mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
195	@git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
196	@dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
197	@rm -rf /tmp/shim-$(VERSION)
198	@echo "The archive is in shim-$(VERSION).tar.bz2"
199
200export ARCH CC LD OBJCOPY EFI_INCLUDE
201