Sourceware Bugzilla – Attachment 12211 Details for
Bug 23960
[2.28 Regression]: New getdents{64} implementation breaks qemu-user
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
getdents emulation for qemu
getdents_emulation.qemu.patch (text/plain), 16.32 KB, created by
Aladjev Andrew
on 2020-01-15 05:49:50 UTC
(
hide
)
Description:
getdents emulation for qemu
Filename:
MIME Type:
Creator:
Aladjev Andrew
Created:
2020-01-15 05:49:50 UTC
Size:
16.32 KB
patch
obsolete
>diff --git a/linux-user/aarch64/syscall_nr.h b/linux-user/aarch64/syscall_nr.h >index f00ffd7fb8..c0392f68ac 100644 >--- a/linux-user/aarch64/syscall_nr.h >+++ b/linux-user/aarch64/syscall_nr.h >@@ -277,4 +277,6 @@ > #define TARGET_NR_mlock2 284 > #define TARGET_NR_copy_file_range 285 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h >index 2e5541bbf9..c9c2f4f8e1 100644 >--- a/linux-user/alpha/syscall_nr.h >+++ b/linux-user/alpha/syscall_nr.h >@@ -454,4 +454,6 @@ > #define TARGET_NR_memfd_create 512 > #define TARGET_NR_execveat 513 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c >index 7be4071751..6cef76c72a 100644 >--- a/linux-user/arm/cpu_loop.c >+++ b/linux-user/arm/cpu_loop.c >@@ -333,7 +333,7 @@ void cpu_loop(CPUARMState *env) > n -= ARM_SYSCALL_BASE; > env->eabi = 0; > } >- if ( n > ARM_NR_BASE) { >+ if (n > ARM_NR_BASE && n != TARGET_NR_getdents64_x32) { > switch (n) { > case ARM_NR_cacheflush: > /* nop */ >diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h >index e7eda0d766..add8414441 100644 >--- a/linux-user/arm/syscall_nr.h >+++ b/linux-user/arm/syscall_nr.h >@@ -400,4 +400,6 @@ > #define TARGET_NR_membarrier (389) > #define TARGET_NR_mlock2 (390) > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h >index 4b6cf65c42..162a2d9911 100644 >--- a/linux-user/cris/syscall_nr.h >+++ b/linux-user/cris/syscall_nr.h >@@ -364,4 +364,6 @@ > #define TARGET_NR_bpf 358 > #define TARGET_NR_execveat 359 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/hppa/syscall_nr.h b/linux-user/hppa/syscall_nr.h >index ae41e94321..80fdcdee17 100644 >--- a/linux-user/hppa/syscall_nr.h >+++ b/linux-user/hppa/syscall_nr.h >@@ -355,4 +355,6 @@ > #define TARGET_NR_preadv2 347 > #define TARGET_NR_pwritev2 348 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h >index 3234ec21c6..3f5765e1c5 100644 >--- a/linux-user/i386/syscall_nr.h >+++ b/linux-user/i386/syscall_nr.h >@@ -384,4 +384,6 @@ > #define TARGET_NR_mlock2 376 > #define TARGET_NR_copy_file_range 377 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h >index d33d8e98a7..38b41ff27a 100644 >--- a/linux-user/m68k/syscall_nr.h >+++ b/linux-user/m68k/syscall_nr.h >@@ -383,4 +383,6 @@ > #define TARGET_NR_preadv2 377 > #define TARGET_NR_pwritev2 378 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h >index aa2eb93881..2dabe4c7c8 100644 >--- a/linux-user/microblaze/syscall_nr.h >+++ b/linux-user/microblaze/syscall_nr.h >@@ -394,4 +394,6 @@ > #define TARGET_NR_bpf 387 > #define TARGET_NR_execveat 388 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c >index 39915b3fde..e317410141 100644 >--- a/linux-user/mips/cpu_loop.c >+++ b/linux-user/mips/cpu_loop.c >@@ -446,14 +446,19 @@ void cpu_loop(CPUMIPSState *env) > env->active_tc.PC += 4; > # ifdef TARGET_ABI_MIPSO32 > syscall_num = env->active_tc.gpr[2] - 4000; >- if (syscall_num >= sizeof(mips_syscall_args)) { >+ if (syscall_num >= sizeof(mips_syscall_args) && env->active_tc.gpr[2] != TARGET_NR_getdents64_x32) { > ret = -TARGET_ENOSYS; > } else { > int nb_args; > abi_ulong sp_reg; > abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0; > >- nb_args = mips_syscall_args[syscall_num]; >+ if (env->active_tc.gpr[2] == TARGET_NR_getdents64_x32) { >+ nb_args = 3; >+ } else { >+ nb_args = mips_syscall_args[syscall_num]; >+ } >+ > sp_reg = env->active_tc.gpr[29]; > switch (nb_args) { > /* these arguments are taken from the stack */ >diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h >index 7fa7fa5a86..c0de530f6f 100644 >--- a/linux-user/mips/syscall_nr.h >+++ b/linux-user/mips/syscall_nr.h >@@ -377,4 +377,6 @@ > #define TARGET_NR_rseq (TARGET_NR_Linux + 367) > #define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 368) > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h >index db40f69ca2..ecaccc81cf 100644 >--- a/linux-user/mips64/syscall_nr.h >+++ b/linux-user/mips64/syscall_nr.h >@@ -676,4 +676,6 @@ > #define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 328) > #endif > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/nios2/syscall_nr.h b/linux-user/nios2/syscall_nr.h >index 8fb87864ca..47b582211f 100644 >--- a/linux-user/nios2/syscall_nr.h >+++ b/linux-user/nios2/syscall_nr.h >@@ -331,4 +331,6 @@ > #define TARGET_NR__sysctl 1078 > #define TARGET_NR_fork 1079 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h >index 7763dbcfd8..0b22f19b1d 100644 >--- a/linux-user/openrisc/syscall_nr.h >+++ b/linux-user/openrisc/syscall_nr.h >@@ -506,4 +506,6 @@ > #define TARGET_NR_lstat64 TARGET_NR_3264_lstat > #endif > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h >index b57a07b931..797ab30b89 100644 >--- a/linux-user/ppc/syscall_nr.h >+++ b/linux-user/ppc/syscall_nr.h >@@ -399,4 +399,6 @@ > #define TARGET_NR_shmctl 377 > #define TARGET_NR_mlock2 378 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/riscv/syscall_nr.h b/linux-user/riscv/syscall_nr.h >index 5c87282209..b3d32dbed3 100644 >--- a/linux-user/riscv/syscall_nr.h >+++ b/linux-user/riscv/syscall_nr.h >@@ -302,4 +302,6 @@ > > #define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1) > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h >index b1553a0810..0475fbb96a 100644 >--- a/linux-user/s390x/syscall_nr.h >+++ b/linux-user/s390x/syscall_nr.h >@@ -395,4 +395,6 @@ > > #endif > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h >index d53a2a07dd..f6c63baa14 100644 >--- a/linux-user/sh4/syscall_nr.h >+++ b/linux-user/sh4/syscall_nr.h >@@ -390,4 +390,6 @@ > #define TARGET_NR_preadv2 381 > #define TARGET_NR_pwritev2 382 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h >index 162099f9ce..8fc2bf676a 100644 >--- a/linux-user/sparc/syscall_nr.h >+++ b/linux-user/sparc/syscall_nr.h >@@ -360,4 +360,6 @@ > #define TARGET_NR_pwritev2 359 > #define TARGET_NR_statx 360 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h >index 6b088c9862..f5830f9e54 100644 >--- a/linux-user/sparc64/syscall_nr.h >+++ b/linux-user/sparc64/syscall_nr.h >@@ -363,4 +363,6 @@ > #define TARGET_NR_pwritev2 359 > #define TARGET_NR_statx 360 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/strace.list b/linux-user/strace.list >index 1de4319dcf..65bb2e9b16 100644 >--- a/linux-user/strace.list >+++ b/linux-user/strace.list >@@ -1656,3 +1656,6 @@ > #ifdef TARGET_NR_statx > { TARGET_NR_statx, "statx", NULL, print_statx, NULL }, > #endif >+#ifdef TARGET_NR_getdents64_x32 >+{ TARGET_NR_getdents64_x32, "getdents64_x32" , NULL, NULL, NULL }, >+#endif >diff --git a/linux-user/syscall.c b/linux-user/syscall.c >index 171c0caef3..957a0e65f6 100644 >--- a/linux-user/syscall.c >+++ b/linux-user/syscall.c >@@ -230,7 +230,6 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ > return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \ > } > >- > #define __NR_sys_uname __NR_uname > #define __NR_sys_getcwd1 __NR_getcwd > #define __NR_sys_getdents __NR_getdents >@@ -245,6 +244,10 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ > #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch > #define __NR_sys_statx __NR_statx > >+#define __X32_SYSCALL_BIT 0x40000000UL >+#define __NR_getdents64_x32 (__X32_SYSCALL_BIT + 217) >+#define __NR_sys_getdents64_x32 __NR_getdents64_x32 >+ > #if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__) > #define __NR__llseek __NR_lseek > #endif >@@ -275,6 +278,11 @@ _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count) > (defined(TARGET_NR_getdents64) && defined(__NR_getdents64)) > _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count); > #endif >+#if (defined(TARGET_NR_getdents) && \ >+ !defined(EMULATE_GETDENTS_WITH_GETDENTS)) || \ >+ (defined(TARGET_NR_getdents64_x32) && defined(__NR_getdents64_x32)) >+_syscall3(int, sys_getdents64_x32, uint, fd, struct linux_dirent64 *, dirp, uint, count); >+#endif > #if defined(TARGET_NR__llseek) && defined(__NR_llseek) > _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, > loff_t *, res, uint, wh); >@@ -1062,7 +1070,7 @@ static inline rlim_t target_to_host_rlim(abi_ulong target_rlim) > { > abi_ulong target_rlim_swap; > rlim_t result; >- >+ > target_rlim_swap = tswapal(target_rlim); > if (target_rlim_swap == TARGET_RLIM_INFINITY) > return RLIM_INFINITY; >@@ -1070,7 +1078,7 @@ static inline rlim_t target_to_host_rlim(abi_ulong target_rlim) > result = target_rlim_swap; > if (target_rlim_swap != (rlim_t)result) > return RLIM_INFINITY; >- >+ > return result; > } > >@@ -1078,13 +1086,13 @@ static inline abi_ulong host_to_target_rlim(rlim_t rlim) > { > abi_ulong target_rlim_swap; > abi_ulong result; >- >+ > if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) > target_rlim_swap = TARGET_RLIM_INFINITY; > else > target_rlim_swap = rlim; > result = tswapal(target_rlim_swap); >- >+ > return result; > } > >@@ -1526,9 +1534,9 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh, > abi_ulong target_cmsg_addr; > struct target_cmsghdr *target_cmsg, *target_cmsg_start; > socklen_t space = 0; >- >+ > msg_controllen = tswapal(target_msgh->msg_controllen); >- if (msg_controllen < sizeof (struct target_cmsghdr)) >+ if (msg_controllen < sizeof (struct target_cmsghdr)) > goto the_end; > target_cmsg_addr = tswapal(target_msgh->msg_control); > target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); >@@ -1610,7 +1618,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, > socklen_t space = 0; > > msg_controllen = tswapal(target_msgh->msg_controllen); >- if (msg_controllen < sizeof (struct target_cmsghdr)) >+ if (msg_controllen < sizeof (struct target_cmsghdr)) > goto the_end; > target_cmsg_addr = tswapal(target_msgh->msg_control); > target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); >@@ -5592,7 +5600,7 @@ abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr) > } > unlock_user_struct(target_ldt_info, ptr, 1); > >- if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || >+ if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || > ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX) > return -TARGET_EINVAL; > seg_32bit = ldt_info.flags & 1; >@@ -5670,7 +5678,7 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) > lp = (uint32_t *)(gdt_table + idx); > entry_1 = tswap32(lp[0]); > entry_2 = tswap32(lp[1]); >- >+ > read_exec_only = ((entry_2 >> 9) & 1) ^ 1; > contents = (entry_2 >> 10) & 3; > seg_not_present = ((entry_2 >> 15) & 1) ^ 1; >@@ -5686,8 +5694,8 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) > (read_exec_only << 3) | (limit_in_pages << 4) | > (seg_not_present << 5) | (useable << 6) | (lm << 7); > limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000); >- base_addr = (entry_1 >> 16) | >- (entry_2 & 0xff000000) | >+ base_addr = (entry_1 >> 16) | >+ (entry_2 & 0xff000000) | > ((entry_2 & 0xff) << 16); > target_ldt_info->base_addr = tswapal(base_addr); > target_ldt_info->limit = tswap32(limit); >@@ -9535,7 +9543,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > #endif > #else >- /* Implement getdents in terms of getdents64 */ >+ /* Implement getdents in terms of getdents64_x32 */ > { > struct linux_dirent64 *dirp; > abi_long count = arg3; >@@ -9544,7 +9552,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > if (!dirp) { > return -TARGET_EFAULT; > } >- ret = get_errno(sys_getdents64(arg1, dirp, count)); >+ ret = get_errno(sys_getdents64_x32(arg1, dirp, count)); > if (!is_error(ret)) { > /* Convert the dirent64 structs to target dirent. We do this > * in-place, since we can guarantee that a target_dirent is no >@@ -9619,6 +9627,34 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > } > return ret; > #endif /* TARGET_NR_getdents64 */ >+#if defined(TARGET_NR_getdents64_x32) && defined(__NR_getdents64_x32) >+ case TARGET_NR_getdents64_x32: >+ { >+ struct linux_dirent64 *dirp; >+ abi_long count = arg3; >+ if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) >+ return -TARGET_EFAULT; >+ ret = get_errno(sys_getdents64_x32(arg1, dirp, count)); >+ if (!is_error(ret)) { >+ struct linux_dirent64 *de; >+ int len = ret; >+ int reclen; >+ de = dirp; >+ while (len > 0) { >+ reclen = de->d_reclen; >+ if (reclen > len) >+ break; >+ de->d_reclen = tswap16(reclen); >+ tswap64s((uint64_t *)&de->d_ino); >+ tswap64s((uint64_t *)&de->d_off); >+ de = (struct linux_dirent64 *)((char *)de + reclen); >+ len -= reclen; >+ } >+ } >+ unlock_user(dirp, arg2, ret); >+ } >+ return ret; >+#endif /* TARGET_NR_getdents64_x32 */ > #if defined(TARGET_NR__newselect) > case TARGET_NR__newselect: > return do_select(arg1, arg2, arg3, arg4, arg5); >@@ -10554,7 +10590,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, > return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); > #if defined(TARGET_NR_fchownat) > case TARGET_NR_fchownat: >- if (!(p = lock_user_string(arg2))) >+ if (!(p = lock_user_string(arg2))) > return -TARGET_EFAULT; > ret = get_errno(fchownat(arg1, p, low2highuid(arg3), > low2highgid(arg4), arg5)); >diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h >index c104b94230..e8c9ff1f14 100644 >--- a/linux-user/tilegx/syscall_nr.h >+++ b/linux-user/tilegx/syscall_nr.h >@@ -324,4 +324,6 @@ > #define TARGET_NR__sysctl 1078 > #define TARGET_NR_fork 1079 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h >index 9b6981e74c..3e0def88d0 100644 >--- a/linux-user/x86_64/syscall_nr.h >+++ b/linux-user/x86_64/syscall_nr.h >@@ -329,4 +329,6 @@ > #define TARGET_NR_mlock2 325 > #define TARGET_NR_copy_file_range 326 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif >diff --git a/linux-user/xtensa/syscall_nr.h b/linux-user/xtensa/syscall_nr.h >index 27645bea47..ba32d29ebf 100644 >--- a/linux-user/xtensa/syscall_nr.h >+++ b/linux-user/xtensa/syscall_nr.h >@@ -434,4 +434,6 @@ > > #define TARGET_NR_syscall_count 352 > >+#define TARGET_NR_getdents64_x32 0xffff >+ > #endif /* XTENSA_SYSCALL_NR_H */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 23960
:
11441
|
11808
|
12210
| 12211