diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
new file mode 100644
index 0000000..91abd81
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -0,0 +1,680 @@
+//===-- CommandObjectMemory.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectMemory.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Args.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Options.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/CommandContext.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Read memory from the inferior process
+//----------------------------------------------------------------------
+class CommandObjectMemoryRead : public CommandObject
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+        CommandOptions () :
+            Options()
+        {
+            ResetOptionValues();
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+            case 'f':
+                error = Args::StringToFormat (option_arg, m_format);
+
+                switch (m_format)
+                {
+                default:
+                    break;
+
+                case eFormatBoolean:
+                    if (m_byte_size == 0)
+                        m_byte_size = 1;
+                    if (m_num_per_line == 0)
+                        m_num_per_line = 1;
+                    break;
+
+                case eFormatCString:
+                    if (m_num_per_line == 0)
+                        m_num_per_line = 1;
+                    break;
+
+                case eFormatPointer:
+                    break;
+
+                case eFormatBinary:
+                case eFormatFloat:
+                case eFormatOctal:
+                case eFormatDecimal:
+                case eFormatEnum:
+                case eFormatUnicode16:
+                case eFormatUnicode32:
+                case eFormatUnsigned:
+                    if (m_byte_size == 0)
+                        m_byte_size = 4;
+                    if (m_num_per_line == 0)
+                        m_num_per_line = 1;
+                    break;
+
+                case eFormatBytes:
+                case eFormatBytesWithASCII:
+                case eFormatChar:
+                case eFormatCharPrintable:
+                    if (m_byte_size == 0)
+                        m_byte_size = 1;
+                    break;
+                case eFormatComplex:
+                    if (m_byte_size == 0)
+                        m_byte_size = 8;
+                    break;
+                case eFormatHex:
+                    if (m_byte_size == 0)
+                        m_byte_size = 4;
+                    break;
+
+                case eFormatVectorOfChar:
+                case eFormatVectorOfSInt8:
+                case eFormatVectorOfUInt8:
+                case eFormatVectorOfSInt16:
+                case eFormatVectorOfUInt16:
+                case eFormatVectorOfSInt32:
+                case eFormatVectorOfUInt32:
+                case eFormatVectorOfSInt64:
+                case eFormatVectorOfUInt64:
+                case eFormatVectorOfFloat32:
+                case eFormatVectorOfFloat64:
+                case eFormatVectorOfUInt128:
+                    break;
+                }
+                break;
+
+            case 'l':
+                m_num_per_line = Args::StringToUInt32 (option_arg, 0);
+                if (m_num_per_line == 0)
+                    error.SetErrorStringWithFormat("Invalid value for --num-per-line option '%s'. Must be positive integer value.\n", option_arg);
+                break;
+
+            case 'c':
+                m_count = Args::StringToUInt32 (option_arg, 0);
+                if (m_count == 0)
+                    error.SetErrorStringWithFormat("Invalid value for --count option '%s'. Must be positive integer value.\n", option_arg);
+                break;
+
+            case 's':
+                m_byte_size = Args::StringToUInt32 (option_arg, 0);
+                if (m_byte_size == 0)
+                    error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg);
+                break;
+
+            default:
+                error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
+                break;
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_format = eFormatBytesWithASCII;
+            m_byte_size = 0;
+            m_count = 0;
+            m_num_per_line = 0;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+
+        static lldb::OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+        lldb::Format m_format;
+        uint32_t m_byte_size;
+        uint32_t m_count;
+        uint32_t m_num_per_line;
+    };
+
+    CommandObjectMemoryRead () :
+        CommandObject ("memory read",
+                       "Read memory from the process being debugged.",
+                       "memory read [<cmd-options>] <start-addr> [<end-addr>]",
+                       eFlagProcessMustBeLaunched)
+    {
+    }
+
+    virtual
+    ~CommandObjectMemoryRead ()
+    {
+    }
+
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        Process *process = context->GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError("need a process to read memory");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        const size_t argc = command.GetArgumentCount();
+
+        if (argc == 0 || argc > 2)
+        {
+            result.AppendErrorWithFormat ("%s takes 1 or two args.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+
+        size_t item_byte_size = m_options.m_byte_size;
+        if (item_byte_size == 0)
+        {
+            if (m_options.m_format == eFormatPointer)
+                item_byte_size = process->GetAddressByteSize();
+            else
+                item_byte_size = 1;
+        }
+
+        size_t item_count = m_options.m_count;
+
+        size_t num_per_line = m_options.m_num_per_line;
+        if (num_per_line == 0)
+        {
+            num_per_line = (16/item_byte_size);
+            if (num_per_line == 0)
+                num_per_line = 1;
+        }
+
+        size_t total_byte_size = m_options.m_count * item_byte_size;
+        if (total_byte_size == 0)
+            total_byte_size = 32;
+
+        lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+
+        if (addr == LLDB_INVALID_ADDRESS)
+        {
+            result.AppendErrorWithFormat("invalid start address string '%s'.\n", command.GetArgumentAtIndex(0));
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+
+        if (argc == 2)
+        {
+            lldb::addr_t end_addr = Args::StringToUInt64(command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
+            if (end_addr == LLDB_INVALID_ADDRESS)
+            {
+                result.AppendErrorWithFormat("Invalid end address string '%s'.\n", command.GetArgumentAtIndex(1));
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+            else if (end_addr <= addr)
+            {
+                result.AppendErrorWithFormat("End address (0x%llx) must be greater that the start address (0x%llx).\n", end_addr, addr);
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+            else if (item_count != 0)
+            {
+                result.AppendErrorWithFormat("Specify either the end address (0x%llx) or the count (--count %u), not both.\n", end_addr, item_count);
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+
+            total_byte_size = end_addr - addr;
+            item_count = total_byte_size / item_byte_size;
+        }
+        else
+        {
+            if (item_count == 0)
+                item_count = 32;
+        }
+
+        DataBufferSP data_sp(new DataBufferHeap (total_byte_size, '\0'));
+        Error error;
+        size_t bytes_read = process->ReadMemory(addr, data_sp->GetBytes (), data_sp->GetByteSize(), error);
+        if (bytes_read == 0)
+        {
+            result.AppendWarningWithFormat("Read from 0x%llx failed.\n", addr);
+            result.AppendError(error.AsCString());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+
+        if (bytes_read < total_byte_size)
+            result.AppendWarningWithFormat("Not all bytes (%u/%u) were able to be read from 0x%llx.\n", bytes_read, total_byte_size, addr);
+
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        DataExtractor data(data_sp, process->GetByteOrder(), process->GetAddressByteSize());
+
+        Stream &output_stream = result.GetOutputStream();
+        data.Dump(&output_stream,
+                  0,
+                  m_options.m_format,
+                  item_byte_size,
+                  item_count,
+                  num_per_line,
+                  addr,
+                  0,
+                  0);
+        output_stream.EOL();
+        return true;
+    }
+
+protected:
+    CommandOptions m_options;
+};
+
+lldb::OptionDefinition
+CommandObjectMemoryRead::CommandOptions::g_option_table[] =
+{
+    { 0, false, "format",       'f', required_argument, NULL, 0, "<format>",   "The format that will be used to display the memory. Defaults to bytes with ASCII (--format=Y)."},
+    { 0, false, "size",         's', required_argument, NULL, 0, "<byte-size>","The size in bytes to use when displaying with the selected format."},
+    { 0, false, "num-per-line", 'l', required_argument, NULL, 0, "<N>",        "The number of items per line to display."},
+    { 0, false, "count",        'c', required_argument, NULL, 0, "<N>",        "The number of total items to display."},
+    { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+
+//----------------------------------------------------------------------
+// Write memory to the inferior process
+//----------------------------------------------------------------------
+class CommandObjectMemoryWrite : public CommandObject
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+        CommandOptions () :
+            Options()
+        {
+            ResetOptionValues();
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            switch (short_option)
+            {
+            case 'f':
+                error = Args::StringToFormat (option_arg, m_format);
+                break;
+
+            case 's':
+                m_byte_size = Args::StringToUInt32 (option_arg, 0);
+                if (m_byte_size == 0)
+                    error.SetErrorStringWithFormat("Invalid value for --size option '%s'.  Must be positive integer value.\n", option_arg);
+                break;
+
+
+            default:
+                error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
+                break;
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_format = eFormatBytes;
+            m_byte_size = 1;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+
+        static lldb::OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+        lldb::Format m_format;
+        uint32_t m_byte_size;
+    };
+
+    CommandObjectMemoryWrite () :
+        CommandObject ("memory write",
+                       "Write memory to the process being debugged.",
+                       "memory write [<cmd-options>] <addr> [value1 value2 ...]",
+                       eFlagProcessMustBeLaunched)
+    {
+    }
+
+    virtual
+    ~CommandObjectMemoryWrite ()
+    {
+    }
+
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+    bool
+    UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
+    {
+        if (total_byte_size > 8)
+            return false;
+
+        if (total_byte_size == 8)
+            return true;
+
+        const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
+        return uval64 <= max;
+    }
+
+    bool
+    SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
+    {
+        if (total_byte_size > 8)
+            return false;
+
+        if (total_byte_size == 8)
+            return true;
+
+        const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
+        const int64_t min = ~(max);
+        return min <= sval64 && sval64 <= max;
+    }
+
+    virtual bool
+    Execute (Args& command,
+             CommandContext *context,
+             CommandInterpreter *interpreter,
+             CommandReturnObject &result)
+    {
+        Process *process = context->GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError("need a process to read memory");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+
+        const size_t argc = command.GetArgumentCount();
+
+        if (argc < 2)
+        {
+            result.AppendErrorWithFormat ("%s takes an address and at least one value.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+
+        size_t item_byte_size = m_options.m_byte_size ? m_options.m_byte_size : 1;
+        StreamString buffer (Stream::eBinary,
+                             process->GetAddressByteSize(),
+                             process->GetByteOrder());
+
+        lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+
+        if (addr == LLDB_INVALID_ADDRESS)
+        {
+            result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0));
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        command.Shift(); // shift off the address argument
+        uint64_t uval64;
+        int64_t sval64;
+        bool success = false;
+        const uint32_t num_value_args = command.GetArgumentCount();
+        uint32_t i;
+        for (i=0; i<num_value_args; ++i)
+        {
+            const char *value_str = command.GetArgumentAtIndex(i);
+
+            switch (m_options.m_format)
+            {
+            case eFormatFloat:  // TODO: add support for floats soon
+            case eFormatCharPrintable:
+            case eFormatBytesWithASCII:
+            case eFormatComplex:
+            case eFormatEnum:
+            case eFormatUnicode16:
+            case eFormatUnicode32:
+            case eFormatVectorOfChar:
+            case eFormatVectorOfSInt8:
+            case eFormatVectorOfUInt8:
+            case eFormatVectorOfSInt16:
+            case eFormatVectorOfUInt16:
+            case eFormatVectorOfSInt32:
+            case eFormatVectorOfUInt32:
+            case eFormatVectorOfSInt64:
+            case eFormatVectorOfUInt64:
+            case eFormatVectorOfFloat32:
+            case eFormatVectorOfFloat64:
+            case eFormatVectorOfUInt128:
+                result.AppendError("unsupported format for writing memory");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+
+            case eFormatDefault:
+            case eFormatBytes:
+            case eFormatHex:
+                // Decode hex bytes
+                uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                else if (!UIntValueIsValidForSize (uval64, item_byte_size))
+                {
+                    result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (uval64, item_byte_size);
+                break;
+
+            case eFormatBoolean:
+                uval64 = Args::StringToBoolean(value_str, false, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (uval64, item_byte_size);
+                break;
+
+            case eFormatBinary:
+                uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                else if (!UIntValueIsValidForSize (uval64, item_byte_size))
+                {
+                    result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (uval64, item_byte_size);
+                break;
+
+            case eFormatChar:
+            case eFormatCString:
+                if (value_str[0])
+                {
+                    size_t len = strlen (value_str);
+                    // Include the NULL for C strings...
+                    if (m_options.m_format == eFormatCString)
+                        ++len;
+                    Error error;
+                    if (process->WriteMemory (addr, value_str, len, error) == len)
+                    {
+                        addr += len;
+                    }
+                    else
+                    {
+                        result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
+                        result.SetStatus(eReturnStatusFailed);
+                        return false;
+                    }
+                }
+                break;
+
+            case eFormatDecimal:
+                sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                else if (!SIntValueIsValidForSize (sval64, item_byte_size))
+                {
+                    result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %u byte signed integer value.\n", sval64, item_byte_size);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (sval64, item_byte_size);
+                break;
+
+            case eFormatUnsigned:
+                uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                else if (!UIntValueIsValidForSize (uval64, item_byte_size))
+                {
+                    result.AppendErrorWithFormat ("Value %llu is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (uval64, item_byte_size);
+                break;
+
+            case eFormatOctal:
+                uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
+                if (!success)
+                {
+                    result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                else if (!UIntValueIsValidForSize (uval64, item_byte_size))
+                {
+                    result.AppendErrorWithFormat ("Value %llo is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                buffer.PutMaxHex64 (uval64, item_byte_size);
+                break;
+            }
+        }
+
+        if (!buffer.GetString().empty())
+        {
+            Error error;
+            if (process->WriteMemory (addr, buffer.GetString().data(), buffer.GetString().size(), error) == buffer.GetString().size())
+                return true;
+            else
+            {
+                result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        return true;
+    }
+
+protected:
+    CommandOptions m_options;
+};
+
+lldb::OptionDefinition
+CommandObjectMemoryWrite::CommandOptions::g_option_table[] =
+{
+    { 0, false, "format", 'f', required_argument, NULL, 0, "<format>",   "The format value types that will be decoded and written to memory."},
+    { 0, false, "size",   's', required_argument, NULL, 0, "<byte-size>","The size in bytes of the values to write to memory."},
+    { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+
+//-------------------------------------------------------------------------
+// CommandObjectMemory
+//-------------------------------------------------------------------------
+
+CommandObjectMemory::CommandObjectMemory (CommandInterpreter *interpreter) :
+    CommandObjectMultiword ("memory",
+                            "A set of commands for operating on a memory.",
+                            "memory <subcommand> [<subcommand-options>]")
+{
+    LoadSubCommand (CommandObjectSP (new CommandObjectMemoryRead ()), "read", interpreter);
+    LoadSubCommand (CommandObjectSP (new CommandObjectMemoryWrite ()), "write", interpreter);
+}
+
+CommandObjectMemory::~CommandObjectMemory ()
+{
+}
