[coreboot-gerrit] New patch to review for coreboot: 85d3057 cbfstool: Add offset field to cbfstool directory's struct buffer

Sol Boucher (solb@chromium.org) gerrit at coreboot.org
Thu May 7 18:21:10 CEST 2015


Sol Boucher (solb at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10133

-gerrit

commit 85d3057cb4a6c32c76a8878b07698588671b425b
Author: Sol Boucher <solb at chromium.org>
Date:   Sun Apr 26 02:32:43 2015 -0700

    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 at chromium.org>
    Original-Commit-Id: 00c40982a21a91a488587dd3cead7109f3a30d98
    Original-Change-Id: Ie99839d36500d3270e4924a3477e076a6d27ffc8
    Original-Signed-off-by: Sol Boucher <solb at chromium.org>
---
 util/cbfstool/common.c |  5 ++++-
 util/cbfstool/common.h | 22 ++++++++++++++++++----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index e8c2ccc..cdc04f3 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 78ec40a..0cf6b6e 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;
 }



More information about the coreboot-gerrit mailing list