#!/usr/bin/env python

# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import binascii
import collections
import hashlib
import optparse
import os
import re
import shutil
import struct
import sys

from tools import CmdError
from tools import Tools
from fdt import Fdt

# Attributes defined outside __init__
#pylint: disable=W0201

# TODO(sjg): Once we have a stable fdt, write some unit tests for this

# TODO(clchiou): Rewrite this part after official flashmap implementation is
# pulled into Chromium OS code base.

# Use this to find the FDT containing the flashmap
FDTMAP_SIGNATURE = '__FDTM__'

# constants imported from lib/fmap.h
FMAP_SIGNATURE = "__FMAP__"
FMAP_VER_MAJOR = 1
FMAP_VER_MINOR = 0
FMAP_STRLEN = 32

FMAP_AREA_STATIC = 1 << 0
FMAP_AREA_COMPRESSED = 1 << 1
FMAP_AREA_RO = 1 << 2

FMAP_HEADER_FORMAT = "<8sBBQI%dsH" % (FMAP_STRLEN)
FMAP_AREA_FORMAT = "<II%dsH" % (FMAP_STRLEN)

FMAP_HEADER_NAMES = (
    'signature',
    'ver_major',
    'ver_minor',
    'base',
    'image_size',
    'name',
    'nareas',
)

FMAP_AREA_NAMES = (
    'offset',
    'size',
    'name',
    'flags',
)

# A useful named tuple.
Value = collections.namedtuple('Value', ['node', 'key', 'params'])

class ConfigError(Exception):
  """A configuration error, normally a mistake in the fdt."""
  pass


class PackError(Exception):
  """A packing error, such as a file being too large for its area."""
  pass


class Entry(dict):
  """The base class for an entry type.

  All entry types are subclasses of this class. It is basically a dictionary
  with a few methods to check that the supplied data is value.

  Subclasses should implement the following methods:

    GetData(): To return the data for this entry as a string.
    RunTools(): To run any required tools to create the data.

  Potentially in the future we could add PutData() to write data from a packed
  image file back into an entry, to allow an image file to be updated.

  Properties which we need in our dictionary:
    pack: The PackFirmware object (essentially this is our parent)
    offset: Byte offset of area.
    size: Size of area in bytes.
    name: Name of area.
    required: True if this entry is required in the image, False if not

  Properties which we create:
    value: The value that we obtain for this entry. This is a list of
        filenames.
  """
  def __init__(self, props):
    super(Entry, self).__init__(props)
    self._CheckFields(('offset', 'size', 'name'))

  def __getattr__(self, name):
    return self[name]

  def __setattr__(self, name, value):
    self[name] = value

  def _CheckFields(self, fields):
    """Check that listed fields are present.

    Args:
      fields: List of field names to check for.

    Raises:
      ConfigError: if a field is not present.
    """
    for f in fields:
      if f not in self:
        raise ConfigError('Entry %s: missing required field: %s' %
            (self['name'], f))

  def _CheckFieldsInt(self, fields):
    """Check that listed fields are present, and convert them to ints.

    Args:
      fields: List of field names to check for.

    Raises:
      ConfigError: if a field is not present or cannot be converted to an int.
    """
    self._CheckFields(fields)
    for f in fields:
      try:
        self[f] = int(self[f])
      except ValueError:
        raise ConfigError("Entry %s, property %s: could not convert '%s'"
            " to integer" % (self['name'], f, self[f]))

  def GetOverlap(self, entry):
    """Returns the amount by which we overlap with the supplied entry.

    Args:
      entry: Entry to check.

    Returns:
      Amount of overlap:
        0: the entries butt up together.
        <0: there is a gap bewteen the entries.
        >0: there is overlap.
    """
    a = [self.offset, self.offset + self.size]
    b = [entry.offset, entry.offset + entry.size]
    return min(a[1], b[1]) - max(a[0], b[0])

  def GetData(self):
    """Method implemented by subclasses to return data for the entry.

    Returns:
      String containing entry data.
    """
    raise PackError('class Entry does not implement GetEntry()')

  def RunTools(self, tools, out, tmpdir):
    """Method implemented by subclasses to run required tools.

    Some entry types require running external tools to create their data.
    This method provides a convenient way of doing this. The supplied
    temporary directory can be used to store files. These should ideally
    not be deleted by this method, since the user may wish to see them
    later.

    Args:
      tools: Tools object to use to run tools.
      out: Output object to send output to
      tmpdir: Temporary directory to use to create required files.
    """
    pass


