Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions makefile_conf/features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ ifneq ($(EIP7702_TEST_WHITELIST),0)
DEFINES += HAVE_EIP7702_WHITELIST_TEST
endif

ENABLE_DYNAMIC_ALLOC = 1
Comment thread
cedelavergne-ledger marked this conversation as resolved.
ifneq ($(DEBUG), 0)
MEMORY_PROFILING ?= 0
ifneq ($(MEMORY_PROFILING),0)
DEFINES += HAVE_MEMORY_PROFILING
endif
endif

# Check features incompatibilities
# --------------------------------
# NFTs
Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void coin_main(eth_libargs_t *args) {

io_init();
ui_idle();
mem_init();
app_mem_init();

// to prevent it from having a fixed value at boot
roll_challenge();
Expand Down
108 changes: 49 additions & 59 deletions src/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,58 @@

#include <stdint.h>
#include "mem.h"
#include "mem_alloc.h"
#include "os_print.h"

#define SIZE_MEM_BUFFER 10240
#define SIZE_MEM_BUFFER_MAIN 10240
#define SIZE_MEM_BUFFER_ALT 2048
#define SIZE_MEM_BUFFER (SIZE_MEM_BUFFER_MAIN + SIZE_MEM_BUFFER_ALT)

static uint8_t mem_buffer[SIZE_MEM_BUFFER];
static uint16_t mem_idx;
static uint16_t mem_rev_idx;
static uint8_t mem_buffer[SIZE_MEM_BUFFER] __attribute__((aligned(8)));
static uint16_t mem_legacy_idx;
static mem_ctx_t mem_ctx = NULL;

bool app_mem_init(void) {
mem_ctx = mem_init(mem_buffer, sizeof(mem_buffer));
return mem_ctx != NULL;
}

void *app_mem_alloc_impl(size_t size, const char *file, int line) {
void *ptr;
ptr = mem_alloc(mem_ctx, size);
#ifdef HAVE_MEMORY_PROFILING
PRINTF("==MP alloc;%u;0x%p;%s:%u\n", size, ptr, file, line);
#else
(void) file;
Comment thread
apaillier-ledger marked this conversation as resolved.
(void) line;
#endif
return ptr;
}

void app_mem_free_impl(void *ptr, const char *file, int line) {
#ifdef HAVE_MEMORY_PROFILING
PRINTF("==MP free;0x%p;%s:%u\n", ptr, file, line);
#else
(void) file;
(void) line;
#endif
mem_free(mem_ctx, ptr);
}

/**
* Initializes the memory buffer index
*/
void mem_init(void) {
mem_idx = 0;
mem_rev_idx = 0;
void mem_legacy_init(void) {
mem_legacy_idx = 0;
// initialize the new allocator to still be able to use it, just in case
mem_ctx = mem_init(mem_buffer + SIZE_MEM_BUFFER_MAIN, SIZE_MEM_BUFFER_ALT);
Comment thread
cedelavergne-ledger marked this conversation as resolved.
}

/**
* Resets the memory buffer index
*/
void mem_reset(void) {
mem_init();
void mem_legacy_reset(void) {
mem_legacy_init();
}

/**
Expand All @@ -40,74 +71,33 @@ void mem_reset(void) {
* @param[in] size Requested allocation size in bytes
* @return Allocated memory pointer; \ref NULL if not enough space left.
*/
void *mem_alloc(size_t size) {
void *mem_legacy_alloc(size_t size) {
size_t new_idx;
size_t free_size;

if (__builtin_add_overflow((size_t) mem_idx, size, &new_idx) ||
__builtin_sub_overflow(sizeof(mem_buffer), (size_t) mem_rev_idx, &free_size)) {
if (__builtin_add_overflow((size_t) mem_legacy_idx, size, &new_idx)) {
PRINTF("Error: overflow detected!\n");
return NULL;
}
// Buffer exceeded
if (new_idx > free_size) {
if (new_idx > SIZE_MEM_BUFFER_MAIN) {
Comment thread
cedelavergne-ledger marked this conversation as resolved.
PRINTF("Error: mem_alloc(%u) failed!\n", size);
return NULL;
}
mem_idx += size;
return &mem_buffer[mem_idx - size];
mem_legacy_idx += size;
return &mem_buffer[mem_legacy_idx - size];
}

/**
* De-allocates (pop) a chunk of memory buffer by a given size.
*
* @param[in] size Requested deallocation size in bytes
*/
void mem_dealloc(size_t size) {
void mem_legacy_dealloc(size_t size) {
// More than is already allocated
if (size > mem_idx) {
if (size > mem_legacy_idx) {
PRINTF("Warning: mem_dealloc(%u) with a value larger than allocated!\n", size);
mem_idx = 0;
} else {
mem_idx -= size;
}
}

/**
* Same as \ref mem_alloc but in reverse
*
* @param[in] size Requested allocation size in bytes
* @return Allocated memory pointer; \ref NULL if not enough space left.
*/
void *mem_rev_alloc(size_t size) {
size_t free_size;
size_t new_rev_idx;

if (__builtin_add_overflow((size_t) mem_rev_idx, size, &new_rev_idx) ||
__builtin_sub_overflow(sizeof(mem_buffer), new_rev_idx, &free_size)) {
PRINTF("Error: overflow detected!\n");
return NULL;
}
// Buffer exceeded
if (free_size < mem_idx) {
PRINTF("Error: mem_rev_alloc(%u) failed!\n", size);
return NULL;
}
mem_rev_idx += size;
return &mem_buffer[sizeof(mem_buffer) - mem_rev_idx];
}

/**
* Same as \ref mem_dealloc but in reverse
*
* @param[in] size Requested deallocation size in bytes
*/
void mem_rev_dealloc(size_t size) {
// More than is already allocated
if (size > mem_rev_idx) {
PRINTF("Warning: mem_rev_dealloc(%u) with a value larger than allocated!\n", size);
mem_rev_idx = 0;
mem_legacy_idx = 0;
} else {
mem_rev_idx -= size;
mem_legacy_idx -= size;
}
}
25 changes: 19 additions & 6 deletions src/mem.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
#pragma once

#include <stdbool.h>
#include <stdlib.h>

void mem_init(void);
void mem_reset(void);
void *mem_alloc(size_t size);
void mem_dealloc(size_t size);
void *mem_rev_alloc(size_t size);
void mem_rev_dealloc(size_t size);
#ifdef HAVE_MEMORY_PROFILING
#define MP_FILE __FILE__
#define MP_LINE __LINE__
#else
#define MP_FILE NULL
#define MP_LINE 0
#endif
#define app_mem_alloc(size) app_mem_alloc_impl(size, MP_FILE, MP_LINE)
#define app_mem_free(ptr) app_mem_free_impl(ptr, MP_FILE, MP_LINE)

bool app_mem_init(void);
void *app_mem_alloc_impl(size_t size, const char *file, int line);
void app_mem_free_impl(void *ptr, const char *file, int line);

void mem_legacy_init(void);
void mem_legacy_reset(void);
void *mem_legacy_alloc(size_t size);
void mem_legacy_dealloc(size_t size);
18 changes: 9 additions & 9 deletions src/mem_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* @return pointer to memory area or \ref NULL if the allocation failed
*/
char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
char *mem_legacy_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
char *mem_ptr;
uint32_t value_copy;
uint8_t size;
Expand All @@ -24,9 +24,9 @@ char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
size += 1;
}
// +1 for the null character
if ((mem_ptr = mem_alloc(sizeof(char) * (size + 1)))) {
if ((mem_ptr = mem_legacy_alloc(sizeof(char) * (size + 1)))) {
snprintf(mem_ptr, (size + 1), "%u", value);
mem_dealloc(sizeof(char)); // to skip the null character
mem_legacy_dealloc(sizeof(char)); // to skip the null character
if (length != NULL) {
*length = size;
}
Expand All @@ -40,12 +40,12 @@ char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
* @param[in] alignment given alignment value
* @return size of the padding required for proper alignment
*/
uint8_t mem_align(size_t alignment) {
uint8_t diff = (uintptr_t) mem_alloc(0) % alignment;
uint8_t mem_legacy_align(size_t alignment) {
uint8_t diff = (uintptr_t) mem_legacy_alloc(0) % alignment;

if (diff > 0) {
diff = alignment - diff;
mem_alloc(diff);
mem_legacy_alloc(diff);
}
return diff;
}
Expand All @@ -59,7 +59,7 @@ uint8_t mem_align(size_t alignment) {
*
* @return pointer to the memory area, \ref NULL if the allocation failed
*/
void *mem_alloc_and_align(size_t size, size_t alignment) {
mem_align(alignment);
return mem_alloc(size);
void *mem_legacy_alloc_and_align(size_t size, size_t alignment) {
mem_legacy_align(alignment);
return mem_legacy_alloc(size);
}
8 changes: 4 additions & 4 deletions src/mem_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <stdint.h>

#define MEM_ALLOC_AND_ALIGN_TYPE(type) mem_alloc_and_align(sizeof(type), __alignof__(type))
#define MEM_ALLOC_AND_ALIGN_TYPE(type) mem_legacy_alloc_and_align(sizeof(type), __alignof__(type))

char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars);
uint8_t mem_align(size_t alignment);
void *mem_alloc_and_align(size_t size, size_t alignment);
char *mem_legacy_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars);
uint8_t mem_legacy_align(size_t alignment);
void *mem_legacy_alloc_and_align(size_t size, size_t alignment);
38 changes: 16 additions & 22 deletions src/tlv_apdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@
static uint8_t *g_tlv_payload = NULL;
static uint16_t g_tlv_size = 0;
static uint16_t g_tlv_pos = 0;
static bool g_dyn = false;

static void reset_state(bool free) {
if ((g_tlv_payload != NULL) && free) {
mem_dealloc(g_tlv_size);
static void reset_state(void) {
if (g_tlv_payload != NULL) {
app_mem_free(g_tlv_payload);
g_tlv_payload = NULL;
}
g_tlv_payload = NULL;
g_tlv_size = 0;
g_tlv_pos = 0;
g_dyn = false;
}

bool tlv_from_apdu(bool first_chunk,
Expand All @@ -34,39 +32,35 @@ bool tlv_from_apdu(bool first_chunk,
g_tlv_size = read_u16_be(payload, offset);
offset += sizeof(g_tlv_size);
g_tlv_pos = 0;
if (g_tlv_payload != NULL) {
PRINTF("Error: remnants from an incomplete TLV payload!\n");
reset_state();
return false;
}

if (g_tlv_size > (lc - offset)) {
if (g_tlv_payload != NULL) {
PRINTF("Error: remnants from an incomplete TLV payload!\n");
reset_state(true);
if ((g_tlv_payload = app_mem_alloc(g_tlv_size)) == NULL) {
reset_state();
return false;
}

g_dyn = true;
g_tlv_payload = mem_alloc(g_tlv_size);
} else {
g_dyn = false;
}
}
if (g_dyn && (g_tlv_payload == NULL)) {
reset_state(true);
return false;
}
chunk_length = lc - offset;
if ((g_tlv_pos + chunk_length) > g_tlv_size) {
PRINTF("TLV payload bigger than expected!\n");
reset_state(true);
reset_state();
return false;
}

if (g_dyn) {
if (g_tlv_payload != NULL) {
memcpy(g_tlv_payload + g_tlv_pos, payload + offset, chunk_length);
}

g_tlv_pos += chunk_length;

if (g_tlv_pos == g_tlv_size) {
ret = (*handler)(g_dyn ? g_tlv_payload : &payload[offset], g_tlv_size, g_dyn);
reset_state(false); // already deallocated in the handler
ret = (*handler)((g_tlv_payload != NULL) ? g_tlv_payload : &payload[offset], g_tlv_size);
reset_state();
}
return ret;
}
2 changes: 1 addition & 1 deletion src/tlv_apdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdbool.h>
#include <stdint.h>

typedef bool (*f_tlv_payload_handler)(const uint8_t *payload, uint16_t size, bool to_free);
typedef bool (*f_tlv_payload_handler)(const uint8_t *payload, uint16_t size);

bool tlv_from_apdu(bool first_chunk,
uint8_t lc,
Expand Down
Loading
Loading