summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorSol Boucher <solb@chromium.org>2015-04-26 02:32:43 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-05-08 20:25:11 +0200
commit64c6cd73f3567e893a9cde7d08eb5505c1a19c62 (patch)
tree3d591fc8effec9e69a0702bff4e5a12e3126a895 /util
parent1a3349ffd1a8b9e0e656ea9ac889ce71860864c0 (diff)
downloadcoreboot-64c6cd73f3567e893a9cde7d08eb5505c1a19c62.tar.xz
cbfstool: Add offset field to cbfstool directory's struct buffer
This allows calls to buffer_delete() to work on a buffer that has been buffer_seek()ed or the buffer created by a buffer_splice(). The same information could also be useful for other purposes, such as writing slices back to a file at the offset they originally occupied. BUG=chromium:470407 TEST=Attempt to perform the following sequence of buffer actions, then run it through valgrind to check for memory errors: for (int pos = 0; pos <= 3; ++pos) { struct buffer seek_test; buffer_create(&seek_test, 3, "seek_test"); if (pos == 0) { buffer_delete(&seek_test); continue; } buffer_seek(&seek_test, 1); if (pos == 1) { buffer_delete(&seek_test); continue; } buffer_seek(&seek_test, 1); if (pos == 2) { buffer_delete(&seek_test); continue; } buffer_seek(&seek_test, 1); if (pos == 3) { buffer_delete(&seek_test); continue; } } for (int pos = 0; pos <= 14; ++pos) { struct buffer slice_test; buffer_create(&slice_test, 3, "slice_test"); if (pos == 0) { buffer_delete(&slice_test); continue; } struct buffer sliced_once; buffer_splice(&sliced_once, &slice_test, 1, 2); if (pos == 1) { buffer_delete(&slice_test); continue; } if (pos == 2) { buffer_delete(&sliced_once); continue; } struct buffer sliced_twice; buffer_splice(&sliced_twice, &sliced_once, 2, 1); if (pos == 3) { buffer_delete(&slice_test); continue; } if (pos == 4) { buffer_delete(&sliced_once); continue; } if (pos == 5) { buffer_delete(&sliced_twice); continue; } struct buffer sliced_same; buffer_splice(&sliced_same, &slice_test, 1, 1); if (pos == 6) { buffer_delete(&slice_test); continue; } if (pos == 7) { buffer_delete(&sliced_once); continue; } if (pos == 8) { buffer_delete(&sliced_twice); continue; } if (pos == 9) { buffer_delete(&sliced_same); continue; } struct buffer sliced_thrice; buffer_splice(&sliced_thrice, &sliced_twice, 1, 0); if (pos == 10) { buffer_delete(&slice_test); continue; } if (pos == 11) { buffer_delete(&sliced_once); continue; } if (pos == 12) { buffer_delete(&sliced_twice); continue; } if (pos == 13) { buffer_delete(&sliced_same); continue; } if (pos == 14) { buffer_delete(&sliced_thrice); continue; } } BRANCH=None Change-Id: Id67734654a62302c0de37746d8a978d49b240505 Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 00c40982a21a91a488587dd3cead7109f3a30d98 Original-Change-Id: Ie99839d36500d3270e4924a3477e076a6d27ffc8 Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/267467 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/10133 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'util')
-rw-r--r--util/cbfstool/common.c5
-rw-r--r--util/cbfstool/common.h22
2 files changed, 22 insertions, 5 deletions
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index e8c2ccc456..cdc04f333e 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -57,6 +57,7 @@ static off_t get_file_size(FILE *f)
int buffer_create(struct buffer *buffer, size_t size, const char *name)
{
buffer->name = strdup(name);
+ buffer->offset = 0;
buffer->size = size;
buffer->data = (char *)malloc(buffer->size);
if (!buffer->data) {
@@ -73,6 +74,7 @@ int buffer_from_file(struct buffer *buffer, const char *filename)
perror(filename);
return -1;
}
+ buffer->offset = 0;
buffer->size = get_file_size(fp);
if (buffer->size == -1u) {
fprintf(stderr, "could not determine size of %s\n", filename);
@@ -116,9 +118,10 @@ void buffer_delete(struct buffer *buffer)
buffer->name = NULL;
}
if (buffer->data) {
- free(buffer->data);
+ free(buffer->data - buffer->offset);
buffer->data = NULL;
}
+ buffer->offset = 0;
buffer->size = 0;
}
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 78ec40aaa1..0cf6b6e31f 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -59,6 +59,7 @@ static inline uint32_t align_up(uint32_t value, uint32_t align)
struct buffer {
char *name;
char *data;
+ size_t offset;
size_t size;
};
@@ -72,6 +73,9 @@ static inline size_t buffer_size(const struct buffer *b)
return b->size;
}
+/*
+ * Shrink a buffer toward the beginning of its previous space.
+ * Afterward, buffer_delete() remains the means of cleaning it up. */
static inline void buffer_set_size(struct buffer *b, size_t size)
{
b->size = size;
@@ -87,22 +91,32 @@ static inline void buffer_init(struct buffer *b, char *name, void *data,
}
/* Splice a buffer into another buffer. Note that it's up to the caller to
- * bounds check the offset and size. */
+ * bounds check the offset and size. The resulting buffer is backed by the same
+ * storage as the original, so although it is valid to buffer_delete() either
+ * one of them, doing so releases both simultaneously. */
static inline void buffer_splice(struct buffer *dest, const struct buffer *src,
size_t offset, size_t size)
{
- buffer_init(dest, src->name, src->data, src->size);
- dest->data += offset;
- buffer_set_size(dest, size);
+ dest->name = src->name;
+ dest->data = src->data + offset;
+ dest->offset = src->offset + offset;
+ dest->size = size;
}
+/*
+ * Shallow copy a buffer. To clean up the resources, buffer_delete()
+ * either one, but not both. */
static inline void buffer_clone(struct buffer *dest, const struct buffer *src)
{
buffer_splice(dest, src, 0, src->size);
}
+/*
+ * Shrink a buffer toward the end of its previous space.
+ * Afterward, buffer_delete() remains the means of cleaning it up. */
static inline void buffer_seek(struct buffer *b, size_t size)
{
+ b->offset += size;
b->size -= size;
b->data += size;
}