diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 1553e96c87..898613ad96 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -19,7 +19,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: ghcr.io/wolfssl/wolfboot-ci-arm:v1.0 + image: ghcr.io/wolfssl/wolfboot-ci-arm:v1.3 timeout-minutes: 30 steps: @@ -45,3 +45,17 @@ jobs: - name: Build wolfboot run: | make ${{inputs.make-args}} + + - name: Rebuild wolfboot with Clang + if: | + inputs.config-file == './config/examples/stm32h7.config' || + inputs.config-file == './config/examples/stm32h7-octospi.config' || + inputs.config-file == './config/examples/stm32u5.config' || + inputs.config-file == './config/examples/stm32u5-wolfcrypt-tz.config' || + inputs.config-file == './config/examples/stm32u5-nonsecure-dualbank.config' || + inputs.config-file == './config/examples/stm32n567.config' + run: | + make distclean + cp ${{inputs.config-file}} .config + make -C tools/keytools && make -C tools/bin-assemble + make USE_CLANG=1 USE_GCC=0 ${{inputs.make-args}} diff --git a/Makefile b/Makefile index a5a81c18b5..f3adcb3139 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,10 @@ OBJS:= \ ./src/libwolfboot.o \ ./hal/hal.o +ifeq ($(USE_CLANG),1) +OBJS+=./src/clang_sections.o +endif + ifeq ($(WOLFCRYPT_TZ_PSA),1) OBJS+=./src/dice/dice.o endif @@ -197,6 +201,7 @@ ifeq ($(USE_GCC_HEADLESS),1) LSCRIPT_FLAGS+=-T $(LSCRIPT) OBJCOPY_FLAGS+=--gap-fill $(FILL_BYTE) endif + ifeq ($(TARGET),ti_hercules) LSCRIPT_FLAGS+=--run_linker $(LSCRIPT) endif diff --git a/arch.mk b/arch.mk index 74663afa57..f56e3444f7 100644 --- a/arch.mk +++ b/arch.mk @@ -1288,14 +1288,16 @@ ifeq ($(USE_CLANG),1) CLANG_NEWLIB_INCLUDE?=$(abspath $(dir $(CLANG_LIBC_A))/../include) CC=$(CLANG_DRIVER) - LD=$(CLANG_DRIVER) + LD=$(CLANG_DRIVER) -fuse-ld=lld AS=$(CLANG_DRIVER) - AR=$(CROSS_COMPILE)ar - OBJCOPY?=$(CROSS_COMPILE)objcopy - SIZE=$(CROSS_COMPILE)size + AR=llvm-ar + OBJCOPY?=llvm-objcopy + SIZE=llvm-size CFLAGS+=-isystem $(CLANG_NEWLIB_INCLUDE) CFLAGS+=-DWOLFSSL_NO_ATOMIC -DWOLFSSL_NO_ATOMICS + CFLAGS+=-Wno-unknown-attributes -Wno-error=unknown-attributes + CFLAGS+=-fno-unwind-tables -fno-asynchronous-unwind-tables LDFLAGS+=-nostdlib endif diff --git a/hal/lpc55s69.ld b/hal/lpc55s69.ld index 84d2b78b07..bb7a7fce14 100644 --- a/hal/lpc55s69.ld +++ b/hal/lpc55s69.ld @@ -30,7 +30,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/mcxn.ld b/hal/mcxn.ld index fe21f44ac4..9d9c9feb76 100644 --- a/hal/mcxn.ld +++ b/hal/mcxn.ld @@ -30,7 +30,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/mcxw.ld b/hal/mcxw.ld index 41f4496f2e..c6c8809a95 100644 --- a/hal/mcxw.ld +++ b/hal/mcxw.ld @@ -30,7 +30,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/nrf5340-ns.ld b/hal/nrf5340-ns.ld index c65e9c5748..512d57bc7f 100644 --- a/hal/nrf5340-ns.ld +++ b/hal/nrf5340-ns.ld @@ -26,6 +26,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) diff --git a/hal/nrf5340.ld b/hal/nrf5340.ld index 98663fa5ee..df216fbb96 100644 --- a/hal/nrf5340.ld +++ b/hal/nrf5340.ld @@ -29,7 +29,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/nrf54l-ns.ld b/hal/nrf54l-ns.ld index 0ba2ccd889..f0eb7eff00 100644 --- a/hal/nrf54l-ns.ld +++ b/hal/nrf54l-ns.ld @@ -25,6 +25,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) diff --git a/hal/nrf54l.ld b/hal/nrf54l.ld index 3a4f2d3a5c..ae2ea18345 100644 --- a/hal/nrf54l.ld +++ b/hal/nrf54l.ld @@ -29,7 +29,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/rp2350.ld b/hal/rp2350.ld index 5ac320778c..3030d16f82 100644 --- a/hal/rp2350.ld +++ b/hal/rp2350.ld @@ -102,7 +102,7 @@ SECTIONS . = ALIGN(4); } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { *(.gnu.sgstubs*) /* Secure Gateway stubs */ . = ALIGN(4); diff --git a/hal/stm32h5-ns.ld b/hal/stm32h5-ns.ld index 0ee538bc73..ce7b51df7c 100644 --- a/hal/stm32h5-ns.ld +++ b/hal/stm32h5-ns.ld @@ -22,6 +22,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) { diff --git a/hal/stm32h5.ld b/hal/stm32h5.ld index 046031198f..49684ee545 100644 --- a/hal/stm32h5.ld +++ b/hal/stm32h5.ld @@ -25,7 +25,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . = ALIGN(32); *(.gnu.sgstubs*) /* Secure Gateway stubs */ diff --git a/hal/stm32h7.ld b/hal/stm32h7.ld index 29c73711b3..dfde5f78b4 100644 --- a/hal/stm32h7.ld +++ b/hal/stm32h7.ld @@ -22,6 +22,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) { diff --git a/hal/stm32l4.ld b/hal/stm32l4.ld index 822f01174d..933985c17e 100644 --- a/hal/stm32l4.ld +++ b/hal/stm32l4.ld @@ -15,6 +15,7 @@ SECTIONS . = ALIGN(4); _end_text = .; } > FLASH + .edidx : { . = ALIGN(4); diff --git a/hal/stm32l5-ns.ld b/hal/stm32l5-ns.ld index ee4634d273..29a401b62f 100644 --- a/hal/stm32l5-ns.ld +++ b/hal/stm32l5-ns.ld @@ -22,6 +22,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) { diff --git a/hal/stm32l5.ld b/hal/stm32l5.ld index 6151b336d0..5f0da10385 100644 --- a/hal/stm32l5.ld +++ b/hal/stm32l5.ld @@ -25,7 +25,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/hal/stm32u5-ns.ld b/hal/stm32u5-ns.ld index ee4634d273..29a401b62f 100644 --- a/hal/stm32u5-ns.ld +++ b/hal/stm32u5-ns.ld @@ -22,6 +22,12 @@ SECTIONS *(.ARM.exidx*) } > FLASH + .keystore : + { + . = ALIGN(4); + KEEP(*(.keystore*)) + } > FLASH + _stored_data = .; .data : AT (_stored_data) { diff --git a/hal/stm32u5.ld b/hal/stm32u5.ld index 6151b336d0..5f0da10385 100644 --- a/hal/stm32u5.ld +++ b/hal/stm32u5.ld @@ -25,7 +25,7 @@ SECTIONS *(.ARM.exidx*) } > FLASH - .gnu.sgstubs : + .gnu.sgstubs ORIGIN(FLASH_NSC) : { . += 0x400; . = ALIGN(4); diff --git a/options.mk b/options.mk index ff8df2c4ad..41bb6e0f20 100644 --- a/options.mk +++ b/options.mk @@ -12,6 +12,9 @@ ifeq ($(USE_CLANG),1) ifeq ($(USE_GCC),1) $(error USE_CLANG=1 is incompatible with USE_GCC=1; set USE_GCC=0) endif + ifeq ($(ARMORED),1) + $(error USE_CLANG=1 requires ARMORED=0) + endif endif # Support for Built-in ROT into OTP flash memory @@ -800,7 +803,13 @@ ifeq ($(WOLFCRYPT_TZ_PKCS11),1) CFLAGS+=-DCK_CALLABLE="__attribute__((cmse_nonsecure_entry))" CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPKCS11) CFLAGS+=-DWP11_HASH_PIN_COST=3 - LDFLAGS+=--specs=nano.specs + ifeq ($(USE_CLANG),1) + CLANG_MULTILIB_FLAGS:=$(filter -mthumb -mlittle-endian,$(LDFLAGS)) $(filter -mcpu=%,$(CFLAGS)) + LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-file-name=libc.a) + LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-libgcc-file-name) + else + LDFLAGS+=--specs=nano.specs + endif WOLFCRYPT_OBJS+=src/store_sbrk.o WOLFCRYPT_OBJS+=src/pkcs11_store.o WOLFCRYPT_OBJS+=src/pkcs11_callable.o @@ -847,7 +856,13 @@ ifeq ($(WOLFCRYPT_TZ_PSA),1) CFLAGS+=-DNO_DES3 -DNO_DES3_TLS_SUITES WOLFPSA_CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPSA) WOLFPSA_CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPSA)/wolfpsa - LDFLAGS+=--specs=nano.specs + ifeq ($(USE_CLANG),1) + CLANG_MULTILIB_FLAGS:=$(filter -mthumb -mlittle-endian,$(LDFLAGS)) $(filter -mcpu=%,$(CFLAGS)) + LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-file-name=libc.a) + LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-libgcc-file-name) + else + LDFLAGS+=--specs=nano.specs + endif WOLFCRYPT_OBJS+=src/store_sbrk.o WOLFCRYPT_OBJS+=src/psa_store.o WOLFCRYPT_OBJS+=src/arm_tee_psa_veneer.o diff --git a/src/clang_sections.S b/src/clang_sections.S new file mode 100644 index 0000000000..df04ec8db7 --- /dev/null +++ b/src/clang_sections.S @@ -0,0 +1,8 @@ +/* Workaround for GNU ld mishandling AT() on output sections when no input + * object contributes a matching section. Clang does not emit empty .data/.bss + * sections in object files (GCC does), so GNU ld fails to assign the correct + * LMA for the .data output section, producing a huge sparse binary. + * Including this object ensures .data and .bss exist as inputs. + */ +.section .data +.section .bss diff --git a/test-app/ARM-stm32h7.ld b/test-app/ARM-stm32h7.ld index 7c595fabb8..4b44d6bd81 100644 --- a/test-app/ARM-stm32h7.ld +++ b/test-app/ARM-stm32h7.ld @@ -18,6 +18,12 @@ SECTIONS _end_text = .; } > FLASH + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + _stored_data = .; .data : AT (_stored_data) diff --git a/test-app/Makefile b/test-app/Makefile index 3a58795173..5ea762546f 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -88,7 +88,7 @@ endif include ../arch.mk ifeq ($(USE_CLANG),1) - APP_OBJS+=../src/string.o + APP_NEEDS_STRING:=1 endif # Optional alias for clearer TZ PSA selection in app builds. @@ -103,8 +103,16 @@ LDFLAGS+=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -nostartfiles # Setup default objcopy flags OBJCOPY_FLAGS+=--gap-fill $(FILL_BYTE) +ifeq ($(USE_CLANG),1) + APP_OBJS+=../src/clang_sections.o +endif + ifeq ($(DEBUG_UART),1) CFLAGS+=-DDEBUG_UART + APP_NEEDS_STRING:=1 +endif + +ifeq ($(APP_NEEDS_STRING),1) APP_OBJS+=../src/string.o endif @@ -292,8 +300,12 @@ ifeq ($(TZEN),1) WOLFCRYPT_APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/random.o endif endif - CFLAGS+=-DWOLFBOOT_SECURE_CALLS -Wstack-usage=19184 - LDFLAGS+=--specs=nosys.specs -u _printf_float + CFLAGS+=-DWOLFBOOT_SECURE_CALLS + ifneq ($(USE_CLANG),1) + CFLAGS+=-Wstack-usage=19184 + LDFLAGS+=--specs=nosys.specs + endif + LDFLAGS+=-u _printf_float endif ifeq ($(WOLFCRYPT_TZ_PSA),1) CFLAGS+=-DWOLFCRYPT_TZ_PSA -DWOLFSSL_HAVE_PSA