-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathminilib_global.h
307 lines (257 loc) · 7.19 KB
/
minilib_global.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#ifndef minilib_global_h
#define minilib_global_h
#ifdef mini_globals_on_stack
#ifndef mini_globals
#define mini_globals
#endif
#endif
#ifdef mini_errno
#ifndef mini_globals
#define mini_globals
#endif
#endif
#ifdef mini_environ
#ifndef mini_globals
#define mini_globals
#endif
#endif
#ifndef mini_pwent
#ifdef mini_getpwent
#define mini_pwent
#endif
#ifdef mini_getpwuid
#define mini_pwent
#endif
#ifdef mini_getpwnam
#define mini_pwent
#endif
#ifdef mini_setpwent
#define mini_pwent
#endif
#endif
#ifndef mini_grent
#ifdef mini_getgrent
#define mini_grent
#endif
#ifdef mini_getgrnam
#define mini_grent
#endif
#ifdef mini_getgroups
#define mini_grent
#endif
#ifdef mini_getgrgid
#define mini_grent
#endif
#endif
#ifdef mini_buf
#if mini_buf > 0
#else
#warning mini_buf defaults to 2048 Bytes
#define mini_buf 2048
#endif
#endif
#ifdef mini_buf
#define mini_bufsize mini_buf
#ifndef mini_globals
#define mini_globals
#endif
#else
#define mini_bufsize 0
#endif
typedef struct {
int errno;
int sysret;
int srand;
int pstream;
int mbufsize;
int _intbufsize;
int align[1];
char **environ;
unsigned long brk;
unsigned long malloc_start;
#ifdef mini_atexit
functionp* atexitp[ATEXIT_MAX];
#endif
void *appdata; // can be used freely.
// intended to be used for globals,
// which can be located on the stack.
// just define a struct on stack,
// (e.g. within main),
// and set this pointer to the struct.
int stream[mini_FOPEN_MAX];
#ifdef mini_pwent
userdb passwdfile;
struct passwd pwent; // quite some overhead. But needed for threadsafety.
// leaving it here for now. possibly todo: make pwent a switch,
// either with or without threadsafety of getpwuid and family.
// (keeping this struct within the globals, or not)
#endif
#ifdef mini_grent
userdb groupfile;
//int groupnamecount; TODO: enlarge the array to the groupname pointers,
// when needed. (shrinking the minibuf) ->getgrent
struct group groupent;
#endif
#ifdef mini_inet_ntoa
char inet_ntoa_addr[16];
#endif
#ifdef mini_ether_ntoa
char ether_ntoa_addr[20]; // padded to %4
#endif
} __globals_shadow;
typedef struct {
int errno;
int sysret;
int srand;
int pstream;
int mbufsize;
int _intbufsize;
int align[1];
char **environ;
unsigned long brk;
unsigned long malloc_start;
#ifdef mini_atexit
functionp* atexitp[ATEXIT_MAX];
#endif
void *appdata; // can be used freely.
// intended to be used for globals,
// which can be located on the stack.
// just define a struct on stack,
// (e.g. within main),
// and set this pointer to the struct.
int stream[mini_FOPEN_MAX];
#ifdef mini_pwent
userdb passwdfile;
struct passwd pwent; // quite some overhead. But needed for threadsafety.
// leaving it here for now. possibly todo: make pwent a switch,
// either with or without threadsafety of getpwuid and family.
// (keeping this struct within the globals, or not)
#endif
#ifdef mini_grent
userdb groupfile;
//int groupnamecount; TODO: enlarge the array to the groupname pointers,
// when needed. (shrinking the minibuf) ->getgrent
struct group groupent;
#endif
#ifdef mini_inet_ntoa
char inet_ntoa_addr[16];
#endif
#ifdef mini_ether_ntoa
char ether_ntoa_addr[20]; // padded to %4
#endif
#if mini_GLOBALS & MINI_GUARDED_GLOBALS && GLOBALS & BSS_SECTION
char __padding1[PAGESIZE-sizeof(__globals_shadow)];
char __guardpage1[PAGESIZE];
#define __mini_guardpage1
#endif
#ifdef mini_internalbuf
union {
int intibuf[(mini_internalbufsize>>2)];
char intmbuf[mini_internalbufsize];
};
#if mini_GLOBALS & MINI_GUARDED_GLOBALS
char __padding2[ PAGESIZE - (mini_internalbufsize % PAGESIZE) ];
char __guardpage2[ PAGESIZE ];
#define __mini_guardpage2
#endif
#endif
union {
int ibuf[(mini_bufsize>>2)];
char mbuf[mini_bufsize];
};
#if mini_GLOBALS & MINI_GUARDED_GLOBALS
char __padding3[ PAGESIZE - (mini_bufsize % PAGESIZE) ];
char __guardpage3[ PAGESIZE ];
#define __mini_guardpage3
#endif
} minilib_globals;
#ifndef __clang__
//+doc prevent optimizations.
// cast a var to void*, and calling this,
// leaves the compiler unknown on what he can strip.
// The function attribute noipa means,
// the compiler doesn't know, what the function itself does.
// (the function does nothing, but don't tell that gcc, please..)
// therefore, everything used as parameter to this function,
// will be calculated, defined, and so on before.
// It's used for the globals,
// shich are pushed within _start onto the stack.
// since _start itself only provides a global pointer,
// and initialitzes some of the globals,
// but doesn't use them again,
// this construction is needed.
// more funnily, the function will never be called.
// It's past the asm inline syscall to exit.
// But again, luckily gcc doesn't know.
// All other options, like having the globals volatile,
// setting the optimization flag of _start to 0,
// having a volatile asm call with the globals as param, and so on,
// have been useless. All after all, seems to me, ai has it's restrictions.
//
// With less overhead the macro OPTFENCE(...) goes.
// There the call to the "ipa" function is jumped over,
// via asm inline instructions.
// Doesn't work with clang.
// But yet I also didn't it with clang.
//+def optimization_fence
static void __attribute__((noipa,cold)) optimization_fence(void*p){}
#endif
// void __attribute__((noipa,naked))prevent_optimization(void*p){
// strangely, naked results in a bigger binary. (+4 Bytes)
// and will result in a runtime error. undefined opcode. so.
#ifdef mini_globals_on_stack
#ifndef mini_globals
#define mini_globals
#endif
#ifndef mini_globalregister
// use register r15 by default (GCC only)
#define mini_globalregister "r15"
#endif
#endif
#ifdef mini_globals
#ifndef mini_globalregister
extern minilib_globals*__restrict__ mlgl;
extern minilib_globals __mlgl;
#ifdef mini_errno
//extern int sysret;
extern int errno;
#endif
#ifdef mini_environ
//+doc pointer to env, when mini_getenv is defined.
extern char **environ;
#endif
#else //mini_globalregister
// when the global are located on the stack,
// (globals_on_stack), the position needs to be saved.
// Using r15 for the position.
// Locating all globals on the stack might only in some special cases
// give advantages. (sparing the .data and .bss segments, for example)
// Same when loading "plugins"
//
// Seems to me the easiest way, mixing position independent code
// and common "globals".
// Especially, since (here r15) is rarely used with amd64 and gcc.
// for Saving the register, it would also be possible to store the address
// of the globals at a fixed position, e.g. the beginning of the text section.
// Or allocating the globals at a fixed memory position..
//
// However.
// The option to have the globals at a varying address gives as a sideeffect
// a certain security advantage. Albite, well.
// I leave this at it is for now.
//
#ifndef __clang__
register minilib_globals __attribute__((used))*__restrict__ mlgl asm(mini_globalregister);
#else
minilib_globals __attribute__((used))*__restrict__ mlgl;
#endif
#define errno mlgl->errno
#ifdef mini_environ
//+doc pointer to env, when mini_getenv is defined.
//extern char **environ;
#define environ mlgl->environ
#endif
#endif //mini_globals_on_stack
#else
#endif
#endif