class EntryFmapArea(Entry):
  """A base class for things that actually produce data for the image.

  Properties:
    flags: The FMAP flags, which is an integer made up from the bit values in
        FMAP_AREA_...
  """
  def __init__(self, props):
    super(EntryFmapArea, self).__init__(props)
    self._CheckFields(('flags',))

  def GetData(self):
    """This section is empty"""
    return ''


class EntryFmap(EntryFmapArea):
  """An entry which contains an Fmap section

  Properties:
    base: Base offset of flash device (normally 0).
    size: Size of the flash device (2MB or 4MB typically).
    nareas: Number of areas in the FMAP = number of sections.
    entries: The list of entries to put in the FMAP.
  """

  def __init__(self, props):
    super(EntryFmap, self).__init__(props)
    self._CheckFieldsInt(('ver_major', 'ver_minor'))

  def SetEntries(self, base, image_size, entries):
    self['base'] = base
    self['image_size'] = image_size
    self['nareas'] = len(entries)
    self['entries'] = entries

  def GetData(self):
    def _FormatBlob(fmt, names, obj):
      params = [obj[name] for name in names]
      return struct.pack(fmt, *params)

    self._CheckFields(('base', 'size'))
    self['signature'] = FMAP_SIGNATURE
    blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, self)
    for entry in self.entries:
      blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, entry)

    return blob


class EntryFdtMap(EntryFmapArea):
  """An entry which contains an FDT-based flashmap

  Properties:
    base: Base offset of flash device (normally 0).
    size: Size of the flash device (2MB or 4MB typically).
  """

  def __init__(self, props):
    super(EntryFdtMap, self).__init__(props)

  # We could potentially include only the flashmap node, but for now put
  # the entire FDT in this region. It provides easy access to all
  # configuration.
  def GetData(self):
    data = self.pack.tools.ReadFile(self.pack.props['fdtmap'])
    crc32 = binascii.crc32(data) & 0xffffffff
    blob = struct.pack('<8sLL', FDTMAP_SIGNATURE, len(data), crc32)
    blob += data

    return blob


class EntryWiped(EntryFmapArea):
  """This entry will be wiped to a particular byte value.

  Properties:
    wipe_value: byte value to set area to.
  """
  def __init__(self, props):
    super(EntryWiped, self).__init__(props)
    self._CheckFields(('wipe_value',))
    if self.wipe_value:
      self.wipe_value = chr(int(self.wipe_value))
    else:
      self.wipe_value = chr(0)
    if len(self.wipe_value) != 1:
      raise ConfigError('wipe_value out of range [00:ff]: %s' %
                        repr(self.wipe_value))

  def GetData(self):
    return self.wipe_value * self.size


class EntryBlobString(EntryFmapArea):
  """This entry contains a single string.

  The string is placed in the area.

  Properties:
    self.value: The string value to store.
  """
  def __init__(self, props):
    super(EntryBlobString, self).__init__(props)

  def GetData(self):
    return self.value[0]


