# This implements the "diagnose-nsstring" command, usually installed in the debug session like
#   command script import lldb.diagnose
# it is used when NSString summary formatter fails to replicate the logic that went into LLDB making the
# decisions it did and  providing some useful context information that can
# be used for improving the formatter

import lldb


def read_memory(process, location, size):
    data = ""
    error = lldb.SBError()
    for x in range(0, size - 1):
        byte = process.ReadUnsignedFromMemory(x + location, 1, error)
        if error.fail:
            data = data + "err%s" % "" if x == size - 2 else ":"
        else:
            try:
                data = data + "0x%x" % byte
                if byte == 0:
                    data = data + "(\\0)"
                elif byte == 0xa:
                    data = data + "(\\a)"
                elif byte == 0xb:
                    data = data + "(\\b)"
                elif byte == 0xc:
                    data = data + "(\\c)"
                elif byte == '\n':
                    data = data + "(\\n)"
                else:
                    data = data + "(%s)" % chr(byte)
                if x < size - 2:
                    data = data + ":"
            except Exception as e:
                print e
    return data


def diagnose_nsstring_Command_Impl(debugger, command, result, internal_dict):
    """
    A command to diagnose the LLDB NSString data formatter
    invoke as
    (lldb) diagnose-nsstring <expr returning NSString>
    e.g.
    (lldb) diagnose-nsstring @"Hello world"
    """
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    thread = process.GetSelectedThread()
    frame = thread.GetSelectedFrame()
    if not target.IsValid() or not process.IsValid():
        return "unable to get target/process - cannot proceed"
    options = lldb.SBExpressionOptions()
    options.SetFetchDynamicValue()
    error = lldb.SBError()
    if frame.IsValid():
        nsstring = frame.EvaluateExpression(command, options)
    else:
        nsstring = target.EvaluateExpression(command, options)
    print >>result, str(nsstring)
    nsstring_address = nsstring.GetValueAsUnsigned(0)
    if nsstring_address == 0:
        return "unable to obtain the string - cannot proceed"
    expression = "\
struct $__lldb__notInlineMutable {\
    char* buffer;\
    signed long length;\
    signed long capacity;\
    unsigned int hasGap:1;\
    unsigned int isFixedCapacity:1;\
    unsigned int isExternalMutable:1;\
    unsigned int capacityProvidedExternally:1;\n\
#if __LP64__\n\
    unsigned long desiredCapacity:60;\n\
#else\n\
    unsigned long desiredCapacity:28;\n\
#endif\n\
    void* contentsAllocator;\
};\
\
struct $__lldb__CFString {\
    void* _cfisa;\
    uint8_t _cfinfo[4];\
    uint32_t _rc;\
    union {\
        struct __inline1 {\
            signed long length;\
        } inline1;\
        struct __notInlineImmutable1 {\
            char* buffer;\
            signed long length;\
            void* contentsDeallocator;\
        } notInlineImmutable1;\
        struct __notInlineImmutable2 {\
            char* buffer;\
            void* contentsDeallocator;\
        } notInlineImmutable2;\
        struct $__lldb__notInlineMutable notInlineMutable;\
    } variants;\
};\
"

    expression = expression + "*(($__lldb__CFString*) %d)" % nsstring_address
    # print expression
    dumped = target.EvaluateExpression(expression, options)
    print >>result, str(dumped)

    little_endian = (target.byte_order == lldb.eByteOrderLittle)
    ptr_size = target.addr_size

    info_bits = dumped.GetChildMemberWithName("_cfinfo").GetChildAtIndex(
        0 if little_endian else 3).GetValueAsUnsigned(0)
    is_mutable = (info_bits & 1) == 1
    is_inline = (info_bits & 0x60) == 0
    has_explicit_length = (info_bits & (1 | 4)) != 4
    is_unicode = (info_bits & 0x10) == 0x10
    is_special = (
        nsstring.GetDynamicValue(
            lldb.eDynamicCanRunTarget).GetTypeName() == "NSPathStore2")
    has_null = (info_bits & 8) == 8

    print >>result, "\nInfo=%d\nMutable=%s\nInline=%s\nExplicit=%s\nUnicode=%s\nSpecial=%s\nNull=%s\n" % \
        (info_bits, "yes" if is_mutable else "no", "yes" if is_inline else "no", "yes" if has_explicit_length else "no", "yes" if is_unicode else "no", "yes" if is_special else "no", "yes" if has_null else "no")

    explicit_length_offset = 0
    if not has_null and has_explicit_length and not is_special:
        explicit_length_offset = 2 * ptr_size
        if is_mutable and not is_inline:
            explicit_length_offset = explicit_length_offset + ptr_size
        elif is_inline:
            pass
        elif not is_inline and not is_mutable:
            explicit_length_offset = explicit_length_offset + ptr_size
        else:
            explicit_length_offset = 0

    if explicit_length_offset == 0:
        print >>result, "There is no explicit length marker - skipping this step\n"
    else:
        explicit_length_offset = nsstring_address + explicit_length_offset
        explicit_length = process.ReadUnsignedFromMemory(
            explicit_length_offset, 4, error)
        print >>result, "Explicit length location is at 0x%x - read value is %d\n" % (
            explicit_length_offset, explicit_length)

    if is_mutable:
        location = 2 * ptr_size + nsstring_address
        location = process.ReadPointerFromMemory(location, error)
    elif is_inline and has_explicit_length and not is_unicode and not is_special and not is_mutable:
        location = 3 * ptr_size + nsstring_address
    elif is_unicode:
        location = 2 * ptr_size + nsstring_address
        if is_inline:
            if not has_explicit_length:
                print >>result, "Unicode & Inline & !Explicit is a new combo - no formula for it"
            else:
                location += ptr_size
        else:
            location = process.ReadPointerFromMemory(location, error)
    elif is_special:
        location = nsstring_address + ptr_size + 4
    elif is_inline:
        location = 2 * ptr_size + nsstring_address
        if not has_explicit_length:
            location += 1
    else:
        location = 2 * ptr_size + nsstring_address
        location = process.ReadPointerFromMemory(location, error)
    print >>result, "Expected data location: 0x%x\n" % (location)
    print >>result, "1K of data around location: %s\n" % read_memory(
        process, location, 1024)
    print >>result, "5K of data around string pointer: %s\n" % read_memory(
        process, nsstring_address, 1024 * 5)


def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand(
        "command script add -f %s.diagnose_nsstring_Command_Impl diagnose-nsstring" %
        __name__)
    print 'The "diagnose-nsstring" command has been installed, type "help diagnose-nsstring" for detailed help.'

__lldb_init_module(lldb.debugger, None)
__lldb_init_module = None
