-
- if (cxt->overflow)
- return -ENOMEM;
-
- /* size of the areas */
- cxt->struct_size = cxt->p - cxt->p_begin;
- cxt->strings_size = cxt->pstr_begin - cxt->pstr;
-
- /* the offset we must move */
- off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size;
-
- /* the new strings start */
- cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
-
- /* move the whole string area */
- memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size);
-
- /* now perform the fixup of the strings */
- p = cxt->p_begin;
- while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) {
- p += 4;
-
- if (tag == OF_DT_BEGIN_NODE) {
- p = (u8 *) _ALIGN((unsigned long)p + strlen(p) + 1, 4);
- continue;
- }
-
- if (tag == OF_DT_END_NODE || tag == OF_DT_NOP)
- continue;
-
- if (tag != OF_DT_PROP)
- return -EINVAL;
-
- sz = be32_to_cpu(*(u32 *) p);
- p += 4;
-
- v = be32_to_cpu(*(u32 *) p);
- v -= off;
- *(u32 *) p = cpu_to_be32(v); /* move down */
- p += 4;
-
- p = (u8 *) _ALIGN((unsigned long)p + sz, 4);
- }
-
- /* fix sizes */
- p = (char *)cxt->bph;
- sz = (cxt->pstr_begin + cxt->strings_size) - p;
- sz1 = _ALIGN(sz, 16); /* align at 16 bytes */
- if (sz != sz1)
- memset(p + sz, 0, sz1 - sz);
- bph->totalsize = cpu_to_be32(sz1);
- bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p);
- bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p);
-
- /* the new strings start */
- cxt->pstr_begin = cxt->p_begin + cxt->struct_size;
- cxt->pstr = cxt->pstr_begin + cxt->strings_size;
-
- return 0;