static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,

                            abi_long cmd, abi_long arg)

{

    void *argptr;

    struct dm_ioctl *host_dm;

    abi_long guest_data;

    uint32_t guest_data_size;

    int target_size;

    const argtype *arg_type = ie->arg_type;

    abi_long ret;

    void *big_buf = NULL;

    char *host_data;



    arg_type++;

    target_size = thunk_type_size(arg_type, 0);

    argptr = lock_user(VERIFY_READ, arg, target_size, 1);

    if (!argptr) {

        ret = -TARGET_EFAULT;

        goto out;

    }

    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);

    unlock_user(argptr, arg, 0);



    /* buf_temp is too small, so fetch things into a bigger buffer */

    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);

    memcpy(big_buf, buf_temp, target_size);

    buf_temp = big_buf;

    host_dm = big_buf;



    guest_data = arg + host_dm->data_start;

    if ((guest_data - arg) < 0) {

        ret = -EINVAL;

        goto out;

    }

    guest_data_size = host_dm->data_size - host_dm->data_start;

    host_data = (char*)host_dm + host_dm->data_start;



    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);

    switch (ie->host_cmd) {

    case DM_REMOVE_ALL:

    case DM_LIST_DEVICES:

    case DM_DEV_CREATE:

    case DM_DEV_REMOVE:

    case DM_DEV_SUSPEND:

    case DM_DEV_STATUS:

    case DM_DEV_WAIT:

    case DM_TABLE_STATUS:

    case DM_TABLE_CLEAR:

    case DM_TABLE_DEPS:

    case DM_LIST_VERSIONS:

        /* no input data */

        break;

    case DM_DEV_RENAME:

    case DM_DEV_SET_GEOMETRY:

        /* data contains only strings */

        memcpy(host_data, argptr, guest_data_size);

        break;

    case DM_TARGET_MSG:

        memcpy(host_data, argptr, guest_data_size);

        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);

        break;

    case DM_TABLE_LOAD:

    {

        void *gspec = argptr;

        void *cur_data = host_data;

        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

        int spec_size = thunk_type_size(arg_type, 0);

        int i;



        for (i = 0; i < host_dm->target_count; i++) {

            struct dm_target_spec *spec = cur_data;

            uint32_t next;

            int slen;



            thunk_convert(spec, gspec, arg_type, THUNK_HOST);

            slen = strlen((char*)gspec + spec_size) + 1;

            next = spec->next;

            spec->next = sizeof(*spec) + slen;

            strcpy((char*)&spec[1], gspec + spec_size);

            gspec += next;

            cur_data += spec->next;

        }

        break;

    }

    default:

        ret = -TARGET_EINVAL;

        goto out;

    }

    unlock_user(argptr, guest_data, 0);



    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));

    if (!is_error(ret)) {

        guest_data = arg + host_dm->data_start;

        guest_data_size = host_dm->data_size - host_dm->data_start;

        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);

        switch (ie->host_cmd) {

        case DM_REMOVE_ALL:

        case DM_DEV_CREATE:

        case DM_DEV_REMOVE:

        case DM_DEV_RENAME:

        case DM_DEV_SUSPEND:

        case DM_DEV_STATUS:

        case DM_TABLE_LOAD:

        case DM_TABLE_CLEAR:

        case DM_TARGET_MSG:

        case DM_DEV_SET_GEOMETRY:

            /* no return data */

            break;

        case DM_LIST_DEVICES:

        {

            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };

            int nl_size = 12; /* can't use thunk_size due to alignment */



            while (1) {

                uint32_t next = nl->next;

                if (next) {

                    nl->next = nl_size + (strlen(nl->name) + 1);

                }

                if (remaining_data < nl->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);

                strcpy(cur_data + nl_size, nl->name);

                cur_data += nl->next;

                remaining_data -= nl->next;

                if (!next) {

                    break;

                }

                nl = (void*)nl + next;

            }

            break;

        }

        case DM_DEV_WAIT:

        case DM_TABLE_STATUS:

        {

            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

            int spec_size = thunk_type_size(arg_type, 0);

            int i;



            for (i = 0; i < host_dm->target_count; i++) {

                uint32_t next = spec->next;

                int slen = strlen((char*)&spec[1]) + 1;

                spec->next = (cur_data - argptr) + spec_size + slen;

                if (guest_data_size < spec->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);

                strcpy(cur_data + spec_size, (char*)&spec[1]);

                cur_data = argptr + spec->next;

                spec = (void*)host_dm + host_dm->data_start + next;

            }

            break;

        }

        case DM_TABLE_DEPS:

        {

            void *hdata = (void*)host_dm + host_dm->data_start;

            int count = *(uint32_t*)hdata;

            uint64_t *hdev = hdata + 8;

            uint64_t *gdev = argptr + 8;

            int i;



            *(uint32_t*)argptr = tswap32(count);

            for (i = 0; i < count; i++) {

                *gdev = tswap64(*hdev);

                gdev++;

                hdev++;

            }

            break;

        }

        case DM_LIST_VERSIONS:

        {

            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };

            int vers_size = thunk_type_size(arg_type, 0);



            while (1) {

                uint32_t next = vers->next;

                if (next) {

                    vers->next = vers_size + (strlen(vers->name) + 1);

                }

                if (remaining_data < vers->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);

                strcpy(cur_data + vers_size, vers->name);

                cur_data += vers->next;

                remaining_data -= vers->next;

                if (!next) {

                    break;

                }

                vers = (void*)vers + next;

            }

            break;

        }

        default:

            ret = -TARGET_EINVAL;

            goto out;

        }

        unlock_user(argptr, guest_data, guest_data_size);



        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);

        if (!argptr) {

            ret = -TARGET_EFAULT;

            goto out;

        }

        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);

        unlock_user(argptr, arg, target_size);

    }

