| Summary: | MIPS mmap can not access over 4G file | ||
|---|---|---|---|
| Product: | uClibc | Reporter: | highfly22 |
| Component: | Standard Compliance | Assignee: | unassigned |
| Status: | RESOLVED FIXED | ||
| Severity: | major | CC: | raj.khem, uclibc-cvs, vapier |
| Priority: | P3 | ||
| Version: | <= 0.9.29.x | ||
| Target Milestone: | --- | ||
| Hardware: | Other | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
| Attachments: |
patch for mmap2 of mips
mantis 1303 bug info mmap64 fix |
||
|
Description
highfly22
2011-06-14 04:43:46 UTC
If you can confirm that mmap2 for mips on something like 2.6.39.1 works then we could enable it for recent versions. Created attachment 3439 [details]
patch for mmap2 of mips
I used this patch to fix the problem. It seems a mmap64 common implementation truncate to 32bit in the NOT USE 64 OFFSET branch.
I apologize that this issue must be renamed - problems with mmap64 & offsets > 4Gb observed on any 32-bit platform(__USE_FILE_OFFSET64 not set) has sizeof(__u_long) == 4. Bug introduced in commit 22a4424b0b "Fix arm mmap when using mmap2 syscall. Fixes bug #1303" - wrong parentheses placement cause off64_t offset argument truncated to low 32-bit. Trivial fix: diff --git a/libc/sysdeps/linux/common/mmap64.c b/libc/sysdeps/linux/common/mmap64.c --- a/libc/sysdeps/linux/common/mmap64.c +++ b/libc/sysdeps/linux/common/mmap64.c @@ -61,10 +61,10 @@ __ptr_t mmap64(__ptr_t addr, size_t len, int prot, int flags, int fd, __off64_t offset) # ifdef __USE_FILE_OFFSET64 return __syscall_mmap2(addr, len, prot, flags, - fd, ((__u_quad_t) offset >> MMAP2_PAGE_SHIFT)); + fd, (__u_quad_t)(offset >> MMAP2_PAGE_SHIFT)); # else return __syscall_mmap2(addr, len, prot, flags, - fd, ((__u_long) offset >> MMAP2_PAGE_SHIFT)); + fd, (__u_long)(offset >> MMAP2_PAGE_SHIFT)); # endif } Created attachment 4244 [details]
mantis 1303 bug info
your proposed change will undo the previous bug fix. here's the text of the old mantis bug that prompted 22a4424b0b.
pretty sure the right way to fix this would be to avoid ifdefs and use:
return __syscall_mmap2(addr, len, prot, flags, fd,
((uint64_t)offset >> MMAP2_PAGE_SHIFT));
this is because we know __off64_t is always going to be a 64bit signed value.
(In reply to comment #4) > Created attachment 4244 [details] > mantis 1303 bug info > > your proposed change will undo the previous bug fix. here's the text of the > old mantis bug that prompted 22a4424b0b. > > pretty sure the right way to fix this would be to avoid ifdefs and use: > return __syscall_mmap2(addr, len, prot, flags, fd, > ((uint64_t)offset >> MMAP2_PAGE_SHIFT)); > > this is because we know __off64_t is always going to be a 64bit signed value. yes that seems to be a better fix. Did you mean to use __off64_t instead of uint64_t (In reply to comment #5) no, because __off64_t is signed, and there doesn't appear to be an "unsigned off64_t" type, so uint64_t is as close as i could get :( Created attachment 4250 [details]
mmap64 fix
please try the attached patch
Yes, it works on our MIPS32 platform. Thank you very much, I had to take into account signedness of offset myself. pushed then ... thanks for testing! Does not work for me on ppc32. Current master gives: LD libuClibc-0.9.34-git.so libc/libc_so.a(mmap64.os): In function `mmap64': /scratch/src/uClibc.push/libc/sysdeps/linux/common/mmap64.c:60: undefined reference to `__illegally_sized_syscall_arg6' collect2: ld returned 1 exit status Mike, can you please have a look? Something like below may be appropriate, but why can't we just use (off_t)offset>>shift, again? index 0086496..75b4ebc 100644 --- a/libc/sysdeps/linux/common/mmap64.c +++ b/libc/sysdeps/linux/common/mmap64.c @@ -57,7 +57,7 @@ void *mmap64(void *addr, size_t len, int prot, int flags, int fd, __off64_t offs * an unsigned 64-bit value before doing the shift. */ return (void*) INLINE_SYSCALL(mmap2, 6, addr, len, prot, flags, fd, - ((uint64_t)offset >> MMAP2_PAGE_SHIFT)); + (off_t)((uint64_t)offset >> MMAP2_PAGE_SHIFT)); } #endif we can't cast the inside value to off_t because it is signed and that will reintroduce a previous bug. you can't cast to off_t outside of the paren because that could be 64bits when LFS is enabled. Khem mentioned this on the list already, so i'll follow up there. |