+#ifdef TARGET_ARM
+ if (((CPUARMState *)cpu_env)->eabi) {
+ struct target_eabi_stat64 *target_st;
+ lock_user_struct(target_st, arg2, 1);
+ memset(target_st, 0, sizeof(struct target_eabi_stat64));
+ /* put_user is probably wrong. */
+ put_user(st.st_dev, &target_st->st_dev);
+ put_user(st.st_ino, &target_st->st_ino);
+#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
+ put_user(st.st_ino, &target_st->__st_ino);
+#endif
+ put_user(st.st_mode, &target_st->st_mode);
+ put_user(st.st_nlink, &target_st->st_nlink);
+ put_user(st.st_uid, &target_st->st_uid);
+ put_user(st.st_gid, &target_st->st_gid);
+ put_user(st.st_rdev, &target_st->st_rdev);
+ /* XXX: better use of kernel struct */
+ put_user(st.st_size, &target_st->st_size);
+ put_user(st.st_blksize, &target_st->st_blksize);
+ put_user(st.st_blocks, &target_st->st_blocks);
+ put_user(st.st_atime, &target_st->target_st_atime);
+ put_user(st.st_mtime, &target_st->target_st_mtime);
+ put_user(st.st_ctime, &target_st->target_st_ctime);
+ unlock_user_struct(target_st, arg2, 0);
+ } else
+#endif
+ {
+ struct target_stat64 *target_st;
+ lock_user_struct(target_st, arg2, 1);
+ memset(target_st, 0, sizeof(struct target_stat64));
+ /* ??? put_user is probably wrong. */
+ put_user(st.st_dev, &target_st->st_dev);
+ put_user(st.st_ino, &target_st->st_ino);
+#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
+ put_user(st.st_ino, &target_st->__st_ino);
+#endif
+ put_user(st.st_mode, &target_st->st_mode);
+ put_user(st.st_nlink, &target_st->st_nlink);
+ put_user(st.st_uid, &target_st->st_uid);
+ put_user(st.st_gid, &target_st->st_gid);
+ put_user(st.st_rdev, &target_st->st_rdev);
+ /* XXX: better use of kernel struct */
+ put_user(st.st_size, &target_st->st_size);
+ put_user(st.st_blksize, &target_st->st_blksize);
+ put_user(st.st_blocks, &target_st->st_blocks);
+ put_user(st.st_atime, &target_st->target_st_atime);
+ put_user(st.st_mtime, &target_st->target_st_mtime);
+ put_user(st.st_ctime, &target_st->target_st_ctime);
+ unlock_user_struct(target_st, arg2, 0);
+ }
+ }
+ }
+ break;
+#endif
+#ifdef USE_UID16
+ case TARGET_NR_lchown:
+ p = lock_user_string(arg1);
+ ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
+ unlock_user(p, arg1, 0);
+ break;
+ case TARGET_NR_getuid:
+ ret = get_errno(high2lowuid(getuid()));
+ break;
+ case TARGET_NR_getgid:
+ ret = get_errno(high2lowgid(getgid()));
+ break;
+ case TARGET_NR_geteuid:
+ ret = get_errno(high2lowuid(geteuid()));
+ break;
+ case TARGET_NR_getegid:
+ ret = get_errno(high2lowgid(getegid()));
+ break;
+ case TARGET_NR_setreuid:
+ ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
+ break;
+ case TARGET_NR_setregid:
+ ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
+ break;
+ case TARGET_NR_getgroups:
+ {
+ int gidsetsize = arg1;
+ uint16_t *target_grouplist;
+ gid_t *grouplist;
+ int i;
+
+ grouplist = alloca(gidsetsize * sizeof(gid_t));
+ ret = get_errno(getgroups(gidsetsize, grouplist));
+ if (!is_error(ret)) {
+ target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
+ for(i = 0;i < gidsetsize; i++)
+ target_grouplist[i] = tswap16(grouplist[i]);
+ unlock_user(target_grouplist, arg2, gidsetsize * 2);
+ }
+ }
+ break;
+ case TARGET_NR_setgroups:
+ {
+ int gidsetsize = arg1;
+ uint16_t *target_grouplist;
+ gid_t *grouplist;
+ int i;
+
+ grouplist = alloca(gidsetsize * sizeof(gid_t));
+ target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
+ for(i = 0;i < gidsetsize; i++)
+ grouplist[i] = tswap16(target_grouplist[i]);
+ unlock_user(target_grouplist, arg2, 0);
+ ret = get_errno(setgroups(gidsetsize, grouplist));
+ }
+ break;
+ case TARGET_NR_fchown:
+ ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
+ break;
+#ifdef TARGET_NR_setresuid
+ case TARGET_NR_setresuid:
+ ret = get_errno(setresuid(low2highuid(arg1),
+ low2highuid(arg2),
+ low2highuid(arg3)));
+ break;
+#endif
+#ifdef TARGET_NR_getresuid
+ case TARGET_NR_getresuid:
+ {
+ uid_t ruid, euid, suid;
+ ret = get_errno(getresuid(&ruid, &euid, &suid));
+ if (!is_error(ret)) {
+ tput16(arg1, tswap16(high2lowuid(ruid)));
+ tput16(arg2, tswap16(high2lowuid(euid)));
+ tput16(arg3, tswap16(high2lowuid(suid)));
+ }
+ }
+ break;
+#endif
+#ifdef TARGET_NR_getresgid
+ case TARGET_NR_setresgid:
+ ret = get_errno(setresgid(low2highgid(arg1),
+ low2highgid(arg2),
+ low2highgid(arg3)));
+ break;
+#endif
+#ifdef TARGET_NR_getresgid
+ case TARGET_NR_getresgid:
+ {
+ gid_t rgid, egid, sgid;
+ ret = get_errno(getresgid(&rgid, &egid, &sgid));
+ if (!is_error(ret)) {
+ tput16(arg1, tswap16(high2lowgid(rgid)));
+ tput16(arg2, tswap16(high2lowgid(egid)));
+ tput16(arg3, tswap16(high2lowgid(sgid)));