# 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

from __future__ import print_function

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(str(nsstring), file=result)
    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(str(dumped), file=result)

    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("\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"), file=result)

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

    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("Unicode & Inline & !Explicit is a new combo - no formula for it", file=result)
            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("Expected data location: 0x%x\n" % (location), file=result)
    print("1K of data around location: %s\n" % read_memory(
        process, location, 1024), file=result)
    print("5K of data around string pointer: %s\n" % read_memory(
        process, nsstring_address, 1024 * 5), file=result)


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