class EntryIfd(EntryFmapArea):
  """This entry marks the use of an Intel Firmware Descriptor.

  The entry itself covers the 'Intel' part of the firmware, containing the
  firmware descriptor and management engine. When this entry appears in a
  flash map, we strip it off the image, and use ifdtool to place the rest
  of the image into a provided skeleton file (which contains the management
  engine and a skeleton firmware descriptor).
  """
  def __init__(self, props):
    super(EntryIfd, self).__init__(props)

  def ProduceFinalImage(self, tools, out, tmpdir, image_fname):
    """Produce the final image for an Intel ME system

    Some Intel systems require that an image contains the Management Engine
    firmware, and also a firmware descriptor.

    This function takes the existing image, removes the front part of it,
    and replaces it with these required pieces using ifdtool.

    Args:
      tools: Tools object to use to run tools.
      out: Output object to send output to
      tmpdir: Temporary directory to use to create required files.
      image_fname: Output image filename
    """
    out.Progress('Setting up Intel ME')
    data = tools.ReadFile(image_fname)

    # We can assume that the ifd section is at the start of the image.
    if self.offset != 0:
      raise ConfigError('IFD section must be at offset 0 in the image')

    # Calculate start and size of BIOS region based off the IFD descriptor and
    # not the size in dts node.
    ifd_layout_tmp = os.path.join(tmpdir, 'ifd-layout-tmp')
    args = ['-f%s' % ifd_layout_tmp, tools.Filename(self.pack.props['skeleton'])]
    tools.Run('ifdtool', args)
    fd = open(ifd_layout_tmp)
    layout = fd.readlines()
    for line in layout:
        line = line.rstrip()
        if line.find("bios") != -1:
            addr_range = line.split(' ')[0]
            start = int(addr_range.split(':')[0], 16)
            end = int(addr_range.split(':')[1], 16)

    fd.close()

    data = data[start:end+1]
    input_fname = os.path.join(tmpdir, 'ifd-input.bin')
    tools.WriteFile(input_fname, data)
    ifd_output = os.path.join(tmpdir, 'image.ifd')

    # This works by modifying a skeleton file.
    shutil.copyfile(tools.Filename(self.pack.props['skeleton']), ifd_output)
    args = ['-i', 'BIOS:%s' % input_fname, ifd_output]
    tools.Run('ifdtool', args)

    # ifdtool puts the output in a file with '.new' tacked on the end.
    shutil.move(ifd_output + '.new', image_fname)
    tools.OutputSize('IFD image', image_fname)

class EntryBlob(EntryFmapArea):
  """This entry contains a binary blob.

  Properties:
    self.value: The filename to read to obtain the blob data.
  """
  def __init__(self, props, params):
    super(EntryBlob, self).__init__(props)
    self.params = params
    if 'compress' not in self:
      self.compress = None
    self.with_index = 'with_index' in props

  def GetData(self):
    return self.pack.tools.ReadFileAndConcat(
        self.value, self.compress, self.with_index)[0]


class EntryKeyBlock(EntryFmapArea):
  """This entry contains a vblock

  Properties:
    keyblock: The filename of the keyblock to use (within the keydir)
        (e.g. 'firmware.keyblock')
    signprivate: Private key filename (e.g. 'firmware_data_key.vbprivk')
    keynelkey: Kernel key filename (e.g. 'kernel_subkey.vbpubk')
    version: Version of vblock (generally 1)
  """
  def __init__(self, props):
    super(EntryKeyBlock, self).__init__(props)
    self._CheckFields(('keyblock', 'signprivate', 'kernelkey'))
    self._CheckFieldsInt(('version', 'preamble_flags'))
    if 'compress' not in self:
      self.compress = None
    self.with_index = 'with_index' in props

# pylint can't figure out that self.value is set by now
#pylint: disable=E0203

  def RunTools(self, tools, out, tmpdir):
    """Create a vblock for the given firmware image"""
    self.path = os.path.join(tmpdir, 'vblock.%s' % self.label)
    input_data = os.path.join(tmpdir, 'input.%s' % self.label)
    try:
      prefix = self.pack.props['keydir'] + '/'

      # Join up the data files to be signed
      data = self.pack.tools.ReadFileAndConcat(
        self.value, self.compress, self.with_index)[0]
      tools.WriteFile(input_data, data)
      args = [
          '--vblock', self.path,
          '--keyblock', prefix + self.keyblock,
          '--signprivate', prefix + self.signprivate,
          '--version', '%d' % self.version,
          '--fv', input_data,
          '--kernelkey', prefix + self.kernelkey,
          '--flags', '%d' % self.preamble_flags,
      ]
      out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
      stdout = tools.Run('vbutil_firmware', args)
      out.Debug(stdout)

      # Update value to the actual filename to be used
      self.value = [self.path]
    except CmdError as err:
      raise PackError('Cannot make key block: vbutil_firmware failed\n%s' %
                      err)

  def GetData(self):
    fd = open(self.path, 'rb')
    data = fd.read()
    fd.close()
    return data


