static struct iovec *lock_iovec(int type, abi_ulong target_addr,

                                int count, int copy)

{

    struct target_iovec *target_vec;

    struct iovec *vec;

    abi_ulong total_len, max_len;

    int i;

    int err = 0;

    bool bad_address = false;



    if (count == 0) {

        errno = 0;

        return NULL;


    if (count < 0 || count > IOV_MAX) {

        errno = EINVAL;

        return NULL;




    vec = calloc(count, sizeof(struct iovec));

    if (vec == NULL) {

        errno = ENOMEM;

        return NULL;




    target_vec = lock_user(VERIFY_READ, target_addr,

                           count * sizeof(struct target_iovec), 1);

    if (target_vec == NULL) {

        err = EFAULT;

        goto fail2;




    /* ??? If host page size > target page size, this will result in a

       value larger than what we can actually support.  */

    max_len = 0x7fffffff & TARGET_PAGE_MASK;

    total_len = 0;



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

        abi_ulong base = tswapal(target_vec[i].iov_base);

        abi_long len = tswapal(target_vec[i].iov_len);



        if (len < 0) {

            err = EINVAL;

            goto fail;

        } else if (len == 0) {

            /* Zero length pointer is ignored.  */

            vec[i].iov_base = 0;

        } else {

            vec[i].iov_base = lock_user(type, base, len, copy);

            /* If the first buffer pointer is bad, this is a fault.  But

             * subsequent bad buffers will result in a partial write; this

             * is realized by filling the vector with null pointers and

             * zero lengths. */

            if (!vec[i].iov_base) {

                if (i == 0) {

                    err = EFAULT;

                    goto fail;

                } else {

                    bad_address = true;



            if (bad_address) {

                len = 0;


            if (len > max_len - total_len) {

                len = max_len - total_len;



        vec[i].iov_len = len;

        total_len += len;




    unlock_user(target_vec, target_addr, 0);

    return vec;



 fail:






    unlock_user(target_vec, target_addr, 0);

 fail2:

    free(vec);

    errno = err;

    return NULL;

static struct iovec *lock_iovec(int type, abi_ulong target_addr,

                                int count, int copy)

{

    struct target_iovec *target_vec;

    struct iovec *vec;

    abi_ulong total_len, max_len;

    int i;

    int err = 0;

    bool bad_address = false;



    if (count == 0) {

        errno = 0;

        return NULL;


    if (count < 0 || count > IOV_MAX) {

        errno = EINVAL;

        return NULL;




    vec = calloc(count, sizeof(struct iovec));

    if (vec == NULL) {

        errno = ENOMEM;

        return NULL;




    target_vec = lock_user(VERIFY_READ, target_addr,

                           count * sizeof(struct target_iovec), 1);

    if (target_vec == NULL) {

        err = EFAULT;

        goto fail2;




    



    max_len = 0x7fffffff & TARGET_PAGE_MASK;

    total_len = 0;



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

        abi_ulong base = tswapal(target_vec[i].iov_base);

        abi_long len = tswapal(target_vec[i].iov_len);



        if (len < 0) {

            err = EINVAL;

            goto fail;

        } else if (len == 0) {

            

            vec[i].iov_base = 0;

        } else {

            vec[i].iov_base = lock_user(type, base, len, copy);

            







            if (!vec[i].iov_base) {

                if (i == 0) {

                    err = EFAULT;

                    goto fail;

                } else {

                    bad_address = true;



            if (bad_address) {

                len = 0;


            if (len > max_len - total_len) {

                len = max_len - total_len;



        vec[i].iov_len = len;

        total_len += len;




    unlock_user(target_vec, target_addr, 0);

    return vec;



 fail:






    unlock_user(target_vec, target_addr, 0);

 fail2:

    free(vec);

    errno = err;

    return NULL;

static struct iovec *FUNC_0(int VAR_0, abi_ulong VAR_1,

                                int VAR_2, int VAR_3)

{

    struct target_iovec *VAR_4;

    struct iovec *VAR_5;

    abi_ulong total_len, max_len;

    int VAR_6;

    int VAR_7 = 0;

    bool bad_address = false;



    if (VAR_2 == 0) {

        errno = 0;

        return NULL;


    if (VAR_2 < 0 || VAR_2 > IOV_MAX) {

        errno = EINVAL;

        return NULL;




    VAR_5 = calloc(VAR_2, sizeof(struct iovec));

    if (VAR_5 == NULL) {

        errno = ENOMEM;

        return NULL;




    VAR_4 = lock_user(VERIFY_READ, VAR_1,

                           VAR_2 * sizeof(struct target_iovec), 1);

    if (VAR_4 == NULL) {

        VAR_7 = EFAULT;

        goto fail2;




    



    max_len = 0x7fffffff & TARGET_PAGE_MASK;

    total_len = 0;



    for (VAR_6 = 0; VAR_6 < VAR_2; VAR_6++) {

        abi_ulong base = tswapal(VAR_4[VAR_6].iov_base);

        abi_long len = tswapal(VAR_4[VAR_6].iov_len);



        if (len < 0) {

            VAR_7 = EINVAL;

            goto fail;

        } else if (len == 0) {

            

            VAR_5[VAR_6].iov_base = 0;

        } else {

            VAR_5[VAR_6].iov_base = lock_user(VAR_0, base, len, VAR_3);

            







            if (!VAR_5[VAR_6].iov_base) {

                if (VAR_6 == 0) {

                    VAR_7 = EFAULT;

                    goto fail;

                } else {

                    bad_address = true;



            if (bad_address) {

                len = 0;


            if (len > max_len - total_len) {

                len = max_len - total_len;



        VAR_5[VAR_6].iov_len = len;

        total_len += len;




    unlock_user(VAR_4, VAR_1, 0);

    return VAR_5;



 fail:






    unlock_user(VAR_4, VAR_1, 0);

 fail2:

    free(VAR_5);

    errno = VAR_7;

    return NULL;

static struct iovec *FUNC_0(int VAR_0, abi_ulong VAR_1,
int VAR_2, int VAR_3)
{ struct target_iovec *VAR_4; struct iovec *VAR_5; abi_ulong total_len, max_len; int VAR_6; int VAR_7 = 0; bool bad_address = false; if (VAR_2 == 0) { errno = 0; return NULL; if (VAR_2 < 0 || VAR_2 > IOV_MAX) { errno = EINVAL; return NULL; VAR_5 = calloc(VAR_2, sizeof(struct iovec)); if (VAR_5 == NULL) { errno = ENOMEM; return NULL; VAR_4 = lock_user(VERIFY_READ, VAR_1,
VAR_2 * sizeof(struct target_iovec), 1); if (VAR_4 == NULL) { VAR_7 = EFAULT; goto fail2; max_len = 0x7fffffff & TARGET_PAGE_MASK; total_len = 0; for (VAR_6 = 0; VAR_6 < VAR_2; VAR_6++) { abi_ulong base = tswapal(VAR_4[VAR_6].iov_base); abi_long len = tswapal(VAR_4[VAR_6].iov_len); if (len < 0) { VAR_7 = EINVAL; goto fail; } else if (len == 0) { VAR_5[VAR_6].iov_base = 0; } else { VAR_5[VAR_6].iov_base = lock_user(VAR_0, base, len, VAR_3); if (!VAR_5[VAR_6].iov_base) { if (VAR_6 == 0) { VAR_7 = EFAULT; goto fail; } else { bad_address = true; if (bad_address) { len = 0; if (len > max_len - total_len) { len = max_len - total_len; VAR_5[VAR_6].iov_len = len; total_len += len; unlock_user(VAR_4, VAR_1, 0); return VAR_5; fail:
unlock_user(VAR_4, VAR_1, 0); fail2:
free(VAR_5); errno = VAR_7; return NULL;