brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · 76a6611 Raw
68 lines · cpp
1//===---------- Linux implementation of the POSIX mmap function -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/sys/mman/mmap.h"10 11#include "src/__support/OSUtil/syscall.h" // For internal syscall function.12#include "src/__support/common.h"13 14#include "src/__support/libc_errno.h"15#include "src/__support/macros/config.h"16#include <linux/param.h> // For EXEC_PAGESIZE.17#include <sys/syscall.h> // For syscall numbers.18 19namespace LIBC_NAMESPACE_DECL {20 21// This function is currently linux only. It has to be refactored suitably if22// mmap is to be supported on non-linux operating systems also.23LLVM_LIBC_FUNCTION(void *, mmap,24                   (void *addr, size_t size, int prot, int flags, int fd,25                    off_t offset)) {26  // A lot of POSIX standard prescribed validation of the parameters is not27  // done in this function as modern linux versions do it in the syscall.28  // TODO: Perform argument validation not done by the linux syscall.29 30  // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, it31  // might not be correct in general.32  // TODO: Use pagesize read from the ELF aux vector instead of EXEC_PAGESIZE.33 34#ifdef SYS_mmap235  offset /= EXEC_PAGESIZE;36  long syscall_number = SYS_mmap2;37#elif defined(SYS_mmap)38  long syscall_number = SYS_mmap;39#else40#error "mmap or mmap2 syscalls not available."41#endif42 43  // We add an explicit cast to silence a "implicit conversion loses integer44  // precision" warning when compiling for 32-bit systems.45  long mmap_offset = static_cast<long>(offset);46  long ret =47      LIBC_NAMESPACE::syscall_impl(syscall_number, reinterpret_cast<long>(addr),48                                   size, prot, flags, fd, mmap_offset);49 50  // The mmap/mmap2 syscalls return negative values on error. These negative51  // values are actually the negative values of the error codes. So, fix them52  // up in case an error code is detected.53  //54  // A point to keep in mind for the fix up is that a negative return value55  // from the syscall can also be an error-free value returned by the syscall.56  // However, since a valid return address cannot be within the last page, a57  // return value corresponding to a location in the last page is an error58  // value.59  if (!linux_utils::is_valid_mmap(ret)) {60    libc_errno = static_cast<int>(-ret);61    return MAP_FAILED;62  }63 64  return reinterpret_cast<void *>(ret);65}66 67} // namespace LIBC_NAMESPACE_DECL68