diff options
author | Jason Ekstrand <[email protected]> | 2017-10-12 20:58:43 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2017-10-12 21:47:06 -0700 |
commit | 3af1c829891a4530682bce113fdd512d4f2de3c6 (patch) | |
tree | 1b6170aa7fbc9ca22b332ff2892c9b7673a0c244 /src/compiler | |
parent | 6935440967e2beccf017c96e75387b9cb71833b4 (diff) |
compiler/blob: Add (reserve|overwrite)_(uint32|intptr) helpers
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 <[email protected]>
Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/blob.c | 27 | ||||
-rw-r--r-- | 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)); } @@ -205,6 +223,15 @@ blob_write_intptr(struct blob *blob, intptr_t 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) { return blob_write_bytes(blob, str, strlen(str) + 1); 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 @@ -139,6 +139,22 @@ 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. * * Writes data to an existing portion of the blob at an offset of \offset. @@ -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); * @@ -221,6 +236,23 @@ 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). * * \return True unless allocation failed. |