[PATCH] powerpc: realloc & other bug fixes for flatdevtree
Mark A. Greer
mgreer at mvista.com
Fri Oct 13 13:57:23 EST 2006
Fix some bugs in flatdevtree.c:
- ft_reorder should update cxt->p.
- ft_make_space didn't follow realloc() semantics properly and
accessed freed memory.
- Fix some other bugs in ft_make_space.
- Don't set cxt->isordered in ft_open to force an ft_reorder the first
time ft_make_space is called. Required so that a malloc is used to
get a pointer that the the realloc in ft_make_space can validly use
later.
- Make ft_end_tree only call adjust_string_offsets if the offsets changed.
Signed-off-by: Mark A. Greer <mgreer at mvista.com>
---
flatdevtree.c | 22 +++++++++++++---------
1 files changed, 13 insertions(+), 9 deletions(-)
---
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
index 0d24f50..c76c194 100644
--- a/arch/powerpc/boot/flatdevtree.c
+++ b/arch/powerpc/boot/flatdevtree.c
@@ -176,6 +176,7 @@ static int ft_reorder(struct ft_cxt *cxt
memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
p - cxt->rgn[FT_STRUCT].start);
+ cxt->p += p - cxt->rgn[FT_STRUCT].start;
cxt->rgn[FT_STRUCT].start = p;
p = pend - cxt->rgn[FT_STRINGS].size;
@@ -281,7 +282,7 @@ static int ft_make_space(struct ft_cxt *
/* cast is to shut gcc up; we know nextra >= 0 */
if (tot < (unsigned int)nextra) {
/* have to reallocate */
- char *newp, *oldp, *new_start;
+ char *newp, *new_start;
int shift;
if (!cxt->realloc)
@@ -291,21 +292,18 @@ static int ft_make_space(struct ft_cxt *
if (!newp)
return 0;
cxt->max_size = size;
- oldp = (char *)cxt->bph;
- shift = newp - oldp;
+ shift = newp - (char *)cxt->bph;
- if (shift != 0) { /* realloc can return same addr */
+ if (shift) { /* realloc can return same addr */
cxt->bph = (struct boot_param_header *)newp;
- memmove(newp, oldp, sizeof(struct boot_param_header));
ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
shift);
- for (r = FT_RSVMAP; r <= FT_STRUCT; ++r) {
+ for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
new_start = cxt->rgn[r].start + shift;
- memmove(new_start, cxt->rgn[r].start,
- cxt->rgn[r].size);
cxt->rgn[r].start = new_start;
}
*pp += shift;
+ cxt->str_anchor += shift;
}
/* move strings up to the end */
@@ -561,7 +559,10 @@ int ft_open(struct ft_cxt *cxt, void *bl
cxt->rgn[FT_STRUCT].size = struct_size(cxt);
cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
+ /* Leave as '0' to force first ft_make_space call to do a ft_reorder
+ * and move dt to an area allocated by realloc.
cxt->isordered = ft_ordered(cxt);
+ */
cxt->p = cxt->rgn[FT_STRUCT].start;
cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
@@ -597,13 +598,16 @@ void ft_end_tree(struct ft_cxt *cxt)
struct boot_param_header *bph = cxt->bph;
char *p, *oldstr, *str, *endp;
unsigned long ssize;
+ int adj;
if (!cxt->isordered)
return; /* we haven't touched anything */
/* adjust string offsets */
oldstr = cxt->rgn[FT_STRINGS].start;
- adjust_string_offsets(cxt, cxt->str_anchor - oldstr);
+ adj = cxt->str_anchor - oldstr;
+ if (adj)
+ adjust_string_offsets(cxt, adj);
/* make strings end on 8-byte boundary */
ssize = cxt->rgn[FT_STRINGS].size;
More information about the Linuxppc-dev
mailing list