diff --git a/.gitignore b/.gitignore index 3139c130..75cc4046 100644 --- a/.gitignore +++ b/.gitignore @@ -133,6 +133,7 @@ tools/tpm/pcr_extend tools/tpm/policy_create tools/tpm/policy_sign config/*.ld +config/*.sct test-lib lib-fs diff --git a/Makefile b/Makefile index dec0224b..4e2af07e 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ SIGN_ALG= OBJCOPY_FLAGS= BIG_ENDIAN?=0 USE_CLANG?=0 -ifeq ($(USE_CLANG),1) +USE_ARMCLANG?=0 +ifneq ($(filter 1,$(USE_CLANG) $(USE_ARMCLANG)),) USE_GCC?=0 else USE_GCC?=1 @@ -251,6 +252,39 @@ ifeq ($(ARCH),AURIX_TC3) endif endif +## ARM Compiler for Embedded (USE_ARMCLANG=1): rebuild the link options from +## scratch and switch the linker script to a scatter file, to support armlink. +ifeq ($(USE_ARMCLANG),1) + CFLAGS+=-D'END_STACK=Image$$$$ARM_LIB_STACK$$$$ZI$$$$Limit' + ifeq ($(WOLFCRYPT_TZ),1) + # Trap stubs for symbols referenced from wolfSSL code paths that are + # dead in this configuration: GNU ld garbage-collects the referencing + # sections, but armlink resolves all symbols before unused section + # elimination + OBJS+=tools/armclang/armclang_stubs.o + CFLAGS+=-DARMCLANG_STUBS_DEAD_REFS + ifeq ($(WOLFCRYPT_TZ_PKCS11),1) + CFLAGS+=-D'_flash_keyvault=Image$$$$KEYVAULT$$$$Base' + CFLAGS+=-D'_flash_keyvault_size=Image$$$$KEYVAULT$$$$ZI$$$$Length' + CFLAGS+=-D'_start_heap=Image$$$$RAM_HEAP$$$$Base' + CFLAGS+=-D'_heap_size=Image$$$$RAM_HEAP$$$$ZI$$$$Length' + # ARM libc malloc needs the C-library init that never runs (entry is + # isr_reset): provide a heap allocator instead + CFLAGS+=-DARMCLANG_STUBS_MALLOC + endif + endif + LDFLAGS:=$(ARMCLANG_LDFLAGS) --map --list=wolfboot.map + LSCRIPT:=config/target.sct + LSCRIPT_IN:=hal/$(TARGET).sct + LSCRIPT_FLAGS:=--scatter=$(LSCRIPT) + LD_START_GROUP:= + LD_END_GROUP:= + SECURE_LDFLAGS:= + ifeq ($(TZEN),1) + SECURE_LDFLAGS:=--import_cmse_lib_out=./src/wolfboot_tz_nsc.o + endif +endif + # Environment variables for sign tool SIGN_ENV=IMAGE_HEADER_SIZE=$(IMAGE_HEADER_SIZE) \ WOLFBOOT_PARTITION_SIZE=$(WOLFBOOT_PARTITION_SIZE) \ @@ -656,7 +690,7 @@ src/flash_otp_keystore.o: $(PRIVATE_KEY) src/flash_otp_keystore.c keys: $(PRIVATE_KEY) clean: - $(Q)rm -f src/*.o hal/*.o hal/spi/*.o test-app/*.o src/x86/*.o + $(Q)rm -f src/*.o hal/*.o hal/spi/*.o hal/uart/*.o test-app/*.o src/x86/*.o $(Q)rm -f src/wolfboot_tz_nsc.o $(Q)rm -f $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/*.o $(WOLFBOOT_LIB_WOLFTPM)/hal/*.o $(WOLFBOOT_LIB_WOLFTPM)/examples/pcr/*.o $(Q)rm -f $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/Renesas/*.o diff --git a/arch.mk b/arch.mk index f19e28c4..df8b0c80 100644 --- a/arch.mk +++ b/arch.mk @@ -1719,6 +1719,45 @@ ifeq ($(USE_CLANG),1) LDFLAGS+=-nostdlib endif +ifeq ($(USE_ARMCLANG),1) + ifneq ($(ARCH),ARM) + $(error USE_ARMCLANG=1 is currently supported only for ARCH=ARM) + endif + ARMCLANG_PATH?= + CC=$(ARMCLANG_PATH)armclang --target=arm-arm-none-eabi + AS=$(CC) + LD=$(ARMCLANG_PATH)armlink + AR=$(ARMCLANG_PATH)armar + FROMELF?=$(ARMCLANG_PATH)fromelf + SIZE=$(FROMELF) -z + OBJCOPY=FROMELF="$(FROMELF)" $(WOLFBOOT_ROOT)/tools/armclang/objcopy.sh + + CFLAGS+=-mfloat-abi=soft + CFLAGS+=-fno-unwind-tables -fno-asynchronous-unwind-tables + CFLAGS+=-Wno-unknown-attributes -Wno-error=unknown-attributes + + # Map scatter files region names to GNU ld symbols used by wolfBoot code + CFLAGS+=-D'_start_text=Image$$$$ER_VECTORS$$$$Base' + CFLAGS+=-D'_stored_data=Load$$$$RW_RAM$$$$Base' + CFLAGS+=-D'_start_data=Image$$$$RW_RAM$$$$Base' + CFLAGS+=-D'_end_data=Image$$$$RW_RAM$$$$Limit' + CFLAGS+=-D'_start_bss=Image$$$$RW_RAM$$$$ZI$$$$Base' + CFLAGS+=-D'_end_bss=Image$$$$RW_RAM$$$$ZI$$$$Limit' + + # Base armlink options shared by both images: + # - the unreferenced vector table needs an explicit --keep or unused + # section elimination removes it + # - RW data compression must be off: wolfBoot copies .data to RAM itself, + # word by word, and would copy the compressed image + # - Suppress L6314W (no section matches pattern) is suppressed: the scatter + # files list sections that are only present in some configurations (e.g. + # .ramcode) + # - --no_startup: wolfBoot has its own reset handler. + ARMCLANG_LDFLAGS=--cpu=Cortex-M33 --fpu=SoftVFP --entry=isr_reset \ + --keep="*(.isr_vector)" --datacompressor=off --remove \ + --no_startup --info=sizes,totals,unused --diag_suppress=6314 +endif + ifeq ($(USE_GCC),1) ## Toolchain setup CC=$(CROSS_COMPILE)gcc diff --git a/config/examples/stm32u5-wolfcrypt-tz.config b/config/examples/stm32u5-wolfcrypt-tz.config index 5cd81fef..573be823 100644 --- a/config/examples/stm32u5-wolfcrypt-tz.config +++ b/config/examples/stm32u5-wolfcrypt-tz.config @@ -20,13 +20,13 @@ RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0x20000 WOLFBOOT_SECTOR_SIZE?=0x2000 -WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 WOLFBOOT_KEYVAULT_SIZE?=0x18000 -WOLFBOOT_NSC_ADDRESS?=0x0C038000 +WOLFBOOT_NSC_ADDRESS?=0x0C058000 WOLFBOOT_NSC_SIZE?=0x8000 -WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000 -WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08060000 -WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08080000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08080000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x080A0000 FLAGS_HOME=0 DISABLE_BACKUP=0 WOLFCRYPT_TZ=1 diff --git a/docs/compile.md b/docs/compile.md index 4f07f488..d7be8605 100644 --- a/docs/compile.md +++ b/docs/compile.md @@ -384,6 +384,25 @@ iterating over a range of flash sectors and erasing them one at a time. Setting single HAL flash erase invocation with a larger erase length versus the iterative approach. On targets where multi-sector erases are more performant, this option can be used to dramatically speed up the image swap procedure. +### Building with the ARM Compiler for Embedded (armclang) + +wolfBoot can be built with the [ARM Compiler for Embedded](https://developer.arm.com/Tools%20and%20Software/Arm%20Compiler%20for%20Embedded) +(AC6: `armclang`, `armlink`, `armar`, `fromelf`), the toolchain used by Keil +MDK. No tool from the GNU or LLVM toolchains is required. + +At the moment, the only supported and tested target is the STM32U5 +(`config/examples/{stm32u5.config,stm32u5-wolfcrypt-tz.config}`). + +To use this, either have the AC6 tools in your `PATH` or set `ARMCLANG_PATH` to +their location (including a trailing slash). Then build with USE_ARMCLANG=1: + +``` +cp config/examples/stm32u5.config .config +make USE_ARMCLANG=1 +``` + +Alternatively, append `USE_ARMCLANG=1` and/or `ARMCLANG_PATH` to your `.config`. + ### Using Mac OS/X If you see 0xC3 0xBF (C3BF) repeated in your factory.bin then your OS is using Unicode characters. diff --git a/hal/stm32u5.ld b/hal/stm32u5.ld index 5f0da103..731053f2 100644 --- a/hal/stm32u5.ld +++ b/hal/stm32u5.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @ARCH_FLASH_OFFSET@ + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @WOLFBOOT_ORIGIN@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00012000 RAM_HEAP (rw): ORIGIN = 0x30012000, LENGTH = 0xe000 /* 56KB Heap for wolfcrypt/PKCS11 */ FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_KEYVAULT_ADDRESS@, LENGTH = @WOLFBOOT_KEYVAULT_SIZE@ diff --git a/hal/stm32u5.sct b/hal/stm32u5.sct new file mode 100644 index 00000000..eb01fa70 --- /dev/null +++ b/hal/stm32u5.sct @@ -0,0 +1,64 @@ +#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m33 -xc +; wolfBoot stm32u5 (TZEN=1) scatter file for armlink, equivalent to +; hal/stm32u5.ld. The @VAR@ placeholders are substituted by the Makefile +; (same rule as the GNU linker scripts), then armlink runs the armclang +; preprocessor on the result (#! line above). +; +; Region symbols consumed by the code (mapped from the GNU-ld symbol names +; via -D in arch.mk / Makefile): +; ER_VECTORS -> _start_text +; RW_RAM -> _stored_data (load), _start_data/_end_data, +; _start_bss/_end_bss +; ARM_LIB_STACK -> END_STACK (stack top, grows down from end of RAM) +; RAM_HEAP -> _start_heap/_heap_size (WOLFCRYPT_TZ PKCS11 heap) +; KEYVAULT -> _flash_keyvault/_flash_keyvault_size + +#define WOLFBOOT_STACK_RESERVE 0x1000 + +LR_FLASH @WOLFBOOT_ORIGIN@ (@WOLFBOOT_KEYVAULT_ADDRESS@ - @WOLFBOOT_ORIGIN@) +{ + ER_VECTORS @WOLFBOOT_ORIGIN@ + { + *(.isr_vector, +FIRST) + } + + ER_TEXT +0 ALIGN 8 + { + .ANY(+RO) + } + + RW_RAM 0x30000000 ALIGN 8 (0x00012000 - WOLFBOOT_STACK_RESERVE) + { + *(.ramcode) + .ANY(+RW) + .ANY(+ZI) + } + + ; Empty region only used to define the initial stack pointer; also lets + ; armlink error out if RW_RAM grows into the stack reserve + ARM_LIB_STACK 0x30012000 EMPTY -WOLFBOOT_STACK_RESERVE + { + } + +#if @WOLFBOOT_KEYVAULT_SIZE@ + 0 + ; 56KB heap for wolfcrypt/PKCS11 + RAM_HEAP 0x30012000 EMPTY 0xe000 + { + } + + KEYVAULT @WOLFBOOT_KEYVAULT_ADDRESS@ EMPTY @WOLFBOOT_KEYVAULT_SIZE@ + { + } +#endif +} + +; CMSE secure gateway veneers, generated by armlink. Placed at NSC + 0x400 +; like the GNU script (hal/stm32u5.ld reserves the first 0x400 bytes of the +; NSC region). +LR_NSC (@WOLFBOOT_NSC_ADDRESS@ + 0x400) (@WOLFBOOT_NSC_SIZE@ - 0x400) +{ + ER_NSC (@WOLFBOOT_NSC_ADDRESS@ + 0x400) + { + *(Veneer$$CMSE) + } +} diff --git a/options.mk b/options.mk index 6f9b9ae4..a463d67e 100644 --- a/options.mk +++ b/options.mk @@ -39,7 +39,8 @@ WOLFHSM_SERVER_OBJS := \ $(WOLFBOOT_LIB_WOLFHSM)/src/wh_message_comm.o USE_CLANG?=0 -ifeq ($(USE_CLANG),1) +USE_ARMCLANG?=0 +ifneq ($(filter 1,$(USE_CLANG) $(USE_ARMCLANG)),) USE_GCC?=0 else USE_GCC?=1 @@ -56,6 +57,18 @@ ifeq ($(USE_CLANG),1) endif endif +ifeq ($(USE_ARMCLANG),1) + ifeq ($(USE_GCC),1) + $(error USE_ARMCLANG=1 is incompatible with USE_GCC=1; set USE_GCC=0) + endif + ifeq ($(USE_CLANG),1) + $(error USE_ARMCLANG=1 is incompatible with USE_CLANG=1) + endif + ifeq ($(ARMORED),1) + $(error USE_ARMCLANG=1 requires ARMORED=0) + endif +endif + # Support for Built-in ROT into OTP flash memory ifeq ($(FLASH_OTP_KEYSTORE),1) CFLAGS+=-D"FLASH_OTP_KEYSTORE" diff --git a/test-app/ARM-stm32u5-ns.sct b/test-app/ARM-stm32u5-ns.sct new file mode 100644 index 00000000..f714bb88 --- /dev/null +++ b/test-app/ARM-stm32u5-ns.sct @@ -0,0 +1,40 @@ +#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m33 -xc +; wolfBoot test-app stm32u5 (TZEN=1, non-secure app) scatter file for +; armlink, equivalent to test-app/ARM-stm32u5-ns.ld. +; +; Region symbols (mapped from the GNU-ld symbol names via -D in arch.mk and +; test-app/Makefile): +; ER_VECTORS -> _start_text +; RW_RAM -> _stored_data (load), _start_data/_end_data, +; _start_bss/_end_bss, _start_heap (= end of ZI) +; ARM_LIB_STACK -> _end_stack (stack top, grows down from end of RAM) + +#define APP_RAM_BASE 0x20020000 +#define APP_RAM_SIZE 0x00020000 +#define APP_STACK_RESERVE 0x1000 + +LR_FLASH @WOLFBOOT_TEST_APP_ADDRESS@ @WOLFBOOT_TEST_APP_SIZE@ +{ + ER_VECTORS @WOLFBOOT_TEST_APP_ADDRESS@ + { + *(.isr_vector, +FIRST) + } + + ER_TEXT +0 ALIGN 8 + { + .ANY(+RO) + } + + RW_RAM APP_RAM_BASE ALIGN 8 (APP_RAM_SIZE - APP_STACK_RESERVE) + { + *(.ramcode) + .ANY(+RW) + .ANY(+ZI) + } + + ; Empty region only used to define the initial stack pointer; also lets + ; armlink error out if RW_RAM grows into the stack reserve + ARM_LIB_STACK (APP_RAM_BASE + APP_RAM_SIZE) EMPTY -APP_STACK_RESERVE + { + } +} diff --git a/test-app/Makefile b/test-app/Makefile index f8058a34..bb27fd6b 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -1258,6 +1258,19 @@ ifeq ($(PPC64),1) CFLAGS:=$(filter-out -DWOLFSSL_PPC32_ASM -DWOLFSSL_PPC32_ASM_INLINE,$(CFLAGS)) endif +## ARM Compiler for Embedded (USE_ARMCLANG=1): rebuild the link options from +## scratch, since the GNU-specific LDFLAGS accumulated above don't apply to +## armlink, and switch the linker script to a scatter file. +ifeq ($(USE_ARMCLANG),1) + CFLAGS+=-D'_end_stack=Image$$$$ARM_LIB_STACK$$$$ZI$$$$Limit' + CFLAGS+=-D'_start_heap=Image$$$$RW_RAM$$$$ZI$$$$Limit' + # GCC-only flags accumulated above + CFLAGS:=$(filter-out -Wstack-usage=% -gstabs,$(CFLAGS)) + LSCRIPT:=../config/target-app.sct + LSCRIPT_TEMPLATE:=ARM-$(TARGET)-ns.sct + LDFLAGS:=$(ARMCLANG_LDFLAGS) --map --list=image.map --scatter=$(LSCRIPT) +endif + # Capture final flags for locally built wolfSSL objects. WOLFSSL_CFLAGS:=$(CFLAGS) WOLFTPM_CFLAGS:=$(CFLAGS) diff --git a/test-app/wcs/user_settings.h b/test-app/wcs/user_settings.h index b09accff..095b748b 100644 --- a/test-app/wcs/user_settings.h +++ b/test-app/wcs/user_settings.h @@ -27,7 +27,8 @@ #include #include -int clock_gettime (clockid_t clock_id, struct timespec *tp); +struct timespec; +int clock_gettime (unsigned long clock_id, struct timespec *tp); #include "wolfboot/wc_secure.h" #define WOLFCRYPT_ONLY diff --git a/tools/armclang/armclang_stubs.c b/tools/armclang/armclang_stubs.c new file mode 100644 index 00000000..d561637c --- /dev/null +++ b/tools/armclang/armclang_stubs.c @@ -0,0 +1,182 @@ +/* armclang_stubs.c + * + * C library glue for building wolfBoot with the ARM Compiler for Embedded + * (USE_ARMCLANG=1). Only used by the WOLFCRYPT_TZ/PKCS11 configurations. + * + * - ARMCLANG_STUBS_MALLOC (secure image): heap allocator over the RAM_HEAP + * scatter region. The GNU build uses newlib-nano's malloc on top of the + * _sbrk hook in src/pkcs11_store.c; the ARM C library malloc cannot be + * used instead because it requires the C library runtime initialization + * (__rt_entry), which never runs since wolfBoot enters at isr_reset. + * + * - ARMCLANG_STUBS_DEAD_REFS: trap stubs for symbols that are only + * referenced from sections that GNU ld garbage-collects; armlink needs + * the definitions to exist before its own unused section elimination. + * + * This file is part of wolfBoot. + * + * wolfBoot 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. + * + * wolfBoot 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, see . + */ + +#ifdef ARMCLANG_STUBS_MALLOC + +#include +#include +#include + +/* Renamed to the RAM_HEAP region symbols by the -D options in the Makefile */ +extern unsigned int _start_heap; +extern unsigned int _heap_size; + +/* First-fit allocator with address-ordered free list and coalescing. + * Block header keeps the total block size (header included); blocks and + * payloads are 8-byte aligned. */ +struct heap_blk { + size_t size; + struct heap_blk *next; +}; + +#define HEAP_ALIGN(sz) (((sz) + 7U) & ~(size_t)7U) +#define HEAP_MIN_SPLIT (sizeof(struct heap_blk) + 8U) + +static struct heap_blk *heap_free_list; +static int heap_initialized; + +static void heap_init(void) +{ + heap_free_list = (struct heap_blk *)HEAP_ALIGN((uintptr_t)&_start_heap); + heap_free_list->size = (size_t)((uintptr_t)&_start_heap + + (uintptr_t)&_heap_size - (uintptr_t)heap_free_list) + & ~(size_t)7U; + heap_free_list->next = NULL; + heap_initialized = 1; +} + +void *malloc(size_t size) +{ + struct heap_blk *blk, **prev; + + if (!heap_initialized) + heap_init(); + if (size == 0) + return NULL; + size = HEAP_ALIGN(size) + sizeof(struct heap_blk); + + for (prev = &heap_free_list; (blk = *prev) != NULL; prev = &blk->next) { + if (blk->size < size) + continue; + if (blk->size - size >= HEAP_MIN_SPLIT) { + struct heap_blk *rest = (struct heap_blk *)((uint8_t *)blk + size); + rest->size = blk->size - size; + rest->next = blk->next; + blk->size = size; + *prev = rest; + } else { + *prev = blk->next; + } + blk->next = NULL; + return (uint8_t *)blk + sizeof(struct heap_blk); + } + return NULL; +} + +void free(void *ptr) +{ + struct heap_blk *blk, *cur, **prev; + + if (ptr == NULL) + return; + blk = (struct heap_blk *)((uint8_t *)ptr - sizeof(struct heap_blk)); + + /* Keep the free list sorted by address */ + for (prev = &heap_free_list; (cur = *prev) != NULL; prev = &cur->next) { + if (cur > blk) + break; + } + blk->next = cur; + *prev = blk; + + /* Coalesce with the next and previous blocks when adjacent */ + if (cur != NULL && (uint8_t *)blk + blk->size == (uint8_t *)cur) { + blk->size += cur->size; + blk->next = cur->next; + } + if (prev != &heap_free_list) { + struct heap_blk *before = (struct heap_blk *)((uint8_t *)prev + - offsetof(struct heap_blk, next)); + if ((uint8_t *)before + before->size == (uint8_t *)blk) { + before->size += blk->size; + before->next = blk->next; + } + } +} + +void *calloc(size_t nmemb, size_t size) +{ + void *ptr; + size_t total = nmemb * size; + + if (size != 0 && total / size != nmemb) + return NULL; + ptr = malloc(total); + if (ptr != NULL) + memset(ptr, 0, total); + return ptr; +} + +void *realloc(void *ptr, size_t size) +{ + void *new_ptr; + struct heap_blk *blk; + size_t old_payload; + + if (ptr == NULL) + return malloc(size); + if (size == 0) { + free(ptr); + return NULL; + } + blk = (struct heap_blk *)((uint8_t *)ptr - sizeof(struct heap_blk)); + old_payload = blk->size - sizeof(struct heap_blk); + if (old_payload >= size) + return ptr; + new_ptr = malloc(size); + if (new_ptr != NULL) { + memcpy(new_ptr, ptr, old_payload); + free(ptr); + } + return new_ptr; +} + +#endif /* ARMCLANG_STUBS_MALLOC */ + +#ifdef ARMCLANG_STUBS_DEAD_REFS + +/* Trap stubs for symbols that are referenced only from wolfSSL sections + * that are dead in the wolfBoot configurations (proven by the GNU builds, + * where the references would be a link error if the referencing sections + * survived garbage collection). armlink resolves all symbols before its + * unused section elimination, so the references need a definition; both + * the stubs and the referencing sections are eliminated from the image. + * The infinite loop makes any unexpected live call fail loudly. */ + +#define ARMCLANG_DEAD_REF_STUB(name) \ + void name(void); \ + void name(void) { while (1) ; } + +ARMCLANG_DEAD_REF_STUB(wc_CryptKey) +ARMCLANG_DEAD_REF_STUB(Base64_Encode) +ARMCLANG_DEAD_REF_STUB(wc_PKCS12_PBKDF) + +#endif /* ARMCLANG_STUBS_DEAD_REFS */ diff --git a/tools/armclang/objcopy.sh b/tools/armclang/objcopy.sh new file mode 100755 index 00000000..b9f94525 --- /dev/null +++ b/tools/armclang/objcopy.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# GNU objcopy command-line adapter over ARM fromelf, used when building with +# the ARM Compiler for Embedded (USE_ARMCLANG=1) so that the .bin/.hex/.srec +# Makefile recipes can be shared with the GNU toolchains. +# +# Only the invocation shapes used by the wolfBoot Makefiles are supported: +# objcopy [--gap-fill ] -O binary +# objcopy -O ihex +# objcopy -O srec +# +# The fromelf executable is taken from the FROMELF environment variable +# (default: fromelf). + +set -e + +FROMELF="${FROMELF:-fromelf}" +GAP_FILL= +FORMAT= +INPUT= +OUTPUT= + +while [ $# -gt 0 ]; do + case "$1" in + --gap-fill) + GAP_FILL="$2" + shift 2 + ;; + --gap-fill=*) + GAP_FILL="${1#*=}" + shift + ;; + -O) + FORMAT="$2" + shift 2 + ;; + -*) + echo "$0: unsupported objcopy option: $1" >&2 + exit 1 + ;; + *) + if [ -z "$INPUT" ]; then + INPUT="$1" + elif [ -z "$OUTPUT" ]; then + OUTPUT="$1" + else + echo "$0: too many arguments: $1" >&2 + exit 1 + fi + shift + ;; + esac +done + +if [ -z "$FORMAT" ] || [ -z "$INPUT" ] || [ -z "$OUTPUT" ]; then + echo "usage: $0 [--gap-fill ] -O binary|ihex|srec " >&2 + exit 1 +fi + +case "$FORMAT" in + binary) + # --bincombined merges all load regions into a single image, padding + # the gaps between them (GNU objcopy -O binary behavior) + set -- --bincombined + if [ -n "$GAP_FILL" ]; then + set -- "$@" "--bincombined_padding=1,$GAP_FILL" + fi + ;; + ihex) + set -- --i32combined + ;; + srec) + set -- --m32combined + ;; + *) + echo "$0: unsupported output format: $FORMAT" >&2 + exit 1 + ;; +esac + +exec "$FROMELF" "$@" --output="$OUTPUT" "$INPUT"