mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
buflib: refactor CRC checks as paranoia
Move CRC checking and updating behind a paranoia bit, like the other checks, so it can be enabled and disabled. Change-Id: Icff66c842cbd5af2d99aa91e6c40447a64e6d4b2
This commit is contained in:
parent
f82f3044a7
commit
dcc4e54b77
1 changed files with 54 additions and 24 deletions
|
|
@ -101,6 +101,7 @@
|
||||||
#define PARANOIA_CHECK_LENGTH (1 << 0)
|
#define PARANOIA_CHECK_LENGTH (1 << 0)
|
||||||
#define PARANOIA_CHECK_HANDLE (1 << 1)
|
#define PARANOIA_CHECK_HANDLE (1 << 1)
|
||||||
#define PARANOIA_CHECK_BLOCK_HANDLE (1 << 2)
|
#define PARANOIA_CHECK_BLOCK_HANDLE (1 << 2)
|
||||||
|
#define PARANOIA_CHECK_CRC (1 << 3)
|
||||||
/* Bitmask of enabled paranoia checks */
|
/* Bitmask of enabled paranoia checks */
|
||||||
#define BUFLIB_PARANOIA 0
|
#define BUFLIB_PARANOIA 0
|
||||||
|
|
||||||
|
|
@ -166,6 +167,16 @@ static void check_handle(struct buflib_context *ctx,
|
||||||
static void check_block_handle(struct buflib_context *ctx,
|
static void check_block_handle(struct buflib_context *ctx,
|
||||||
union buflib_data *block);
|
union buflib_data *block);
|
||||||
|
|
||||||
|
/* Update the block's CRC checksum if CRCs are enabled. */
|
||||||
|
static void update_block_crc(struct buflib_context *ctx,
|
||||||
|
union buflib_data *block,
|
||||||
|
union buflib_data *block_end);
|
||||||
|
|
||||||
|
/* Check the block's CRC if CRCs are enabled. */
|
||||||
|
static void check_block_crc(struct buflib_context *ctx,
|
||||||
|
union buflib_data *block,
|
||||||
|
union buflib_data *block_end);
|
||||||
|
|
||||||
/* Initialize buffer manager */
|
/* Initialize buffer manager */
|
||||||
void
|
void
|
||||||
buflib_init(struct buflib_context *ctx, void *buf, size_t size)
|
buflib_init(struct buflib_context *ctx, void *buf, size_t size)
|
||||||
|
|
@ -334,14 +345,6 @@ static inline bool handle_table_shrink(struct buflib_context *ctx)
|
||||||
return handle != old_last;
|
return handle != old_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t calc_block_crc(union buflib_data *block,
|
|
||||||
union buflib_data *block_end)
|
|
||||||
{
|
|
||||||
union buflib_data *crc_slot = &block_end[-bidx_CRC];
|
|
||||||
const size_t size = (crc_slot - block) * sizeof(*block);
|
|
||||||
return crc_32(block, size, 0xffffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If shift is non-zero, it represents the number of places to move
|
/* If shift is non-zero, it represents the number of places to move
|
||||||
* blocks in memory. Calculate the new address for this block,
|
* blocks in memory. Calculate the new address for this block,
|
||||||
* update its entry in the handle table, and then move its contents.
|
* update its entry in the handle table, and then move its contents.
|
||||||
|
|
@ -358,11 +361,7 @@ move_block(struct buflib_context* ctx, union buflib_data* block, int shift)
|
||||||
check_block_handle(ctx, block);
|
check_block_handle(ctx, block);
|
||||||
union buflib_data *h_entry = block[fidx_HANDLE].handle;
|
union buflib_data *h_entry = block[fidx_HANDLE].handle;
|
||||||
union buflib_data *block_end = h_entry_to_block_end(ctx, h_entry);
|
union buflib_data *block_end = h_entry_to_block_end(ctx, h_entry);
|
||||||
|
check_block_crc(ctx, block, block_end);
|
||||||
uint32_t crc = calc_block_crc(block, block_end);
|
|
||||||
if (crc != block_end[-bidx_CRC].crc)
|
|
||||||
buflib_panic(ctx, "buflib metadata corrupted, crc: 0x%08x, expected: 0x%08x",
|
|
||||||
(unsigned int)crc, (unsigned int)block_end[-bidx_CRC].crc);
|
|
||||||
|
|
||||||
if (!IS_MOVABLE(block))
|
if (!IS_MOVABLE(block))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -722,13 +721,12 @@ buffer_alloc:
|
||||||
size_t bsize = BUFLIB_NUM_FIELDS + name_len/sizeof(union buflib_data);
|
size_t bsize = BUFLIB_NUM_FIELDS + name_len/sizeof(union buflib_data);
|
||||||
union buflib_data *block_end = block + bsize;
|
union buflib_data *block_end = block + bsize;
|
||||||
block_end[-bidx_BSIZE].val = bsize;
|
block_end[-bidx_BSIZE].val = bsize;
|
||||||
block_end[-bidx_CRC].crc = calc_block_crc(block, block_end);
|
update_block_crc(ctx, block, block_end);
|
||||||
|
|
||||||
handle->alloc = (char*)&block_end[-bidx_USER];
|
handle->alloc = (char*)&block_end[-bidx_USER];
|
||||||
|
|
||||||
BDEBUGF("buflib_alloc_ex: size=%d handle=%p clb=%p crc=0x%0x name=\"%s\"\n",
|
BDEBUGF("buflib_alloc_ex: size=%d handle=%p clb=%p name=\"%s\"\n",
|
||||||
(unsigned int)size, (void *)handle, (void *)ops,
|
(unsigned int)size, (void *)handle, (void *)ops, name ? name : "");
|
||||||
(unsigned int)block_end[-bidx_CRC].crc, name ? name : "");
|
|
||||||
|
|
||||||
block += size;
|
block += size;
|
||||||
/* alloc_end must be kept current if we're taking the last block. */
|
/* alloc_end must be kept current if we're taking the last block. */
|
||||||
|
|
@ -1000,7 +998,7 @@ buflib_shrink(struct buflib_context* ctx, int handle, void* new_start, size_t ne
|
||||||
/* update crc of the metadata */
|
/* update crc of the metadata */
|
||||||
union buflib_data *new_h_entry = new_block[fidx_HANDLE].handle;
|
union buflib_data *new_h_entry = new_block[fidx_HANDLE].handle;
|
||||||
union buflib_data *new_block_end = h_entry_to_block_end(ctx, new_h_entry);
|
union buflib_data *new_block_end = h_entry_to_block_end(ctx, new_h_entry);
|
||||||
new_block_end[-bidx_CRC].crc = calc_block_crc(new_block, new_block_end);
|
update_block_crc(ctx, new_block, new_block_end);
|
||||||
|
|
||||||
/* Now deal with size changes that create free blocks after the allocation */
|
/* Now deal with size changes that create free blocks after the allocation */
|
||||||
if (old_next_block != new_next_block)
|
if (old_next_block != new_next_block)
|
||||||
|
|
@ -1055,12 +1053,7 @@ void buflib_check_valid(struct buflib_context *ctx)
|
||||||
check_block_handle(ctx, block);
|
check_block_handle(ctx, block);
|
||||||
union buflib_data *h_entry = block[fidx_HANDLE].handle;
|
union buflib_data *h_entry = block[fidx_HANDLE].handle;
|
||||||
union buflib_data *block_end = h_entry_to_block_end(ctx, h_entry);
|
union buflib_data *block_end = h_entry_to_block_end(ctx, h_entry);
|
||||||
uint32_t crc = calc_block_crc(block, block_end);
|
check_block_crc(ctx, block, block_end);
|
||||||
if (crc != block_end[-bidx_CRC].crc)
|
|
||||||
{
|
|
||||||
buflib_panic(ctx, "crc mismatch: 0x%08x, expected: 0x%08x",
|
|
||||||
(unsigned int)crc, (unsigned int)block_end[-bidx_CRC].crc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1217,3 +1210,40 @@ static void check_block_handle(struct buflib_context *ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t calc_block_crc(union buflib_data *block,
|
||||||
|
union buflib_data *block_end)
|
||||||
|
{
|
||||||
|
union buflib_data *crc_slot = &block_end[-bidx_CRC];
|
||||||
|
const size_t size = (crc_slot - block) * sizeof(*block);
|
||||||
|
return crc_32(block, size, 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_block_crc(struct buflib_context *ctx,
|
||||||
|
union buflib_data *block,
|
||||||
|
union buflib_data *block_end)
|
||||||
|
{
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
if (BUFLIB_PARANOIA & PARANOIA_CHECK_CRC)
|
||||||
|
{
|
||||||
|
block_end[-bidx_CRC].crc = calc_block_crc(block, block_end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_block_crc(struct buflib_context *ctx,
|
||||||
|
union buflib_data *block,
|
||||||
|
union buflib_data *block_end)
|
||||||
|
{
|
||||||
|
if (BUFLIB_PARANOIA & PARANOIA_CHECK_CRC)
|
||||||
|
{
|
||||||
|
uint32_t crc = calc_block_crc(block, block_end);
|
||||||
|
if (block_end[-bidx_CRC].crc != crc)
|
||||||
|
{
|
||||||
|
buflib_panic(ctx, "buflib crc mismatch [%p]=%08lx, got %08lx",
|
||||||
|
&block_end[-bidx_CRC],
|
||||||
|
(unsigned long)block_end[-bidx_CRC].crc,
|
||||||
|
(unsigned long)crc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue