[libc-commits] [libc] [libc][mmap] force offset to long for mmap2 (PR #96522)
via libc-commits
libc-commits at lists.llvm.org
Mon Jun 24 13:56:53 PDT 2024
https://github.com/enh-google commented:
> llvm-libc's "Large File Support" isn't really complete. We define off_t to be
> a uint64_t always,
an int64_t, i assume :-)
> which breaks with convention in an attempt to drop
eh, iOS/macOS would say "whose convention?". it's only really a historical accident that bionic has different off_t/off64_t in the ILP32 ABI. in 2024, having two off_t types is deep into "historical cruft" territory.
> force off_t to long when using mmap2
this sounds worse than what the actual change does --- you're actually only truncating `offset >> 12`, not the offset.
but why not just do the right thing? it's only a couple of lines. see bionic:
```
// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks (regardless
// of page size), not bytes, to enable mapping parts of large files past the
// 4GiB limit but without the inconvenience of dealing with 64-bit values, with
// no down side since mappings need to be page aligned anyway, and the 32-bit
// architectures that support this system call all have 4KiB pages.
extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
static constexpr size_t MMAP2_SHIFT = 12;
if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT) - 1)) != 0) {
errno = EINVAL;
return MAP_FAILED;
}
// Prevent allocations large enough for `end - start` to overflow,
// to avoid security bugs.
size_t rounded = __BIONIC_ALIGN(size, page_size());
if (rounded < size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
}
return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
}
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
return mmap64(addr, size, prot, flags, fd, static_cast<off64_t>(offset));
}
```
(annoyingly there's no named constant in the kernel for that 12 that i've ever found, but if you grep arch/ for mmap2, you find lots of copy & pasted comments reminding the various arch maintainers that it's not the page size :-) )
note that that's only used for ILP32. for LP64 we use the trivial generated assembler syscall stub, which doesn't need any of this.
https://github.com/llvm/llvm-project/pull/96522
More information about the libc-commits
mailing list