out:

    if (big_buf) {

        free(big_buf);

    }

    return ret;

}

static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,

                            abi_long cmd, abi_long arg)

{

    void *argptr;

    struct dm_ioctl *host_dm;

    abi_long guest_data;

    uint32_t guest_data_size;

    int target_size;

    const argtype *arg_type = ie->arg_type;

    abi_long ret;

    void *big_buf = NULL;

    char *host_data;



    arg_type++;

    target_size = thunk_type_size(arg_type, 0);

    argptr = lock_user(VERIFY_READ, arg, target_size, 1);

    if (!argptr) {

        ret = -TARGET_EFAULT;

        goto out;

    }

    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);

    unlock_user(argptr, arg, 0);



    

    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);

    memcpy(big_buf, buf_temp, target_size);

    buf_temp = big_buf;

    host_dm = big_buf;



    guest_data = arg + host_dm->data_start;

    if ((guest_data - arg) < 0) {

        ret = -EINVAL;

        goto out;

    }

    guest_data_size = host_dm->data_size - host_dm->data_start;

    host_data = (char*)host_dm + host_dm->data_start;



    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);

    switch (ie->host_cmd) {

    case DM_REMOVE_ALL:

    case DM_LIST_DEVICES:

    case DM_DEV_CREATE:

    case DM_DEV_REMOVE:

    case DM_DEV_SUSPEND:

    case DM_DEV_STATUS:

    case DM_DEV_WAIT:

    case DM_TABLE_STATUS:

    case DM_TABLE_CLEAR:

    case DM_TABLE_DEPS:

    case DM_LIST_VERSIONS:

        

        break;

    case DM_DEV_RENAME:

    case DM_DEV_SET_GEOMETRY:

        

        memcpy(host_data, argptr, guest_data_size);

        break;

    case DM_TARGET_MSG:

        memcpy(host_data, argptr, guest_data_size);

        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);

        break;

    case DM_TABLE_LOAD:

    {

        void *gspec = argptr;

        void *cur_data = host_data;

        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

        int spec_size = thunk_type_size(arg_type, 0);

        int i;



        for (i = 0; i < host_dm->target_count; i++) {

            struct dm_target_spec *spec = cur_data;

            uint32_t next;

            int slen;



            thunk_convert(spec, gspec, arg_type, THUNK_HOST);

            slen = strlen((char*)gspec + spec_size) + 1;

            next = spec->next;

            spec->next = sizeof(*spec) + slen;

            strcpy((char*)&spec[1], gspec + spec_size);

            gspec += next;

            cur_data += spec->next;

        }

        break;

    }

    default:

        ret = -TARGET_EINVAL;

        goto out;

    }

    unlock_user(argptr, guest_data, 0);



    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));

    if (!is_error(ret)) {

        guest_data = arg + host_dm->data_start;

        guest_data_size = host_dm->data_size - host_dm->data_start;

        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);

        switch (ie->host_cmd) {

        case DM_REMOVE_ALL:

        case DM_DEV_CREATE:

        case DM_DEV_REMOVE:

        case DM_DEV_RENAME:

        case DM_DEV_SUSPEND:

        case DM_DEV_STATUS:

        case DM_TABLE_LOAD:

        case DM_TABLE_CLEAR:

        case DM_TARGET_MSG:

        case DM_DEV_SET_GEOMETRY:

            

            break;

        case DM_LIST_DEVICES:

        {

            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };

            int nl_size = 12; 



            while (1) {

                uint32_t next = nl->next;

                if (next) {

                    nl->next = nl_size + (strlen(nl->name) + 1);

                }

                if (remaining_data < nl->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);

                strcpy(cur_data + nl_size, nl->name);

                cur_data += nl->next;

                remaining_data -= nl->next;

                if (!next) {

                    break;

                }

                nl = (void*)nl + next;

            }

            break;

        }

        case DM_DEV_WAIT:

        case DM_TABLE_STATUS:

        {

            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

            int spec_size = thunk_type_size(arg_type, 0);

            int i;



            for (i = 0; i < host_dm->target_count; i++) {

                uint32_t next = spec->next;

                int slen = strlen((char*)&spec[1]) + 1;

                spec->next = (cur_data - argptr) + spec_size + slen;

                if (guest_data_size < spec->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);

                strcpy(cur_data + spec_size, (char*)&spec[1]);

                cur_data = argptr + spec->next;

                spec = (void*)host_dm + host_dm->data_start + next;

            }

            break;

        }

        case DM_TABLE_DEPS:

        {

            void *hdata = (void*)host_dm + host_dm->data_start;

            int count = *(uint32_t*)hdata;

            uint64_t *hdev = hdata + 8;

            uint64_t *gdev = argptr + 8;

            int i;



            *(uint32_t*)argptr = tswap32(count);

            for (i = 0; i < count; i++) {

                *gdev = tswap64(*hdev);

                gdev++;

                hdev++;

            }

            break;

        }

        case DM_LIST_VERSIONS:

        {

            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };

            int vers_size = thunk_type_size(arg_type, 0);



            while (1) {

                uint32_t next = vers->next;

                if (next) {

                    vers->next = vers_size + (strlen(vers->name) + 1);

                }

                if (remaining_data < vers->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);

                strcpy(cur_data + vers_size, vers->name);

                cur_data += vers->next;

                remaining_data -= vers->next;

                if (!next) {

                    break;

                }

                vers = (void*)vers + next;

            }

            break;

        }

        default:

            ret = -TARGET_EINVAL;

            goto out;

        }

        unlock_user(argptr, guest_data, guest_data_size);



        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);

        if (!argptr) {

            ret = -TARGET_EFAULT;

            goto out;

        }

        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);

        unlock_user(argptr, arg, target_size);

    }

