When reading files, it is actually only necessary to read the amount of bytes specified in the FDT header. Any trailing data that is not part of the FDT is not relevant to the operation of any of the utilities and is discarded anyways. Stop reading when reaching either fdt_totalsize bytes or end-of-file. Stopping reading before end-of-file saves a considerable amount of memory when using FIT (Flattened Image Tree) [1] images with "external data" which are used by bootloaders such as Das U-Boot. In case of FIT images, the FDT is a few kilobytes, while the actual file can be several megabytes, which is quite a significant difference in memory usage. [1] https://fitspec.osfw.foundation/ Signed-off-by: Andreas Gnau <andreas.gnau@xxxxxxxxx> --- util.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/util.c b/util.c index 507f0120cd13..093303078d5f 100644 --- a/util.c +++ b/util.c @@ -249,6 +249,7 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len) char *buf = NULL; size_t bufsize = 1024, offset = 0; int ret = 0; + uint32_t totalsize = UINT32_MAX; *buffp = NULL; if (strcmp(filename, "-") != 0) { @@ -257,7 +258,7 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len) return errno; } - /* Loop until we have read everything */ + /* Loop until we have read until the end of file or end of FDT */ buf = xmalloc(bufsize); do { /* Expand the buffer to hold the next chunk */ @@ -272,14 +273,24 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len) break; } offset += ret; - } while (ret != 0); + + /* assumes that the size is always stored in V1 part */ + if (totalsize == UINT32_MAX && offset >= FDT_V1_SIZE) { + totalsize = fdt_totalsize(buf); + if (totalsize <= 0) + /* read file up to INT32_MAX in case of errors */ + totalsize = UINT32_MAX; + } + } while (ret != 0 && offset < totalsize); /* Clean up, including closing stdin; return errno on error */ close(fd); - if (ret) + if (ret <= 0) free(buf); - else + else { *buffp = buf; + ret = 0; + } if (len) *len = bufsize; return ret; -- 2.46.1