Exemplo n.º 1
0
/******************************************************************
 *		types_deref
 *
 */
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
{
    struct dbg_type     type = lvalue->type;
    DWORD               tag;

    memset(result, 0, sizeof(*result));
    result->type.id = dbg_itype_none;
    result->type.module = 0;

    /*
     * Make sure that this really makes sense.
     */
    if (!types_get_real_type(&type, &tag) || tag != SymTagPointerType ||
        !memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
        !types_get_info(&type, TI_GET_TYPE, &result->type.id))
        return FALSE;
    result->type.module = type.module;
    result->cookie = DLV_TARGET;
    /* FIXME: this is currently buggy.
     * there is no way to tell were the deref:ed value is...
     * for example:
     *	x is a pointer to struct s, x being on the stack
     *		=> lvalue is in debuggee, result is in debugger
     *	x is a pointer to struct s, x being optimized into a reg
     *		=> lvalue is debugger, result is debuggee
     *	x is a pointer to internal variable x
     *	       	=> lvalue is debugger, result is debuggee
     * so we force debuggee address space, because dereferencing pointers to
     * internal variables is very unlikely. A correct fix would be
     * rather large.
     */
    result->addr.Mode = AddrModeFlat;
    return TRUE;
}
Exemplo n.º 2
0
/******************************************************************
 *		types_extract_as_longlong
 *
 * Given a lvalue, try to get an integral (or pointer/address) value
 * out of it
 */
