static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)

{

    abi_long raddr;

    void *host_raddr;

    struct shmid_ds shm_info;

    int i,ret;



    /* find out the length of the shared memory segment */

    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));

    if (is_error(ret)) {

        /* can't get length, bail out */

        return ret;

    }



    mmap_lock();



    if (shmaddr)

        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);

    else {

        abi_ulong mmap_start;



        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);



        if (mmap_start == -1) {

            errno = ENOMEM;

            host_raddr = (void *)-1;

        } else

            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);

    }



    if (host_raddr == (void *)-1) {

        mmap_unlock();

        return get_errno((long)host_raddr);

    }

    raddr=h2g((unsigned long)host_raddr);



    page_set_flags(raddr, raddr + shm_info.shm_segsz,

                   PAGE_VALID | PAGE_READ |

                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));



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

        if (!shm_regions[i].in_use) {

            shm_regions[i].in_use = true;

            shm_regions[i].start = raddr;

            shm_regions[i].size = shm_info.shm_segsz;

            break;

        }

    }



    mmap_unlock();

    return raddr;



}

static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)

{

    abi_long raddr;

    void *host_raddr;

    struct shmid_ds shm_info;

    int i,ret;



    

    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));

    if (is_error(ret)) {

        

        return ret;

    }



    mmap_lock();



    if (shmaddr)

        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);

    else {

        abi_ulong mmap_start;



        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);



        if (mmap_start == -1) {

            errno = ENOMEM;

            host_raddr = (void *)-1;

        } else

            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);

    }



    if (host_raddr == (void *)-1) {

        mmap_unlock();

        return get_errno((long)host_raddr);

    }

    raddr=h2g((unsigned long)host_raddr);



    page_set_flags(raddr, raddr + shm_info.shm_segsz,

                   PAGE_VALID | PAGE_READ |

                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));



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

        if (!shm_regions[i].in_use) {

            shm_regions[i].in_use = true;

            shm_regions[i].start = raddr;

            shm_regions[i].size = shm_info.shm_segsz;

            break;

        }

    }



    mmap_unlock();

    return raddr;



}

static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
static inline abi_ulong FUNC_0(int shmid, abi_ulong shmaddr, int shmflg)

{

    abi_long raddr;

    void *VAR_0;

    struct shmid_ds VAR_1;

    int VAR_2,VAR_3;



    

    VAR_3 = get_errno(shmctl(shmid, IPC_STAT, &VAR_1));

    if (is_error(VAR_3)) {

        

        return VAR_3;

    }



    mmap_lock();



    if (shmaddr)

        VAR_0 = shmat(shmid, (void *)g2h(shmaddr), shmflg);

    else {

        abi_ulong mmap_start;



        mmap_start = mmap_find_vma(0, VAR_1.shm_segsz);



        if (mmap_start == -1) {

            errno = ENOMEM;

            VAR_0 = (void *)-1;

        } else

            VAR_0 = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);

    }



    if (VAR_0 == (void *)-1) {

        mmap_unlock();

        return get_errno((long)VAR_0);

    }

    raddr=h2g((unsigned long)VAR_0);



    page_set_flags(raddr, raddr + VAR_1.shm_segsz,

                   PAGE_VALID | PAGE_READ |

                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));



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

        if (!shm_regions[VAR_2].in_use) {

            shm_regions[VAR_2].in_use = true;

            shm_regions[VAR_2].start = raddr;

            shm_regions[VAR_2].size = VAR_1.shm_segsz;

            break;

        }

    }



    mmap_unlock();

    return raddr;



}

static inline abi_ulong FUNC_0(int shmid, abi_ulong shmaddr, int shmflg)
{ abi_long raddr; void *VAR_0; struct shmid_ds VAR_1; int VAR_2,VAR_3; VAR_3 = get_errno(shmctl(shmid, IPC_STAT, &VAR_1)); if (is_error(VAR_3)) { return VAR_3; } mmap_lock(); if (shmaddr)
VAR_0 = shmat(shmid, (void *)g2h(shmaddr), shmflg); else { abi_ulong mmap_start; mmap_start = mmap_find_vma(0, VAR_1.shm_segsz); if (mmap_start == -1) { errno = ENOMEM; VAR_0 = (void *)-1; } else VAR_0 = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP); } if (VAR_0 == (void *)-1) { mmap_unlock(); return get_errno((long)VAR_0); } raddr=h2g((unsigned long)VAR_0); page_set_flags(raddr, raddr + VAR_1.shm_segsz,
PAGE_VALID | PAGE_READ |
((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE)); for (VAR_2 = 0; VAR_2 < N_SHM_REGIONS; VAR_2++) { if (!shm_regions[VAR_2].in_use) { shm_regions[VAR_2].in_use = true; shm_regions[VAR_2].start = raddr; shm_regions[VAR_2].size = VAR_1.shm_segsz; break; } } mmap_unlock(); return raddr; }