device: optimize handles array

Optimize the handles array by making the following observations:
 * The devicetree ordinal at index 0 in pass1 is discarded by
   gen_handles.py, and therefore does not appear in the pass2 array.
 * gen_handles.py does not need `DEVICE_HANDLE_ENDS` to determine the
   end of the handle array, as that information is present in the .elf.

Therefore, instead of replacing the devicetree ordinal with an
additional `DEVICE_HANDLE_ENDS` at the end (to preserve lengths), we
can simply move the ordinal to the end and have it be the original
`DEVICE_HANDLE_ENDS` symbol. This reduces the size of the array by
one handle per device (2 bytes).

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
diff --git a/scripts/gen_handles.py b/scripts/gen_handles.py
index 00de909..c5e9e09 100755
--- a/scripts/gen_handles.py
+++ b/scripts/gen_handles.py
@@ -241,7 +241,7 @@
         handle.dev_deps = []
         handle.ext_deps = []
         deps = handle.dev_deps
-        while True:
+        while hvi < len(hv):
             h = hv[hvi]
             if h == DEVICE_HANDLE_ENDS:
                 break
@@ -302,8 +302,10 @@
 
             # When CONFIG_USERSPACE is enabled the pre-built elf is
             # also used to get hashes that identify kernel objects by
-            # address.  We can't allow the size of any object in the
-            # final elf to change.
+            # address. We can't allow the size of any object in the
+            # final elf to change. We also must make sure at least one
+            # DEVICE_HANDLE_ENDS is inserted.
+            assert len(hdls) < len(hs.handles), "%s no DEVICE_HANDLE_ENDS inserted" % (dev.sym.name,)
             while len(hdls) < len(hs.handles):
                 hdls.append(DEVICE_HANDLE_ENDS)
             assert len(hdls) == len(hs.handles), "%s handle overflow" % (dev.sym.name,)