From 3af1c829891a4530682bce113fdd512d4f2de3c6 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 12 Oct 2017 20:58:43 -0700 Subject: [PATCH] compiler/blob: Add (reserve|overwrite)_(uint32|intptr) helpers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These helpers not only call blob_reserve_bytes but also make sure that the blob is properly aligned as if blob_write_* were called. Reviewed-by: Nicolai Hähnle Reviewed-by: Jordan Justen --- src/compiler/blob.c | 27 +++++++++++++++++++++++++++ src/compiler/blob.h | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/compiler/blob.c b/src/compiler/blob.c index 65c450ee979..5375c647b02 100644 --- a/src/compiler/blob.c +++ b/src/compiler/blob.c @@ -172,6 +172,20 @@ blob_reserve_bytes(struct blob *blob, size_t to_write) return ret; } +ssize_t +blob_reserve_uint32(struct blob *blob) +{ + align_blob(blob, sizeof(uint32_t)); + return blob_reserve_bytes(blob, sizeof(uint32_t)); +} + +ssize_t +blob_reserve_intptr(struct blob *blob) +{ + align_blob(blob, sizeof(intptr_t)); + return blob_reserve_bytes(blob, sizeof(intptr_t)); +} + bool blob_write_uint32(struct blob *blob, uint32_t value) { @@ -180,11 +194,15 @@ blob_write_uint32(struct blob *blob, uint32_t value) return blob_write_bytes(blob, &value, sizeof(value)); } +#define ASSERT_ALIGNED(_offset, _align) \ + assert(ALIGN((_offset), (_align)) == (_offset)) + bool blob_overwrite_uint32 (struct blob *blob, size_t offset, uint32_t value) { + ASSERT_ALIGNED(offset, sizeof(value)); return blob_overwrite_bytes(blob, offset, &value, sizeof(value)); } @@ -204,6 +222,15 @@ blob_write_intptr(struct blob *blob, intptr_t value) return blob_write_bytes(blob, &value, sizeof(value)); } +bool +blob_overwrite_intptr (struct blob *blob, + size_t offset, + intptr_t value) +{ + ASSERT_ALIGNED(offset, sizeof(value)); + return blob_overwrite_bytes(blob, offset, &value, sizeof(value)); +} + bool blob_write_string(struct blob *blob, const char *str) { diff --git a/src/compiler/blob.h b/src/compiler/blob.h index 72a601d5345..62105c8ebd9 100644 --- a/src/compiler/blob.h +++ b/src/compiler/blob.h @@ -138,6 +138,22 @@ blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write); ssize_t blob_reserve_bytes(struct blob *blob, size_t to_write); +/** + * Similar to \sa blob_reserve_bytes, but only reserves an uint32_t worth of + * space. Note that this must be used if later reading with \sa + * blob_read_uint32, since it aligns the offset correctly. + */ +ssize_t +blob_reserve_uint32(struct blob *blob); + +/** + * Similar to \sa blob_reserve_bytes, but only reserves an intptr_t worth of + * space. Note that this must be used if later reading with \sa + * blob_read_intptr, since it aligns the offset correctly. + */ +ssize_t +blob_reserve_intptr(struct blob *blob); + /** * Overwrite some data previously written to the blob. * @@ -181,8 +197,7 @@ blob_write_uint32(struct blob *blob, uint32_t value); * * size_t offset; * - * offset = blob->size; - * blob_write_uint32 (blob, 0); // placeholder + * offset = blob_reserve_uint32(blob); * ... various blob write calls, writing N items ... * blob_overwrite_uint32 (blob, offset, N); * @@ -220,6 +235,23 @@ blob_write_uint64(struct blob *blob, uint64_t value); bool blob_write_intptr(struct blob *blob, intptr_t value); +/** + * Overwrite an intptr_t previously written to the blob. + * + * Writes a intptr_t value to an existing portion of the blob at an offset of + * \offset. This data range must have previously been written to the blob by + * one of the blob_write_* calls. + * + * For example usage, see blob_overwrite_uint32 + * + * \return True unless the requested position or position+to_write lie outside + * the current blob's size. + */ +bool +blob_overwrite_intptr(struct blob *blob, + size_t offset, + intptr_t value); + /** * Add a NULL-terminated string to a blob, (including the NULL terminator). * -- 2.30.2