aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_mmap.c')
-rw-r--r--libraries/eina/src/lib/eina_mmap.c190
1 files changed, 0 insertions, 190 deletions
diff --git a/libraries/eina/src/lib/eina_mmap.c b/libraries/eina/src/lib/eina_mmap.c
deleted file mode 100644
index 7929f0e..0000000
--- a/libraries/eina/src/lib/eina_mmap.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2011 Carsten Haitzler
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#ifdef HAVE_SIGINFO_T
24
25#ifdef STDC_HEADERS
26# include <stdlib.h>
27# include <stddef.h>
28#else
29# ifdef HAVE_STDLIB_H
30# include <stdlib.h>
31# endif
32#endif
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <sys/mman.h>
40#include <limits.h>
41#include <signal.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <unistd.h>
45
46#if HAVE_SIGINFO_H
47# include <siginfo.h>
48#endif
49
50#endif
51
52#include "eina_config.h"
53#include "eina_private.h"
54#include "eina_log.h"
55#include "eina_mmap.h"
56
57/*============================================================================*
58 * Local *
59 *============================================================================*/
60
61static Eina_Bool mmap_safe = EINA_FALSE;
62#ifdef HAVE_SIGINFO_T
63
64static int _eina_mmap_log_dom = -1;
65static int _eina_mmap_zero_fd = -1;
66static long _eina_mmap_pagesize = -1;
67
68#ifdef ERR
69#undef ERR
70#endif
71#define ERR(...) EINA_LOG_DOM_ERR(_eina_mmap_log_dom, __VA_ARGS__)
72
73#ifdef DBG
74#undef DBG
75#endif
76#define DBG(...) EINA_LOG_DOM_DBG(_eina_mmap_log_dom, __VA_ARGS__)
77
78static void
79_eina_mmap_safe_sigbus(int sig __UNUSED__,
80 siginfo_t *siginfo,
81 void *ptr __UNUSED__)
82{
83 unsigned char *addr = (unsigned char *)(siginfo->si_addr);
84 int perrno;
85
86 /* save previous errno */
87 perrno = errno;
88 /* if problems was an unaligned access - complain accordingly and abort */
89 if (siginfo->si_code == BUS_ADRALN)
90 {
91 ERR("Unaligned memory access. SIGBUS!!!");
92 errno = perrno;
93 abort();
94 }
95 /* send this to stderr - not eina_log. Specifically want this on stderr */
96 fprintf(stderr,
97 "EINA: Data at address 0x%lx is invalid. Replacing with zero page.\n",
98 (unsigned long)addr);
99 /* align address to the lower page boundary */
100 addr = (unsigned char *)((long)addr & (~(_eina_mmap_pagesize - 1)));
101 /* mmap a pzge of zero's from /dev/zero in there */
102 if (mmap(addr, _eina_mmap_pagesize,
103 PROT_READ | PROT_WRITE | PROT_EXEC,
104 MAP_PRIVATE | MAP_FIXED,
105 _eina_mmap_zero_fd, 0) == MAP_FAILED)
106 {
107 /* mmap of /dev/zero failed :( */
108 perror("mmap");
109 ERR("Failed to mmap() /dev/zero in place of page. SIGBUS!!!");
110 errno = perrno;
111 abort();
112 }
113 /* Look into mmaped Eina_File if it was one of them, just to remember for later request */
114 eina_file_mmap_faulty(addr, _eina_mmap_pagesize);
115 /* restore previous errno */
116 errno = perrno;
117}
118#endif
119
120/*============================================================================*
121 * API *
122 *============================================================================*/
123
124EAPI Eina_Bool
125eina_mmap_safety_enabled_set(Eina_Bool enabled)
126{
127#ifndef HAVE_SIGINFO_T
128 (void) enabled;
129 return EINA_FALSE;
130#else
131 if (_eina_mmap_log_dom < 0)
132 {
133 _eina_mmap_log_dom = eina_log_domain_register("eina_mmap",
134 EINA_LOG_COLOR_DEFAULT);
135 if (_eina_mmap_log_dom < 0)
136 {
137 EINA_LOG_ERR("Could not register log domain: eina_mmap");
138 return EINA_FALSE;
139 }
140 }
141
142 enabled = !!enabled;
143
144 if (mmap_safe == enabled) return mmap_safe;
145 if (enabled)
146 {
147 struct sigaction sa;
148
149 /* find out system page size the cleanest way we can */
150#ifdef _SC_PAGESIZE
151 _eina_mmap_pagesize = sysconf(_SC_PAGESIZE);
152 if (_eina_mmap_pagesize <= 0) return EINA_FALSE;
153#else
154 _eina_mmap_pagesize = 4096;
155#endif
156 /* no zero page device - open it */
157 if (_eina_mmap_zero_fd < 0)
158 {
159 _eina_mmap_zero_fd = open("/dev/zero", O_RDWR);
160 /* if we don;'t have one - fail to set up mmap safety */
161 if (_eina_mmap_zero_fd < 0) return EINA_FALSE;
162 }
163 /* set up signal handler for SIGBUS */
164 sa.sa_sigaction = _eina_mmap_safe_sigbus;
165 sa.sa_flags = SA_RESTART | SA_SIGINFO;
166 sigemptyset(&sa.sa_mask);
167 /* FIXME: This is rubbish. We return EINA_FALSE whether sigaction
168 * fails or not. And we never set mmap_safe, so we always hit this
169 * code path. */
170 if (sigaction(SIGBUS, &sa, NULL) == 0) return EINA_FALSE;
171 /* setup of SIGBUS handler failed, lets close zero page dev and fail */
172 close(_eina_mmap_zero_fd);
173 _eina_mmap_zero_fd = -1;
174 return EINA_FALSE;
175 }
176 else
177 {
178 /* reset signal handler to default for SIGBUS */
179 signal(SIGBUS, SIG_DFL);
180 }
181 mmap_safe = enabled;
182 return mmap_safe;
183#endif
184}
185
186EAPI Eina_Bool
187eina_mmap_safety_enabled_get(void)
188{
189 return mmap_safe;
190}