binman: Support shrinking a entry after packing

Sometimes an entry may shrink after it has already been packed. In that
case we must repack the items. Of course it is always possible to just
leave the entry at its original size and waste space at the end. This is
what binman does by default, since there is the possibility of the entry
changing size every time binman calculates its contents, thus causing a
loop.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2019-07-20 12:23:58 -06:00
parent 79d3c58d12
commit 61ec04f9ed
5 changed files with 91 additions and 11 deletions

View file

@ -285,16 +285,26 @@ class Entry(object):
"""
size_ok = True
new_size = len(data)
if state.AllowEntryExpansion():
if state.AllowEntryExpansion() and new_size > self.contents_size:
# self.data will indicate the new size needed
size_ok = False
elif state.AllowEntryContraction() and new_size < self.contents_size:
size_ok = False
# If not allowed to change, try to deal with it or give up
if size_ok:
if new_size > self.contents_size:
tout.Debug("Entry '%s' size change from %s to %s" % (
self._node.path, ToHex(self.contents_size),
ToHex(new_size)))
# self.data will indicate the new size needed
size_ok = False
elif new_size != self.contents_size:
self.Raise('Cannot update entry size from %d to %d' %
(self.contents_size, new_size))
self.Raise('Cannot update entry size from %d to %d' %
(self.contents_size, new_size))
# Don't let the data shrink. Pad it if necessary
if size_ok and new_size < self.contents_size:
data += tools.GetBytes(0, self.contents_size - new_size)
if not size_ok:
tout.Debug("Entry '%s' size change from %s to %s" % (
self._node.path, ToHex(self.contents_size),
ToHex(new_size)))
self.SetContents(data)
return size_ok