LONGLONG types_extract_as_longlong(const struct dbg_lvalue* lvalue,
                                   unsigned* psize, BOOL *issigned)
{
    LONGLONG            rtn;
    DWORD               tag, bt;
    DWORD64             size;
    struct dbg_type     type = lvalue->type;
    BOOL                s = FALSE;

    if (!types_get_real_type(&type, &tag))
        RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);

    if (type.id == dbg_itype_segptr)
    {
        return (LONG_PTR)memory_to_linear_addr(&lvalue->addr);
    }

    if (psize) *psize = 0;
    if (issigned) *issigned = FALSE;
    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
            !types_get_info(&type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        if (size > sizeof(rtn))
        {
            WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size));
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        switch (bt)
        {
        case btChar:
        case btInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, s = TRUE, &rtn))
                RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
            break;
        case btUInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
                RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
            break;
        case btFloat:
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        if (psize) *psize = (unsigned)size;
        if (issigned) *issigned = s;
        break;
    case SymTagPointerType:
        if (!be_cpu->fetch_integer(lvalue, sizeof(void*), s = FALSE, &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagArrayType:
    case SymTagUDT:
        if (!be_cpu->fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagEnum:
        /* FIXME: we don't handle enum size */
        if (!be_cpu->fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagFunctionType:
        rtn = (ULONG_PTR)memory_to_linear_addr(&lvalue->addr);
        break;
    default:
        WINE_FIXME("Unsupported tag %u\n", tag);
        RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        break;
    }

    return rtn;
}
Exemplo n.º 3
0
static void print_typed_basic(const struct dbg_lvalue* lvalue)
{
    LONGLONG            val_int;
    void*               val_ptr;
    long double         val_real;
    DWORD64             size64;
    DWORD               tag, size, count, bt;
    struct dbg_type     type = lvalue->type;
    struct dbg_type     sub_type;

    if (!types_get_real_type(&type, &tag)) return;

    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&type, TI_GET_LENGTH, &size64) ||
            !types_get_info(&type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        size = (DWORD)size64;
        switch (bt)
        {
        case btInt:
            if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return;
            dbg_printf("%lld", val_int);
            break;
        case btUInt:
            if (!be_cpu->fetch_integer(lvalue, size, FALSE, &val_int)) return;
            dbg_printf("%llu", val_int);
            break;
        case btFloat:
            if (!be_cpu->fetch_float(lvalue, size, &val_real)) return;
            dbg_printf("%Lf", val_real);
            break;
        case btChar:
            if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return;
            /* FIXME: should do the same for a Unicode character (size == 2) */
            if (size == 1 && (val_int < 0x20 || val_int > 0x80))
                dbg_printf("%d", (int)val_int);
            else
                dbg_printf("'%c'", (char)val_int);
            break;
        default:
            WINE_FIXME("Unsupported basetype %lu\n", bt);
            break;
        }
        break;
    case SymTagPointerType:
        if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return;

        sub_type.module = lvalue->type.module;
        if (!types_get_info(&type, TI_GET_TYPE, &sub_type.id) ||
            sub_type.id == dbg_itype_none)
        {
            dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr);
            break;
        }
        if (!types_get_real_type(&sub_type, &tag)) return;

        if (types_get_info(&sub_type, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType &&
            types_get_info(&sub_type, TI_GET_BASETYPE, &bt) && bt == btChar &&
            types_get_info(&sub_type, TI_GET_LENGTH, &size64))
        {
            char    buffer[1024];

            if (!val_ptr) dbg_printf("0x0");
            else if (memory_get_string(dbg_curr_process, val_ptr, 
                                       lvalue->cookie == DLV_TARGET,
                                       size64 == 2, buffer, sizeof(buffer)))
                dbg_printf("\"%s\"", buffer);
            else
                dbg_printf("*** invalid address %p ***", val_ptr);
        }
        else dbg_printf("%p", val_ptr);
        break;
    case SymTagArrayType:
    case SymTagUDT:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(val_ptr), &val_ptr)) return;
        dbg_printf("%p", val_ptr);
        break;
    case SymTagEnum:
        {
            BOOL        ok = FALSE;

            assert(lvalue->cookie == DLV_TARGET);
            /* FIXME: it depends on underlying type for enums 
             * (not supported yet in dbghelp)
             * Assuming 4 as for an int
             */
            if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return;

            if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
            {
                char                    buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
                TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
                WCHAR*                  ptr;
                char                    tmp[256];
                VARIANT                 variant;
                int                     i;

                fcp->Start = 0;
                while (count)
                {
                    fcp->Count = min(count, 256);
                    if (types_get_info(&type, TI_FINDCHILDREN, fcp))
                    {
                        sub_type.module = type.module;
                        for (i = 0; i < min(fcp->Count, count); i++)
                        {
                            sub_type.id = fcp->ChildId[i];
                            if (!types_get_info(&sub_type, TI_GET_VALUE, &variant)) 
                                continue;
                            switch (variant.n1.n2.vt)
                            {
                            case VT_I4: ok = (val_int == variant.n1.n2.n3.lVal); break;
                            default: WINE_FIXME("Unsupported variant type (%u)\n", variant.n1.n2.vt);
                            }
                            if (ok)
                            {
                                ptr = NULL;
                                types_get_info(&sub_type, TI_GET_SYMNAME, &ptr);
                                if (!ptr) continue;
                                WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                                HeapFree(GetProcessHeap(), 0, ptr);
                                dbg_printf("%s", tmp);
                                count = 0; /* so that we'll get away from outter loop */
                                break;
                            }
                        }
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
            if (!ok) dbg_printf("%lld", val_int);
        }
        break;
    default:
        WINE_FIXME("Unsupported tag %lu\n", tag);
        break;
    }
}
Exemplo n.º 4
0
/******************************************************************
 *		types_extract_as_integer
 *
 * Given a lvalue, try to get an integral (or pointer/address) value
 * out of it
 */
long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
{
    long int            rtn;
    LONGLONG            val;
    DWORD               tag, bt;
    DWORD64             size;
    struct dbg_type     type = lvalue->type;

    if (!types_get_real_type(&type, &tag))
        RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);

    if (type.id == dbg_itype_segptr)
    {
        return (long int)memory_to_linear_addr(&lvalue->addr);
    }

    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
            !types_get_info(&type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        if (size > sizeof(rtn))
        {
            WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size));
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        switch (bt)
        {
        case btChar:
        case btInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, TRUE, &val))
                RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
            rtn = (long)val;
            break;
        case btUInt:
            if (!be_cpu->fetch_integer(lvalue, (unsigned)size, FALSE, &val))
                RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
            rtn = (DWORD)(DWORD64)val;
            break;
        case btFloat:
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        break;
    case SymTagPointerType:
        if (!memory_read_value(lvalue, sizeof(void*), &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagArrayType:
    case SymTagUDT:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagEnum:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn))
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    case SymTagFunctionType:
        rtn = (unsigned)memory_to_linear_addr(&lvalue->addr);
        break;
    default:
        WINE_FIXME("Unsupported tag %lu\n", tag);
        RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        break;
    }

    return rtn;
}