1 | /* ----------------------------------------------------------------------- * |
2 | * |
3 | * Copyright 1996-2018 The NASM Authors - All Rights Reserved |
4 | * See the file AUTHORS included with the NASM distribution for |
5 | * the specific copyright holders. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * |
11 | * * Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * * Redistributions in binary form must reproduce the above |
14 | * copyright notice, this list of conditions and the following |
15 | * disclaimer in the documentation and/or other materials provided |
16 | * with the distribution. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
19 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | * |
32 | * ----------------------------------------------------------------------- */ |
33 | |
34 | /* |
35 | * nasmlib.h header file for nasmlib.c |
36 | */ |
37 | |
38 | #ifndef NASM_NASMLIB_H |
39 | #define NASM_NASMLIB_H |
40 | |
41 | #include "compiler.h" |
42 | #include "bytesex.h" |
43 | |
44 | #include <ctype.h> |
45 | #include <stdio.h> |
46 | #include <string.h> |
47 | #ifdef HAVE_STRINGS_H |
48 | # include <strings.h> |
49 | #endif |
50 | |
51 | /* |
52 | * tolower table -- avoids a function call on some platforms. |
53 | * NOTE: unlike the tolower() function in ctype, EOF is *NOT* |
54 | * a permitted value, for obvious reasons. |
55 | */ |
56 | void tolower_init(void); |
57 | extern unsigned char nasm_tolower_tab[256]; |
58 | #define nasm_tolower(x) nasm_tolower_tab[(unsigned char)(x)] |
59 | |
60 | /* Wrappers around <ctype.h> functions */ |
61 | /* These are only valid for values that cannot include EOF */ |
62 | #define nasm_isspace(x) isspace((unsigned char)(x)) |
63 | #define nasm_isalpha(x) isalpha((unsigned char)(x)) |
64 | #define nasm_isdigit(x) isdigit((unsigned char)(x)) |
65 | #define nasm_isalnum(x) isalnum((unsigned char)(x)) |
66 | #define nasm_isxdigit(x) isxdigit((unsigned char)(x)) |
67 | |
68 | /* |
69 | * Wrappers around malloc, realloc and free. nasm_malloc will |
70 | * fatal-error and die rather than return NULL; nasm_realloc will |
71 | * do likewise, and will also guarantee to work right on being |
72 | * passed a NULL pointer; nasm_free will do nothing if it is passed |
73 | * a NULL pointer. |
74 | */ |
75 | void * safe_malloc(1) nasm_malloc(size_t); |
76 | void * safe_malloc(1) nasm_zalloc(size_t); |
77 | void * safe_malloc2(1,2) nasm_calloc(size_t, size_t); |
78 | void * safe_realloc(2) nasm_realloc(void *, size_t); |
79 | void nasm_free(void *); |
80 | char * safe_alloc nasm_strdup(const char *); |
81 | char * safe_alloc nasm_strndup(const char *, size_t); |
82 | char * safe_alloc nasm_strcat(const char *one, const char *two); |
83 | char * safe_alloc end_with_null nasm_strcatn(const char *one, ...); |
84 | |
85 | /* Assert the argument is a pointer without evaluating it */ |
86 | #define nasm_assert_pointer(p) ((void)sizeof(*(p))) |
87 | |
88 | #define nasm_new(p) ((p) = nasm_zalloc(sizeof(*(p)))) |
89 | #define nasm_newn(p,n) ((p) = nasm_calloc(sizeof(*(p)),(n))) |
90 | /* |
91 | * This is broken on platforms where there are pointers which don't |
92 | * match void * in their internal layout. It unfortunately also |
93 | * loses any "const" part of the argument, although hopefully the |
94 | * compiler will warn in that case. |
95 | */ |
96 | #define nasm_delete(p) \ |
97 | do { \ |
98 | void **_pp = (void **)&(p); \ |
99 | nasm_assert_pointer(p); \ |
100 | nasm_free(*_pp); \ |
101 | *_pp = NULL; \ |
102 | } while (0) |
103 | #define nasm_zero(x) (memset(&(x), 0, sizeof(x))) |
104 | #define nasm_zeron(p,n) (memset((p), 0, (n)*sizeof(*(p)))) |
105 | |
106 | /* |
107 | * Wrappers around fread()/fwrite() which fatal-errors on failure. |
108 | * For fread(), only use this if EOF is supposed to be a fatal error! |
109 | */ |
110 | void nasm_read(void *, size_t, FILE *); |
111 | void nasm_write(const void *, size_t, FILE *); |
112 | |
113 | /* |
114 | * NASM assert failure |
115 | */ |
116 | fatal_func nasm_assert_failed(const char *, int, const char *); |
117 | #define nasm_assert(x) \ |
118 | do { \ |
119 | if (unlikely(!(x))) \ |
120 | nasm_assert_failed(__FILE__,__LINE__,#x); \ |
121 | } while (0) |
122 | |
123 | /* |
124 | * NASM failure at build time if the argument is false |
125 | */ |
126 | #ifdef static_assert |
127 | # define nasm_static_assert(x) static_assert(x, #x) |
128 | #elif defined(HAVE_FUNC_ATTRIBUTE_ERROR) && defined(__OPTIMIZE__) |
129 | # define nasm_static_assert(x) \ |
130 | if (!(x)) { \ |
131 | extern void __attribute__((error("assertion " #x " failed"))) \ |
132 | _nasm_static_fail(void); \ |
133 | _nasm_static_fail(); \ |
134 | } |
135 | #else |
136 | /* See http://www.drdobbs.com/compile-time-assertions/184401873 */ |
137 | # define nasm_static_assert(x) \ |
138 | do { enum { _static_assert_failed = 1/(!!(x)) }; } while (0) |
139 | #endif |
140 | |
141 | /* Utility function to generate a string for an invalid enum */ |
142 | const char *invalid_enum_str(int); |
143 | |
144 | /* |
145 | * ANSI doesn't guarantee the presence of `stricmp' or |
146 | * `strcasecmp'. |
147 | */ |
148 | #if defined(HAVE_STRCASECMP) |
149 | #define nasm_stricmp strcasecmp |
150 | #elif defined(HAVE_STRICMP) |
151 | #define nasm_stricmp stricmp |
152 | #else |
153 | int pure_func nasm_stricmp(const char *, const char *); |
154 | #endif |
155 | |
156 | #if defined(HAVE_STRNCASECMP) |
157 | #define nasm_strnicmp strncasecmp |
158 | #elif defined(HAVE_STRNICMP) |
159 | #define nasm_strnicmp strnicmp |
160 | #else |
161 | int pure_func nasm_strnicmp(const char *, const char *, size_t); |
162 | #endif |
163 | |
164 | int pure_func nasm_memicmp(const char *, const char *, size_t); |
165 | |
166 | #if defined(HAVE_STRSEP) |
167 | #define nasm_strsep strsep |
168 | #else |
169 | char *nasm_strsep(char **stringp, const char *delim); |
170 | #endif |
171 | |
172 | #ifndef HAVE_DECL_STRNLEN |
173 | size_t pure_func strnlen(const char *, size_t); |
174 | #endif |
175 | |
176 | /* This returns the numeric value of a given 'digit'. */ |
177 | #define numvalue(c) ((c) >= 'a' ? (c) - 'a' + 10 : (c) >= 'A' ? (c) - 'A' + 10 : (c) - '0') |
178 | |
179 | /* |
180 | * Convert a string into a number, using NASM number rules. Sets |
181 | * `*error' to true if an error occurs, and false otherwise. |
182 | */ |
183 | int64_t readnum(const char *str, bool *error); |
184 | |
185 | /* |
186 | * Convert a character constant into a number. Sets |
187 | * `*warn' to true if an overflow occurs, and false otherwise. |
188 | * str points to and length covers the middle of the string, |
189 | * without the quotes. |
190 | */ |
191 | int64_t readstrnum(char *str, int length, bool *warn); |
192 | |
193 | /* |
194 | * seg_alloc: allocate a hitherto unused segment number. |
195 | */ |
196 | int32_t seg_alloc(void); |
197 | |
198 | /* |
199 | * Add/replace or remove an extension to the end of a filename |
200 | */ |
201 | const char *filename_set_extension(const char *inname, const char *extension); |
202 | |
203 | /* |
204 | * Utility macros... |
205 | * |
206 | * This is a useful #define which I keep meaning to use more often: |
207 | * the number of elements of a statically defined array. |
208 | */ |
209 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
210 | |
211 | /* |
212 | * List handling |
213 | * |
214 | * list_for_each - regular iterator over list |
215 | * list_for_each_safe - the same but safe against list items removal |
216 | * list_last - find the last element in a list |
217 | */ |
218 | #define list_for_each(pos, head) \ |
219 | for (pos = head; pos; pos = pos->next) |
220 | #define list_for_each_safe(pos, n, head) \ |
221 | for (pos = head, n = (pos ? pos->next : NULL); pos; \ |
222 | pos = n, n = (n ? n->next : NULL)) |
223 | #define list_last(pos, head) \ |
224 | for (pos = head; pos && pos->next; pos = pos->next) \ |
225 | ; |
226 | #define list_reverse(head, prev, next) \ |
227 | do { \ |
228 | if (!head || !head->next) \ |
229 | break; \ |
230 | prev = NULL; \ |
231 | while (head) { \ |
232 | next = head->next; \ |
233 | head->next = prev; \ |
234 | prev = head; \ |
235 | head = next; \ |
236 | } \ |
237 | head = prev; \ |
238 | } while (0) |
239 | |
240 | /* |
241 | * Power of 2 align helpers |
242 | */ |
243 | #undef ALIGN_MASK /* Some BSD flavors define these in system headers */ |
244 | #undef ALIGN |
245 | #define ALIGN_MASK(v, mask) (((v) + (mask)) & ~(mask)) |
246 | #define ALIGN(v, a) ALIGN_MASK(v, (a) - 1) |
247 | #define IS_ALIGNED(v, a) (((v) & ((a) - 1)) == 0) |
248 | |
249 | /* |
250 | * Routines to write littleendian data to a file |
251 | */ |
252 | #define fwriteint8_t(d,f) putc(d,f) |
253 | void fwriteint16_t(uint16_t data, FILE * fp); |
254 | void fwriteint32_t(uint32_t data, FILE * fp); |
255 | void fwriteint64_t(uint64_t data, FILE * fp); |
256 | void fwriteaddr(uint64_t data, int size, FILE * fp); |
257 | |
258 | /* |
259 | * Binary search routine. Returns index into `array' of an entry |
260 | * matching `string', or <0 if no match. `array' is taken to |
261 | * contain `size' elements. |
262 | * |
263 | * bsi() is case sensitive, bsii() is case insensitive. |
264 | */ |
265 | int bsi(const char *string, const char **array, int size); |
266 | int bsii(const char *string, const char **array, int size); |
267 | |
268 | /* |
269 | * These functions are used to keep track of the source code file and name. |
270 | */ |
271 | void src_init(void); |
272 | void src_free(void); |
273 | const char *src_set_fname(const char *newname); |
274 | const char *src_get_fname(void); |
275 | int32_t src_set_linnum(int32_t newline); |
276 | int32_t src_get_linnum(void); |
277 | /* Can be used when there is no need for the old information */ |
278 | void src_set(int32_t line, const char *filename); |
279 | /* |
280 | * src_get gets both the source file name and line. |
281 | * It is also used if you maintain private status about the source location |
282 | * It return 0 if the information was the same as the last time you |
283 | * checked, -2 if the name changed and (new-old) if just the line changed. |
284 | */ |
285 | int32_t src_get(int32_t *xline, const char **xname); |
286 | |
287 | char *nasm_skip_spaces(const char *p); |
288 | char *nasm_skip_word(const char *p); |
289 | char *nasm_zap_spaces_fwd(char *p); |
290 | char *nasm_zap_spaces_rev(char *p); |
291 | char *nasm_trim_spaces(char *p); |
292 | char *nasm_get_word(char *p, char **tail); |
293 | char *nasm_opt_val(char *p, char **opt, char **val); |
294 | |
295 | /* |
296 | * Converts a relative pathname rel_path into an absolute path name. |
297 | * |
298 | * The buffer returned must be freed by the caller |
299 | */ |
300 | char * safe_alloc nasm_realpath(const char *rel_path); |
301 | |
302 | /* |
303 | * Path-splitting and merging functions |
304 | */ |
305 | char * safe_alloc nasm_dirname(const char *path); |
306 | char * safe_alloc nasm_basename(const char *path); |
307 | char * safe_alloc nasm_catfile(const char *dir, const char *path); |
308 | |
309 | const char * pure_func prefix_name(int); |
310 | |
311 | /* |
312 | * Wrappers around fopen()... for future change to a dedicated structure |
313 | */ |
314 | enum file_flags { |
315 | NF_BINARY = 0x00000000, /* Binary file (default) */ |
316 | NF_TEXT = 0x00000001, /* Text file */ |
317 | NF_NONFATAL = 0x00000000, /* Don't die on open failure (default) */ |
318 | NF_FATAL = 0x00000002, /* Die on open failure */ |
319 | NF_FORMAP = 0x00000004 /* Intended to use nasm_map_file() */ |
320 | }; |
321 | |
322 | FILE *nasm_open_read(const char *filename, enum file_flags flags); |
323 | FILE *nasm_open_write(const char *filename, enum file_flags flags); |
324 | |
325 | /* Probe for existence of a file */ |
326 | bool nasm_file_exists(const char *filename); |
327 | |
328 | #define ZERO_BUF_SIZE 65536 /* Default value */ |
329 | #if defined(BUFSIZ) && (BUFSIZ > ZERO_BUF_SIZE) |
330 | # undef ZERO_BUF_SIZE |
331 | # define ZERO_BUF_SIZE BUFSIZ |
332 | #endif |
333 | extern const uint8_t zero_buffer[ZERO_BUF_SIZE]; |
334 | |
335 | /* Missing fseeko/ftello */ |
336 | #ifndef HAVE_FSEEKO |
337 | # undef off_t /* Just in case it is a macro */ |
338 | # ifdef HAVE__FSEEKI64 |
339 | # define fseeko _fseeki64 |
340 | # define ftello _ftelli64 |
341 | # define off_t int64_t |
342 | # else |
343 | # define fseeko fseek |
344 | # define ftello ftell |
345 | # define off_t long |
346 | # endif |
347 | #endif |
348 | |
349 | const void *nasm_map_file(FILE *fp, off_t start, off_t len); |
350 | void nasm_unmap_file(const void *p, size_t len); |
351 | off_t nasm_file_size(FILE *f); |
352 | off_t nasm_file_size_by_path(const char *pathname); |
353 | bool nasm_file_time(time_t *t, const char *pathname); |
354 | void fwritezero(off_t bytes, FILE *fp); |
355 | |
356 | static inline bool const_func overflow_general(int64_t value, int bytes) |
357 | { |
358 | int sbit; |
359 | int64_t vmax, vmin; |
360 | |
361 | if (bytes >= 8) |
362 | return false; |
363 | |
364 | sbit = (bytes << 3) - 1; |
365 | vmax = ((int64_t)2 << sbit) - 1; |
366 | vmin = -((int64_t)2 << sbit); |
367 | |
368 | return value < vmin || value > vmax; |
369 | } |
370 | |
371 | static inline bool const_func overflow_signed(int64_t value, int bytes) |
372 | { |
373 | int sbit; |
374 | int64_t vmax, vmin; |
375 | |
376 | if (bytes >= 8) |
377 | return false; |
378 | |
379 | sbit = (bytes << 3) - 1; |
380 | vmax = ((int64_t)1 << sbit) - 1; |
381 | vmin = -((int64_t)1 << sbit); |
382 | |
383 | return value < vmin || value > vmax; |
384 | } |
385 | |
386 | static inline bool const_func overflow_unsigned(int64_t value, int bytes) |
387 | { |
388 | int sbit; |
389 | int64_t vmax, vmin; |
390 | |
391 | if (bytes >= 8) |
392 | return false; |
393 | |
394 | sbit = (bytes << 3) - 1; |
395 | vmax = ((int64_t)2 << sbit) - 1; |
396 | vmin = 0; |
397 | |
398 | return value < vmin || value > vmax; |
399 | } |
400 | |
401 | static inline int64_t const_func signed_bits(int64_t value, int bits) |
402 | { |
403 | if (bits < 64) { |
404 | value &= ((int64_t)1 << bits) - 1; |
405 | if (value & (int64_t)1 << (bits - 1)) |
406 | value |= (int64_t)((uint64_t)-1 << bits); |
407 | } |
408 | return value; |
409 | } |
410 | |
411 | /* check if value is power of 2 */ |
412 | #define is_power2(v) ((v) && ((v) & ((v) - 1)) == 0) |
413 | |
414 | #endif |
415 | |