blob: d5f4aabc4269c5f26fa9280db58d980e1623dee6 [file] [log] [blame]
Kostya Serebryany98d592c2017-01-20 20:57:07 +00001//===- 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"
Marcos Pividori764b65c2017-01-20 22:49:13 +000012#if LIBFUZZER_POSIX
Kostya Serebryany98d592c2017-01-20 20:57:07 +000013
14#include "FuzzerIO.h"
15#include "FuzzerShmem.h"
16
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#include <sys/mman.h>
21#include <semaphore.h>
22#include <stdio.h>
23#include <unistd.h>
24
25namespace fuzzer {
26
27std::string SharedMemoryRegion::Path(const char *Name) {
28 return DirPlusFile(TmpDir(), Name);
29}
30
31std::string SharedMemoryRegion::SemName(const char *Name, int Idx) {
32 std::string Res(Name);
33 return Res + (char)('0' + Idx);
34}
35
36bool SharedMemoryRegion::Map(int fd) {
37 Data = (uint8_t *)mmap(0, Size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
38 if (Data == (uint8_t*)-1)
39 return false;
40 return true;
41}
42
43bool SharedMemoryRegion::Create(const char *Name, size_t Size) {
44 int fd = open(Path(Name).c_str(), O_CREAT | O_RDWR, 0777);
45 if (fd < 0) return false;
46 if (ftruncate(fd, Size) < 0) return false;
47 this->Size = Size;
48 if (!Map(fd))
49 return false;
50 for (int i = 0; i < 2; i++) {
51 sem_unlink(SemName(Name, i).c_str());
52 Semaphore[i] = sem_open(SemName(Name, i).c_str(), O_CREAT, 0644, 0);
53 if (Semaphore[i] == (void *)-1)
54 return false;
55 }
56 IAmServer = true;
57 return true;
58}
59
60bool SharedMemoryRegion::Open(const char *Name) {
61 int fd = open(Path(Name).c_str(), O_RDWR);
62 if (fd < 0) return false;
63 struct stat stat_res;
64 if (0 != fstat(fd, &stat_res))
65 return false;
66 Size = stat_res.st_size;
67 if (!Map(fd))
68 return false;
69 for (int i = 0; i < 2; i++) {
70 Semaphore[i] = sem_open(SemName(Name, i).c_str(), 0);
71 if (Semaphore[i] == (void *)-1)
72 return false;
73 }
74 IAmServer = false;
75 return true;
76}
77
78bool SharedMemoryRegion::Destroy(const char *Name) {
79 return 0 == unlink(Path(Name).c_str());
80}
81
82void SharedMemoryRegion::Post(int Idx) {
83 assert(Idx == 0 || Idx == 1);
84 sem_post((sem_t*)Semaphore[Idx]);
85}
86
87void SharedMemoryRegion::Wait(int Idx) {
88 assert(Idx == 0 || Idx == 1);
Kostya Serebryany6d58dbb2017-01-27 22:41:30 +000089 for (int i = 0; i < 10 && sem_wait((sem_t*)Semaphore[Idx]); i++) {
90 // sem_wait may fail if interrupted by a signal.
91 sleep(i);
92 if (i)
93 Printf("%s: sem_wait[%d] failed %s\n", i < 9 ? "WARNING" : "ERROR", i,
94 strerror(errno));
95 if (i == 9) abort();
Kostya Serebryany98d592c2017-01-20 20:57:07 +000096 }
97}
98
99} // namespace fuzzer
100
101#endif // LIBFUZZER_POSIX