+add_gen_header(
+ linux_syscall_h
+ DEF_FILE syscall.h.def
+ GEN_HDR syscall.h
+ PARAMS
+ inline_syscalls=${LIBC_TARGET_MACHINE}/syscall.h.inc
+ DATA_FILES
+ ${LIBC_TARGET_MACHINE}/syscall.h.inc
+)
+
add_subdirectory(x86_64)
#define ENTRYPOINT_SECTION_ATTRIBUTE(name) \
__attribute__((section(".llvm.libc.entrypoint."#name)))
#define LLVM_LIBC_ENTRYPOINT(name) ENTRYPOINT_SECTION_ATTRIBUTE(name) name
-
-// TODO: Get rid of the PAGE_SIZE macro. It is present only as an interim
-// measure until we can move the implementations of mmap and munmap to under
-// the config/linux directory. After that, the implementations can use
-// EXEC_PAGESIZE until page size can be read from the aux vector.
-#define PAGE_SIZE 4096
--- /dev/null
+//===--------------- Internal syscall declarations --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+%%include_file(${inline_syscalls})
GEN_HDR sys/mman.h
DEPENDS
libc_posix_types_h
+ llvm_libc_common_h
)
add_gen_header(
add_subdirectory(string)
# TODO: Add this target conditional to the target OS.
add_subdirectory(sys)
-add_subdirectory(unistd)
add_subdirectory(__support)
-#TODO: The sources and target listed here should ideally live in config/linux.
-
-add_entrypoint_object(
- mmap
- SRCS
- mmap.cpp
- HDRS
- mmap.h
- DEPENDS
- sys_mman_h
- sys_syscall_h
- syscall_impl_h
- __errno_location
-)
-
-add_entrypoint_object(
- munmap
- SRCS
- munmap.cpp
- HDRS
- munmap.h
- DEPENDS
- sys_mman_h
- sys_syscall_h
- syscall_impl_h
- __errno_location
-)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${LIBC_TARGET_OS})
+endif()
--- /dev/null
+add_entrypoint_object(
+ mmap
+ SRCS
+ mmap.cpp
+ HDRS
+ ../mmap.h
+ DEPENDS
+ sys_mman_h
+ sys_syscall_h
+ linux_syscall_h
+ __errno_location
+)
+
+add_entrypoint_object(
+ munmap
+ SRCS
+ munmap.cpp
+ HDRS
+ ../munmap.h
+ DEPENDS
+ sys_mman_h
+ sys_syscall_h
+ linux_syscall_h
+ __errno_location
+)
--- /dev/null
+//===---------- Linux implementation of the POSIX mmap function -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/mmap.h"
+
+#include "config/linux/syscall.h" // For internal syscall function.
+#include "include/sys/syscall.h" // For syscall numbers.
+#include "src/__support/common.h"
+#include "src/errno/llvmlibc_errno.h"
+
+#include <linux/param.h> // For EXEC_PAGESIZE.
+
+namespace __llvm_libc {
+
+// This function is currently linux only. It has to be refactored suitably if
+// mmap is to be supported on non-linux operating systems also.
+void *LLVM_LIBC_ENTRYPOINT(mmap)(void *addr, size_t size, int prot, int flags,
+ int fd, off_t offset) {
+ // A lot of POSIX standard prescribed validation of the parameters is not
+ // done in this function as modern linux versions do it in the syscall.
+ // TODO: Perform argument validation not done by the linux syscall.
+
+ // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, it
+ // might not be correct in general.
+ // TODO: Use pagesize read from the ELF aux vector instead of EXEC_PAGESIZE.
+
+#ifdef SYS_mmap2
+ offset /= EXEC_PAGESIZE;
+ long syscall_number = SYS_mmap2;
+#elif SYS_mmap
+ long syscall_number = SYS_mmap;
+#else
+#error "Target platform does not have SYS_mmap or SYS_mmap2 defined"
+#endif
+
+ long ret_val =
+ __llvm_libc::syscall(syscall_number, reinterpret_cast<long>(addr), size,
+ prot, flags, fd, offset);
+
+ // The mmap/mmap2 syscalls return negative values on error. These negative
+ // values are actually the negative values of the error codes. So, fix them
+ // up in case an error code is detected.
+ //
+ // A point to keep in mind for the fix up is that a negative return value
+ // from the syscall can also be an error-free value returned by the syscall.
+ // However, since a valid return address cannot be within the last page, a
+ // return value corresponding to a location in the last page is an error
+ // value.
+ if (ret_val < 0 && ret_val > -EXEC_PAGESIZE) {
+ llvmlibc_errno = -ret_val;
+ return MAP_FAILED;
+ }
+
+ return reinterpret_cast<void *>(ret_val);
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===---------- Linux implementation of the POSIX munmap function ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/mman/munmap.h"
+
+#include "config/linux/syscall.h" // For internal syscall function.
+#include "include/sys/syscall.h" // For syscall numbers.
+#include "src/__support/common.h"
+#include "src/errno/llvmlibc_errno.h"
+
+namespace __llvm_libc {
+
+// This function is currently linux only. It has to be refactored suitably if
+// mmap is to be supported on non-linux operating systems also.
+int LLVM_LIBC_ENTRYPOINT(munmap)(void *addr, size_t size) {
+ long ret_val =
+ __llvm_libc::syscall(SYS_munmap, reinterpret_cast<long>(addr), size);
+
+ // A negative return value indicates an error with the magnitude of the
+ // value being the error code.
+ if (ret_val < 0) {
+ llvmlibc_errno = -ret_val;
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace __llvm_libc
+++ /dev/null
-//===-------------- Implementation of the POSIX mmap function -------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/sys/mman/mmap.h"
-#include "include/sys/syscall.h" // For syscall numbers.
-#include "src/__support/common.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/unistd/syscall.h" // For internal syscall function.
-
-namespace __llvm_libc {
-
-// This function is currently linux only. It has to be refactored suitably if
-// mmap is to be supported on non-linux operating systems also.
-void *LLVM_LIBC_ENTRYPOINT(mmap)(void *addr, size_t size, int prot, int flags,
- int fd, off_t offset) {
- // A lot of POSIX standard prescribed validation of the parameters is not
- // done in this function as modern linux versions do it in the syscall.
- // TODO: Perform argument validation not done by the linux syscall.
-
-#ifdef SYS_mmap2
- offset /= PAGE_SIZE;
- long syscall_number = SYS_mmap2;
-#elif SYS_mmap
- long syscall_number = SYS_mmap;
-#else
-#error "Target platform does not have SYS_mmap or SYS_mmap2 defined"
-#endif
-
- long ret_val =
- __llvm_libc::syscall(syscall_number, reinterpret_cast<long>(addr), size,
- prot, flags, fd, offset);
-
- // The mmap/mmap2 syscalls return negative values on error. These negative
- // values are actually the negative values of the error codes. So, fix them
- // up in case an error code is detected.
- //
- // A point to keep in mind for the fix up is that a negative return value
- // from the syscall can also be an error-free value returned by the syscall.
- // However, since a valid return address cannot be within the last page, a
- // return value corresponding to a location in the last page is an error
- // value.
- if (ret_val < 0 && ret_val > -PAGE_SIZE) {
- llvmlibc_errno = -ret_val;
- return MAP_FAILED;
- }
-
- return reinterpret_cast<void *>(ret_val);
-}
-
-} // namespace __llvm_libc
+++ /dev/null
-//===------------- Implementation of the POSIX munmap function ------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/sys/mman/munmap.h"
-#include "include/sys/syscall.h" // For syscall numbers.
-#include "src/__support/common.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/unistd/syscall.h" // For internal syscall function.
-
-namespace __llvm_libc {
-
-// This function is currently linux only. It has to be refactored suitably if
-// mmap is to be supported on non-linux operating systems also.
-int LLVM_LIBC_ENTRYPOINT(munmap)(void *addr, size_t size) {
- long ret_val =
- __llvm_libc::syscall(SYS_munmap, reinterpret_cast<long>(addr), size);
-
- // A negative return value indicates an error with the magnitude of the
- // value being the error code.
- if (ret_val < 0) {
- llvmlibc_errno = -ret_val;
- return -1;
- }
-
- return 0;
-}
-
-} // namespace __llvm_libc
+++ /dev/null
-add_gen_header(
- syscall_impl_h
- DEF_FILE syscall.h.def
- GEN_HDR syscall.h
- PARAMS
- inline_syscalls=../../config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/syscall.h.inc
- DATA_FILES
- ../../config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/syscall.h.inc
-)
+++ /dev/null
-//===--------------- Internal syscall declarations --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-%%include_file(${inline_syscalls})
SUITE libc_linux_tests
SRCS syscall_test.cpp
DEPENDS
- syscall_impl_h
+ linux_syscall_h
support_common_h
)
//
//===----------------------------------------------------------------------===//
-#include "src/unistd/syscall.h"
+#include "config/linux/syscall.h"
#include "utils/UnitTest/Test.h"
#include <functional>
-add_libc_testsuite(libc_sys_mman_unittests)
-
-add_libc_unittest(
- mmap_test
- SUITE
- libc_sys_mman_unittests
- SRCS
- mmap_test.cpp
- DEPENDS
- errno_h
- sys_mman_h
- mmap
- munmap
- __errno_location
-)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${LIBC_TARGET_OS})
+endif()
--- /dev/null
+add_libc_testsuite(libc_sys_mman_unittests)
+
+add_libc_unittest(
+ mmap_test
+ SUITE
+ libc_sys_mman_unittests
+ SRCS
+ mmap_test.cpp
+ DEPENDS
+ errno_h
+ sys_mman_h
+ mmap
+ munmap
+ __errno_location
+)
--- /dev/null
+//===------------------ Unittests for mmap and munmap ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "include/errno.h"
+#include "include/sys/mman.h"
+#include "src/errno/llvmlibc_errno.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munmap.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(MMapTest, NoError) {
+ size_t alloc_size = 128;
+ llvmlibc_errno = 0;
+ void *addr = __llvm_libc::mmap(nullptr, alloc_size, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ EXPECT_EQ(0, llvmlibc_errno);
+ EXPECT_NE(addr, MAP_FAILED);
+
+ int *array = reinterpret_cast<int *>(addr);
+ // Reading from the memory should not crash the test.
+ // Since we used the MAP_ANONYMOUS flag, the contents of the newly
+ // allocated memory should be initialized to zero.
+ EXPECT_EQ(array[0], 0);
+
+ int ret_val = __llvm_libc::munmap(addr, alloc_size);
+ EXPECT_EQ(0, ret_val);
+ EXPECT_EQ(0, llvmlibc_errno);
+}
+
+TEST(MMapTest, Error_InvalidSize) {
+ llvmlibc_errno = 0;
+ void *addr = __llvm_libc::mmap(nullptr, 0, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ EXPECT_EQ(EINVAL, llvmlibc_errno);
+ EXPECT_EQ(addr, MAP_FAILED);
+
+ llvmlibc_errno = 0;
+ int ret_val = __llvm_libc::munmap(0, 0);
+ EXPECT_EQ(-1, ret_val);
+ EXPECT_EQ(EINVAL, llvmlibc_errno);
+}
+++ /dev/null
-//===------------------ Unittests for mmap and munmap ---------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "include/errno.h"
-#include "include/sys/mman.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/sys/mman/mmap.h"
-#include "src/sys/mman/munmap.h"
-#include "utils/UnitTest/Test.h"
-
-TEST(MMapTest, NoError) {
- size_t alloc_size = 128;
- llvmlibc_errno = 0;
- void *addr = __llvm_libc::mmap(nullptr, alloc_size, PROT_READ,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(0, llvmlibc_errno);
- EXPECT_NE(addr, MAP_FAILED);
-
- int *array = reinterpret_cast<int *>(addr);
- // Reading from the memory should not crash the test.
- // Since we used the MAP_ANONYMOUS flag, the contents of the newly
- // allocated memory should be initialized to zero.
- EXPECT_EQ(array[0], 0);
-
- int ret_val = __llvm_libc::munmap(addr, alloc_size);
- EXPECT_EQ(0, ret_val);
- EXPECT_EQ(0, llvmlibc_errno);
-}
-
-TEST(MMapTest, Error_InvalidSize) {
- llvmlibc_errno = 0;
- void *addr = __llvm_libc::mmap(nullptr, 0, PROT_READ,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- EXPECT_EQ(EINVAL, llvmlibc_errno);
- EXPECT_EQ(addr, MAP_FAILED);
-
- llvmlibc_errno = 0;
- int ret_val = __llvm_libc::munmap(0, 0);
- EXPECT_EQ(-1, ret_val);
- EXPECT_EQ(EINVAL, llvmlibc_errno);
-}