#!/usr/bin/env python3

# Copyright (c) 2014 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.


"""Access memory using /dev/mem.

Can be used as a command-line tool or via 'import mem' in python.
"""


import argparse
import code
import inspect
import mmap
import struct
import sys


_BANNER = """Welcome to mem interactive mode (featuring python!)

Available functions:
"""


class HexInt(int):
  """An int that prints out as hex but is still just a number."""

  def __repr__(self):
    try:
      width = getattr(self, 'width')
    except AttributeError:
      width = 4
    return '%#0*x' % (2 * width + 2, self)

  def __str__(self):
    return repr(self)


def rm(addr, nbytes):
  """Read memory at the given addr as a string.

  Args:
    addr: The address to read at.
    nbytes: The number of bytes to read.

  Returns:
    The string that was read.
  """
  with open('/dev/mem', 'r+b') as mem:
    offset = addr & 0xfff
    mem_map = mmap.mmap(mem.fileno(), nbytes + offset, offset=addr & ~0xfff)
    return mem_map[offset:offset + nbytes]


def wm(addr, val):
  """Write a string to memory at the given addr.

  Args:
    addr: The address to read at.
    val: A string to write.
  """
  with open('/dev/mem', 'r+b') as mem:
    nbytes = len(val)
    offset = addr & 0xfff
    mem_map = mmap.mmap(mem.fileno(), nbytes + offset, offset=addr & ~0xfff)
    mem_map[offset:offset + nbytes] = val


def r(addr):
  """Read a single 32-bit word (little endian).

  Args:
    addr: The address to read at.

  Returns:
    The value that was read; returns as a HexInt (a subclass of long) so that
    it by default prints itself in hex.  You can use this like any other int.
  """
  return HexInt(struct.unpack('<I', rm(addr, 4))[0])


def w(addr, val):
  """Write a single 32-bit word (little endian).

  Args:
    addr: The address to write to.
    val:  The value to write.
  """
  wm(addr, struct.pack('<I', val))


def _ParseInt(x):
  """Create an int from a string, autodetecting the base."""
  return int(x, 0)


# Commands we export and their argument types.
_COMMANDS = {
    'r': [_ParseInt],
    'w': [_ParseInt, _ParseInt],
    'rm': [_ParseInt, _ParseInt],
    'wm': [_ParseInt, str],
}


def _ListCommands():
  """Return a list of commands as a string.

  Returns:
    A string that can be printed to the user.
  """
  commands = []

  for cmd_name in sorted(_COMMANDS.keys()):
    func = eval(cmd_name)
    arg_names = inspect.signature(func).parameters
    short_doc = func.__doc__.splitlines()[0]

    arg_string = ', '.join(arg_names)
    commands.append('- %s(%s) # %s' % (cmd_name, arg_string, short_doc))

  return '\n'.join(commands)


def _CreateParser():
  """Create an argparse object we can use.

  Returns:
    An argparse object that can be used to parse our options.
  """
  parser = argparse.ArgumentParser()
  subparsers = parser.add_subparsers()

  for cmd_name, arg_types in sorted(_COMMANDS.items()):
    func = eval(cmd_name)
    arg_names = inspect.signature(func).parameters
    short_doc = func.__doc__.splitlines()[0]

    # Get descriptions out assuming single-line descs.
    arg_descs = {}
    for line in func.__doc__.splitlines():
      line = line.strip()
      arg_name = line.split(':')[0]
      if arg_name in arg_names:
        arg_descs[arg_name] = line.partition(':')[-1]

    subparser = subparsers.add_parser(cmd_name, help=short_doc)
    for arg_name, arg_type in zip(arg_names, arg_types):
      subparser.add_argument(arg_name, type=arg_type,
                             help=arg_descs[arg_name])
      subparser.set_defaults(func=func)

  return parser


def main(args=None):
  if args is None:
    args = sys.argv[1:]

  if not args:
    # Try to pretend that they ran python -i to just use us interactively.
    return code.interact(banner=_BANNER + _ListCommands(), local=globals())

  parser = _CreateParser()
  try:
    # Parse args and get back something we can use to call the function.
    namespace = parser.parse_args(args)
    func_kwargs = vars(namespace).copy()
    func = func_kwargs.pop('func')

    result = func(**func_kwargs)

    # Print the result; no trailing return if we're not on a tty.
    if result is not None:
      print(result, end='\n' if sys.stdout.isatty() else '')
  except Exception as e:
    # For now really simple error handling...
    parser.error(str(e))

    return 1
  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
