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 <nicolai.haehnle@amd.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Jason Ekstrand
2017-10-12 20:58:43 -07:00
parent 6935440967
commit 3af1c82989
2 changed files with 61 additions and 2 deletions

View 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));
}
@@ -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)
{

View File

@@ -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).
*