| 417 | } |
| 418 | |
| 419 | int fdt_open_into(const void *fdt, void *buf, int bufsize) |
| 420 | { |
| 421 | int err; |
| 422 | int mem_rsv_size, struct_size; |
| 423 | int newsize; |
| 424 | const char *fdtstart = fdt; |
| 425 | const char *fdtend = fdtstart + fdt_totalsize(fdt); |
| 426 | char *tmp; |
| 427 | |
| 428 | FDT_RO_PROBE(fdt); |
| 429 | |
| 430 | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) |
| 431 | * sizeof(struct fdt_reserve_entry); |
| 432 | |
| 433 | if (can_assume(LATEST) || fdt_version(fdt) >= 17) { |
| 434 | struct_size = fdt_size_dt_struct(fdt); |
| 435 | } else if (fdt_version(fdt) == 16) { |
| 436 | struct_size = 0; |
| 437 | while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) |
| 438 | ; |
| 439 | if (struct_size < 0) |
| 440 | return struct_size; |
| 441 | } else { |
| 442 | return -FDT_ERR_BADVERSION; |
| 443 | } |
| 444 | |
| 445 | if (can_assume(LIBFDT_ORDER) || |
| 446 | !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { |
| 447 | /* no further work necessary */ |
| 448 | err = fdt_move(fdt, buf, bufsize); |
| 449 | if (err) |
| 450 | return err; |
| 451 | fdt_set_version(buf, 17); |
| 452 | fdt_set_size_dt_struct(buf, struct_size); |
| 453 | fdt_set_totalsize(buf, bufsize); |
| 454 | return 0; |
| 455 | } |
| 456 | |
| 457 | /* Need to reorder */ |
| 458 | newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size |
| 459 | + struct_size + fdt_size_dt_strings(fdt); |
| 460 | |
| 461 | if (bufsize < newsize) |
| 462 | return -FDT_ERR_NOSPACE; |
| 463 | |
| 464 | /* First attempt to build converted tree at beginning of buffer */ |
| 465 | tmp = buf; |
| 466 | /* But if that overlaps with the old tree... */ |
| 467 | if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { |
| 468 | /* Try right after the old tree instead */ |
| 469 | tmp = (char *)(uintptr_t)fdtend; |
| 470 | if ((tmp + newsize) > ((char *)buf + bufsize)) |
| 471 | return -FDT_ERR_NOSPACE; |
| 472 | } |
| 473 | |
| 474 | fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size, |
| 475 | fdt_size_dt_strings(fdt)); |
| 476 | memmove(buf, tmp, newsize); |
no test coverage detected