[Crosstoolchain-logs] [device-tree-compiler] 102/198: libfdt: Add function to resize the buffer for a sequential write tree

Hector Oron zumbi at moszumanska.debian.org
Thu Dec 8 17:06:58 UTC 2016


This is an automated email from the git hooks/post-receive script.

zumbi pushed a commit to branch upstream/1.4.x
in repository device-tree-compiler.

commit 79eebb23dbf1f6eeff1789cd0d6f1c1fe620a487
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Sat Oct 26 00:17:37 2013 +1100

    libfdt: Add function to resize the buffer for a sequential write tree
    
    At present, when using sequential write mode, there's no straightforward
    means of resizing the buffer the fdt is being built into.  This patch
    adds an fdt_resize() function for this purpose.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
 libfdt/fdt_sw.c    | 32 +++++++++++++++++++++
 libfdt/libfdt.h    |  1 +
 tests/run_tests.sh |  8 ++++++
 tests/sw_tree1.c   | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 114 insertions(+), 8 deletions(-)

diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
index f422754..6a80485 100644
--- a/libfdt/fdt_sw.c
+++ b/libfdt/fdt_sw.c
@@ -107,6 +107,38 @@ int fdt_create(void *buf, int bufsize)
 	return 0;
 }
 
+int fdt_resize(void *fdt, void *buf, int bufsize)
+{
+	size_t headsize, tailsize;
+	char *oldtail, *newtail;
+
+	FDT_SW_CHECK_HEADER(fdt);
+
+	headsize = fdt_off_dt_struct(fdt);
+	tailsize = fdt_size_dt_strings(fdt);
+
+	if ((headsize + tailsize) > bufsize)
+		return -FDT_ERR_NOSPACE;
+
+	oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
+	newtail = (char *)buf + bufsize - tailsize;
+
+	/* Two cases to avoid clobbering data if the old and new
+	 * buffers partially overlap */
+	if (buf <= fdt) {
+		memmove(buf, fdt, headsize);
+		memmove(newtail, oldtail, tailsize);
+	} else {
+		memmove(newtail, oldtail, tailsize);
+		memmove(buf, fdt, headsize);
+	}
+
+	fdt_set_off_dt_strings(buf, bufsize);
+	fdt_set_totalsize(buf, bufsize);
+
+	return 0;
+}
+
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
 {
 	struct fdt_reserve_entry *re;
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index 02baa84..c4d5a91 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -1023,6 +1023,7 @@ int fdt_nop_node(void *fdt, int nodeoffset);
 /**********************************************************************/
 
 int fdt_create(void *buf, int bufsize);
+int fdt_resize(void *fdt, void *buf, int bufsize);
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
 int fdt_finish_reservemap(void *fdt);
 int fdt_begin_node(void *fdt, const char *name);
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index c0a136b..a8905a7 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -190,6 +190,14 @@ libfdt_tests () {
     tree1_tests unfinished_tree1.test.dtb
     run_test dtbs_equal_ordered test_tree1.dtb sw_tree1.test.dtb
 
+    # Resizing tests
+    for mode in resize realloc; do
+	run_test sw_tree1 $mode
+	tree1_tests sw_tree1.test.dtb
+	tree1_tests unfinished_tree1.test.dtb
+	run_test dtbs_equal_ordered test_tree1.dtb sw_tree1.test.dtb
+    done
+
     # fdt_move tests
     for tree in test_tree1.dtb sw_tree1.test.dtb unfinished_tree1.test.dtb; do
 	rm -f moved.$tree shunted.$tree deshunted.$tree
diff --git a/tests/sw_tree1.c b/tests/sw_tree1.c
index e9ea7e7..de00707 100644
--- a/tests/sw_tree1.c
+++ b/tests/sw_tree1.c
@@ -31,22 +31,87 @@
 
 #define SPACE	65536
 
-#define CHECK(code) \
-	{ \
-		err = (code); \
-		if (err) \
-			FAIL(#code ": %s", fdt_strerror(err)); \
+static enum {
+	FIXED = 0,
+	RESIZE,
+	REALLOC,
+} alloc_mode;
+
+static void realloc_fdt(void **fdt, size_t *size)
+{
+	switch (alloc_mode) {
+	case FIXED:
+		if (!(*fdt))
+			fdt = xmalloc(*size);
+		else
+			FAIL("Ran out of space");
+		return;
+
+	case RESIZE:
+		if (!(*fdt)) {
+			fdt = xmalloc(SPACE);
+		} else if (*size < SPACE) {
+			*size += 1;
+			fdt_resize(*fdt, *fdt, *size);
+		} else {
+			FAIL("Ran out of space");
+		}		
+		return;
+
+	case REALLOC:
+		*size += 1;
+		*fdt = xrealloc(*fdt, *size);
+		fdt_resize(*fdt, *fdt, *size);
+		return;
+
+	default:
+		CONFIG("Bad allocation mode");
 	}
+}
+
+#define CHECK(code) \
+	do {			      \
+		err = (code);			     \
+		if (err == -FDT_ERR_NOSPACE)			\
+			realloc_fdt(&fdt, &size);			\
+		else if (err)						\
+			FAIL(#code ": %s", fdt_strerror(err));		\
+	} while (err != 0)
 
 int main(int argc, char *argv[])
 {
-	void *fdt;
+	void *fdt = NULL;
+	size_t size;
 	int err;
 
 	test_init(argc, argv);
 
-	fdt = xmalloc(SPACE);
-	CHECK(fdt_create(fdt, SPACE));
+	if (argc == 1) {
+		alloc_mode = FIXED;
+		size = SPACE;
+	} else if (argc == 2) {
+		if (streq(argv[1], "resize")) {
+			alloc_mode = REALLOC;
+			size = 0;
+		} else if (streq(argv[1], "realloc")) {
+			alloc_mode = REALLOC;
+			size = 0;
+		} else {
+			char *endp;
+
+			size = strtoul(argv[1], &endp, 0);
+			if (*endp == '\0')
+				alloc_mode = FIXED;
+			else 
+				CONFIG("Bad allocation mode \"%s\" specified",
+				       argv[1]);
+		}
+	}
+
+	realloc_fdt(&fdt, &size);
+	
+	fdt = xmalloc(size);
+	CHECK(fdt_create(fdt, size));
 
 	CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1));
 	CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_2, TEST_SIZE_2));

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/crosstoolchain/device-tree-compiler.git



More information about the Crosstoolchain-logs mailing list