aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/libfdt/fdt_rw.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 2e49855d7cf8..9e7661509e9f 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -136,6 +136,14 @@ static int fdt_splice_struct_(void *fdt, void *p,
return 0;
}
+/* Must only be used to roll back in case of error */
+static void fdt_del_last_string_(void *fdt, const char *s)
+{
+ int newlen = strlen(s) + 1;
+
+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - newlen);
+}
+
static int fdt_splice_string_(void *fdt, int newlen)
{
void *p = (char *)fdt
@@ -149,7 +157,7 @@ static int fdt_splice_string_(void *fdt, int newlen)
return 0;
}
-static int fdt_find_add_string_(void *fdt, const char *s)
+static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
{
char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
const char *p;
@@ -157,6 +165,8 @@ static int fdt_find_add_string_(void *fdt, const char *s)
int len = strlen(s) + 1;
int err;
+ *allocated = 0;
+
p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
if (p)
/* found it */
@@ -167,6 +177,8 @@ static int fdt_find_add_string_(void *fdt, const char *s)
if (err)
return err;
+ *allocated = 1;
+
memcpy(new, s, len);
return (new - strtab);
}
@@ -225,11 +237,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
int nextoffset;
int namestroff;
int err;
+ int allocated;
if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
return nextoffset;
- namestroff = fdt_find_add_string_(fdt, name);
+ namestroff = fdt_find_add_string_(fdt, name, &allocated);
if (namestroff < 0)
return namestroff;
@@ -237,8 +250,11 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
proplen = sizeof(**prop) + FDT_TAGALIGN(len);
err = fdt_splice_struct_(fdt, *prop, 0, proplen);
- if (err)
+ if (err) {
+ if (allocated)
+ fdt_del_last_string_(fdt, name);
return err;
+ }
(*prop)->tag = cpu_to_fdt32(FDT_PROP);
(*prop)->nameoff = cpu_to_fdt32(namestroff);