LLVM  6.0.0svn
FuzzerShmemPosix.cpp
Go to the documentation of this file.
1 //===- FuzzerShmemPosix.cpp - Posix shared memory ---------------*- C++ -* ===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // SharedMemoryRegion
10 //===----------------------------------------------------------------------===//
11 #include "FuzzerDefs.h"
12 #if LIBFUZZER_POSIX
13 
14 #include "FuzzerIO.h"
15 #include "FuzzerShmem.h"
16 
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <semaphore.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/mman.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 namespace fuzzer {
28 
29 std::string SharedMemoryRegion::Path(const char *Name) {
30  return DirPlusFile(TmpDir(), Name);
31 }
32 
33 std::string SharedMemoryRegion::SemName(const char *Name, int Idx) {
34  std::string Res(Name);
35  return Res + (char)('0' + Idx);
36 }
37 
38 bool SharedMemoryRegion::Map(int fd) {
39  Data =
40  (uint8_t *)mmap(0, kShmemSize, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
41  if (Data == (uint8_t*)-1)
42  return false;
43  return true;
44 }
45 
46 bool SharedMemoryRegion::Create(const char *Name) {
47  int fd = open(Path(Name).c_str(), O_CREAT | O_RDWR, 0777);
48  if (fd < 0) return false;
49  if (ftruncate(fd, kShmemSize) < 0) return false;
50  if (!Map(fd))
51  return false;
52  for (int i = 0; i < 2; i++) {
53  sem_unlink(SemName(Name, i).c_str());
54  Semaphore[i] = sem_open(SemName(Name, i).c_str(), O_CREAT, 0644, 0);
55  if (Semaphore[i] == (void *)-1)
56  return false;
57  }
58  IAmServer = true;
59  return true;
60 }
61 
62 bool SharedMemoryRegion::Open(const char *Name) {
63  int fd = open(Path(Name).c_str(), O_RDWR);
64  if (fd < 0) return false;
65  struct stat stat_res;
66  if (0 != fstat(fd, &stat_res))
67  return false;
68  assert(stat_res.st_size == kShmemSize);
69  if (!Map(fd))
70  return false;
71  for (int i = 0; i < 2; i++) {
72  Semaphore[i] = sem_open(SemName(Name, i).c_str(), 0);
73  if (Semaphore[i] == (void *)-1)
74  return false;
75  }
76  IAmServer = false;
77  return true;
78 }
79 
80 bool SharedMemoryRegion::Destroy(const char *Name) {
81  return 0 == unlink(Path(Name).c_str());
82 }
83 
84 void SharedMemoryRegion::Post(int Idx) {
85  assert(Idx == 0 || Idx == 1);
86  sem_post((sem_t*)Semaphore[Idx]);
87 }
88 
89 void SharedMemoryRegion::Wait(int Idx) {
90  assert(Idx == 0 || Idx == 1);
91  for (int i = 0; i < 10 && sem_wait((sem_t*)Semaphore[Idx]); i++) {
92  // sem_wait may fail if interrupted by a signal.
93  sleep(i);
94  if (i)
95  Printf("%s: sem_wait[%d] failed %s\n", i < 9 ? "WARNING" : "ERROR", i,
96  strerror(errno));
97  if (i == 9) abort();
98  }
99 }
100 
101 } // namespace fuzzer
102 
103 #endif // LIBFUZZER_POSIX
bool Create(const char *Name)
bool Open(const char *Name)
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:112
std::string DirPlusFile(const std::string &DirPath, const std::string &FileName)
Definition: FuzzerIO.cpp:89
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
bool Destroy(const char *Name)
std::string TmpDir()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ProcessInfo Wait(const ProcessInfo &PI, unsigned SecondsToWait, bool WaitUntilTerminates, std::string *ErrMsg=nullptr)
This function waits for the process specified by PI to finish.