Revision 6a24a778

b/linux-user/syscall.c
156 156
#define __NR_sys_faccessat __NR_faccessat
157 157
#define __NR_sys_fchmodat __NR_fchmodat
158 158
#define __NR_sys_fchownat __NR_fchownat
159
#define __NR_sys_fstatat64 __NR_fstatat64
159 160
#define __NR_sys_getcwd1 __NR_getcwd
160 161
#define __NR_sys_getdents __NR_getdents
161 162
#define __NR_sys_getdents64 __NR_getdents64
......
200 201
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
201 202
          uid_t,owner,gid_t,group,int,flags)
202 203
#endif
204
#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
205
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
206
          struct stat *,buf,int,flags)
207
#endif
203 208
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
204 209
#if TARGET_ABI_BITS == 32
205 210
_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
......
3149 3154
    return 0;
3150 3155
}
3151 3156

  
3157
#ifdef TARGET_NR_stat64
3158
static inline abi_long host_to_target_stat64(void *cpu_env,
3159
                                             abi_ulong target_addr,
3160
                                             struct stat *host_st)
3161
{
3162
#ifdef TARGET_ARM
3163
    if (((CPUARMState *)cpu_env)->eabi) {
3164
        struct target_eabi_stat64 *target_st;
3165

  
3166
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3167
            return -TARGET_EFAULT;
3168
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3169
        __put_user(host_st->st_dev, &target_st->st_dev);
3170
        __put_user(host_st->st_ino, &target_st->st_ino);
3171
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3172
        __put_user(host_st->st_ino, &target_st->__st_ino);
3173
#endif
3174
        __put_user(host_st->st_mode, &target_st->st_mode);
3175
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3176
        __put_user(host_st->st_uid, &target_st->st_uid);
3177
        __put_user(host_st->st_gid, &target_st->st_gid);
3178
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3179
        __put_user(host_st->st_size, &target_st->st_size);
3180
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3181
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3182
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3183
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3184
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3185
        unlock_user_struct(target_st, target_addr, 1);
3186
    } else
3187
#endif
3188
    {
3189
        struct target_stat64 *target_st;
3190

  
3191
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3192
            return -TARGET_EFAULT;
3193
        memset(target_st, 0, sizeof(struct target_stat64));
3194
        __put_user(host_st->st_dev, &target_st->st_dev);
3195
        __put_user(host_st->st_ino, &target_st->st_ino);
3196
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3197
        __put_user(host_st->st_ino, &target_st->__st_ino);
3198
#endif
3199
        __put_user(host_st->st_mode, &target_st->st_mode);
3200
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3201
        __put_user(host_st->st_uid, &target_st->st_uid);
3202
        __put_user(host_st->st_gid, &target_st->st_gid);
3203
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3204
        /* XXX: better use of kernel struct */
3205
        __put_user(host_st->st_size, &target_st->st_size);
3206
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3207
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3208
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3209
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3210
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3211
        unlock_user_struct(target_st, target_addr, 1);
3212
    }
3213

  
3214
    return 0;
3215
}
3216
#endif
3217

  
3152 3218
#if defined(USE_NPTL)
3153 3219
/* ??? Using host futex calls even when target atomic operations
3154 3220
   are not really atomic probably breaks things.  However implementing
......
5142 5208
            goto efault;
5143 5209
        ret = get_errno(stat(path(p), &st));
5144 5210
        unlock_user(p, arg1, 0);
5145
        goto do_stat64;
5211
        if (!is_error(ret))
5212
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5213
        break;
5146 5214
#endif
5147 5215
#ifdef TARGET_NR_lstat64
5148 5216
    case TARGET_NR_lstat64:
......
5150 5218
            goto efault;
5151 5219
        ret = get_errno(lstat(path(p), &st));
5152 5220
        unlock_user(p, arg1, 0);
5153
        goto do_stat64;
5221
        if (!is_error(ret))
5222
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5223
        break;
5154 5224
#endif
5155 5225
#ifdef TARGET_NR_fstat64
5156 5226
    case TARGET_NR_fstat64:
5157
        {
5158
            ret = get_errno(fstat(arg1, &st));
5159
        do_stat64:
5160
            if (!is_error(ret)) {
5161
#ifdef TARGET_ARM
5162
                if (((CPUARMState *)cpu_env)->eabi) {
5163
                    struct target_eabi_stat64 *target_st;
5164

  
5165
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5166
                        goto efault;
5167
                    memset(target_st, 0, sizeof(struct target_eabi_stat64));
5168
                    __put_user(st.st_dev, &target_st->st_dev);
5169
                    __put_user(st.st_ino, &target_st->st_ino);
5170
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5171
                    __put_user(st.st_ino, &target_st->__st_ino);
5172
#endif
5173
                    __put_user(st.st_mode, &target_st->st_mode);
5174
                    __put_user(st.st_nlink, &target_st->st_nlink);
5175
                    __put_user(st.st_uid, &target_st->st_uid);
5176
                    __put_user(st.st_gid, &target_st->st_gid);
5177
                    __put_user(st.st_rdev, &target_st->st_rdev);
5178
                    __put_user(st.st_size, &target_st->st_size);
5179
                    __put_user(st.st_blksize, &target_st->st_blksize);
5180
                    __put_user(st.st_blocks, &target_st->st_blocks);
5181
                    __put_user(st.st_atime, &target_st->target_st_atime);
5182
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5183
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5184
                    unlock_user_struct(target_st, arg2, 1);
5185
                } else
5227
        ret = get_errno(fstat(arg1, &st));
5228
        if (!is_error(ret))
5229
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5230
        break;
5186 5231
#endif
5187
                {
5188
                    struct target_stat64 *target_st;
5189

  
5190
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5191
                        goto efault;
5192
                    memset(target_st, 0, sizeof(struct target_stat64));
5193
                    __put_user(st.st_dev, &target_st->st_dev);
5194
                    __put_user(st.st_ino, &target_st->st_ino);
5195
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5196
                    __put_user(st.st_ino, &target_st->__st_ino);
5197
#endif
5198
                    __put_user(st.st_mode, &target_st->st_mode);
5199
                    __put_user(st.st_nlink, &target_st->st_nlink);
5200
                    __put_user(st.st_uid, &target_st->st_uid);
5201
                    __put_user(st.st_gid, &target_st->st_gid);
5202
                    __put_user(st.st_rdev, &target_st->st_rdev);
5203
                    /* XXX: better use of kernel struct */
5204
                    __put_user(st.st_size, &target_st->st_size);
5205
                    __put_user(st.st_blksize, &target_st->st_blksize);
5206
                    __put_user(st.st_blocks, &target_st->st_blocks);
5207
                    __put_user(st.st_atime, &target_st->target_st_atime);
5208
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5209
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5210
                    unlock_user_struct(target_st, arg2, 1);
5211
                }
5212
            }
5213
        }
5232
#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5233
    case TARGET_NR_fstatat64:
5234
        if (!(p = lock_user_string(arg2)))
5235
            goto efault;
5236
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5237
        if (!is_error(ret))
5238
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5214 5239
        break;
5215 5240
#endif
5216 5241
#ifdef USE_UID16

Also available in: Unified diff