There are differences in handling of stat64/statfs64 calls by sanitizers between Linux and macOS. Versions of macOS starting with 10.6 drop the stat64/statfs64 APIs completely, relying on the linker to redirect stat/statfs to the appropriate 64 bit versions. Emitting variables needed by sanitizers is thus controlled by convoluted sets of conditions, involving Linux, IOS, macOS and Android, sprinkled around files. This change adresses it, allowing to specify presence/absence of stat64/statfs64 for each platform, in a single location. Also, it adresses the Android case which handles stat64, but not statfs64. Adding Vitaly as a reviewer since he seems to be actively working on sanitizers, perhaps can comment on the Android bit Differential Revision: https://reviews.llvm.org/D127343
103 lines
3.3 KiB
C++
103 lines
3.3 KiB
C++
//===-- sanitizer_platform_limits_linux.cpp -------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of Sanitizer common code.
|
|
//
|
|
// Sizes and layouts of linux kernel data structures.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// This is a separate compilation unit for linux headers that conflict with
|
|
// userspace headers.
|
|
// Most "normal" includes go in sanitizer_platform_limits_posix.cpp
|
|
|
|
#include "sanitizer_platform.h"
|
|
#if SANITIZER_LINUX
|
|
|
|
#include "sanitizer_internal_defs.h"
|
|
#include "sanitizer_platform_limits_posix.h"
|
|
|
|
// For offsetof -> __builtin_offsetof definition.
|
|
#include <stddef.h>
|
|
|
|
// With old kernels (and even new kernels on powerpc) asm/stat.h uses types that
|
|
// are not defined anywhere in userspace headers. Fake them. This seems to work
|
|
// fine with newer headers, too.
|
|
#include <linux/posix_types.h>
|
|
# if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__)
|
|
# include <sys/stat.h>
|
|
# else
|
|
# define ino_t __kernel_ino_t
|
|
# define mode_t __kernel_mode_t
|
|
# define nlink_t __kernel_nlink_t
|
|
# define uid_t __kernel_uid_t
|
|
# define gid_t __kernel_gid_t
|
|
# define off_t __kernel_off_t
|
|
# define time_t __kernel_time_t
|
|
// This header seems to contain the definitions of _kernel_ stat* structs.
|
|
# include <asm/stat.h>
|
|
# undef ino_t
|
|
# undef mode_t
|
|
# undef nlink_t
|
|
# undef uid_t
|
|
# undef gid_t
|
|
# undef off_t
|
|
# endif
|
|
|
|
# include <linux/aio_abi.h>
|
|
|
|
# if !SANITIZER_ANDROID
|
|
# include <sys/statfs.h>
|
|
# include <linux/perf_event.h>
|
|
# endif
|
|
|
|
using namespace __sanitizer;
|
|
|
|
# if !defined(__powerpc64__) && !defined(__x86_64__) && \
|
|
!defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \
|
|
!defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__)
|
|
COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));
|
|
#endif
|
|
|
|
COMPILER_CHECK(struct_kernel_stat_sz == sizeof(struct stat));
|
|
|
|
#if defined(__i386__)
|
|
COMPILER_CHECK(struct_kernel_stat64_sz == sizeof(struct stat64));
|
|
#endif
|
|
|
|
CHECK_TYPE_SIZE(io_event);
|
|
CHECK_SIZE_AND_OFFSET(io_event, data);
|
|
CHECK_SIZE_AND_OFFSET(io_event, obj);
|
|
CHECK_SIZE_AND_OFFSET(io_event, res);
|
|
CHECK_SIZE_AND_OFFSET(io_event, res2);
|
|
|
|
#if !SANITIZER_ANDROID
|
|
COMPILER_CHECK(sizeof(struct __sanitizer_perf_event_attr) <=
|
|
sizeof(struct perf_event_attr));
|
|
CHECK_SIZE_AND_OFFSET(perf_event_attr, type);
|
|
CHECK_SIZE_AND_OFFSET(perf_event_attr, size);
|
|
#endif
|
|
|
|
COMPILER_CHECK(iocb_cmd_pread == IOCB_CMD_PREAD);
|
|
COMPILER_CHECK(iocb_cmd_pwrite == IOCB_CMD_PWRITE);
|
|
#if !SANITIZER_ANDROID
|
|
COMPILER_CHECK(iocb_cmd_preadv == IOCB_CMD_PREADV);
|
|
COMPILER_CHECK(iocb_cmd_pwritev == IOCB_CMD_PWRITEV);
|
|
#endif
|
|
|
|
CHECK_TYPE_SIZE(iocb);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_data);
|
|
// Skip aio_key, it's weird.
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_lio_opcode);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_reqprio);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_fildes);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_buf);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_nbytes);
|
|
CHECK_SIZE_AND_OFFSET(iocb, aio_offset);
|
|
|
|
#endif // SANITIZER_LINUX
|