From c89fc81fcff94f0d99ab34814d1a8a0405e239a5 Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jun 2020 12:41:18 +0200 Subject: [PATCH 1/9] Make BigBuf take dynamically the available space with a fixed (4K) stack --- armsrc/BigBuf.c | 38 ++++++++++++++++++++++++++------------ armsrc/BigBuf.h | 3 ++- armsrc/appmain.c | 6 +++--- common_arm/ldscript.common | 4 ++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 07f32239f..20e2e3e2d 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -14,34 +14,48 @@ #include "dbprint.h" #include "pm3_cmd.h" +extern uint8_t _stack_start, __bss_end__; + // BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. // Also used to hold various smaller buffers and the Mifare Emulator Memory. -// declare it as uint32_t to achieve alignment to 4 Byte boundary -static uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)]; +// We know that bss is aligned to 4 bytes. +static uint8_t* BigBuf = &__bss_end__; /* BigBuf memory layout: Pointer to highest available memory: BigBuf_hi - - high BIGBUF_SIZE + high BigBuf_size reserved = BigBuf_malloc() subtracts amount from BigBuf_hi, low 0x00 */ +static uint32_t BigBuf_size = 0; + // High memory mark -static uint16_t BigBuf_hi = BIGBUF_SIZE; +static uint32_t BigBuf_hi = 0; // pointer to the emulator memory. static uint8_t *emulator_memory = NULL; // trace related variables static uint32_t traceLen = 0; -static bool tracing = true; //todo static? +static bool tracing = true; + +// compute the available size for BigBuf +void BigBuf_initialize(void) { + BigBuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__; + BigBuf_hi = BigBuf_size; + traceLen = 0; +} // get the address of BigBuf uint8_t *BigBuf_get_addr(void) { return (uint8_t *)BigBuf; } +uint32_t BigBuf_get_size(void) { + return BigBuf_size; +} + // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done uint8_t *BigBuf_get_EM_addr(void) { // not yet allocated @@ -58,9 +72,9 @@ void BigBuf_Clear(void) { // clear ALL of BigBuf void BigBuf_Clear_ext(bool verbose) { - memset(BigBuf, 0, BIGBUF_SIZE); + memset(BigBuf, 0, BigBuf_size); if (verbose) - Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); + Dbprintf("Buffer cleared (%i bytes)", BigBuf_size); } void BigBuf_Clear_EM(void) { @@ -74,7 +88,7 @@ void BigBuf_Clear_keep_EM(void) { // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory // at the beginning of BigBuf is always for traces/samples uint8_t *BigBuf_malloc(uint16_t chunksize) { - if (BigBuf_hi - chunksize < 0) + if (BigBuf_hi < chunksize) return NULL; // no memory left chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 @@ -84,7 +98,7 @@ uint8_t *BigBuf_malloc(uint16_t chunksize) { // free ALL allocated chunks. The whole BigBuf is available for traces or samples again. void BigBuf_free(void) { - BigBuf_hi = BIGBUF_SIZE; + BigBuf_hi = BigBuf_size; emulator_memory = NULL; // shouldn't this empty BigBuf also? } @@ -94,14 +108,14 @@ void BigBuf_free_keep_EM(void) { if (emulator_memory != NULL) BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; else - BigBuf_hi = BIGBUF_SIZE; + BigBuf_hi = BigBuf_size; // shouldn't this empty BigBuf also? } void BigBuf_print_status(void) { DbpString(_BLUE_("Memory")); - Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); + Dbprintf(" BigBuf_size.............%d", BigBuf_size); Dbprintf(" Available memory........%d", BigBuf_hi); DbpString(_BLUE_("Tracing")); Dbprintf(" tracing ................%d", tracing); diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index ad967c4c7..60857e82a 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -14,7 +14,6 @@ #include "common.h" -#define BIGBUF_SIZE 40000 #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame #define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC @@ -23,8 +22,10 @@ #define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!? uint8_t *BigBuf_get_addr(void); +uint32_t BigBuf_get_size(void); uint8_t *BigBuf_get_EM_addr(void); uint16_t BigBuf_max_traceLen(void); +void BigBuf_initialize(void); void BigBuf_Clear(void); void BigBuf_Clear_ext(bool verbose); void BigBuf_Clear_keep_EM(void); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index fd5b4853c..96f133f49 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1659,12 +1659,12 @@ static void PacketReceived(PacketCommandNG *packet) { } // offset should not be over buffer - if (payload->offset >= BIGBUF_SIZE) { + if (payload->offset >= BigBuf_get_size()) { reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0); break; } // ensure len bytes copied wont go past end of bigbuf - uint16_t len = MIN(BIGBUF_SIZE - payload->offset, sizeof(payload->data)); + uint16_t len = MIN(BigBuf_get_size() - payload->offset, sizeof(payload->data)); uint8_t *mem = BigBuf_get_addr(); @@ -2054,7 +2054,7 @@ static void PacketReceived(PacketCommandNG *packet) { void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); - clear_trace(); + BigBuf_initialize(); if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ diff --git a/common_arm/ldscript.common b/common_arm/ldscript.common index 1be33df95..c94d0dcff 100644 --- a/common_arm/ldscript.common +++ b/common_arm/ldscript.common @@ -9,6 +9,8 @@ ms of the GNU GPL, version 2 or, ----------------------------------------------------------------------------- */ +stacksize = DEFINED(stacksize) ? stacksize : 4K; + /* AT91SAM7S256 has 256k Flash and 64k RAM */ /* AT91SAM7S512 has 512k Flash and 64k RAM */ /* boot space = 8192bytes (0x2000) */ @@ -19,6 +21,7 @@ MEMORY bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */ + stack : ORIGIN = 0x00200000 + 64K - 4K - 0x20, LENGTH = stacksize /* Stack */ commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */ } @@ -29,4 +32,5 @@ _bootrom_start = ORIGIN(bootphase1); _bootrom_end = ORIGIN(bootphase2) + LENGTH(bootphase2); _flash_start = ORIGIN(bootphase1); _flash_end = ORIGIN(osimage) + LENGTH(osimage); +_stack_start = ORIGIN(stack); _stack_end = ORIGIN(ram) + LENGTH(ram) - 8; From cba76ca1674dc20a1b8704c48e4e4f6bfe613a9f Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jun 2020 14:06:45 +0200 Subject: [PATCH 2/9] Fix stacksize & make common area size a variable --- common_arm/ldscript.common | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/common_arm/ldscript.common b/common_arm/ldscript.common index c94d0dcff..8400f740a 100644 --- a/common_arm/ldscript.common +++ b/common_arm/ldscript.common @@ -10,6 +10,7 @@ ms of the GNU GPL, version 2 or, */ stacksize = DEFINED(stacksize) ? stacksize : 4K; +commonareasize = 0x20; /* AT91SAM7S256 has 256k Flash and 64k RAM */ /* AT91SAM7S512 has 512k Flash and 64k RAM */ @@ -17,12 +18,12 @@ stacksize = DEFINED(stacksize) ? stacksize : 4K; /* osimage space = (512k - 0x2000 == 524288 - 8192 == 516096bytes == 0x7E000 ) */ MEMORY { - bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ - bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ - osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ - ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */ - stack : ORIGIN = 0x00200000 + 64K - 4K - 0x20, LENGTH = stacksize /* Stack */ - commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */ + bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ + bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ + osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ + ram : ORIGIN = 0x00200000, LENGTH = 64K - commonareasize /* RAM, minus small common area */ + stack : ORIGIN = 0x00200000 + 64K - stacksize - commonareasize, LENGTH = stacksize /* Stack */ + commonarea : ORIGIN = 0x00200000 + 64K - commonareasize, LENGTH = commonareasize /* Communication between bootloader and main OS */ } /* Export some information that can be used from within the firmware */ From df4bdc89ea9499e2ac0d2389e17ec546d62f0bf3 Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jun 2020 19:06:40 +0200 Subject: [PATCH 3/9] Fix BIGBUF_SIZE used in #WITH_FLASH --- armsrc/mifarecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ef1a15864..9e19cbc53 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1392,7 +1392,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da // limit size of availlable for keys in bigbuff // a key is 6bytes - uint16_t key_mem_available = MIN(BIGBUF_SIZE, keyCount * 6); + uint16_t key_mem_available = MIN(BigBuf_get_size(), keyCount * 6); keyCount = key_mem_available / 6; From c11c7ab54533aae7f2640225b8137b7f8ba45de2 Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jun 2020 23:03:03 +0200 Subject: [PATCH 4/9] Add support for client getting bigbufsize --- armsrc/appmain.c | 9 +++++++++ client/src/cmddata.c | 14 ++++++++------ client/src/cmddata.h | 1 - client/src/cmdlft55xx.c | 2 +- include/pm3_cmd.h | 3 ++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 96f133f49..7ba6158c7 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -392,6 +392,7 @@ static void SendCapabilities(void) { capabilities.version = CAPABILITIES_VERSION; capabilities.via_fpc = g_reply_via_fpc; capabilities.via_usb = g_reply_via_usb; + capabilities.bigbuf_size = BigBuf_get_size(); capabilities.baudrate = 0; // no real baudrate for USB-CDC #ifdef WITH_FPC_USART if (g_reply_via_fpc) @@ -2051,11 +2052,15 @@ static void PacketReceived(PacketCommandNG *packet) { } } +extern uint32_t _stack_start; + void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); BigBuf_initialize(); + _stack_start = 0xdeadbeef; + if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area)); @@ -2121,6 +2126,10 @@ void __attribute__((noreturn)) AppMain(void) { for (;;) { WDT_HIT(); + if (_stack_start != 0xdeadbeef) { + Dbprintf("Stack overflow detected! Please increase stack size."); + } + // Check if there is a packet available PacketCommandNG rx; memset(&rx.data, 0, sizeof(rx.data)); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 326e0d457..99908d1ea 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -567,7 +567,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &); - if (!maxLen) maxLen = BIGBUF_SIZE; + if (!maxLen) maxLen = pm3_capabilities.bigbuf_size; if (invert != 0 && invert != 1) { PrintAndLogEx(WARNING, "Invalid argument: %s", Cmd); @@ -1517,16 +1517,18 @@ static int CmdHexsamples(const char *Cmd) { uint32_t offset = 0; char string_buf[25]; char *string_ptr = string_buf; - uint8_t got[BIGBUF_SIZE]; + uint8_t got[512*1024]; sscanf(Cmd, "%u %u", &requested, &offset); /* if no args send something */ if (requested == 0) requested = 8; + if (requested > pm3_capabilities.bigbuf_size) + requested = pm3_capabilities.bigbuf_size; if (offset + requested > sizeof(got)) { - PrintAndLogEx(NORMAL, "Tried to read past end of buffer, + > %d", BIGBUF_SIZE); + PrintAndLogEx(NORMAL, "Tried to read past end of buffer, + > %d", pm3_capabilities.bigbuf_size); return PM3_EINVARG; } @@ -1595,10 +1597,10 @@ int getSamples(uint32_t n, bool verbose) { // we don't have to worry about remaining trash // in the last byte in case the bits-per-sample // does not line up on byte boundaries - uint8_t got[BIGBUF_SIZE - 1] = { 0 }; + uint8_t got[512*1024] = { 0 }; - if (n == 0 || n > sizeof(got)) - n = sizeof(got); + if (n == 0 || n > pm3_capabilities.bigbuf_size) + n = pm3_capabilities.bigbuf_size; if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") " bytes from device memory", n); diff --git a/client/src/cmddata.h b/client/src/cmddata.h index a7a69e430..abef8fde8 100644 --- a/client/src/cmddata.h +++ b/client/src/cmddata.h @@ -79,7 +79,6 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold); int demodIdteck(void); #define MAX_DEMOD_BUF_LEN (1024*128) -#define BIGBUF_SIZE 40000 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern size_t DemodBufferLen; diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 6294ffef6..b2f048665 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2837,7 +2837,7 @@ static int CmdResetRead(const char *Cmd) { if (resp.status == PM3_SUCCESS) { - uint16_t gotsize = BIGBUF_SIZE - 1; + uint16_t gotsize = pm3_capabilities.bigbuf_size - 1; uint8_t *got = calloc(gotsize, sizeof(uint8_t)); if (got == NULL) { PrintAndLogEx(WARNING, "failed to allocate memory"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index b6de6f292..3cafb9df1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -175,6 +175,7 @@ typedef struct { typedef struct { uint8_t version; uint32_t baudrate; + uint32_t bigbuf_size; bool via_fpc : 1; bool via_usb : 1; // rdv4 @@ -203,7 +204,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 4 +#define CAPABILITIES_VERSION 5 extern capabilities_t pm3_capabilities; // For CMD_LF_T55XX_WRITEBL From 3b757a627bed6dfab479651c438fd93099decd4e Mon Sep 17 00:00:00 2001 From: slurdge Date: Wed, 10 Jun 2020 23:03:17 +0200 Subject: [PATCH 5/9] Increase stack to 5KiB --- common_arm/ldscript.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_arm/ldscript.common b/common_arm/ldscript.common index 8400f740a..9e53d8436 100644 --- a/common_arm/ldscript.common +++ b/common_arm/ldscript.common @@ -9,7 +9,7 @@ ms of the GNU GPL, version 2 or, ----------------------------------------------------------------------------- */ -stacksize = DEFINED(stacksize) ? stacksize : 4K; +stacksize = DEFINED(stacksize) ? stacksize : 5K; commonareasize = 0x20; /* AT91SAM7S256 has 256k Flash and 64k RAM */ From 73b6138f7f53d441bc18c538e8587de425a3165d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 11 Jun 2020 01:18:50 +0200 Subject: [PATCH 6/9] cmddata: Adjust bigbuf size on client side as before but fix 1b overflow --- client/src/cmddata.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 99908d1ea..007c32c8a 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1517,7 +1517,7 @@ static int CmdHexsamples(const char *Cmd) { uint32_t offset = 0; char string_buf[25]; char *string_ptr = string_buf; - uint8_t got[512*1024]; + uint8_t got[pm3_capabilities.bigbuf_size]; sscanf(Cmd, "%u %u", &requested, &offset); @@ -1597,10 +1597,11 @@ int getSamples(uint32_t n, bool verbose) { // we don't have to worry about remaining trash // in the last byte in case the bits-per-sample // does not line up on byte boundaries - uint8_t got[512*1024] = { 0 }; + uint8_t got[pm3_capabilities.bigbuf_size - 1]; + memset(got, 0x00, sizeof(got)); - if (n == 0 || n > pm3_capabilities.bigbuf_size) - n = pm3_capabilities.bigbuf_size; + if (n == 0 || n > pm3_capabilities.bigbuf_size - 1) + n = pm3_capabilities.bigbuf_size - 1; if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") " bytes from device memory", n); From 35857f535d42b8e42f40675abea1de31e5ff16aa Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 11 Jun 2020 11:14:53 +0200 Subject: [PATCH 7/9] Compute the max usage --- armsrc/appmain.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7ba6158c7..b9225bed5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -71,6 +71,8 @@ uint8_t ToSend[TOSEND_BUFFER_SIZE]; int ToSendMax = -1; +extern uint32_t _stack_start, _stack_end; + static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); @@ -359,6 +361,12 @@ static void SendStatus(void) { #endif printConnSpeed(); DbpString(_BLUE_("Various")); + for (uint32_t *p = &_stack_start; ; ++p) { + if (*p != 0xdeadbeef) { + Dbprintf(" Max stack usage.........%d", (&_stack_end - p)*4); + break; + } + } Dbprintf(" DBGLEVEL................%d", DBGLEVEL); Dbprintf(" ToSendMax...............%d", ToSendMax); Dbprintf(" ToSendBit...............%d", ToSendBit); @@ -2052,15 +2060,15 @@ static void PacketReceived(PacketCommandNG *packet) { } } -extern uint32_t _stack_start; - void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); BigBuf_initialize(); - _stack_start = 0xdeadbeef; - + for (uint32_t * p = &_stack_start; p < (&_stack_end) - 0x80; ++p) { + *p = 0xdeadbeef; + } + if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area)); From 53c5456f7ac7607b4eff516d559f8aae013608c8 Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 11 Jun 2020 11:35:15 +0200 Subject: [PATCH 8/9] Fix ptr arithmetic hopefully --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b9225bed5..a4b5fc6a7 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2065,7 +2065,7 @@ void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); BigBuf_initialize(); - for (uint32_t * p = &_stack_start; p < (&_stack_end) - 0x80; ++p) { + for (uint32_t * p = &_stack_start; p < ((uint32_t *)(uintptr_t)&_stack_end) - 0x80; ++p) { *p = 0xdeadbeef; } From 05ed3f7018207b350887f7a4ce17a558e994fdad Mon Sep 17 00:00:00 2001 From: slurdge Date: Thu, 11 Jun 2020 12:12:20 +0200 Subject: [PATCH 9/9] Second try to fix appveyor --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a4b5fc6a7..28e2d9625 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2065,7 +2065,7 @@ void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); BigBuf_initialize(); - for (uint32_t * p = &_stack_start; p < ((uint32_t *)(uintptr_t)&_stack_end) - 0x80; ++p) { + for (uint32_t * p = &_stack_start; p < (uint32_t *)((uintptr_t)&_stack_end - 0x200); ++p) { *p = 0xdeadbeef; }