binman: Add more tests for image header position
authorSimon Glass <sjg@chromium.org>
Sat, 20 Jul 2019 18:23:55 +0000 (12:23 -0600)
committerSimon Glass <sjg@chromium.org>
Mon, 29 Jul 2019 15:38:06 +0000 (09:38 -0600)
The positioning does not currently work correctly if at the end of an
image with no fixed size. Also if the header is in the middle of an image
it can cause a gap in the image since the header position is normally at
the image end, so entries after it are placed after the end of the image.

Fix these problems and add more tests to cover these cases.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/entry.py
tools/binman/etype/image_header.py
tools/binman/etype/section.py
tools/binman/ftest.py
tools/binman/test/135_fdtmap_hdr_middle.dts [new file with mode: 0644]
tools/binman/test/136_fdtmap_hdr_startbad.dts [new file with mode: 0644]
tools/binman/test/137_fdtmap_hdr_endbad.dts [new file with mode: 0644]
tools/binman/test/138_fdtmap_hdr_nosize.dts [new file with mode: 0644]

index 74e280849c4d76f2f19917ec6bce68e5af4e3608..8dacc61f5a1b467271bf6b041637f5172f575986 100644 (file)
@@ -745,3 +745,18 @@ features to produce new behaviours.
         ok = self.ProcessContentsUpdate(data)
         self.Detail('WriteData: size=%x, ok=%s' % (len(data), ok))
         return ok
+
+    def GetSiblingOrder(self):
+        """Get the relative order of an entry amoung its siblings
+
+        Returns:
+            'start' if this entry is first among siblings, 'end' if last,
+                otherwise None
+        """
+        entries = list(self.section.GetEntries().values())
+        if entries:
+            if self == entries[0]:
+                return 'start'
+            elif self == entries[-1]:
+                return 'end'
+        return 'middle'
index 8f9c5aa5d9e642153622f53cf0a302534f9f4506..4b69eda1a22bbf8c9d622bcfafc49b1d9c8581de 100644 (file)
@@ -86,8 +86,20 @@ class Entry_image_header(Entry):
             if self.location not in ['start', 'end']:
                 self.Raise("Invalid location '%s', expected 'start' or 'end'" %
                            self.location)
-            image_size = self.section.GetImageSize() or 0
-            self.offset = (0 if self.location != 'end' else image_size - 8)
+            order = self.GetSiblingOrder()
+            if self.location != order and not self.section.GetSort():
+                self.Raise("Invalid sibling order '%s' for image-header: Must be at '%s' to match location" %
+                           (order, self.location))
+            if self.location != 'end':
+                offset = 0
+            else:
+                image_size = self.section.GetImageSize()
+                if image_size is None:
+                    # We don't know the image, but this must be the last entry,
+                    # so we can assume it goes
+                    offset = offset
+                else:
+                    offset = image_size - IMAGE_HEADER_LEN
         return Entry.Pack(self, offset)
 
     def ProcessContents(self):
index 0fb81419ceaed069d15a535deedc9a04e6086770..3ce013d5029a8a68553ea2bb55524633b388092c 100644 (file)
@@ -479,3 +479,12 @@ class Entry_section(Entry):
         if not self.section:
             return self
         return self.section.GetImage()
+
+    def GetSort(self):
+        """Check if the entries in this section will be sorted
+
+        Returns:
+            True if to be sorted, False if entries will be left in the order
+                they appear in the device tree
+        """
+        return self._sort
index b67e8a15086b370ca02cb8ef7327f8b7288504bc..bc751893edbdc6df6efb18cec3d39f7f13f159c2 100644 (file)
@@ -2886,6 +2886,31 @@ class TestFunctional(unittest.TestCase):
             else:
                 start += dtb._fdt_obj.totalsize()
 
+    def testFdtmapHeaderMiddle(self):
+        """Test an FDT map in the middle of an image when it should be at end"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFileRealDtb('135_fdtmap_hdr_middle.dts')
+        self.assertIn("Invalid sibling order 'middle' for image-header: Must be at 'end' to match location",
+                      str(e.exception))
+
+    def testFdtmapHeaderStartBad(self):
+        """Test an FDT map in middle of an image when it should be at start"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFileRealDtb('136_fdtmap_hdr_startbad.dts')
+        self.assertIn("Invalid sibling order 'end' for image-header: Must be at 'start' to match location",
+                      str(e.exception))
+
+    def testFdtmapHeaderEndBad(self):
+        """Test an FDT map at the start of an image when it should be at end"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFileRealDtb('137_fdtmap_hdr_endbad.dts')
+        self.assertIn("Invalid sibling order 'start' for image-header: Must be at 'end' to match location",
+                      str(e.exception))
+
+    def testFdtmapHeaderNoSize(self):
+        """Test an image header at the end of an image with undefined size"""
+        self._DoReadFileRealDtb('138_fdtmap_hdr_nosize.dts')
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/135_fdtmap_hdr_middle.dts b/tools/binman/test/135_fdtmap_hdr_middle.dts
new file mode 100644 (file)
index 0000000..d6211da
--- /dev/null
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u-boot {
+               };
+               image-header {
+                       location = "end";
+               };
+               fdtmap {
+               };
+       };
+};
diff --git a/tools/binman/test/136_fdtmap_hdr_startbad.dts b/tools/binman/test/136_fdtmap_hdr_startbad.dts
new file mode 100644 (file)
index 0000000..ec5f4bc
--- /dev/null
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u-boot {
+               };
+               fdtmap {
+               };
+               image-header {
+                       location = "start";
+               };
+       };
+};
diff --git a/tools/binman/test/137_fdtmap_hdr_endbad.dts b/tools/binman/test/137_fdtmap_hdr_endbad.dts
new file mode 100644 (file)
index 0000000..ebacd71
--- /dev/null
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               image-header {
+                       location = "end";
+               };
+               u-boot {
+               };
+               fdtmap {
+               };
+       };
+};
diff --git a/tools/binman/test/138_fdtmap_hdr_nosize.dts b/tools/binman/test/138_fdtmap_hdr_nosize.dts
new file mode 100644 (file)
index 0000000..c362f8f
--- /dev/null
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u-boot {
+               };
+               fdtmap {
+               };
+               image-header {
+                       location = "end";
+               };
+       };
+};