diff --git a/checks.c b/checks.c index c8a099e..cacb5b4 100644 --- a/checks.c +++ b/checks.c @@ -243,26 +243,22 @@ NODE_CHECK(explicit_phandles, NULL, ERROR); static void fixup_phandle_references(struct check *c, struct node *dt, struct node *node, struct property *prop) { - struct fixup *f = prop->val.refs; + struct marker *m = prop->val.markers; struct node *refnode; cell_t phandle; - while (f) { - assert(f->offset + sizeof(cell_t) <= prop->val.len); + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset + sizeof(cell_t) <= prop->val.len); - refnode = get_node_by_ref(dt, f->ref); + refnode = get_node_by_ref(dt, m->ref); if (! refnode) { FAIL(c, "Reference to non-existent node or label \"%s\"\n", - f->ref); - } else { - phandle = get_node_phandle(dt, refnode); - - *((cell_t *)(prop->val.val + f->offset)) = cpu_to_be32(phandle); + m->ref); + continue; } - prop->val.refs = f->next; - fixup_free(f); - f = prop->val.refs; + phandle = get_node_phandle(dt, refnode); + *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle); } } CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR, diff --git a/data.c b/data.c index b6cd00e..46cc081 100644 --- a/data.c +++ b/data.c @@ -20,28 +20,16 @@ #include "dtc.h" -void fixup_free(struct fixup *f) -{ - free(f->ref); - free(f); -} - void data_free(struct data d) { - struct fixup *f, *nf; - - f = d.refs; - while (f) { - nf = f->next; - fixup_free(f); - f = nf; - } - - f = d.labels; - while (f) { - nf = f->next; - fixup_free(f); - f = nf; + struct marker *m, *nm; + + m = d.markers; + while (m) { + nm = m->next; + free(m->ref); + free(m); + m = nm; } assert(!d.val || d.asize); @@ -214,37 +202,29 @@ struct data data_append_data(struct data d, void *p, int len) return d; } -void fixup_merge(struct fixup **fd, struct fixup **fd2, int d1_len) +struct data data_append_markers(struct data d, struct marker *m) { - struct fixup **ff; - struct fixup *f, *f2; - - /* Extract d2's fixups */ - f2 = *fd2; - *fd2 = NULL; - - /* Tack them onto d's list of fixups */ - ff = fd; - while (*ff) - ff = &((*ff)->next); - *ff = f2; - - /* And correct them for their new position */ - for (f = f2; f; f = f->next) - f->offset += d1_len; - + struct marker **mp = &d.markers; + /* Find the end of the markerlist */ + while (*mp) + mp = &((*mp)->next); + *mp = m; + return d; } struct data data_merge(struct data d1, struct data d2) { struct data d; + struct marker *m2 = d2.markers; - d = data_append_data(d1, d2.val, d2.len); + d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2); - fixup_merge(&d.refs, &d2.refs, d1.len); - fixup_merge(&d.labels, &d2.labels, d1.len); + /* Adjust for the length of d1 */ + for_each_marker(m2) + m2->offset += d1.len; + d2.markers = NULL; /* So data_free() doesn't clobber them */ data_free(d2); return d; @@ -294,42 +274,17 @@ struct data data_append_align(struct data d, int align) return data_append_zeroes(d, newlen - d.len); } -struct data data_add_fixup(struct data d, char *ref) -{ - struct fixup *f; - struct data nd; - - f = xmalloc(sizeof(*f)); - f->offset = d.len; - f->ref = ref; - f->next = d.refs; - - nd = d; - nd.refs = f; - - return nd; -} - -struct data data_add_label(struct data d, char *label) +struct data data_add_marker(struct data d, enum markertype type, char *ref) { - struct fixup *f, **p; - struct data nd; - - f = xmalloc(sizeof(*f)); - f->offset = d.len; - f->ref = label; - - nd = d; - p = &nd.labels; - - /* adding to end keeps them sorted */ - while (*p) - p = &((*p)->next); + struct marker *m; - f->next = *p; - *p = f; + m = xmalloc(sizeof(*m)); + m->offset = d.len; + m->type = type; + m->ref = ref; + m->next = NULL; - return nd; + return data_append_markers(d, m); } int data_is_one_string(struct data d) diff --git a/dtc-parser.y b/dtc-parser.y index d998bfe..2407af4 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -194,7 +194,7 @@ propdata: } | propdata DT_LABEL { - $$ = data_add_label($1, $2); + $$ = data_add_marker($1, LABEL, $2); } ; @@ -209,7 +209,7 @@ propdataprefix: } | propdataprefix DT_LABEL { - $$ = data_add_label($1, $2); + $$ = data_add_marker($1, LABEL, $2); } ; @@ -224,11 +224,12 @@ celllist: } | celllist DT_REF { - $$ = data_append_cell(data_add_fixup($1, $2), -1); + $$ = data_append_cell(data_add_marker($1, REF_PHANDLE, + $2), -1); } | celllist DT_LABEL { - $$ = data_add_label($1, $2); + $$ = data_add_marker($1, LABEL, $2); } ; @@ -262,7 +263,7 @@ bytestring: } | bytestring DT_LABEL { - $$ = data_add_label($1, $2); + $$ = data_add_marker($1, LABEL, $2); } ; diff --git a/dtc.h b/dtc.h index ac3657b..ad21e0d 100644 --- a/dtc.h +++ b/dtc.h @@ -101,23 +101,34 @@ typedef u32 cell_t; #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /* Data blobs */ -struct fixup { +enum markertype { + REF_PHANDLE, + LABEL, +}; + +struct marker { + enum markertype type; int offset; char *ref; - struct fixup *next; + struct marker *next; }; struct data { int len; char *val; int asize; - struct fixup *refs; - struct fixup *labels; + struct marker *markers; }; + #define empty_data ((struct data){ /* all .members = 0 or NULL */ }) -void fixup_free(struct fixup *f); +#define for_each_marker(m) \ + for (; (m); (m) = (m)->next) +#define for_each_marker_of_type(m, t) \ + for_each_marker(m) \ + if ((m)->type == (t)) + void data_free(struct data d); struct data data_grow_for(struct data d, int xlen); @@ -135,8 +146,7 @@ struct data data_append_byte(struct data d, uint8_t byte); struct data data_append_zeroes(struct data d, int len); struct data data_append_align(struct data d, int align); -struct data data_add_fixup(struct data d, char *ref); -struct data data_add_label(struct data d, char *label); +struct data data_add_marker(struct data d, enum markertype type, char *ref); int data_is_one_string(struct data d); diff --git a/flattree.c b/flattree.c index 5889900..c1032d1 100644 --- a/flattree.c +++ b/flattree.c @@ -162,12 +162,13 @@ static void asm_emit_data(void *e, struct data d) { FILE *f = e; int off = 0; - struct fixup *l; + struct marker *m; - l = d.labels; - while (l) { - emit_offset_label(f, l->ref, l->offset); - l = l->next; + m = d.markers; + while (m) { + if (m->type == LABEL) + emit_offset_label(f, m->ref, m->offset); + m = m->next; } while ((d.len - off) >= sizeof(u32)) { diff --git a/treesource.c b/treesource.c index df3df7e..202b8a7 100644 --- a/treesource.c +++ b/treesource.c @@ -61,7 +61,7 @@ static void write_propval_string(FILE *f, struct data val) char *str = val.val; int i; int newchunk = 1; - struct fixup *l = val.labels; + struct marker *m = val.markers; assert(str[val.len-1] == '\0'); @@ -69,10 +69,12 @@ static void write_propval_string(FILE *f, struct data val) char c = str[i]; if (newchunk) { - while (l && (l->offset <= i)) { - assert(l->offset == i); - fprintf(f, "%s: ", l->ref); - l = l->next; + while (m && (m->offset <= i)) { + if (m->type == LABEL) { + assert(m->offset == i); + fprintf(f, "%s: ", m->ref); + } + m = m->next; } fprintf(f, "\""); newchunk = 0; @@ -120,10 +122,9 @@ static void write_propval_string(FILE *f, struct data val) fprintf(f, "\""); /* Wrap up any labels at the end of the value */ - while (l) { - assert (l->offset == val.len); - fprintf(f, " %s:", l->ref); - l = l->next; + for_each_marker_of_type(m, LABEL) { + assert (m->offset == val.len); + fprintf(f, " %s:", m->ref); } } @@ -131,14 +132,16 @@ static void write_propval_cells(FILE *f, struct data val) { void *propend = val.val + val.len; cell_t *cp = (cell_t *)val.val; - struct fixup *l = val.labels; + struct marker *m = val.markers; fprintf(f, "<"); for (;;) { - while (l && (l->offset <= ((char *)cp - val.val))) { - assert(l->offset == ((char *)cp - val.val)); - fprintf(f, "%s: ", l->ref); - l = l->next; + while (m && (m->offset <= ((char *)cp - val.val))) { + if (m->type == LABEL) { + assert(m->offset == ((char *)cp - val.val)); + fprintf(f, "%s: ", m->ref); + } + m = m->next; } fprintf(f, "0x%x", be32_to_cpu(*cp++)); @@ -148,10 +151,9 @@ static void write_propval_cells(FILE *f, struct data val) } /* Wrap up any labels at the end of the value */ - while (l) { - assert (l->offset == val.len); - fprintf(f, " %s:", l->ref); - l = l->next; + for_each_marker_of_type(m, LABEL) { + assert (m->offset == val.len); + fprintf(f, " %s:", m->ref); } fprintf(f, ">"); } @@ -160,13 +162,14 @@ static void write_propval_bytes(FILE *f, struct data val) { void *propend = val.val + val.len; char *bp = val.val; - struct fixup *l = val.labels; + struct marker *m = val.markers; fprintf(f, "["); for (;;) { - while (l && (l->offset == (bp-val.val))) { - fprintf(f, "%s: ", l->ref); - l = l->next; + while (m && (m->offset == (bp-val.val))) { + if (m->type == LABEL) + fprintf(f, "%s: ", m->ref); + m = m->next; } fprintf(f, "%02hhx", *bp++); @@ -176,10 +179,9 @@ static void write_propval_bytes(FILE *f, struct data val) } /* Wrap up any labels at the end of the value */ - while (l) { - assert (l->offset == val.len); - fprintf(f, " %s:", l->ref); - l = l->next; + for_each_marker_of_type(m, LABEL) { + assert (m->offset == val.len); + fprintf(f, " %s:", m->ref); } fprintf(f, "]"); } @@ -188,7 +190,7 @@ static void write_propval(FILE *f, struct property *prop) { int len = prop->val.len; char *p = prop->val.val; - struct fixup *l; + struct marker *m = prop->val.markers; int nnotstring = 0, nnul = 0; int nnotstringlbl = 0, nnotcelllbl = 0; int i; @@ -205,10 +207,10 @@ static void write_propval(FILE *f, struct property *prop) nnul++; } - for (l = prop->val.labels; l; l = l->next) { - if ((l->offset > 0) && (prop->val.val[l->offset - 1] != '\0')) + for_each_marker_of_type(m, LABEL) { + if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) nnotstringlbl++; - if ((l->offset % sizeof(cell_t)) != 0) + if ((m->offset % sizeof(cell_t)) != 0) nnotcelllbl++; }