out:

    if (big_buf) {

        free(big_buf);

    }

    return ret;

}

static abi_long FUNC_0(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,

                            abi_long cmd, abi_long arg)

{

    void *VAR_0;

    struct dm_ioctl *VAR_1;

    abi_long guest_data;

    uint32_t guest_data_size;

    int VAR_2;

    const argtype *VAR_17 = ie->VAR_17;

    abi_long ret;

    void *VAR_4 = NULL;

    char *VAR_5;



    VAR_17++;

    VAR_2 = thunk_type_size(VAR_17, 0);

    VAR_0 = lock_user(VERIFY_READ, arg, VAR_2, 1);

    if (!VAR_0) {

        ret = -TARGET_EFAULT;

        goto out;

    }

    thunk_convert(buf_temp, VAR_0, VAR_17, THUNK_HOST);

    unlock_user(VAR_0, arg, 0);



    

    VAR_4 = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);

    memcpy(VAR_4, buf_temp, VAR_2);

    buf_temp = VAR_4;

    VAR_1 = VAR_4;



    guest_data = arg + VAR_1->data_start;

    if ((guest_data - arg) < 0) {

        ret = -EINVAL;

        goto out;

    }

    guest_data_size = VAR_1->data_size - VAR_1->data_start;

    VAR_5 = (char*)VAR_1 + VAR_1->data_start;



    VAR_0 = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);

    switch (ie->host_cmd) {

    case DM_REMOVE_ALL:

    case DM_LIST_DEVICES:

    case DM_DEV_CREATE:

    case DM_DEV_REMOVE:

    case DM_DEV_SUSPEND:

    case DM_DEV_STATUS:

    case DM_DEV_WAIT:

    case DM_TABLE_STATUS:

    case DM_TABLE_CLEAR:

    case DM_TABLE_DEPS:

    case DM_LIST_VERSIONS:

        

        break;

    case DM_DEV_RENAME:

    case DM_DEV_SET_GEOMETRY:

        

        memcpy(VAR_5, VAR_0, guest_data_size);

        break;

    case DM_TARGET_MSG:

        memcpy(VAR_5, VAR_0, guest_data_size);

        *(uint64_t*)VAR_5 = tswap64(*(uint64_t*)VAR_0);

        break;

    case DM_TABLE_LOAD:

    {

        void *VAR_6 = VAR_0;

        void *VAR_17 = VAR_5;

        const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_spec) };

        int VAR_14 = thunk_type_size(VAR_17, 0);

        int VAR_16;



        for (VAR_16 = 0; VAR_16 < VAR_1->target_count; VAR_16++) {

            struct dm_target_spec *VAR_14 = VAR_17;

            uint32_t next;

            int VAR_14;



            thunk_convert(VAR_14, VAR_6, VAR_17, THUNK_HOST);

            VAR_14 = strlen((char*)VAR_6 + VAR_14) + 1;

            next = VAR_14->next;

            VAR_14->next = sizeof(*VAR_14) + VAR_14;

            strcpy((char*)&VAR_14[1], VAR_6 + VAR_14);

            VAR_6 += next;

            VAR_17 += VAR_14->next;

        }

        break;

    }

    default:

        ret = -TARGET_EINVAL;

        goto out;

    }

    unlock_user(VAR_0, guest_data, 0);



    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));

    if (!is_error(ret)) {

        guest_data = arg + VAR_1->data_start;

        guest_data_size = VAR_1->data_size - VAR_1->data_start;

        VAR_0 = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);

        switch (ie->host_cmd) {

        case DM_REMOVE_ALL:

        case DM_DEV_CREATE:

        case DM_DEV_REMOVE:

        case DM_DEV_RENAME:

        case DM_DEV_SUSPEND:

        case DM_DEV_STATUS:

        case DM_TABLE_LOAD:

        case DM_TABLE_CLEAR:

        case DM_TARGET_MSG:

        case DM_DEV_SET_GEOMETRY:

            

            break;

        case DM_LIST_DEVICES:

        {

            struct dm_name_list *VAR_12 = (void*)VAR_1 + VAR_1->data_start;

            uint32_t remaining_data = guest_data_size;

            void *VAR_17 = VAR_0;

            const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_name_list) };

            int VAR_13 = 12; 



            while (1) {

                uint32_t next = VAR_12->next;

                if (next) {

                    VAR_12->next = VAR_13 + (strlen(VAR_12->name) + 1);

                }

                if (remaining_data < VAR_12->next) {

                    VAR_1->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(VAR_17, VAR_12, VAR_17, THUNK_TARGET);

                strcpy(VAR_17 + VAR_13, VAR_12->name);

                VAR_17 += VAR_12->next;

                remaining_data -= VAR_12->next;

                if (!next) {

                    break;

                }

                VAR_12 = (void*)VAR_12 + next;

            }

            break;

        }

        case DM_DEV_WAIT:

        case DM_TABLE_STATUS:

        {

            struct dm_target_spec *VAR_14 = (void*)VAR_1 + VAR_1->data_start;

            void *VAR_17 = VAR_0;

            const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_spec) };

            int VAR_14 = thunk_type_size(VAR_17, 0);

            int VAR_16;



            for (VAR_16 = 0; VAR_16 < VAR_1->target_count; VAR_16++) {

                uint32_t next = VAR_14->next;

                int VAR_14 = strlen((char*)&VAR_14[1]) + 1;

                VAR_14->next = (VAR_17 - VAR_0) + VAR_14 + VAR_14;

                if (guest_data_size < VAR_14->next) {

                    VAR_1->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(VAR_17, VAR_14, VAR_17, THUNK_TARGET);

                strcpy(VAR_17 + VAR_14, (char*)&VAR_14[1]);

                VAR_17 = VAR_0 + VAR_14->next;

                VAR_14 = (void*)VAR_1 + VAR_1->data_start + next;

            }

            break;

        }

        case DM_TABLE_DEPS:

        {

            void *VAR_14 = (void*)VAR_1 + VAR_1->data_start;

            int VAR_15 = *(uint32_t*)VAR_14;

            uint64_t *hdev = VAR_14 + 8;

            uint64_t *gdev = VAR_0 + 8;

            int VAR_16;



            *(uint32_t*)VAR_0 = tswap32(VAR_15);

            for (VAR_16 = 0; VAR_16 < VAR_15; VAR_16++) {

                *gdev = tswap64(*hdev);

                gdev++;

                hdev++;

            }

            break;

        }

        case DM_LIST_VERSIONS:

        {

            struct dm_target_versions *VAR_16 = (void*)VAR_1 + VAR_1->data_start;

            uint32_t remaining_data = guest_data_size;

            void *VAR_17 = VAR_0;

            const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_versions) };

            int VAR_17 = thunk_type_size(VAR_17, 0);



            while (1) {

                uint32_t next = VAR_16->next;

                if (next) {

                    VAR_16->next = VAR_17 + (strlen(VAR_16->name) + 1);

                }

                if (remaining_data < VAR_16->next) {

                    VAR_1->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(VAR_17, VAR_16, VAR_17, THUNK_TARGET);

                strcpy(VAR_17 + VAR_17, VAR_16->name);

                VAR_17 += VAR_16->next;

                remaining_data -= VAR_16->next;

                if (!next) {

                    break;

                }

                VAR_16 = (void*)VAR_16 + next;

            }

            break;

        }

        default:

            ret = -TARGET_EINVAL;

            goto out;

        }

        unlock_user(VAR_0, guest_data, guest_data_size);



        VAR_0 = lock_user(VERIFY_WRITE, arg, VAR_2, 0);

        if (!VAR_0) {

            ret = -TARGET_EFAULT;

            goto out;

        }

        thunk_convert(VAR_0, buf_temp, VAR_17, THUNK_TARGET);

        unlock_user(VAR_0, arg, VAR_2);

    }