class PackFirmware:
  """Class for packing a firmware image

  A firmware image consists of a number of areas, called entries here.
  Together they cover the entire firmware device from start to finish.

  We use the fdt to define the format of the output - things like the
  name, start and size of each entry, as well as what type of thing
  to pack in there.

  We maintain a list of available data files (in self.props) and these can be
  requested by each entry. Each entry is a subclass of Entry, such as
  EntryBlob which handles the 'blob' entry type.

  One of the entry types is the fmap (flash map). It basically has a header
  and a representation of the list of sections. We create this from the fdt
  auotmatically. You can find this format documented here:

      http://code.google.com/p/flashmap/wiki/FmapSpec


  The following methods must be called in order:

    SetupFiles
    SelectFdt
    PackImage
  """
  def __init__(self, tools, output):
    """
    Args:
      output: A method to call to diplay output:
                def output(msg):
                Args:
                  msg: Message to output.
      tools: A tools object for calling external tools.
      verbose: 0 for silent, 1 for progress only, 2 for some info, 3 for
          full info, 4 for debug info including sub-tool output.
    """
    self.props = {}             # Properties / files we know about.
    self.entries = []           # The entries in the flash image.
    self._out = output
    self.tools = tools
    self.use_efs = False        # Early firmware selection

  def _GetFlags(self, props):
    """Create the fmap flags value from the given properties.

    Args:
      props: Dictionary containing properties.

    Returns
      Integer containing flags from _FMAP_AREA_...
    """
    flags = FMAP_AREA_STATIC
    if 'read-only' in props:
      flags |= FMAP_AREA_RO
    if 'compressed' in props:
      flags |= FMAP_AREA_COMPRESSED
    return flags

  def _CreateEntry(self, node, props):
    """Create an entry based on a node in the fdt.

    For example this fdt line:

      type = "blob signed";

    means it is a 'blob' type and will create an EntryBlob, and the blob
    used will be self.props['signed'].

    Args:
      node: The node to use, e.g. /flash/ro-stub
      props: Doctionary containing all properties from the node.

    Returns:
      An entry set up and ready for packing.

    Raises:
      ValueError: If fdt has an unknown entry type.
    """
    entry_list = ['empty']

    # Try to use the early-firmware-selection type if we are in that mode.
    if self.use_efs:
      entry_list = props.get('type,efs', 'empty').split()
    if entry_list[0] == 'empty':
      entry_list = props.get('type', 'empty').split()
    ftype = entry_list[0]
    if ftype == 'empty':
      ftype = ''
    key = None
    if len(entry_list) > 1:
      key = entry_list[1]
    params = entry_list[2:]

    # Create an entry of the correct type.
    entry = None
    if not ftype:
      entry = EntryFmapArea(props)
    elif ftype == 'blob':
      entry = EntryBlob(props, params)
    elif ftype == 'wiped':
      entry = EntryWiped(props)
    elif ftype == 'keyblock':
      entry = EntryKeyBlock(props)
    elif ftype == 'blobstring':
      entry = EntryBlobString(props)
    elif ftype == 'fmap':
      entry = EntryFmap(props)
    elif ftype == 'ifd':
      entry = EntryIfd(props)
    elif ftype == 'fdtmap':
      entry = EntryFdtMap(props)
    else:
      raise ValueError('%s: unknown entry type' % ftype)

    entry.pack = self
    entry.node = node
    entry.key = key
    entry.required = 'required' in props
    entry.ftype = ftype
    return entry

  def _IsRequired(self, entry):
    """Check if an entry is required in the final image.

    Args:
      entry: Entry to check

    Returns:
      True if this entry must be included, False if not.
    """
    return entry.required

  def SetupFiles(self, boot, signed, gbb, fwid, keydir):
    """Set up files required for packing the firmware.

    Args:
      boot: Filename of bootloader image.
      signed: Filename of signed bootloader image.
      gbb: Filename of Google Binary Block (GBB).
      fwid: String containing the firmware ID.
      keydir: Key directory to use (containing signing keys).
    """
    self.props['boot'] = boot
    self.props['signed'] = signed
    self.props['gbb'] = gbb
    self.props['fwid'] = fwid
    self.keydir = keydir

  def _CheckOverlap(self):
    """Check that no entries overlap each other.

    We only allow section areas to overlap - anything with actual data in it
    must not overlap.

    Returns:
      True if all entries are required in the image, else False
    """
    required = filter(self._IsRequired, self.entries)
    entries = sorted(required, key=lambda e: e.offset)
    all_entries = len(self.entries) == len(required)
    for e1, e2 in zip(entries, entries[1:]):
      # Allow overlap between "pure" fmap areas, but not any of its subclasses
      # Here we exploit the fact that Entry is a new-style class
      if type(e1) is EntryFmapArea or type(e2) is EntryFmapArea:
        continue

      overlap = e1.GetOverlap(e2)
      if overlap > 0:
        raise ValueError('Flash map entries overlap by %d bytes: '
            '%s: %08x-%08x, %s: %08x-%08x' %
            (overlap, e1.label, e1.offset, e1.offset + e1.size,
             e2.label, e2.offset, e2.offset + e2.size))
      elif overlap is not 0:
        self._out.Warning('Warning: Flash map has a gap of %d bytes: '
            '%s: %08x-%08x, %s: %08x-%08x' %
            (-overlap, e1.label, e1.offset, e1.offset + e1.size,
             e2.label, e2.offset, e2.offset + e2.size))

    return all_entries

  def SelectFdt(self, fdt, board=None):
    """Scan FDT and build entry objects.

    This creates a list of entry objects which we can later use to generate
    a firmware image. Each entry's properties are set up correcty but at this
    stage no data is processed. The result is a list of entries in
    self.entries.

    Args:
      fdt: fdt object containing the device tree.
      board: Name of board type if known (None if not known).

    Raises:
      ConfigError if an error is detected in the fdt configuration.
    """
    def _AddNode(node, props):
      """Add a new flash map node to the entry list.

      Args:
        node: Name of node to read from
        props: Dictionary containing properties of the node
      """
      align = int(props.get('align', '1'))
      align_mask = align - 1
      if align == 0 or (align & align_mask) != 0:
        raise ValueError("Invalid alignment %d in node '%s'" % props['label'])
      # Read the two cells from the node's /reg property to get entry extent.
      reg = props.get('reg', None)
      if reg:
        offset, size = fdt.DecodeIntList(node, 'reg', reg, 2)
        if (offset & align_mask) or (size & align_mask):
          raise ValueError("Alignment of %d conflicts with 'reg' setting in"
                           "node '%s': offset=%#08x, size=%#08x" %
                           (align, props['label'], offset, size))
      else:
        size = props.get('size', None)
        if not size:
          raise ValueError("Must specify either 'reg' or 'size' in flash"
                           "node '%s'" % props['label'])
        size = int(size)
        offset = self.upto_offset
        offset = (offset + align_mask) & ~align_mask

      props['node'] = node
      props['offset'] = offset
      props['size'] = size

      # The section names must be upper case with underscores, for other tools
      props['name'] = re.sub('-', '_', props['label']).upper()
      props['flags'] = self._GetFlags(props)
      try:
        entry = self._CreateEntry(node, props)
        self.entries.append(entry)

      except ConfigError as err:
        raise ValueError('Config error: %s' % err)

      if entry.ftype:
        self.upto_offset = offset + size
      else:
        self.upto_offset = offset
      if entry.required:
        self.required_count += 1
      if entry.key == 'signed':
        self.first_blob_entry = entry

    self.fdt = fdt
    root = '/flash'

    # Current offset to use for entries with only a 'size' property.
    self.upto_offset = 0
    self.required_count = 0
    self.first_blob_entry = None

    if not fdt.GetProp(root, 'reg', ''):
      raise ValueError("No /flash present in fdt, and no available default"
                        " for board '%s'" % board)
    self.image_size = int(fdt.GetIntList(root, 'reg', 2)[1])

    # Scan the flash map in the fdt, creating a list of Entry objects.
    children = fdt.GetChildren(root)

    for child in children:
      node = root + '/' + child
      props = fdt.GetProps(node, True)

      _AddNode(node, props)

      # If there was only a 'size' property, write a full 'reg' property
      # based on the offset we calculated
      if not props.get('reg'):
        fdt.PutIntList(node, 'reg', [props['offset'], props['size']])

  def GetBlobList(self):
    """Generate a list of blob types that we are going to need.

    Returns:
      List of blob type strings
    """
    blob_set = set()
    for entry in self.entries:
      if isinstance(entry, EntryBlob):
        blob_set.update(entry.key.split(','))

    return list(blob_set)

  def GetBlobParams(self, blob_type):
    """Returns the parameters for a blob of the given type.

    There should be only one blob of this type in the entire flashmap.

    Args:
      blob_type: Type of the blob (e.g. 'exynos-bl2')

    Raises:
      ValueError if the blob cannot be found.

    Returns:
      The list of parameters for this blob, which may be empty
    """
    for entry in self.entries:
      if isinstance(entry, EntryBlob):
        if entry.key == blob_type:
          return entry.params

    raise ValueError("Blob type '%s' cannot be found" % blob_type)

  def AddProperty(self, name, value):
    """Add a new property which can be used by the fdt.

    Args:
      name: Name of property
      value: Value of property (typically a filename)
    """
    if not value:
      raise CmdError("Cannot find value for entry property '%s'" % name)
    self.props[name] = value

  def GetProperty(self, name):
    """Get the value of a property required by the fdt.

    Args:
      name: Name of property

    Returns:
      Value of property, normally a filename string
    """
    return self.props.get(name, None)

  def ConcatPropContents(self, prop_list, compress, with_index):
    """Read, concatenate and return the contents of the listed props.

    Each property references a filename. We read the contents of each
    file and join it together.

    Each section starts on a 32-bit boundary.

    Args:
      prop_list: List of properties to process
      compress: compression type, like 'lzo', None for no compression
      with_index: Wether an index structure should be prepended
          See ReadFileAndConcat for more details.

    Returns:
      Tuple:
        Contents of the files (as a string), optionally with an index
          prepended (see ReadFileAndConcat for details)
        Directory of the position of the contents, as a dictionary:
          key: Name of the property
          value: List containing:
            offset of the start of this property's data
            size of this property's data
    """
    filenames = [self.props[prop] for prop in prop_list]
    data, offset, length = \
        self.tools.ReadFileAndConcat(filenames, compress, with_index)
    directory = {}
    for i in xrange(len(prop_list)):
      directory[prop_list[i]] = [offset[i], length[i]]
    return data, directory

