diff options
| author | Kamil Rytarowski <n54@gmx.com> | 2018-03-03 12:04:40 +0000 | 
|---|---|---|
| committer | Kamil Rytarowski <n54@gmx.com> | 2018-03-03 12:04:40 +0000 | 
| commit | c18102fed5fc2f8a3020a548544daf2d1a743a90 (patch) | |
| tree | f36b980f371bed393f6bd6af34fb2a1b08527fda /compiler-rt | |
| parent | 8ec9586851ae5e8b5897281cbf4497826244065d (diff) | |
| download | bcm5719-llvm-c18102fed5fc2f8a3020a548544daf2d1a743a90.tar.gz bcm5719-llvm-c18102fed5fc2f8a3020a548544daf2d1a743a90.zip  | |
OpenBSD UBsan support / common
Summary:
Sanitizer common, enable OpenBSD platform.
- Enable common interceptors as possible and create few distinct ones.
- Create necessary sanitizer_struct types.
Patch by: David CARLIER
Reviewers: krytarowski, vitalybuka, visa, kettenis
Reviewed By: vitalybuka
Subscribers: emaste, srhines, kubamracek, mgorny, fedor.sergeev, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D43909
llvm-svn: 326650
Diffstat (limited to 'compiler-rt')
4 files changed, 762 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index a77849acfa2..fb73c879293 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -16,9 +16,11 @@ set(SANITIZER_SOURCES_NOTERMINATION    sanitizer_linux.cc    sanitizer_linux_s390.cc    sanitizer_mac.cc +  sanitizer_openbsd.cc    sanitizer_persistent_allocator.cc    sanitizer_platform_limits_linux.cc    sanitizer_platform_limits_netbsd.cc +  sanitizer_platform_limits_openbsd.cc    sanitizer_platform_limits_posix.cc    sanitizer_platform_limits_solaris.cc    sanitizer_posix.cc diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cc b/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cc new file mode 100644 index 00000000000..2aea7cb1487 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cc @@ -0,0 +1,101 @@ +//===-- sanitizer_openbsd.cc ----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements Solaris-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_OPENBSD + +#include <stdio.h> + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_platform_limits_posix.h" +#include "sanitizer_procmaps.h" + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/shm.h> +#include <sys/sysctl.h> +#include <sys/types.h> +#include <unistd.h> + +extern char **environ; + +namespace __sanitizer { + +uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd, +                   u64 offset) { +  return (uptr)mmap(addr, length, prot, flags, fd, offset); +} + +uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); } + +int internal_mprotect(void *addr, uptr length, int prot) { +  return mprotect(addr, length, prot); +} + +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { +  // On OpenBSD we cannot get the full path +  struct kinfo_proc kp; +  size_t kl; +  const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; +  if (sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1) +    return internal_snprintf(buf, +                             (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len), +                             "%s", kp.p_comm); +  return (uptr)0; +} + +static void GetArgsAndEnv(char ***argv, char ***envp) { +  size_t nargv; +  size_t nenv; +  int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV}; +  int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV}; +  if (sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) { +    Printf("sysctl KERN_PROC_NARGV failed\n"); +    Die(); +  } +  if (sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) { +    Printf("sysctl KERN_PROC_NENV failed\n"); +    Die(); +  } +  if (sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) { +    Printf("sysctl KERN_PROC_ARGV failed\n"); +    Die(); +  } +  if (sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) { +    Printf("sysctl KERN_PROC_ENV failed\n"); +    Die(); +  } +} + +char **GetArgv() { +  char **argv, **envp; +  GetArgsAndEnv(&argv, &envp); +  return argv; +} + +void ReExec() { +  UNIMPLEMENTED(); +} + +}  // namespace __sanitizer + +#endif  // SANITIZER_OPENBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc new file mode 100644 index 00000000000..7ab0ff60a24 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc @@ -0,0 +1,279 @@ +//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific NetBSD data structures. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_OPENBSD +#include <arpa/inet.h> +#include <dirent.h> +#include <glob.h> +#include <grp.h> +#include <ifaddrs.h> +#include <limits.h> +#include <link_elf.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/ppp_defs.h> +#include <net/route.h> +#include <netdb.h> +#include <netinet/in.h> +#include <netinet/ip_mroute.h> +#include <poll.h> +#include <pthread.h> +#include <pwd.h> +#include <semaphore.h> +#include <signal.h> +#include <soundcard.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/filio.h> +#include <sys/ipc.h> +#include <sys/mman.h> +#include <sys/mount.h> +#include <sys/msg.h> +#include <sys/mtio.h> +#include <sys/ptrace.h> +#include <sys/resource.h> +#include <sys/shm.h> +#include <sys/signal.h> +#include <sys/sockio.h> +#include <sys/stat.h> +#include <sys/statvfs.h> +#include <sys/time.h> +#include <sys/times.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <term.h> +#include <time.h> +#include <utime.h> +#include <utmp.h> +#include <wchar.h> + +// Include these after system headers to avoid name clashes and ambiguities. +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_openbsd.h" + +namespace __sanitizer { +unsigned struct_utsname_sz = sizeof(struct utsname); +unsigned struct_stat_sz = sizeof(struct stat); +unsigned struct_rusage_sz = sizeof(struct rusage); +unsigned struct_tm_sz = sizeof(struct tm); +unsigned struct_passwd_sz = sizeof(struct passwd); +unsigned struct_group_sz = sizeof(struct group); +unsigned siginfo_t_sz = sizeof(siginfo_t); +unsigned struct_sigaction_sz = sizeof(struct sigaction); +unsigned struct_itimerval_sz = sizeof(struct itimerval); +unsigned pthread_t_sz = sizeof(pthread_t); +unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t); +unsigned pthread_cond_t_sz = sizeof(pthread_cond_t); +unsigned pid_t_sz = sizeof(pid_t); +unsigned timeval_sz = sizeof(timeval); +unsigned uid_t_sz = sizeof(uid_t); +unsigned gid_t_sz = sizeof(gid_t); +unsigned mbstate_t_sz = sizeof(mbstate_t); +unsigned sigset_t_sz = sizeof(sigset_t); +unsigned struct_timezone_sz = sizeof(struct timezone); +unsigned struct_tms_sz = sizeof(struct tms); +unsigned struct_sched_param_sz = sizeof(struct sched_param); +unsigned struct_sockaddr_sz = sizeof(struct sockaddr); +unsigned struct_rlimit_sz = sizeof(struct rlimit); +unsigned struct_timespec_sz = sizeof(struct timespec); +unsigned struct_utimbuf_sz = sizeof(struct utimbuf); +unsigned struct_itimerspec_sz = sizeof(struct itimerspec); +unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); +unsigned struct_statvfs_sz = sizeof(struct statvfs); + +const uptr sig_ign = (uptr)SIG_IGN; +const uptr sig_dfl = (uptr)SIG_DFL; +const uptr sig_err = (uptr)SIG_ERR; +const uptr sa_siginfo = (uptr)SA_SIGINFO; + +int shmctl_ipc_stat = (int)IPC_STAT; + +unsigned struct_utmp_sz = sizeof(struct utmp); + +int map_fixed = MAP_FIXED; + +int af_inet = (int)AF_INET; +int af_inet6 = (int)AF_INET6; + +uptr __sanitizer_in_addr_sz(int af) { +  if (af == AF_INET) +    return sizeof(struct in_addr); +  else if (af == AF_INET6) +    return sizeof(struct in6_addr); +  else +    return 0; +} + +unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + +int glob_nomatch = GLOB_NOMATCH; +int glob_altdirfunc = GLOB_ALTDIRFUNC; + +unsigned path_max = PATH_MAX; + +const int si_SEGV_MAPERR = SEGV_MAPERR; +const int si_SEGV_ACCERR = SEGV_ACCERR; +}  // namespace __sanitizer + +using namespace __sanitizer; + +COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t)); + +COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned)); +CHECK_TYPE_SIZE(pthread_key_t); + +CHECK_TYPE_SIZE(dl_phdr_info); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum); + +CHECK_TYPE_SIZE(glob_t); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); +CHECK_SIZE_AND_OFFSET(glob_t, gl_offs); +CHECK_SIZE_AND_OFFSET(glob_t, gl_flags); +CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat); +CHECK_SIZE_AND_OFFSET(glob_t, gl_stat); + +CHECK_TYPE_SIZE(addrinfo); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_family); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_next); + +CHECK_TYPE_SIZE(hostent); +CHECK_SIZE_AND_OFFSET(hostent, h_name); +CHECK_SIZE_AND_OFFSET(hostent, h_aliases); +CHECK_SIZE_AND_OFFSET(hostent, h_addrtype); +CHECK_SIZE_AND_OFFSET(hostent, h_length); +CHECK_SIZE_AND_OFFSET(hostent, h_addr_list); + +CHECK_TYPE_SIZE(iovec); +CHECK_SIZE_AND_OFFSET(iovec, iov_base); +CHECK_SIZE_AND_OFFSET(iovec, iov_len); + +CHECK_TYPE_SIZE(msghdr); +CHECK_SIZE_AND_OFFSET(msghdr, msg_name); +CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iov); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_control); +CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_flags); + +CHECK_TYPE_SIZE(cmsghdr); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type); + +COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); +CHECK_SIZE_AND_OFFSET(dirent, d_fileno); +CHECK_SIZE_AND_OFFSET(dirent, d_off); +CHECK_SIZE_AND_OFFSET(dirent, d_reclen); + +CHECK_TYPE_SIZE(ifconf); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_len); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu); + +CHECK_TYPE_SIZE(pollfd); +CHECK_SIZE_AND_OFFSET(pollfd, fd); +CHECK_SIZE_AND_OFFSET(pollfd, events); +CHECK_SIZE_AND_OFFSET(pollfd, revents); + +CHECK_TYPE_SIZE(nfds_t); + +CHECK_TYPE_SIZE(sigset_t); + +COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction)); +// Can't write checks for sa_handler and sa_sigaction due to them being +// preprocessor macros. +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); + +CHECK_TYPE_SIZE(tm); +CHECK_SIZE_AND_OFFSET(tm, tm_sec); +CHECK_SIZE_AND_OFFSET(tm, tm_min); +CHECK_SIZE_AND_OFFSET(tm, tm_hour); +CHECK_SIZE_AND_OFFSET(tm, tm_mday); +CHECK_SIZE_AND_OFFSET(tm, tm_mon); +CHECK_SIZE_AND_OFFSET(tm, tm_year); +CHECK_SIZE_AND_OFFSET(tm, tm_wday); +CHECK_SIZE_AND_OFFSET(tm, tm_yday); +CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); +CHECK_SIZE_AND_OFFSET(tm, tm_zone); + +CHECK_TYPE_SIZE(ipc_perm); +CHECK_SIZE_AND_OFFSET(ipc_perm, cuid); +CHECK_SIZE_AND_OFFSET(ipc_perm, cgid); +CHECK_SIZE_AND_OFFSET(ipc_perm, uid); +CHECK_SIZE_AND_OFFSET(ipc_perm, gid); +CHECK_SIZE_AND_OFFSET(ipc_perm, mode); +CHECK_SIZE_AND_OFFSET(ipc_perm, seq); +CHECK_SIZE_AND_OFFSET(ipc_perm, key); + +CHECK_TYPE_SIZE(shmid_ds); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_atimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_dtimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_ctimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch); + +CHECK_TYPE_SIZE(clock_t); + +CHECK_TYPE_SIZE(ifaddrs); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask); +// Compare against the union, because we can't reach into the union in a +// compliant way. +#ifdef ifa_dstaddr +#undef ifa_dstaddr +#endif +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data); + +CHECK_TYPE_SIZE(passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_name); +CHECK_SIZE_AND_OFFSET(passwd, pw_passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_uid); +CHECK_SIZE_AND_OFFSET(passwd, pw_gid); +CHECK_SIZE_AND_OFFSET(passwd, pw_dir); +CHECK_SIZE_AND_OFFSET(passwd, pw_shell); + +CHECK_SIZE_AND_OFFSET(passwd, pw_gecos); + +CHECK_TYPE_SIZE(group); +CHECK_SIZE_AND_OFFSET(group, gr_name); +CHECK_SIZE_AND_OFFSET(group, gr_passwd); +CHECK_SIZE_AND_OFFSET(group, gr_gid); +CHECK_SIZE_AND_OFFSET(group, gr_mem); + +#endif  // SANITIZER_OPENBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.h new file mode 100644 index 00000000000..b926ca628eb --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_openbsd.h @@ -0,0 +1,380 @@ +//===-- sanitizer_platform_limits_openbsd.h -------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific OpenBSD data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_OPENBSD_H +#define SANITIZER_PLATFORM_LIMITS_OPENBSD_H + +#if SANITIZER_OPENBSD + +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" + +#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \ +  ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift)))) + +#if defined(__x86_64__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ +  _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312) +#elif defined(__i386__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ +  _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164) +#endif + +namespace __sanitizer { +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +extern unsigned struct_sigevent_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; + +extern unsigned struct_rlimit_sz; +extern unsigned struct_utimbuf_sz; +extern unsigned struct_timespec_sz; + +struct __sanitizer_iocb { +  u64 aio_offset; +  uptr aio_buf; +  long aio_nbytes; +  u32 aio_fildes; +  u32 aio_lio_opcode; +  long aio_reqprio; +#if SANITIZER_WORDSIZE == 64 +  u8 aio_sigevent[32]; +#else +  u8 aio_sigevent[20]; +#endif +  u32 _state; +  u32 _errno; +  long _retval; +}; + +struct __sanitizer___sysctl_args { +  int *name; +  int nlen; +  void *oldval; +  uptr *oldlenp; +  void *newval; +  uptr newlen; +}; + +struct __sanitizer_sem_t { +  uptr data[5]; +}; + +struct __sanitizer_ipc_perm { +  u32 cuid; +  u32 cgid; +  u32 uid; +  u32 gid; +  u32 mode; +  unsigned short seq; +  long key; +}; + +struct __sanitizer_shmid_ds { +  __sanitizer_ipc_perm shm_perm; +  int shm_segsz; +  u32 shm_lpid; +  u32 shm_cpid; +  short shm_nattch; +  u64 shm_atime; +  long __shm_atimensec; +  u64 shm_dtime; +  long __shm_dtimensec; +  u64 shm_ctime; +  long __shm_ctimensec; +  void *_shm_internal; +}; + +extern unsigned struct_msqid_ds_sz; +extern unsigned struct_mq_attr_sz; +extern unsigned struct_timex_sz; +extern unsigned struct_statvfs_sz; + +struct __sanitizer_iovec { +  void *iov_base; +  uptr iov_len; +}; + +struct __sanitizer_ifaddrs { +  struct __sanitizer_ifaddrs *ifa_next; +  char *ifa_name; +  unsigned int ifa_flags; +  struct __sanitizer_sockaddr *ifa_addr;     // (struct sockaddr *) +  struct __sanitizer_sockaddr *ifa_netmask;  // (struct sockaddr *) +  struct __sanitizer_sockaddr *ifa_dstaddr;  // (struct sockaddr *) +  void *ifa_data; +}; + +typedef unsigned __sanitizer_pthread_key_t; + +typedef long long __sanitizer_time_t; +typedef int __sanitizer_suseconds_t; + +struct __sanitizer_timeval { +  __sanitizer_time_t tv_sec; +  __sanitizer_suseconds_t tv_usec; +}; + +struct __sanitizer_itimerval { +  struct __sanitizer_timeval it_interval; +  struct __sanitizer_timeval it_value; +}; + +struct __sanitizer_passwd { +  char *pw_name; +  char *pw_passwd; +  int pw_uid; +  int pw_gid; +  __sanitizer_time_t pw_change; +  char *pw_class; +  char *pw_gecos; +  char *pw_dir; +  char *pw_shell; +  __sanitizer_time_t pw_expire; +}; + +struct __sanitizer_group { +  char *gr_name; +  char *gr_passwd; +  int gr_gid; +  char **gr_mem; +}; + +struct __sanitizer_ether_addr { +  u8 octet[6]; +}; + +struct __sanitizer_tm { +  int tm_sec; +  int tm_min; +  int tm_hour; +  int tm_mday; +  int tm_mon; +  int tm_year; +  int tm_wday; +  int tm_yday; +  int tm_isdst; +  long int tm_gmtoff; +  const char *tm_zone; +}; + +struct __sanitizer_msghdr { +  void *msg_name; +  unsigned msg_namelen; +  struct __sanitizer_iovec *msg_iov; +  unsigned msg_iovlen; +  void *msg_control; +  unsigned msg_controllen; +  int msg_flags; +}; +struct __sanitizer_cmsghdr { +  unsigned cmsg_len; +  int cmsg_level; +  int cmsg_type; +}; + +struct __sanitizer_dirent { +  u64 d_fileno; +  u64 d_off; +  u16 d_reclen; +}; + +typedef u64 __sanitizer_clock_t; +typedef u32 __sanitizer_clockid_t; + +typedef u32 __sanitizer___kernel_uid_t; +typedef u32 __sanitizer___kernel_gid_t; +typedef u64 __sanitizer___kernel_off_t; +typedef struct { +  u32 fds_bits[8]; +} __sanitizer___kernel_fd_set; + +typedef struct { +  unsigned int pta_magic; +  int pta_flags; +  void *pta_private; +} __sanitizer_pthread_attr_t; + +typedef unsigned int __sanitizer_sigset_t; + +struct __sanitizer_siginfo { +  // The size is determined by looking at sizeof of real siginfo_t on linux. +  u64 opaque[128 / sizeof(u64)]; +}; + +using __sanitizer_sighandler_ptr = void (*)(int sig); +using __sanitizer_sigactionhandler_ptr = void (*)(int sig, +                                                  __sanitizer_siginfo *siginfo, +                                                  void *uctx); + +struct __sanitizer_sigaction { +  union { +    __sanitizer_sighandler_ptr handler; +    __sanitizer_sigactionhandler_ptr sigaction; +  }; +  __sanitizer_sigset_t sa_mask; +  int sa_flags; +}; + +typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; + +struct __sanitizer_kernel_sigaction_t { +  union { +    void (*handler)(int signo); +    void (*sigaction)(int signo, void *info, void *ctx); +  }; +  unsigned long sa_flags; +  void (*sa_restorer)(void); +  __sanitizer_kernel_sigset_t sa_mask; +}; + +extern const uptr sig_ign; +extern const uptr sig_dfl; +extern const uptr sig_err; +extern const uptr sa_siginfo; + +extern int af_inet; +extern int af_inet6; +uptr __sanitizer_in_addr_sz(int af); + +struct __sanitizer_dl_phdr_info { +#if SANITIZER_WORDSIZE == 64 +  u64 dlpi_addr; +#else +  u32 dlpi_addr; +#endif +  const char *dlpi_name; +  const void *dlpi_phdr; +#if SANITIZER_WORDSIZE == 64 +  u32 dlpi_phnum; +#else +  u16 dlpi_phnum; +#endif +}; + +extern unsigned struct_ElfW_Phdr_sz; + +struct __sanitizer_addrinfo { +  int ai_flags; +  int ai_family; +  int ai_socktype; +  int ai_protocol; +  unsigned ai_addrlen; +  struct __sanitizer_sockaddr *ai_addr; +  char *ai_canonname; +  struct __sanitizer_addrinfo *ai_next; +}; + +struct __sanitizer_hostent { +  char *h_name; +  char **h_aliases; +  int h_addrtype; +  int h_length; +  char **h_addr_list; +}; + +struct __sanitizer_pollfd { +  int fd; +  short events; +  short revents; +}; + +typedef unsigned __sanitizer_nfds_t; + +struct __sanitizer_glob_t { +  int gl_pathc; +  int gl_matchc; +  int gl_offs; +  int gl_flags; +  char **gl_pathv; +  void **gl_statv; +  int (*gl_errfunc)(const char *, int); +  void (*gl_closedir)(void *dirp); +  struct dirent *(*gl_readdir)(void *dirp); +  void *(*gl_opendir)(const char *); +  int (*gl_lstat)(const char *, void * /* struct stat* */); +  int (*gl_stat)(const char *, void * /* struct stat* */); +}; + +extern int glob_nomatch; +extern int glob_altdirfunc; + +extern unsigned path_max; + +typedef char __sanitizer_FILE; +#define SANITIZER_HAS_STRUCT_FILE 0 + +extern int shmctl_ipc_stat; + +// This simplifies generic code +#define struct_shminfo_sz -1 +#define struct_shm_info_sz -1 +#define shmctl_shm_stat -1 +#define shmctl_ipc_info -1 +#define shmctl_shm_info -1 + +extern unsigned struct_utmp_sz; +extern unsigned struct_utmpx_sz; + +extern int map_fixed; + +// ioctl arguments +struct __sanitizer_ifconf { +  int ifc_len; +  union { +    void *ifcu_req; +  } ifc_ifcu; +}; + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; +}  // namespace __sanitizer + +#define CHECK_TYPE_SIZE(TYPE) \ +  COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) + +#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER)                      \ +  COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ +                 sizeof(((CLASS *)NULL)->MEMBER));                \ +  COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) ==         \ +                 offsetof(CLASS, MEMBER)) + +// For sigaction, which is a function and struct at the same time, +// and thus requires explicit "struct" in sizeof() expression. +#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER)                      \ +  COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \ +                 sizeof(((struct CLASS *)NULL)->MEMBER));                \ +  COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) ==         \ +                 offsetof(struct CLASS, MEMBER)) + +#define SIGACTION_SYMNAME __sigaction14 + +#endif  // SANITIZER_OPENBSD + +#endif  | 

