mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 23:22:21 +01:00
* refactor .PHONY Kbuild target rename-pie-text-and-data-sections into macro RENAME_PIE_TEXT_AND_DATA_SECTIONS, and execute it conditional on module_exports.c regeneration;
* use .ONESHELL in the wrapper Makefile too, and rework the changes in bf5536d6b8 such that the recursive make is always executed, but will leave the target untouched if it was already up-to-date relative to its dependencies.
these tweaks fix the module build to restore automatic rebuild when dependencies are updated.
325 lines
12 KiB
Makefile
325 lines
12 KiB
Makefile
# Linux kernel-native Makefile ("Kbuild") for libwolfssl.ko
|
|
#
|
|
# Copyright (C) 2006-2025 wolfSSL Inc.
|
|
#
|
|
# This file is part of wolfSSL.
|
|
#
|
|
# wolfSSL is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# wolfSSL is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
|
|
.ONESHELL:
|
|
SHELL=bash
|
|
|
|
ifeq "$(KERNEL_ARCH)" "x86"
|
|
KERNEL_ARCH_X86 := yes
|
|
else ifeq "$(KERNEL_ARCH)" "x86_64"
|
|
KERNEL_ARCH_X86 := yes
|
|
else
|
|
KERNEL_ARCH_X86 := no
|
|
endif
|
|
|
|
ifeq "$(WOLFSSL_OBJ_FILES)" ""
|
|
$(error $$WOLFSSL_OBJ_FILES is unset.)
|
|
endif
|
|
|
|
ifeq "$(WOLFSSL_CFLAGS)" ""
|
|
$(error $$WOLFSSL_CFLAGS is unset.)
|
|
endif
|
|
|
|
WOLFSSL_CFLAGS += -ffreestanding -Wframe-larger-than=$(MAX_STACK_FRAME_SIZE) -isystem $(shell $(CC) -print-file-name=include)
|
|
|
|
ifeq "$(KERNEL_ARCH)" "aarch64"
|
|
WOLFSSL_CFLAGS += -mno-outline-atomics
|
|
else ifeq "$(KERNEL_ARCH)" "arm64"
|
|
WOLFSSL_CFLAGS += -mno-outline-atomics
|
|
endif
|
|
|
|
obj-m := libwolfssl.o
|
|
|
|
WOLFSSL_OBJ_TARGETS := $(patsubst %, $(obj)/%, $(WOLFSSL_OBJ_FILES))
|
|
|
|
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
|
|
WOLFCRYPT_PIE_FILES := $(patsubst %, $(obj)/%, $(WOLFCRYPT_PIE_FILES))
|
|
endif
|
|
|
|
$(obj)/linuxkm/module_exports.o: $(WOLFSSL_OBJ_TARGETS)
|
|
|
|
ifndef KERNEL_THREAD_STACK_SIZE
|
|
ifdef CROSS_COMPILE
|
|
KERNEL_THREAD_STACK_SIZE=16384
|
|
endif
|
|
endif
|
|
|
|
# this mechanism only works in kernel 5.x+ (fallback to hardcoded value)
|
|
ifndef KERNEL_THREAD_STACK_SIZE
|
|
hostprogs := linuxkm/get_thread_size
|
|
always-y := $(hostprogs)
|
|
endif
|
|
|
|
HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer
|
|
|
|
# "-mindirect-branch=keep -mfunction-return=keep" to avoid "undefined reference
|
|
# to `__x86_return_thunk'" on CONFIG_RETHUNK kernels (5.19.0-rc7)
|
|
ifeq "$(KERNEL_ARCH_X86)" "yes"
|
|
HOST_EXTRACFLAGS += -mindirect-branch=keep -mfunction-return=keep
|
|
endif
|
|
|
|
# this rule is needed to get build to succeed in 4.x (get_thread_size still doesn't get built)
|
|
$(obj)/linuxkm/get_thread_size: $(src)/linuxkm/get_thread_size.c
|
|
|
|
ifndef KERNEL_THREAD_STACK_SIZE
|
|
$(WOLFSSL_OBJ_TARGETS): | $(obj)/linuxkm/get_thread_size
|
|
KERNEL_THREAD_STACK_SIZE=$(shell test -x $(obj)/linuxkm/get_thread_size && $(obj)/linuxkm/get_thread_size || echo 16384)
|
|
endif
|
|
MAX_STACK_FRAME_SIZE=$(shell echo $$(( $(KERNEL_THREAD_STACK_SIZE) / 4)))
|
|
|
|
libwolfssl-y := $(WOLFSSL_OBJ_FILES) linuxkm/module_hooks.o linuxkm/module_exports.o
|
|
|
|
WOLFSSL_CFLAGS_NO_VECTOR_INSNS := $(CFLAGS_SIMD_DISABLE) $(CFLAGS_FPU_DISABLE)
|
|
ifeq "$(ENABLED_ASM)" "yes"
|
|
WOLFSSL_CFLAGS_YES_VECTOR_INSNS := $(CFLAGS_SIMD_ENABLE) $(CFLAGS_FPU_DISABLE) $(CFLAGS_AUTO_VECTORIZE_DISABLE)
|
|
else
|
|
WOLFSSL_CFLAGS_YES_VECTOR_INSNS := $(WOLFSSL_CFLAGS_NO_VECTOR_INSNS)
|
|
endif
|
|
|
|
ccflags-y := $(WOLFSSL_CFLAGS) $(WOLFSSL_CFLAGS_NO_VECTOR_INSNS)
|
|
|
|
$(obj)/libwolfssl.mod.o: ccflags-y :=
|
|
$(obj)/wolfcrypt/test/test.o: ccflags-y += -DNO_MAIN_DRIVER -DWOLFSSL_NO_OPTIONS_H
|
|
|
|
$(obj)/wolfcrypt/src/aes.o: ccflags-y = $(WOLFSSL_CFLAGS) $(WOLFSSL_CFLAGS_YES_VECTOR_INSNS)
|
|
|
|
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
|
|
# note, we need -fno-stack-protector to avoid references to
|
|
# "__stack_chk_fail" from the wolfCrypt container.
|
|
PIE_FLAGS := -fPIE -fno-stack-protector -fno-toplevel-reorder
|
|
PIE_SUPPORT_FLAGS := -DUSE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE
|
|
# the kernel sanitizers generate external references to
|
|
# __ubsan_handle_out_of_bounds(), __ubsan_handle_shift_out_of_bounds(), etc.
|
|
KASAN_SANITIZE := n
|
|
UBSAN_SANITIZE := n
|
|
ifeq "$(KERNEL_ARCH_X86)" "yes"
|
|
PIE_FLAGS += -mcmodel=small
|
|
ifeq "$(CONFIG_MITIGATION_RETPOLINE)" "y"
|
|
PIE_FLAGS += -mfunction-return=thunk-inline
|
|
else
|
|
PIE_FLAGS += -mfunction-return=keep
|
|
endif
|
|
ifeq "$(CONFIG_MITIGATION_RETHUNK)" "y"
|
|
PIE_FLAGS += -mindirect-branch=thunk-inline
|
|
else
|
|
PIE_FLAGS += -mindirect-branch=keep
|
|
endif
|
|
endif
|
|
ifeq "$(KERNEL_ARCH)" "mips"
|
|
PIE_FLAGS += -mabicalls
|
|
endif
|
|
$(WOLFCRYPT_PIE_FILES): ccflags-y += $(PIE_SUPPORT_FLAGS) $(PIE_FLAGS)
|
|
$(WOLFCRYPT_PIE_FILES): ccflags-remove-y += -pg
|
|
$(obj)/linuxkm/module_hooks.o: ccflags-y += $(PIE_SUPPORT_FLAGS)
|
|
# using inline retpolines leads to "unannotated intra-function call"
|
|
# warnings from objtool without this:
|
|
$(WOLFCRYPT_PIE_FILES): OBJECT_FILES_NON_STANDARD := y
|
|
ifdef FORCE_GLOBAL_OBJTOOL_OFF
|
|
undefine CONFIG_OBJTOOL
|
|
endif
|
|
endif
|
|
|
|
ifdef KERNEL_EXTRA_CFLAGS_REMOVE
|
|
ccflags-remove-y += KERNEL_EXTRA_CFLAGS_REMOVE
|
|
endif
|
|
|
|
$(obj)/wolfcrypt/benchmark/benchmark.o: ccflags-y = $(WOLFSSL_CFLAGS) $(CFLAGS_FPU_ENABLE) $(CFLAGS_SIMD_ENABLE) $(PIE_SUPPORT_FLAGS) -DNO_MAIN_FUNCTION -DWOLFSSL_NO_OPTIONS_H
|
|
$(obj)/wolfcrypt/benchmark/benchmark.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_ENABLE_SIMD_DISABLE)
|
|
|
|
asflags-y := $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPUSIMD_DISABLE)
|
|
|
|
# vectorized implementations that are kernel-safe are listed here.
|
|
# these are known kernel-compatible, but need the vector instructions enabled in the assembler,
|
|
# and most of them still irritate objtool.
|
|
$(obj)/wolfcrypt/src/aes_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/aes_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/aes_gcm_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/aes_gcm_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/aes_xts_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/aes_xts_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/sp_x86_64_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/sp_x86_64_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/sha256_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/sha256_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/sha512_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/sha512_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/sha3_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/sha3_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/chacha_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/chacha_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/poly1305_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/poly1305_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/wc_mlkem_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/wc_mlkem_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
$(obj)/wolfcrypt/src/wc_mldsa_asm.o: asflags-y = $(WOLFSSL_ASFLAGS) $(ASFLAGS_FPU_DISABLE_SIMD_ENABLE)
|
|
$(obj)/wolfcrypt/src/wc_mldsa_asm.o: OBJECT_FILES_NON_STANDARD := y
|
|
|
|
ifndef READELF
|
|
READELF := readelf
|
|
endif
|
|
|
|
ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
|
|
|
|
LDFLAGS_libwolfssl.o += -T $(src)/wolfcrypt.lds
|
|
|
|
ifndef NM
|
|
NM := nm
|
|
endif
|
|
|
|
ifndef OBJCOPY
|
|
OBJCOPY := objcopy
|
|
endif
|
|
|
|
RENAME_PIE_TEXT_AND_DATA_SECTIONS := \
|
|
if [[ "$(quiet)" != "silent_" ]]; then \
|
|
echo -n ' Checking wolfCrypt for unresolved symbols and forbidden relocations... '; \
|
|
fi; \
|
|
cd "$(obj)" || exit $$?; \
|
|
$(LD) -relocatable -o wolfcrypt_test_link.o $(WOLFCRYPT_PIE_FILES) || exit $$?; \
|
|
undefined=$$($(NM) --undefined-only wolfcrypt_test_link.o) || exit $$?; \
|
|
GOT_relocs=$$($(READELF) --relocs --wide wolfcrypt_test_link.o | grep -E '^[^ ]+ +[^ ]+ +[^ ]*GOT[^ ]* ') || [ $$? = 1 ] || exit 2; \
|
|
rm wolfcrypt_test_link.o; \
|
|
if [ -n "$$undefined" ]; then \
|
|
echo "wolfCrypt container has unresolved symbols:" 1>&2; \
|
|
echo "$$undefined" 1>&2; \
|
|
exit 1; \
|
|
fi; \
|
|
if [ -n "$$GOT_relocs" ]; then \
|
|
echo "wolfCrypt container has GOT relocations (non-local function address used as operand?):" 1>&2; \
|
|
echo "$$GOT_relocs" 1>&2; \
|
|
exit 1; \
|
|
fi; \
|
|
if [[ "$(quiet)" != "silent_" ]]; then \
|
|
echo 'OK.'; \
|
|
fi; \
|
|
cd "$(obj)" || exit $$?; \
|
|
for file in $(WOLFCRYPT_PIE_FILES); do \
|
|
$(OBJCOPY) --rename-section .text=.text.wolfcrypt \
|
|
--rename-section .text.unlikely=.text.wolfcrypt \
|
|
--rename-section .rodata=.rodata.wolfcrypt \
|
|
--rename-section .rodata.str1.1=.rodata.wolfcrypt \
|
|
--rename-section .rodata.str1.8=.rodata.wolfcrypt \
|
|
--rename-section .rodata.cst16=.rodata.wolfcrypt \
|
|
--rename-section .rodata.cst32=.rodata.wolfcrypt \
|
|
--rename-section .data=.data.wolfcrypt \
|
|
--rename-section .data.rel.local=.data.wolfcrypt \
|
|
--rename-section .bss=.bss.wolfcrypt "$$file" || exit $$?; \
|
|
done; \
|
|
[ "$(KERNEL_ARCH_X86)" != "yes" ] || \
|
|
{ $(READELF) --sections --syms --wide $(WOLFCRYPT_PIE_FILES) | \
|
|
$(AWK) -v obj="$(obj)" ' \
|
|
/^File:/ { \
|
|
phase = 0; \
|
|
delete wolfcrypt_data_sections; \
|
|
delete wolfcrypt_text_sections; \
|
|
delete other_sections; \
|
|
if (substr($$2, 1, length(obj)) == obj) { \
|
|
curfile = substr($$2, length(obj) + 2); \
|
|
} else { \
|
|
curfile=$$2; \
|
|
} \
|
|
next; \
|
|
} \
|
|
/^Section Headers:/ { \
|
|
phase = 1; \
|
|
next; \
|
|
} \
|
|
/^Symbol table / { \
|
|
phase = 2; \
|
|
next; \
|
|
} \
|
|
{ \
|
|
if (phase == 1) { \
|
|
if (match($$0, "^ *\\[ *([0-9]+)\\] +([^ ]+) ", a)) {\
|
|
switch (a[2]) { \
|
|
case ".text.wolfcrypt": \
|
|
{ \
|
|
wolfcrypt_text_sections[a[1]] = a[2]; \
|
|
next; \
|
|
} \
|
|
case /^\.(data|rodata|bss)\.wolfcrypt$$/: \
|
|
{ \
|
|
wolfcrypt_data_sections[a[1]] = a[2]; \
|
|
next; \
|
|
} \
|
|
default: \
|
|
{ \
|
|
other_sections[a[1]] = a[2]; \
|
|
} \
|
|
} \
|
|
next; \
|
|
} \
|
|
next; \
|
|
} \
|
|
else if (phase == 2) { \
|
|
if ($$4 == "FUNC") { \
|
|
if (! ($$7 in wolfcrypt_text_sections)) { \
|
|
print curfile ": " $$4 " " $$8 " " other_sections[$$7] >"/dev/stderr"; \
|
|
++warnings; \
|
|
} \
|
|
next; \
|
|
} \
|
|
else if ($$4 == "OBJECT") { \
|
|
if (! ($$7 in wolfcrypt_data_sections)) { \
|
|
if ((other_sections[$$7] == ".printk_index") || \
|
|
(($$8 ~ /^_entry\.[0-9]+$$|^kernel_read_file_str$$/) && \
|
|
(other_sections[$$7] == ".data.rel.ro.local"))) \
|
|
next; \
|
|
print curfile ": " $$4 " " $$8 " " other_sections[$$7] >"/dev/stderr"; \
|
|
++warnings; \
|
|
} \
|
|
next; \
|
|
} \
|
|
} \
|
|
} \
|
|
END { \
|
|
if (warnings) { \
|
|
exit(1); \
|
|
} else { \
|
|
exit(0); \
|
|
}}'; } || \
|
|
{ echo 'Error: symbol(s) missed by containerization.' >&2; exit 1; }; \
|
|
if [[ "$(quiet)" != "silent_" ]]; then \
|
|
echo ' wolfCrypt .{text,data,rodata} sections containerized to .{text,data,rodata}.wolfcrypt'; \
|
|
fi
|
|
endif
|
|
|
|
# auto-generate the exported symbol list, leveraging the WOLFSSL_API visibility tags.
|
|
# exclude symbols that don't match wc_* or wolf*.
|
|
$(obj)/linuxkm/module_exports.c: $(src)/module_exports.c.template $(WOLFSSL_OBJ_TARGETS) $(obj)/linuxkm/module_hooks.o
|
|
@$(RENAME_PIE_TEXT_AND_DATA_SECTIONS)
|
|
@cp $< $@ || exit $$?
|
|
if [[ "$${VERSION}" -gt 6 || ("$${VERSION}" -eq 6 && "$${PATCHLEVEL}" -ge 13) ]]; then
|
|
# use ASCII octal escape to avoid syntax disruption in the awk script.
|
|
ns='\042WOLFSSL\042'
|
|
else
|
|
ns='WOLFSSL'
|
|
fi
|
|
$(READELF) --symbols --wide $(filter %.o,$^) |
|
|
$(AWK) '/^ *[0-9]+: / {
|
|
if ($$8 !~ /^(wc_|wolf|WOLF|TLSX_)/){next;}
|
|
if (($$4 == "FUNC") && ($$5 == "GLOBAL") && ($$6 == "DEFAULT")) {
|
|
print "EXPORT_SYMBOL_NS_GPL(" $$8 ", '"$$ns"');";
|
|
}
|
|
}' >> $@ || exit $$?
|
|
echo -e "#ifndef NO_CRYPT_TEST\nEXPORT_SYMBOL_NS_GPL(wolfcrypt_test, $${ns});\n#endif" >> $@
|
|
|
|
clean-files := linuxkm src wolfcrypt
|