# For some weird reason pylint presumes that sha256 is not in hashlib
#pylint: disable=E1101

  def UpdateBlobPositionsAndHashes(self, fdt):
    """Record position and size of all blob members in the FDT.

    Some blobs have multiple files within them. We want a way to
    access these individiually. We do this by adding a subnode for
    each, and putting the offset and size information in there.

    This function scans for blobs with more than one file and adds
    a 'reg' property to the subnode for each file. It also adds 'hash'
    nodes with the sha 256 hash of the file's contents.

    Note: Since one of the members may in fact be the fdt, and we are
    updating the fdt, we may change the size it. To get around this,
    we perform two passes of the algorithm. On the second pass we will
    be writing data that is already there, so the fdt size will not
    change.
    """
    for _ in range(0, 2):
      for entry in self.entries:
        if isinstance(entry, EntryBlob) and entry.required:
          self._out.Info("Updating blob positions in fdt for '%s'" % entry.key)
          data, directory = self.ConcatPropContents(
              entry.key.split(','), None, entry.with_index)
          fdt.PutInteger(entry.node, 'used', len(data))
          add_hash = fdt.GetBool(entry.node, 'add-hash')
          if len(directory) > 1 or add_hash:
            # Deprecate this: crbug.com/254311
            # In fact entry.with_index should be deprecated - it is not needed
            # since we can just look at the FDT. Ick.
            fdt.PutInteger(entry.node, '#address-cells', 1)
            fdt.PutInteger(entry.node, '#size-cells', 1)
            for key, item in directory.iteritems():
              fdt.PutIntList(entry.node + '/' + key, 'reg', item)
              hasher = hashlib.sha256()
              offset, size = item
              hasher.update(data[offset:offset + size])
              hash_value = hasher.digest()
              byte_count = struct.unpack('%dB' % len(hash_value), hash_value)
              fdt.PutBytes(entry.node + '/' + key, 'hash', byte_count)
              fdt.PutBool(entry.node + '/' + key, 'this-is-deprecated', True)
          if add_hash:
            hasher = hashlib.sha256()
            hasher.update(data)
            hash_value = hasher.digest()
            byte_count = struct.unpack('%dB' % len(hash_value), hash_value)
            fdt.PutBytes(entry.node, 'hash', byte_count)

  def CheckProperties(self):
    """Check that each entry has the properties that it needs.

    Entries with a 'key' use that to look up properties. We need to make
    sure that there is a property for that key. If not, then the entry will
    not be able to access the data it needs during the packing stage.

    Raises:
      ConfigError: The property for a required key is missing
    """
    for entry in self.entries:
      if entry.required and entry.key:
        if 'value' not in entry:
          entry.value = []
        for prop in entry.key.split(','):
          if not self.props.get(prop):
            raise ConfigError("%s: Requests property '%s' but we only "
                "have %s" % (entry.node, prop, self.props.keys()))
          entry.value.append(self.props[prop])

  def RequireAllEntries(self):
    """Mark all entries as required, to produce a full image."""
    for entry in self.entries:
      entry.required = True

  def GetMissingBlobs(self):
    """Returns a list of blobs that do not currently have data assigned.

    Some blobs may not yet have data assigned, ie. self.props[] does not
    contain a filename for one or more of the blob's data types. This
    function returns a list of nodes that still need to be processed.

    Returns:
      List of device tree nodes that have no data assigned. Each is a
      namedtuple with these members:
        node: Full path to device tree node
        key: Key name (e.g. exynos-bl2')
        params: List of [arameters to the node - the first element is the
            list of files within the blob, for example 'boot,dtb'
    """
    missing = []
    for entry in self.entries:
      if entry.required and isinstance(entry, EntryBlob):
        for prop in entry.key.split(','):
          if not self.props.get(prop):
            value = Value(entry.node, entry.key, entry.params)
            missing.append(value)
            break

    return missing

  def PackImage(self, tmpdir, output_path):
    """Pack the various components into a firmware image,

    You must call SetupFiles() and SelectFdt() first, to set things up. Then
    this function will create a firmware image for you.

    Args:
      output_path: Full path of file to contain the resulting image.

    Raises:
      PackError: If unable to fit something in the space available, or a
          required file or setup piece is missing.
    """
    self.tmpdir = tmpdir

    all_entries = self._CheckOverlap()
    image_used = 0

    # Set up a zeroed file of the correct size.
    with open(output_path, 'wb') as image:
      if all_entries:
        image.write('\0' * self.image_size)

      # Pack all the entriess.
      ifd = None
      for entry in self.entries:
        if not entry.required:
          self._out.Info("Section '%s' is not required, skipping" % entry.name)
          continue

        # Add in the info for the fmap.
        if type(entry) == EntryFmap:
          entry.SetEntries(base=0, image_size=self.image_size,
              entries=self.entries)
        elif type(entry) == EntryIfd:
          ifd = entry

        try:
          # First run any required tools.
          entry.RunTools(self.tools, self._out, self.tmpdir)
          if 'value' in entry:
            self._out.Notice("Pack '%s' into %s" % (', '.join(entry.value),
                entry.name))

          # Now read out the data
          data = entry.GetData()
          self._out.Debug('Entry: %s' % entry.name)
          self._out.Debug('Entry data: %s' % entry)
          self._out.Debug('Data size: %s bytes, at %#x' %
              (len(data), entry.offset))
          if len(data) > entry.size:
            raise PackError("Data for '%s' too large for area: %d/%#x >"
                " %d/%#x" % (entry.name, len(data), len(data), entry.size,
                entry.size))
          if entry.size:
            usage = len(data) * 100 / entry.size
          else:
            usage = 0
          self._out.Notice('Entry: %s, size %#x, data %#x, usage %d%%' %
              (entry.name, entry.size, len(data), usage))
          entry.used = len(data)
          image_used += entry.used

          image.seek(entry.offset)
          image.write(data)

        except PackError as err:
          raise ValueError('Packing error: %s' % err)

    # If the image contain an IFD section, process it
    if ifd:
      ifd.ProduceFinalImage(self.tools, self._out, self.tmpdir, output_path)

    self._out.Notice('Image size %#x, data %#x, usage %d%%' %
      (self.image_size, image_used, image_used * 100 / self.image_size))

  def _OutEntry(self, status, offset, size, name, fname):
    """Display a flash map entry.

    Args:
      status: Status character.
      offset: Byte offset of entry.
      size: Size of entry in bytes.
      name: Name of entry.
      fname: Filename of entry
    """
    indent = '' if status == '-' else ' '
    self._out.UserOutput('%s %08x  %08x  %s%-12s  %s' % (status, offset, size,
        indent, name, fname))

  def ShowMap(self):
    """Show a map of the final image."""
    self._out.UserOutput('Final Flash Map:')
    self._out.UserOutput('%s %8s  %8s  %-12s  %s' %
                         ('S', 'Start', 'Size', 'Name', 'File'))
    offset = 0
    for entry in self.entries:
      if not entry.ftype:
        status = '-'
      elif entry.required:
        status = 'P'
      else:
        status = '.'
      if offset != entry.offset:
        self._OutEntry('!', offset, entry.offset - offset, '<gap>', '')
      self._OutEntry(status, entry.offset, entry.size, entry.name,
                     entry.get('value', ''))
      if entry.ftype:
        offset = entry.offset + entry.size
      else:
        offset = entry.offset

  def GetFmap(self):
    """Get FMAP offset and contents

    Returns:
      Tuple of (FMAP offset, FMAP data)
    """
    for entry in self.entries:
      if type(entry) != EntryFmap:
        continue
      entry.SetEntries(base=0, image_size=self.image_size,
          entries=self.entries)
      return (entry.offset, entry.GetData())

