compiler/blob: Add (reserve|overwrite)_(uint32|intptr) helpers
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 13 Oct 2017 03:58:43 +0000 (20:58 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 13 Oct 2017 04:47:06 +0000 (21:47 -0700)
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 <nicolai.haehnle@amd.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/compiler/blob.c
src/compiler/blob.h

index 65c450e..5375c64 100644 (file)
@@ -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);
index 72a601d..62105c8 100644 (file)
@@ -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.