diff --git a/tools/binman/bsection.py b/tools/binman/bsection.py
index 3e3d369d5e4..f49a6e93bc7 100644
--- a/tools/binman/bsection.py
+++ b/tools/binman/bsection.py
@@ -317,9 +317,15 @@ class Section(object):
         """Call the ProcessContents() method for each entry
 
         This is intended to adjust the contents as needed by the entry type.
+
+        Returns:
+            True if no entries needed to change their size
         """
+        sizes_ok = True
         for entry in self._entries.values():
-            entry.ProcessContents()
+            if not entry.ProcessContents():
+                sizes_ok = False
+        return sizes_ok
 
     def WriteSymbols(self):
         """Write symbol values into binary files for access at run time"""
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index b19a3b026f2..7db1402b84f 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -245,7 +245,8 @@ class Entry(object):
     def ProcessContentsUpdate(self, data):
         """Update the contents of an entry, after the size is fixed
 
-        This checks that the new data is the same size as the old.
+        This checks that the new data is the same size as the old. If the size
+        has changed, this triggers a re-run of the packing algorithm.
 
         Args:
             data: Data to set to the contents (bytes)
@@ -253,10 +254,12 @@ class Entry(object):
         Raises:
             ValueError if the new data size is not the same as the old
         """
+        size_ok = True
         if len(data) != self.contents_size:
             self.Raise('Cannot update entry size from %d to %d' %
                        (self.contents_size, len(data)))
         self.SetContents(data)
+        return size_ok
 
     def ObtainContents(self):
         """Figure out the contents of an entry.
@@ -401,7 +404,22 @@ class Entry(object):
         self.image_pos = image_pos + self.offset
 
     def ProcessContents(self):
-        pass
+        """Do any post-packing updates of entry contents
+
+        This function should call ProcessContentsUpdate() to update the entry
+        contents, if necessary, returning its return value here.
+
+        Args:
+            data: Data to set to the contents (bytes)
+
+        Returns:
+            True if the new data size is OK, False if expansion is needed
+
+        Raises:
+            ValueError if the new data size is not the same as the old and
+                state.AllowEntryExpansion() is False
+        """
+        return True
 
     def WriteSymbols(self, section):
         """Write symbol values into binary files for access at run time
diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py
index ac62d2e2005..2204362281c 100644
--- a/tools/binman/etype/_testing.py
+++ b/tools/binman/etype/_testing.py
@@ -88,9 +88,10 @@ class Entry__testing(Entry):
 
     def ProcessContents(self):
         if self.bad_update_contents:
-            # Request to update the conents with something larger, to cause a
+            # Request to update the contents with something larger, to cause a
             # failure.
-            self.ProcessContentsUpdate('aa')
+            return self.ProcessContentsUpdate('aa')
+        return True
 
     def ProcessFdt(self, fdt):
         """Force reprocessing the first time"""
diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py
index d80c3d7e006..09d5d727138 100644
--- a/tools/binman/etype/blob_dtb.py
+++ b/tools/binman/etype/blob_dtb.py
@@ -30,4 +30,4 @@ class Entry_blob_dtb(Entry_blob):
     def ProcessContents(self):
         """Re-read the DTB contents so that we get any calculated properties"""
         _, data = state.GetFdtContents(self._filename)
-        self.ProcessContentsUpdate(data)
+        return self.ProcessContentsUpdate(data)
diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py
index ddac148b9ba..bfd7962be3a 100644
--- a/tools/binman/etype/fdtmap.py
+++ b/tools/binman/etype/fdtmap.py
@@ -106,4 +106,4 @@ class Entry_fdtmap(Entry):
         This is necessary since new data may have been written back to it during
         processing, e.g. the image-pos properties.
         """
-        self.ProcessContentsUpdate(self._GetFdtmap())
+        return self.ProcessContentsUpdate(self._GetFdtmap())
diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py
index 45d6db18a31..3a809486098 100644
--- a/tools/binman/etype/fmap.py
+++ b/tools/binman/etype/fmap.py
@@ -62,4 +62,4 @@ class Entry_fmap(Entry):
         return True
 
     def ProcessContents(self):
-        self.ProcessContentsUpdate(self._GetFmap())
+        return self.ProcessContentsUpdate(self._GetFmap())
diff --git a/tools/binman/etype/image_header.py b/tools/binman/etype/image_header.py
index d6de58ce4b7..b1c4f8a07e9 100644
--- a/tools/binman/etype/image_header.py
+++ b/tools/binman/etype/image_header.py
@@ -73,4 +73,4 @@ class Entry_image_header(Entry):
         This is necessary since image_pos is not available when ObtainContents()
         is called, since by then the entries have not been packed in the image.
         """
-        self.ProcessContentsUpdate(self._GetHeader())
+        return self.ProcessContentsUpdate(self._GetHeader())
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 3681a484689..51eddcd995a 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -85,8 +85,9 @@ class Entry_section(Entry):
         self._section.SetCalculatedProperties()
 
     def ProcessContents(self):
-        self._section.ProcessEntryContents()
-        super(Entry_section, self).ProcessContents()
+        sizes_ok = self._section.ProcessEntryContents()
+        sizes_ok_base = super(Entry_section, self).ProcessContents()
+        return sizes_ok and sizes_ok_base
 
     def CheckOffset(self):
         self._section.CheckEntries()
diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py
index da0e12417b5..4104bf8bf13 100644
--- a/tools/binman/etype/u_boot_with_ucode_ptr.py
+++ b/tools/binman/etype/u_boot_with_ucode_ptr.py
@@ -91,6 +91,6 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob):
         # Write the microcode offset and size into the entry
         offset_and_size = struct.pack('<2L', offset, size)
         self.target_offset -= self.image_pos
-        self.ProcessContentsUpdate(self.data[:self.target_offset] +
-                                   offset_and_size +
-                                   self.data[self.target_offset + 8:])
+        return self.ProcessContentsUpdate(self.data[:self.target_offset] +
+                                          offset_and_size +
+                                          self.data[self.target_offset + 8:])
diff --git a/tools/binman/image.py b/tools/binman/image.py
index f237ae302df..c8bce394aa1 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -122,8 +122,11 @@ class Image:
         """Call the ProcessContents() method for each entry
 
         This is intended to adjust the contents as needed by the entry type.
+
+        Returns:
+            True if the new data size is OK, False if expansion is needed
         """
-        self._section.ProcessEntryContents()
+        return self._section.ProcessEntryContents()
 
     def WriteSymbols(self):
         """Write symbol values into binary files for access at run time"""