out:

    if (VAR_4) {

        free(VAR_4);

    }

    return ret;

}

static abi_long FUNC_0(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
abi_long cmd, abi_long arg)
{ void *VAR_0; struct dm_ioctl *VAR_1; abi_long guest_data; uint32_t guest_data_size; int VAR_2; const argtype *VAR_17 = ie->VAR_17; abi_long ret; void *VAR_4 = NULL; char *VAR_5; VAR_17++; VAR_2 = thunk_type_size(VAR_17, 0); VAR_0 = lock_user(VERIFY_READ, arg, VAR_2, 1); if (!VAR_0) { ret = -TARGET_EFAULT; goto out; } thunk_convert(buf_temp, VAR_0, VAR_17, THUNK_HOST); unlock_user(VAR_0, arg, 0); VAR_4 = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2); memcpy(VAR_4, buf_temp, VAR_2); buf_temp = VAR_4; VAR_1 = VAR_4; guest_data = arg + VAR_1->data_start; if ((guest_data - arg) < 0) { ret = -EINVAL; goto out; } guest_data_size = VAR_1->data_size - VAR_1->data_start; VAR_5 = (char*)VAR_1 + VAR_1->data_start; VAR_0 = lock_user(VERIFY_READ, guest_data, guest_data_size, 1); switch (ie->host_cmd) { case DM_REMOVE_ALL:
case DM_LIST_DEVICES:
case DM_DEV_CREATE:
case DM_DEV_REMOVE:
case DM_DEV_SUSPEND:
case DM_DEV_STATUS:
case DM_DEV_WAIT:
case DM_TABLE_STATUS:
case DM_TABLE_CLEAR:
case DM_TABLE_DEPS:
case DM_LIST_VERSIONS:
break; case DM_DEV_RENAME:
case DM_DEV_SET_GEOMETRY:
memcpy(VAR_5, VAR_0, guest_data_size); break; case DM_TARGET_MSG:
memcpy(VAR_5, VAR_0, guest_data_size); *(uint64_t*)VAR_5 = tswap64(*(uint64_t*)VAR_0); break; case DM_TABLE_LOAD:
{ void *VAR_6 = VAR_0; void *VAR_17 = VAR_5; const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_spec) }; int VAR_14 = thunk_type_size(VAR_17, 0); int VAR_16; for (VAR_16 = 0; VAR_16 < VAR_1->target_count; VAR_16++) { struct dm_target_spec *VAR_14 = VAR_17; uint32_t next; int VAR_14; thunk_convert(VAR_14, VAR_6, VAR_17, THUNK_HOST); VAR_14 = strlen((char*)VAR_6 + VAR_14) + 1; next = VAR_14->next; VAR_14->next = sizeof(*VAR_14) + VAR_14; strcpy((char*)&VAR_14[1], VAR_6 + VAR_14); VAR_6 += next; VAR_17 += VAR_14->next; } break; } default:
ret = -TARGET_EINVAL; goto out; } unlock_user(VAR_0, guest_data, 0); ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); if (!is_error(ret)) { guest_data = arg + VAR_1->data_start; guest_data_size = VAR_1->data_size - VAR_1->data_start; VAR_0 = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0); switch (ie->host_cmd) { case DM_REMOVE_ALL:
case DM_DEV_CREATE:
case DM_DEV_REMOVE:
case DM_DEV_RENAME:
case DM_DEV_SUSPEND:
case DM_DEV_STATUS:
case DM_TABLE_LOAD:
case DM_TABLE_CLEAR:
case DM_TARGET_MSG:
case DM_DEV_SET_GEOMETRY:
break; case DM_LIST_DEVICES:
{ struct dm_name_list *VAR_12 = (void*)VAR_1 + VAR_1->data_start; uint32_t remaining_data = guest_data_size; void *VAR_17 = VAR_0; const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_name_list) }; int VAR_13 = 12; while (1) { uint32_t next = VAR_12->next; if (next) { VAR_12->next = VAR_13 + (strlen(VAR_12->name) + 1); } if (remaining_data < VAR_12->next) { VAR_1->flags |= DM_BUFFER_FULL_FLAG; break; } thunk_convert(VAR_17, VAR_12, VAR_17, THUNK_TARGET); strcpy(VAR_17 + VAR_13, VAR_12->name); VAR_17 += VAR_12->next; remaining_data -= VAR_12->next; if (!next) { break; } VAR_12 = (void*)VAR_12 + next; } break; } case DM_DEV_WAIT:
case DM_TABLE_STATUS:
{ struct dm_target_spec *VAR_14 = (void*)VAR_1 + VAR_1->data_start; void *VAR_17 = VAR_0; const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_spec) }; int VAR_14 = thunk_type_size(VAR_17, 0); int VAR_16; for (VAR_16 = 0; VAR_16 < VAR_1->target_count; VAR_16++) { uint32_t next = VAR_14->next; int VAR_14 = strlen((char*)&VAR_14[1]) + 1; VAR_14->next = (VAR_17 - VAR_0) + VAR_14 + VAR_14; if (guest_data_size < VAR_14->next) { VAR_1->flags |= DM_BUFFER_FULL_FLAG; break; } thunk_convert(VAR_17, VAR_14, VAR_17, THUNK_TARGET); strcpy(VAR_17 + VAR_14, (char*)&VAR_14[1]); VAR_17 = VAR_0 + VAR_14->next; VAR_14 = (void*)VAR_1 + VAR_1->data_start + next; } break; } case DM_TABLE_DEPS:
{ void *VAR_14 = (void*)VAR_1 + VAR_1->data_start; int VAR_15 = *(uint32_t*)VAR_14; uint64_t *hdev = VAR_14 + 8; uint64_t *gdev = VAR_0 + 8; int VAR_16; *(uint32_t*)VAR_0 = tswap32(VAR_15); for (VAR_16 = 0; VAR_16 < VAR_15; VAR_16++) { *gdev = tswap64(*hdev); gdev++; hdev++; } break; } case DM_LIST_VERSIONS:
{ struct dm_target_versions *VAR_16 = (void*)VAR_1 + VAR_1->data_start; uint32_t remaining_data = guest_data_size; void *VAR_17 = VAR_0; const argtype VAR_17[] = { MK_STRUCT(STRUCT_dm_target_versions) }; int VAR_17 = thunk_type_size(VAR_17, 0); while (1) { uint32_t next = VAR_16->next; if (next) { VAR_16->next = VAR_17 + (strlen(VAR_16->name) + 1); } if (remaining_data < VAR_16->next) { VAR_1->flags |= DM_BUFFER_FULL_FLAG; break; } thunk_convert(VAR_17, VAR_16, VAR_17, THUNK_TARGET); strcpy(VAR_17 + VAR_17, VAR_16->name); VAR_17 += VAR_16->next; remaining_data -= VAR_16->next; if (!next) { break; } VAR_16 = (void*)VAR_16 + next; } break; } default:
ret = -TARGET_EINVAL; goto out; } unlock_user(VAR_0, guest_data, guest_data_size); VAR_0 = lock_user(VERIFY_WRITE, arg, VAR_2, 0); if (!VAR_0) { ret = -TARGET_EFAULT; goto out; } thunk_convert(VAR_0, buf_temp, VAR_17, THUNK_TARGET); unlock_user(VAR_0, arg, VAR_2); } out:
if (VAR_4) { free(VAR_4); } return ret; }