1//===-- sanitizer_openbsd.cpp ---------------------------------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is shared between various sanitizers' runtime libraries and
10// implements Solaris-specific functions.
11//===----------------------------------------------------------------------===//
12
13#include "sanitizer_platform.h"
14#if SANITIZER_OPENBSD
15
16#include <stdio.h>
17
18#include "sanitizer_common.h"
19#include "sanitizer_flags.h"
20#include "sanitizer_internal_defs.h"
21#include "sanitizer_libc.h"
22#include "sanitizer_placement_new.h"
23#include "sanitizer_platform_limits_posix.h"
24#include "sanitizer_procmaps.h"
25
26#include <errno.h>
27#include <fcntl.h>
28#include <limits.h>
29#include <pthread.h>
30#include <sched.h>
31#include <signal.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <sys/mman.h>
35#include <sys/shm.h>
36#include <sys/sysctl.h>
37#include <sys/types.h>
38#include <unistd.h>
39
40extern char **environ;
41
42namespace __sanitizer {
43
44uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd,
45                   u64 offset) {
46  return (uptr)mmap(addr, length, prot, flags, fd, offset);
47}
48
49uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); }
50
51int internal_mprotect(void *addr, uptr length, int prot) {
52  return mprotect(addr, length, prot);
53}
54
55int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
56                          const void *newp, uptr newlen) {
57  Printf("internal_sysctlbyname not implemented for OpenBSD");
58  Die();
59  return 0;
60}
61
62uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
63  // On OpenBSD we cannot get the full path
64  struct kinfo_proc kp;
65  uptr kl;
66  const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
67  if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
68    return internal_snprintf(buf,
69                             (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len),
70                             "%s", kp.p_comm);
71  return (uptr)0;
72}
73
74static void GetArgsAndEnv(char ***argv, char ***envp) {
75  uptr nargv;
76  uptr nenv;
77  int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV};
78  int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV};
79  if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
80    Printf("sysctl KERN_PROC_NARGV failed\n");
81    Die();
82  }
83  if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
84    Printf("sysctl KERN_PROC_NENV failed\n");
85    Die();
86  }
87  if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
88    Printf("sysctl KERN_PROC_ARGV failed\n");
89    Die();
90  }
91  if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
92    Printf("sysctl KERN_PROC_ENV failed\n");
93    Die();
94  }
95}
96
97char **GetArgv() {
98  char **argv, **envp;
99  GetArgsAndEnv(&argv, &envp);
100  return argv;
101}
102
103char **GetEnviron() {
104  char **argv, **envp;
105  GetArgsAndEnv(&argv, &envp);
106  return envp;
107}
108
109void ReExec() {
110  UNIMPLEMENTED();
111}
112
113}  // namespace __sanitizer
114
115#endif  // SANITIZER_OPENBSD
116