Merge "feat(fiptool): handle FIP in a disk partition" into integration
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 5c240b5..fadf319 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,9 +1,12 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#ifndef _MSC_VER
+#include <sys/mount.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -298,6 +301,7 @@
 	fip_toc_header_t *toc_header;
 	fip_toc_entry_t *toc_entry;
 	int terminated = 0;
+	size_t st_size;
 
 	fp = fopen(filename, "rb");
 	if (fp == NULL)
@@ -306,13 +310,21 @@
 	if (fstat(fileno(fp), &st) == -1)
 		log_err("fstat %s", filename);
 
+	st_size = st.st_size;
+
-	buf = xmalloc(st.st_size, "failed to load file into memory");
-	if (fread(buf, 1, st.st_size, fp) != st.st_size)
+#ifdef BLKGETSIZE64
+	if ((st.st_mode & S_IFBLK) != 0)
+		if (ioctl(fileno(fp), BLKGETSIZE64, &st_size) == -1)
+			log_err("ioctl %s", filename);
+#endif
+
+	buf = xmalloc(st_size, "failed to load file into memory");
+	if (fread(buf, 1, st_size, fp) != st_size)
 		log_errx("Failed to read %s", filename);
-	bufend = buf + st.st_size;
+	bufend = buf + st_size;
 	fclose(fp);
 
-	if (st.st_size < sizeof(fip_toc_header_t))
+	if (st_size < sizeof(fip_toc_header_t))
 		log_errx("FIP %s is truncated", filename);
 
 	toc_header = (fip_toc_header_t *)buf;
@@ -347,9 +359,11 @@
 		    "failed to allocate image buffer, is FIP file corrupted?");
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address)
-			log_errx("FIP %s is corrupted", filename);
-		if (toc_entry->size + toc_entry->offset_address > st.st_size)
-			log_errx("FIP %s is corrupted", filename);
+			log_errx("FIP %s is corrupted: entry size exceeds 64 bit address space",
+				filename);
+		if (toc_entry->size + toc_entry->offset_address > st_size)
+			log_errx("FIP %s is corrupted: entry size exceeds FIP file size",
+				filename);
 
 		memcpy(image->buffer, buf + toc_entry->offset_address,
 		    toc_entry->size);