[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