1 // binutils.c
2 // hosts2zones
3 //
4 // Created by Dr. Rolf Jansen on 2016-08-13.
5 // Copyright (c) 2016 projectworld.net. All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without modification,
8 // are permitted provided that the following conditions are met:
9 //
10 // 1. Redistributions of source code must retain the above copyright notice,
11 // this list of conditions and the following disclaimer.
12 //
13 // 2. Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
20 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
24 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <syslog.h>
34
35 #include "binutils.h"
36
37 #pragma mark ••• Fencing Memory Allocation Wrappers •••
38
39 ssize_t gAllocationTotal = 0;
40
countAllocation(ssize_t size)41 static inline void countAllocation(ssize_t size)
42 {
43 if (__sync_add_and_fetch(&gAllocationTotal, size) < 0)
44 {
45 syslog(LOG_ERR, "Corruption of allocated memory detected by countAllocation().");
46 exit(EXIT_FAILURE);
47 }
48 }
49
allocate(ssize_t size,bool cleanout)50 void *allocate(ssize_t size, bool cleanout)
51 {
52 if (size >= 0)
53 {
54 allocation *a;
55
56 if (cleanout)
57 {
58 if ((a = calloc(1, allocationMetaSize + size + sizeof(size_t))) == NULL)
59 return NULL;
60 }
61
62 else
63 {
64 if ((a = malloc(allocationMetaSize + size + sizeof(size_t))) == NULL)
65 return NULL;
66
67 *(size_t *)((void *)a + allocationMetaSize + size) = 0; // place a (size_t)0 just above the payload as the upper boundary of the allocation
68 }
69
70 countAllocation(size);
71 a->size = size;
72 a->check = size | (size_t)a;
73 return &a->payload;
74 }
75 else
76 return NULL;
77 }
78
reallocate(void * p,ssize_t size,bool cleanout,bool free_on_error)79 void *reallocate(void *p, ssize_t size, bool cleanout, bool free_on_error)
80 {
81 if (size >= 0)
82 if (p)
83 {
84 allocation *a = p - allocationMetaSize;
85
86 if (a->check == (a->size | (size_t)a) && *(ssize_t *)((void *)a + allocationMetaSize + a->size) == 0)
87 a->check = 0;
88 else
89 {
90 syslog(LOG_ERR, "Corruption of allocated memory detected by reallocate().");
91 exit(EXIT_FAILURE);
92 }
93
94 if ((p = realloc(a, allocationMetaSize + size + sizeof(size_t))) == NULL)
95 {
96 if (free_on_error)
97 {
98 countAllocation(-a->size);
99 free(a);
100 }
101 return NULL;
102 }
103 else
104 a = p;
105
106 if (cleanout)
107 bzero((void *)a + allocationMetaSize + a->size, size - a->size + sizeof(size_t));
108 else
109 *(ssize_t *)((void *)a + allocationMetaSize + size) = 0; // place a (size_t)0 just above the payload as the upper boundary of the allocation
110
111 countAllocation(size - a->size);
112 a->size = size;
113 a->check = size | (size_t)a;
114 return &a->payload;
115 }
116 else
117 return allocate(size, cleanout);
118
119 return NULL;
120 }
121
deallocate(void ** p,bool cleanout)122 void deallocate(void **p, bool cleanout)
123 {
124 if (p && *p)
125 {
126 allocation *a = *p - allocationMetaSize;
127 *p = NULL;
128
129 if (a->check == (a->size | (size_t)a) && *(ssize_t *)((void *)a + allocationMetaSize + a->size) == 0)
130 a->check = 0;
131 else
132 {
133 syslog(LOG_ERR, "Corruption of allocated memory detected by deallocate().");
134 exit(EXIT_FAILURE);
135 }
136
137 countAllocation(-a->size);
138 if (cleanout)
139 bzero((void *)a, allocationMetaSize + a->size + sizeof(size_t));
140 free(a);
141 }
142 }
143
deallocate_batch(unsigned cleanout,...)144 void deallocate_batch(unsigned cleanout, ...)
145 {
146 void **p;
147 va_list vl;
148 va_start(vl, cleanout);
149
150 while (p = va_arg(vl, void **))
151 if (*p)
152 {
153 allocation *a = *p - allocationMetaSize;
154 *p = NULL;
155
156 if (a->check == (a->size | (size_t)a) && *(ssize_t *)((void *)a + allocationMetaSize + a->size) == 0)
157 a->check = 0;
158 else
159 {
160 syslog(LOG_ERR, "Corruption of allocated memory detected by deallocate_batch().");
161 exit(EXIT_FAILURE);
162 }
163
164 countAllocation(-a->size);
165 if (cleanout)
166 bzero((void *)a, allocationMetaSize + a->size + sizeof(size_t));
167 free(a);
168 }
169
170 va_end(vl);
171 }
172