def _Test():
  """Run any built-in tests."""
  import doctest
  assert doctest.testmod().failed == 0

def _PackOutput(msg):
  """Helper function to write output from PackFirmware (verbose level 2).

  This is passed to PackFirmware for it to use to write output.

  Args:
    msg: Message to display.
  """
  print msg

def main():
  """Main function for pack_firmware.

  We provide a way of packing firmware from the command line using this module
  directly.
  """
  parser = optparse.OptionParser()
  parser.add_option('-v', '--verbosity', dest='verbosity', default=1,
      type='int', help='Control verbosity: 0=silent, 1=progress, 3=full, '
      '4=debug')
  parser.add_option('-k', '--key', dest='key', type='string', action='store',
      help='Path to signing key directory (default to dev key)',
      default='##/usr/share/vboot/devkeys')
  parser.add_option('-d', '--dt', dest='fdt', type='string', action='store',
      help='Path to fdt file to use (binary ,dtb)', default='u-boot.dtb')
  parser.add_option('-u', '--uboot', dest='uboot', type='string',
      action='store', help='Executable bootloader file (U-Boot)',
      default='u-boot.bin')
  parser.add_option('-S', '--signed', dest='signed', type='string',
      action='store', help='Path to signed boot binary (U-Boot + BCT + FDT)',
      default='u-boot-fdt-signed.bin')
  parser.add_option('-g', '--gbb', dest='gbb', type='string',
      action='store', help='Path to Google Binary Block file',
      default='gbb.bin')
  parser.add_option('-o', '--outdir', dest='outdir', type='string',
      action='store', help='Path to directory to use for intermediate and '
      'output files', default='out')

  (options, _) = parser.parse_args(sys.argv)

  # Set up the output directory.
  if not os.path.isdir(options.outdir):
    os.makedirs(options.outdir)

  # Get tools and fdt.
  tools = Tools(options.verbosity)
  fdt = Fdt(tools, options.fdt)

  # Pack the firmware.
  pack = PackFirmware(_PackOutput, tools, options.verbosity)
  pack.SetupFiles(boot=options.uboot, signed=options.signed, gbb=options.gbb,
      fwid=tools.GetChromeosVersion(), keydir=options.key)
  pack.SelectFdt(fdt)
  out_fname = os.path.join(options.outdir, 'image.bin')
  pack.PackImage(options.outdir, out_fname)
  print 'Output binary is %s' % out_fname

if __name__ == '__main__':
  if sys.argv[1:2] == ["--test"]:
    _Test(*sys.argv[2:])
  else:
    main()
