summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-10-12 20:58:43 -0700
committerJason Ekstrand <[email protected]>2017-10-12 21:47:06 -0700
commit3af1c829891a4530682bce113fdd512d4f2de3c6 (patch)
tree1b6170aa7fbc9ca22b332ff2892c9b7673a0c244
parent6935440967e2beccf017c96e75387b9cb71833b4 (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]>
-rw-r--r--src/compiler/blob.c27
-rw-r--r--src/compiler/blob.h36
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.