diff --git a/src/delta.c b/src/delta.c index 6ab6aa6b..3acb3e12 100644 --- a/src/delta.c +++ b/src/delta.c @@ -50,10 +50,6 @@ struct BLOCK_HDR_PACKED block_hdr { #define ext_flash_check_read ext_flash_read #endif -#ifndef WOLFBOOT_SECTOR_SIZE -# define WOLFBOOT_SECTOR_SIZE 0x1000 -#endif - int wb_patch_init(WB_PATCH_CTX *bm, uint8_t *src, uint32_t ssz, uint8_t *patch, uint32_t psz) { @@ -223,20 +219,31 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len) break; if ((memcmp(pa, (ctx->src_b + ctx->off_b), BLOCK_HDR_SIZE) == 0)) { uint32_t b_start; + /* Identical areas of BLOCK_HDR_SIZE bytes match between the images. + * initialize match_len; blk_start is the relative offset within + * the src image. + */ match_len = BLOCK_HDR_SIZE; blk_start = pa - ctx->src_a; b_start = ctx->off_b; pa+= BLOCK_HDR_SIZE; ctx->off_b += BLOCK_HDR_SIZE; while (*pa == *(ctx->src_b + ctx->off_b)) { - match_len++; - pa++; - ctx->off_b++; - if ((uint32_t)(pa - ctx->src_a) >= ctx->size_a) - break; - if ((b_start / WOLFBOOT_SECTOR_SIZE) < (ctx->off_b / WOLFBOOT_SECTOR_SIZE)) { + /* Extend matching block if possible, as long as the + * identical sequence continues. + */ + if ((uint32_t)(pa + 1 - ctx->src_a) >= ctx->size_a) { + /* Stop matching if the source image size limit is hit. */ break; } + if ((b_start / WOLFBOOT_SECTOR_SIZE) < ((ctx->off_b + 1) / WOLFBOOT_SECTOR_SIZE)) { + /* Stop matching when the sector bound is hit. */ + break; + } + /* Increase match len, test next byte */ + pa++; + ctx->off_b++; + match_len++; } hdr.esc = ESC; hdr.off[0] = ((blk_start >> 16) & 0x000000FF); @@ -256,23 +263,42 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len) uint32_t pb_end = page_start * WOLFBOOT_SECTOR_SIZE; pb = ctx->src_b; while (((uint32_t)(pb - ctx->src_b) < pb_end) && (p_off < len)) { + /* Check image boundary */ if ((ctx->size_b - ctx->off_b) < BLOCK_HDR_SIZE) break; if ((uint32_t)(ctx->size_b - (pb - ctx->src_b)) < BLOCK_HDR_SIZE) break; + + /* Don't try matching backwards if the distance between the two + * blocks is smaller than one sector. + */ if (WOLFBOOT_SECTOR_SIZE > (pb - ctx->src_b) - (page_start * WOLFBOOT_SECTOR_SIZE)) break; + if ((memcmp(pb, (ctx->src_b + ctx->off_b), BLOCK_HDR_SIZE) == 0)) { + /* A match was found between the current pointer and a + * previously patched area in the resulting image. + * Initialize match_len and set the blk_start to the beginning + * of the matching area in the image. + */ match_len = BLOCK_HDR_SIZE; blk_start = pb - ctx->src_b; pb+= BLOCK_HDR_SIZE; ctx->off_b += BLOCK_HDR_SIZE; while (*pb == *(ctx->src_b + ctx->off_b)) { - match_len++; + /* Extend match as long as the areas have the + * same content. Block skipping in this case is + * not a problem since the distance between the patched + * area and the area to patch is always larger than one + * block size. + */ pb++; - ctx->off_b++; - if ((uint32_t)(pb - ctx->src_b) >= pb_end) + if ((uint32_t)(pb - ctx->src_b) >= pb_end) { + pb--; break; + } + match_len++; + ctx->off_b++; } hdr.esc = ESC; hdr.off[0] = ((blk_start >> 16) & 0x000000FF); diff --git a/tools/delta/bmdiff.c b/tools/delta/bmdiff.c index 59e2e456..ad11d3fd 100644 --- a/tools/delta/bmdiff.c +++ b/tools/delta/bmdiff.c @@ -23,7 +23,6 @@ */ #define MODE_DIFF 0 #define MODE_PATCH 1 -#define BUF_SIZE 4096 #include #include #include @@ -36,7 +35,7 @@ #include "delta.h" #define MAX_SRC_SIZE (1 << 24) -#define PATCH_BLOCK_SIZE 4096 +#define PATCH_BLOCK_SIZE WOLFBOOT_SECTOR_SIZE int main(int argc, char *argv[]) {