mirror of https://github.com/wolfSSL/wolfBoot.git
Add support for ARM Compiler for Embedded on stm32u5
parent
6b8702dd63
commit
6da07ffc3d
|
|
@ -133,6 +133,7 @@ tools/tpm/pcr_extend
|
|||
tools/tpm/policy_create
|
||||
tools/tpm/policy_sign
|
||||
config/*.ld
|
||||
config/*.sct
|
||||
test-lib
|
||||
lib-fs
|
||||
|
||||
|
|
|
|||
38
Makefile
38
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
|
||||
|
|
|
|||
39
arch.mk
39
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
15
options.mk
15
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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
#include <target.h>
|
||||
#include <time.h>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef ARMCLANG_STUBS_MALLOC
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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 */
|
||||
|
|
@ -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 <byte>] -O binary <in.elf> <out.bin>
|
||||
# objcopy -O ihex <in.elf> <out.hex>
|
||||
# objcopy -O srec <in.elf> <out.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 <byte>] -O binary|ihex|srec <in.elf> <out>" >&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"
|
||||
Loading…
Reference in New Issue