diff options
Diffstat (limited to 'vere/ext/nasm/nasmlib')
29 files changed, 4606 insertions, 0 deletions
diff --git a/vere/ext/nasm/nasmlib/alloc.c b/vere/ext/nasm/nasmlib/alloc.c new file mode 100644 index 0000000..e25e0e0 --- /dev/null +++ b/vere/ext/nasm/nasmlib/alloc.c @@ -0,0 +1,197 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2019 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" +#include "alloc.h" + +size_t _nasm_last_string_size; + +fatal_func nasm_alloc_failed(void) +{ + nasm_critical("out of memory!"); +} + +void *nasm_malloc(size_t size) +{ + void *p; + +again: + p = malloc(size); + + if (unlikely(!p)) { + if (!size) { + size = 1; + goto again; + } + nasm_alloc_failed(); + } + return p; +} + +void *nasm_calloc(size_t nelem, size_t size) +{ + void *p; + +again: + p = calloc(nelem, size); + + if (unlikely(!p)) { + if (!nelem || !size) { + nelem = size = 1; + goto again; + } + nasm_alloc_failed(); + } + + return p; +} + +void *nasm_zalloc(size_t size) +{ + return nasm_calloc(size, 1); +} + +/* + * Unlike the system realloc, we do *not* allow size == 0 to be + * the equivalent to free(); we guarantee returning a non-NULL pointer. + * + * The check for calling malloc() is theoretically redundant, but be + * paranoid about the system library... + */ +void *nasm_realloc(void *q, size_t size) +{ + if (unlikely(!size)) + size = 1; + q = q ? realloc(q, size) : malloc(size); + return validate_ptr(q); +} + +void nasm_free(void *q) +{ + if (q) + free(q); +} + +char *nasm_strdup(const char *s) +{ + char *p; + const size_t size = strlen(s) + 1; + + _nasm_last_string_size = size; + p = nasm_malloc(size); + return memcpy(p, s, size); +} + +char *nasm_strndup(const char *s, size_t len) +{ + char *p; + + len = strnlen(s, len); + _nasm_last_string_size = len + 1; + p = nasm_malloc(len+1); + p[len] = '\0'; + return memcpy(p, s, len); +} + +char *nasm_strcat(const char *one, const char *two) +{ + char *rslt; + const size_t l1 = strlen(one); + const size_t s2 = strlen(two) + 1; + + _nasm_last_string_size = l1 + s2; + rslt = nasm_malloc(l1 + s2); + memcpy(rslt, one, l1); + memcpy(rslt + l1, two, s2); + return rslt; +} + +char *nasm_strcatn(const char *str1, ...) +{ + va_list ap; + char *rslt; /* Output buffer */ + size_t s; /* Total buffer size */ + size_t n; /* Number of arguments */ + size_t *ltbl; /* Table of lengths */ + size_t l, *lp; /* Length for current argument */ + const char *p; /* Currently examined argument */ + char *q; /* Output pointer */ + + n = 0; /* No strings encountered yet */ + p = str1; + va_start(ap, str1); + while (p) { + n++; + p = va_arg(ap, const char *); + } + va_end(ap); + + ltbl = nasm_malloc(n * sizeof(size_t)); + + s = 1; /* Space for final NULL */ + p = str1; + lp = ltbl; + va_start(ap, str1); + while (p) { + *lp++ = l = strlen(p); + s += l; + p = va_arg(ap, const char *); + } + va_end(ap); + + _nasm_last_string_size = s; + + q = rslt = nasm_malloc(s); + + p = str1; + lp = ltbl; + va_start(ap, str1); + while (p) { + l = *lp++; + memcpy(q, p, l); + q += l; + p = va_arg(ap, const char *); + } + va_end(ap); + *q = '\0'; + + nasm_free(ltbl); + + return rslt; +} diff --git a/vere/ext/nasm/nasmlib/alloc.h b/vere/ext/nasm/nasmlib/alloc.h new file mode 100644 index 0000000..9b8ad19 --- /dev/null +++ b/vere/ext/nasm/nasmlib/alloc.h @@ -0,0 +1,50 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#ifndef NASMLIB_ALLOC_H +#define NASMLIB_ALLOC_H + +#include "compiler.h" + +fatal_func nasm_alloc_failed(void); + +static inline void *validate_ptr(void *p) +{ + if (unlikely(!p)) + nasm_alloc_failed(); + return p; +} + +extern size_t _nasm_last_string_size; + +#endif /* NASMLIB_ALLOC_H */ diff --git a/vere/ext/nasm/nasmlib/asprintf.c b/vere/ext/nasm/nasmlib/asprintf.c new file mode 100644 index 0000000..0b8e49d --- /dev/null +++ b/vere/ext/nasm/nasmlib/asprintf.c @@ -0,0 +1,94 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" +#include "nasmlib.h" +#include "alloc.h" + +/* + * nasm_[v]asprintf() are variants of the semi-standard [v]asprintf() + * functions, except that we return the pointer instead of a count. + * The length of the string (with or without the final NUL) is available + * by calling nasm_last_string_{len,size}() afterwards. + * + * nasm_[v]axprintf() are similar, but allocates a user-defined amount + * of storage before the string, and returns a pointer to the + * allocated buffer. The size of that area is not included in the value + * returned by nasm_last_string_size(). + */ + +void *nasm_vaxprintf(size_t extra, const char *fmt, va_list ap) +{ + char *strp; + va_list xap; + size_t bytes; + + va_copy(xap, ap); + bytes = vsnprintf(NULL, 0, fmt, xap) + 1; + _nasm_last_string_size = bytes; + va_end(xap); + + strp = nasm_malloc(extra+bytes); + memset(strp, 0, extra); + vsnprintf(strp+extra, bytes, fmt, ap); + return strp; +} + +char *nasm_vasprintf(const char *fmt, va_list ap) +{ + return nasm_vaxprintf(0, fmt, ap); +} + +void *nasm_axprintf(size_t extra, const char *fmt, ...) +{ + va_list ap; + void *strp; + + va_start(ap, fmt); + strp = nasm_vaxprintf(extra, fmt, ap); + va_end(ap); + + return strp; +} + +char *nasm_asprintf(const char *fmt, ...) +{ + va_list ap; + char *strp; + + va_start(ap, fmt); + strp = nasm_vaxprintf(0, fmt, ap); + va_end(ap); + + return strp; +} diff --git a/vere/ext/nasm/nasmlib/badenum.c b/vere/ext/nasm/nasmlib/badenum.c new file mode 100644 index 0000000..6f880c8 --- /dev/null +++ b/vere/ext/nasm/nasmlib/badenum.c @@ -0,0 +1,43 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "nasmlib.h" + +/* Used to avoid returning NULL to a debug printing function */ +const char *invalid_enum_str(int x) +{ + static char buf[64]; + + snprintf(buf, sizeof buf, "<invalid %d>", x); + return buf; +} diff --git a/vere/ext/nasm/nasmlib/bsi.c b/vere/ext/nasm/nasmlib/bsi.c new file mode 100644 index 0000000..ae31f48 --- /dev/null +++ b/vere/ext/nasm/nasmlib/bsi.c @@ -0,0 +1,76 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" + + +#include "nasmlib.h" + +/* + * Binary search. + */ +int bsi(const char *string, const char **array, int size) +{ + int i = -1, j = size; /* always, i < index < j */ + while (j - i >= 2) { + int k = (i + j) / 2; + int l = strcmp(string, array[k]); + if (l < 0) /* it's in the first half */ + j = k; + else if (l > 0) /* it's in the second half */ + i = k; + else /* we've got it :) */ + return k; + } + return -1; /* we haven't got it :( */ +} + +int bsii(const char *string, const char **array, int size) +{ + int i = -1, j = size; /* always, i < index < j */ + while (j - i >= 2) { + int k = (i + j) / 2; + int l = nasm_stricmp(string, array[k]); + if (l < 0) /* it's in the first half */ + j = k; + else if (l > 0) /* it's in the second half */ + i = k; + else /* we've got it :) */ + return k; + } + return -1; /* we haven't got it :( */ +} diff --git a/vere/ext/nasm/nasmlib/crc32.c b/vere/ext/nasm/nasmlib/crc32.c new file mode 100644 index 0000000..9b4068e --- /dev/null +++ b/vere/ext/nasm/nasmlib/crc32.c @@ -0,0 +1,115 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2021 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" +#include "hashtbl.h" + +const uint32_t crc32_tab[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +uint32_t crc32b(uint32_t crc, const void *data, size_t len) +{ + register const uint8_t *p = data; + register uint32_t hashval = crc; + + while (len--) + { + hashval = (hashval >> 8) ^ crc32_tab[(hashval ^ *p++) & 0xff]; + } + + return hashval; +} diff --git a/vere/ext/nasm/nasmlib/crc64.c b/vere/ext/nasm/nasmlib/crc64.c new file mode 100644 index 0000000..e37e07b --- /dev/null +++ b/vere/ext/nasm/nasmlib/crc64.c @@ -0,0 +1,207 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2014 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" +#include "nctype.h" +#include "hashtbl.h" + +const uint64_t crc64_tab[256] = { + UINT64_C(0x0000000000000000), UINT64_C(0x7ad870c830358979), + UINT64_C(0xf5b0e190606b12f2), UINT64_C(0x8f689158505e9b8b), + UINT64_C(0xc038e5739841b68f), UINT64_C(0xbae095bba8743ff6), + UINT64_C(0x358804e3f82aa47d), UINT64_C(0x4f50742bc81f2d04), + UINT64_C(0xab28ecb46814fe75), UINT64_C(0xd1f09c7c5821770c), + UINT64_C(0x5e980d24087fec87), UINT64_C(0x24407dec384a65fe), + UINT64_C(0x6b1009c7f05548fa), UINT64_C(0x11c8790fc060c183), + UINT64_C(0x9ea0e857903e5a08), UINT64_C(0xe478989fa00bd371), + UINT64_C(0x7d08ff3b88be6f81), UINT64_C(0x07d08ff3b88be6f8), + UINT64_C(0x88b81eabe8d57d73), UINT64_C(0xf2606e63d8e0f40a), + UINT64_C(0xbd301a4810ffd90e), UINT64_C(0xc7e86a8020ca5077), + UINT64_C(0x4880fbd87094cbfc), UINT64_C(0x32588b1040a14285), + UINT64_C(0xd620138fe0aa91f4), UINT64_C(0xacf86347d09f188d), + UINT64_C(0x2390f21f80c18306), UINT64_C(0x594882d7b0f40a7f), + UINT64_C(0x1618f6fc78eb277b), UINT64_C(0x6cc0863448deae02), + UINT64_C(0xe3a8176c18803589), UINT64_C(0x997067a428b5bcf0), + UINT64_C(0xfa11fe77117cdf02), UINT64_C(0x80c98ebf2149567b), + UINT64_C(0x0fa11fe77117cdf0), UINT64_C(0x75796f2f41224489), + UINT64_C(0x3a291b04893d698d), UINT64_C(0x40f16bccb908e0f4), + UINT64_C(0xcf99fa94e9567b7f), UINT64_C(0xb5418a5cd963f206), + UINT64_C(0x513912c379682177), UINT64_C(0x2be1620b495da80e), + UINT64_C(0xa489f35319033385), UINT64_C(0xde51839b2936bafc), + UINT64_C(0x9101f7b0e12997f8), UINT64_C(0xebd98778d11c1e81), + UINT64_C(0x64b116208142850a), UINT64_C(0x1e6966e8b1770c73), + UINT64_C(0x8719014c99c2b083), UINT64_C(0xfdc17184a9f739fa), + UINT64_C(0x72a9e0dcf9a9a271), UINT64_C(0x08719014c99c2b08), + UINT64_C(0x4721e43f0183060c), UINT64_C(0x3df994f731b68f75), + UINT64_C(0xb29105af61e814fe), UINT64_C(0xc849756751dd9d87), + UINT64_C(0x2c31edf8f1d64ef6), UINT64_C(0x56e99d30c1e3c78f), + UINT64_C(0xd9810c6891bd5c04), UINT64_C(0xa3597ca0a188d57d), + UINT64_C(0xec09088b6997f879), UINT64_C(0x96d1784359a27100), + UINT64_C(0x19b9e91b09fcea8b), UINT64_C(0x636199d339c963f2), + UINT64_C(0xdf7adabd7a6e2d6f), UINT64_C(0xa5a2aa754a5ba416), + UINT64_C(0x2aca3b2d1a053f9d), UINT64_C(0x50124be52a30b6e4), + UINT64_C(0x1f423fcee22f9be0), UINT64_C(0x659a4f06d21a1299), + UINT64_C(0xeaf2de5e82448912), UINT64_C(0x902aae96b271006b), + UINT64_C(0x74523609127ad31a), UINT64_C(0x0e8a46c1224f5a63), + UINT64_C(0x81e2d7997211c1e8), UINT64_C(0xfb3aa75142244891), + UINT64_C(0xb46ad37a8a3b6595), UINT64_C(0xceb2a3b2ba0eecec), + UINT64_C(0x41da32eaea507767), UINT64_C(0x3b024222da65fe1e), + UINT64_C(0xa2722586f2d042ee), UINT64_C(0xd8aa554ec2e5cb97), + UINT64_C(0x57c2c41692bb501c), UINT64_C(0x2d1ab4dea28ed965), + UINT64_C(0x624ac0f56a91f461), UINT64_C(0x1892b03d5aa47d18), + UINT64_C(0x97fa21650afae693), UINT64_C(0xed2251ad3acf6fea), + UINT64_C(0x095ac9329ac4bc9b), UINT64_C(0x7382b9faaaf135e2), + UINT64_C(0xfcea28a2faafae69), UINT64_C(0x8632586aca9a2710), + UINT64_C(0xc9622c4102850a14), UINT64_C(0xb3ba5c8932b0836d), + UINT64_C(0x3cd2cdd162ee18e6), UINT64_C(0x460abd1952db919f), + UINT64_C(0x256b24ca6b12f26d), UINT64_C(0x5fb354025b277b14), + UINT64_C(0xd0dbc55a0b79e09f), UINT64_C(0xaa03b5923b4c69e6), + UINT64_C(0xe553c1b9f35344e2), UINT64_C(0x9f8bb171c366cd9b), + UINT64_C(0x10e3202993385610), UINT64_C(0x6a3b50e1a30ddf69), + UINT64_C(0x8e43c87e03060c18), UINT64_C(0xf49bb8b633338561), + UINT64_C(0x7bf329ee636d1eea), UINT64_C(0x012b592653589793), + UINT64_C(0x4e7b2d0d9b47ba97), UINT64_C(0x34a35dc5ab7233ee), + UINT64_C(0xbbcbcc9dfb2ca865), UINT64_C(0xc113bc55cb19211c), + UINT64_C(0x5863dbf1e3ac9dec), UINT64_C(0x22bbab39d3991495), + UINT64_C(0xadd33a6183c78f1e), UINT64_C(0xd70b4aa9b3f20667), + UINT64_C(0x985b3e827bed2b63), UINT64_C(0xe2834e4a4bd8a21a), + UINT64_C(0x6debdf121b863991), UINT64_C(0x1733afda2bb3b0e8), + UINT64_C(0xf34b37458bb86399), UINT64_C(0x8993478dbb8deae0), + UINT64_C(0x06fbd6d5ebd3716b), UINT64_C(0x7c23a61ddbe6f812), + UINT64_C(0x3373d23613f9d516), UINT64_C(0x49aba2fe23cc5c6f), + UINT64_C(0xc6c333a67392c7e4), UINT64_C(0xbc1b436e43a74e9d), + UINT64_C(0x95ac9329ac4bc9b5), UINT64_C(0xef74e3e19c7e40cc), + UINT64_C(0x601c72b9cc20db47), UINT64_C(0x1ac40271fc15523e), + UINT64_C(0x5594765a340a7f3a), UINT64_C(0x2f4c0692043ff643), + UINT64_C(0xa02497ca54616dc8), UINT64_C(0xdafce7026454e4b1), + UINT64_C(0x3e847f9dc45f37c0), UINT64_C(0x445c0f55f46abeb9), + UINT64_C(0xcb349e0da4342532), UINT64_C(0xb1eceec59401ac4b), + UINT64_C(0xfebc9aee5c1e814f), UINT64_C(0x8464ea266c2b0836), + UINT64_C(0x0b0c7b7e3c7593bd), UINT64_C(0x71d40bb60c401ac4), + UINT64_C(0xe8a46c1224f5a634), UINT64_C(0x927c1cda14c02f4d), + UINT64_C(0x1d148d82449eb4c6), UINT64_C(0x67ccfd4a74ab3dbf), + UINT64_C(0x289c8961bcb410bb), UINT64_C(0x5244f9a98c8199c2), + UINT64_C(0xdd2c68f1dcdf0249), UINT64_C(0xa7f41839ecea8b30), + UINT64_C(0x438c80a64ce15841), UINT64_C(0x3954f06e7cd4d138), + UINT64_C(0xb63c61362c8a4ab3), UINT64_C(0xcce411fe1cbfc3ca), + UINT64_C(0x83b465d5d4a0eece), UINT64_C(0xf96c151de49567b7), + UINT64_C(0x76048445b4cbfc3c), UINT64_C(0x0cdcf48d84fe7545), + UINT64_C(0x6fbd6d5ebd3716b7), UINT64_C(0x15651d968d029fce), + UINT64_C(0x9a0d8ccedd5c0445), UINT64_C(0xe0d5fc06ed698d3c), + UINT64_C(0xaf85882d2576a038), UINT64_C(0xd55df8e515432941), + UINT64_C(0x5a3569bd451db2ca), UINT64_C(0x20ed197575283bb3), + UINT64_C(0xc49581ead523e8c2), UINT64_C(0xbe4df122e51661bb), + UINT64_C(0x3125607ab548fa30), UINT64_C(0x4bfd10b2857d7349), + UINT64_C(0x04ad64994d625e4d), UINT64_C(0x7e7514517d57d734), + UINT64_C(0xf11d85092d094cbf), UINT64_C(0x8bc5f5c11d3cc5c6), + UINT64_C(0x12b5926535897936), UINT64_C(0x686de2ad05bcf04f), + UINT64_C(0xe70573f555e26bc4), UINT64_C(0x9ddd033d65d7e2bd), + UINT64_C(0xd28d7716adc8cfb9), UINT64_C(0xa85507de9dfd46c0), + UINT64_C(0x273d9686cda3dd4b), UINT64_C(0x5de5e64efd965432), + UINT64_C(0xb99d7ed15d9d8743), UINT64_C(0xc3450e196da80e3a), + UINT64_C(0x4c2d9f413df695b1), UINT64_C(0x36f5ef890dc31cc8), + UINT64_C(0x79a59ba2c5dc31cc), UINT64_C(0x037deb6af5e9b8b5), + UINT64_C(0x8c157a32a5b7233e), UINT64_C(0xf6cd0afa9582aa47), + UINT64_C(0x4ad64994d625e4da), UINT64_C(0x300e395ce6106da3), + UINT64_C(0xbf66a804b64ef628), UINT64_C(0xc5bed8cc867b7f51), + UINT64_C(0x8aeeace74e645255), UINT64_C(0xf036dc2f7e51db2c), + UINT64_C(0x7f5e4d772e0f40a7), UINT64_C(0x05863dbf1e3ac9de), + UINT64_C(0xe1fea520be311aaf), UINT64_C(0x9b26d5e88e0493d6), + UINT64_C(0x144e44b0de5a085d), UINT64_C(0x6e963478ee6f8124), + UINT64_C(0x21c640532670ac20), UINT64_C(0x5b1e309b16452559), + UINT64_C(0xd476a1c3461bbed2), UINT64_C(0xaeaed10b762e37ab), + UINT64_C(0x37deb6af5e9b8b5b), UINT64_C(0x4d06c6676eae0222), + UINT64_C(0xc26e573f3ef099a9), UINT64_C(0xb8b627f70ec510d0), + UINT64_C(0xf7e653dcc6da3dd4), UINT64_C(0x8d3e2314f6efb4ad), + UINT64_C(0x0256b24ca6b12f26), UINT64_C(0x788ec2849684a65f), + UINT64_C(0x9cf65a1b368f752e), UINT64_C(0xe62e2ad306bafc57), + UINT64_C(0x6946bb8b56e467dc), UINT64_C(0x139ecb4366d1eea5), + UINT64_C(0x5ccebf68aecec3a1), UINT64_C(0x2616cfa09efb4ad8), + UINT64_C(0xa97e5ef8cea5d153), UINT64_C(0xd3a62e30fe90582a), + UINT64_C(0xb0c7b7e3c7593bd8), UINT64_C(0xca1fc72bf76cb2a1), + UINT64_C(0x45775673a732292a), UINT64_C(0x3faf26bb9707a053), + UINT64_C(0x70ff52905f188d57), UINT64_C(0x0a2722586f2d042e), + UINT64_C(0x854fb3003f739fa5), UINT64_C(0xff97c3c80f4616dc), + UINT64_C(0x1bef5b57af4dc5ad), UINT64_C(0x61372b9f9f784cd4), + UINT64_C(0xee5fbac7cf26d75f), UINT64_C(0x9487ca0fff135e26), + UINT64_C(0xdbd7be24370c7322), UINT64_C(0xa10fceec0739fa5b), + UINT64_C(0x2e675fb4576761d0), UINT64_C(0x54bf2f7c6752e8a9), + UINT64_C(0xcdcf48d84fe75459), UINT64_C(0xb71738107fd2dd20), + UINT64_C(0x387fa9482f8c46ab), UINT64_C(0x42a7d9801fb9cfd2), + UINT64_C(0x0df7adabd7a6e2d6), UINT64_C(0x772fdd63e7936baf), + UINT64_C(0xf8474c3bb7cdf024), UINT64_C(0x829f3cf387f8795d), + UINT64_C(0x66e7a46c27f3aa2c), UINT64_C(0x1c3fd4a417c62355), + UINT64_C(0x935745fc4798b8de), UINT64_C(0xe98f353477ad31a7), + UINT64_C(0xa6df411fbfb21ca3), UINT64_C(0xdc0731d78f8795da), + UINT64_C(0x536fa08fdfd90e51), UINT64_C(0x29b7d047efec8728), +}; + +uint64_t crc64(uint64_t crc, const char *str) +{ + uint8_t c; + + while ((c = *str++) != 0) + crc = crc64_byte(crc, c); + + return crc; +} + +uint64_t crc64i(uint64_t crc, const char *str) +{ + uint8_t c; + + while ((c = *str++) != 0) + crc = crc64_byte(crc, nasm_tolower(c)); + + return crc; +} + +uint64_t crc64b(uint64_t crc, const void *data, size_t len) +{ + const uint8_t *str = data; + + while (len--) + crc = crc64_byte(crc, *str++); + + return crc; +} + +uint64_t crc64ib(uint64_t crc, const void *data, size_t len) +{ + const uint8_t *str = data; + + while (len--) + crc = crc64_byte(crc, nasm_tolower(*str++)); + + return crc; +} diff --git a/vere/ext/nasm/nasmlib/errfile.c b/vere/ext/nasm/nasmlib/errfile.c new file mode 100644 index 0000000..a2c5e4f --- /dev/null +++ b/vere/ext/nasm/nasmlib/errfile.c @@ -0,0 +1,4 @@ +#include "compiler.h" + +FILE *error_file; + diff --git a/vere/ext/nasm/nasmlib/file.c b/vere/ext/nasm/nasmlib/file.c new file mode 100644 index 0000000..62b854d --- /dev/null +++ b/vere/ext/nasm/nasmlib/file.c @@ -0,0 +1,352 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "file.h" + +void nasm_read(void *ptr, size_t size, FILE *f) +{ + size_t n = fread(ptr, 1, size, f); + if (ferror(f)) { + nasm_fatal("unable to read input: %s", strerror(errno)); + } else if (n != size || feof(f)) { + nasm_fatal("fatal short read on input"); + } +} + +void nasm_write(const void *ptr, size_t size, FILE *f) +{ + size_t n = fwrite(ptr, 1, size, f); + if (n != size || ferror(f) || feof(f)) + nasm_fatal("unable to write output: %s", strerror(errno)); +} + +void fwriteint16_t(uint16_t data, FILE * fp) +{ + data = cpu_to_le16(data); + nasm_write(&data, 2, fp); +} + +void fwriteint32_t(uint32_t data, FILE * fp) +{ + data = cpu_to_le32(data); + nasm_write(&data, 4, fp); +} + +void fwriteint64_t(uint64_t data, FILE * fp) +{ + data = cpu_to_le64(data); + nasm_write(&data, 8, fp); +} + +void fwriteaddr(uint64_t data, int size, FILE * fp) +{ + data = cpu_to_le64(data); + nasm_write(&data, size, fp); +} + +void fwritezero(off_t bytes, FILE *fp) +{ + size_t blksize; + +#ifdef os_ftruncate + if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) { + off_t pos = ftello(fp); + if (pos != (off_t)-1) { + off_t end = pos + bytes; + if (!fflush(fp) && !os_ftruncate(fileno(fp), end)) { + fseeko(fp, 0, SEEK_END); + pos = ftello(fp); + if (pos != (off_t)-1) + bytes = end - pos; /* This SHOULD be zero */ + } + } + } +#endif + + while (bytes > 0) { + blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE; + + nasm_write(zero_buffer, blksize, fp); + bytes -= blksize; + } +} + +#ifdef _WIN32 + +/* + * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit + * on the path length that it supports. + * + * Previously we tried to prefix the path name with \\?\ in order to + * let the Windows kernel know that we are not limited to PATH_MAX + * characters, but it breaks relative paths among other things, and + * apparently Windows 10 contains a registry option to override this + * limit anyway. One day maybe they will even implement UTF-8 as byte + * characters so we can use the standard file API even on this OS. + */ + +os_filename os_mangle_filename(const char *filename) +{ + mbstate_t ps; + size_t wclen; + wchar_t *buf; + const char *p; + + /* + * Note: mbsrtowcs() return (size_t)-1 on error, otherwise + * the length of the string *without* final NUL in wchar_t + * units. Thus we add 1 for the final NUL; the error value + * now becomes 0. + */ + memset(&ps, 0, sizeof ps); /* Begin in the initial state */ + p = filename; + wclen = mbsrtowcs(NULL, &p, 0, &ps) + 1; + if (!wclen) + return NULL; + + buf = nasm_malloc(wclen * sizeof(wchar_t)); + + memset(&ps, 0, sizeof ps); /* Begin in the initial state */ + p = filename; + if (mbsrtowcs(buf, &p, wclen, &ps) + 1 != wclen || p) { + nasm_free(buf); + return NULL; + } + + return buf; +} + +#endif + +void nasm_set_binary_mode(FILE *f) +{ + os_set_binary_mode(f); +} + +FILE *nasm_open_read(const char *filename, enum file_flags flags) +{ + FILE *f = NULL; + os_filename osfname; + + osfname = os_mangle_filename(filename); + if (osfname) { + os_fopenflag fopen_flags[4]; + memset(fopen_flags, 0, sizeof fopen_flags); + + fopen_flags[0] = 'r'; + fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b'; + +#if defined(__GLIBC__) || defined(__linux__) + /* + * Try to open this file with memory mapping for speed, unless we are + * going to do it "manually" with nasm_map_file() + */ + if (!(flags & NF_FORMAP)) + fopen_flags[2] = 'm'; +#endif + + while (true) { + f = os_fopen(osfname, fopen_flags); + if (f || errno != EINVAL || !fopen_flags[2]) + break; + + /* We got EINVAL but with 'm'; try again without 'm' */ + fopen_flags[2] = '\0'; + } + + os_free_filename(osfname); + } + + if (!f && (flags & NF_FATAL)) + nasm_fatalf(ERR_NOFILE, "unable to open input file: `%s': %s", + filename, strerror(errno)); + + return f; +} + +FILE *nasm_open_write(const char *filename, enum file_flags flags) +{ + FILE *f = NULL; + os_filename osfname; + + osfname = os_mangle_filename(filename); + if (osfname) { + os_fopenflag fopen_flags[3]; + + fopen_flags[0] = 'w'; + fopen_flags[1] = (flags & NF_TEXT) ? 't' : 'b'; + fopen_flags[2] = '\0'; + + f = os_fopen(osfname, fopen_flags); + os_free_filename(osfname); + } + + if (!f && (flags & NF_FATAL)) + nasm_fatalf(ERR_NOFILE, "unable to open output file: `%s': %s", + filename, strerror(errno)); + + switch (flags & NF_BUF_MASK) { + case NF_IONBF: + setvbuf(f, NULL, _IONBF, 0); + break; + case NF_IOLBF: + setvbuf(f, NULL, _IOLBF, 0); + break; + case NF_IOFBF: + setvbuf(f, NULL, _IOFBF, 0); + break; + default: + break; + } + + return f; +} + +/* The appropriate "rb" strings for os_fopen() */ +static const os_fopenflag fopenflags_rb[3] = { 'r', 'b', 0 }; + +/* + * Report the existence of a file + */ +bool nasm_file_exists(const char *filename) +{ +#ifndef os_access + FILE *f; +#endif + os_filename osfname; + bool exists; + + osfname = os_mangle_filename(filename); + if (!osfname) + return false; + +#ifdef os_access + exists = os_access(osfname, R_OK) == 0; +#else + f = os_fopen(osfname, fopenflags_rb); + exists = f != NULL; + if (f) + fclose(f); +#endif + + os_free_filename(osfname); + return exists; +} + +/* + * Report the file size of an open file. This MAY move the file pointer. + */ +off_t nasm_file_size(FILE *f) +{ + off_t where, end; + os_struct_stat st; + + if (!os_fstat(fileno(f), &st) && S_ISREG(st.st_mode)) + return st.st_size; + + /* Do it the hard way... this tests for seekability */ + + if (fseeko(f, 0, SEEK_CUR)) + goto fail; /* Not seekable, don't even try */ + + where = ftello(f); + if (where == (off_t)-1) + goto fail; + + if (fseeko(f, 0, SEEK_END)) + goto fail; + + end = ftello(f); + if (end == (off_t)-1) + goto fail; + + /* + * Move the file pointer back. If this fails, this is probably + * not a plain file. + */ + if (fseeko(f, where, SEEK_SET)) + goto fail; + + return end; + +fail: + return -1; +} + +/* + * Report file size given pathname + */ +off_t nasm_file_size_by_path(const char *pathname) +{ + os_filename osfname; + off_t len = -1; + os_struct_stat st; + FILE *fp; + + osfname = os_mangle_filename(pathname); + + if (!os_stat(osfname, &st) && S_ISREG(st.st_mode)) + len = st.st_size; + + fp = os_fopen(osfname, fopenflags_rb); + if (fp) { + len = nasm_file_size(fp); + fclose(fp); + } + + return len; +} + +/* + * Report the timestamp on a file, returns true if successful + */ +bool nasm_file_time(time_t *t, const char *pathname) +{ +#ifdef os_stat + os_filename osfname; + os_struct_stat st; + bool rv = false; + + osfname = os_mangle_filename(pathname); + if (!osfname) + return false; + + rv = !os_stat(osfname, &st); + *t = st.st_mtime; + os_free_filename(osfname); + + return rv; +#else + return false; /* No idea how to do this on this OS */ +#endif +} diff --git a/vere/ext/nasm/nasmlib/file.h b/vere/ext/nasm/nasmlib/file.h new file mode 100644 index 0000000..140cde3 --- /dev/null +++ b/vere/ext/nasm/nasmlib/file.h @@ -0,0 +1,234 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2022 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#ifndef NASMLIB_FILE_H +#define NASMLIB_FILE_H + +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" + +#include <errno.h> + +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_IO_H +# include <io.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#ifndef R_OK +# define R_OK 4 /* Classic Unix constant, same on Windows */ +#endif + +/* Can we adjust the file size without actually writing all the bytes? */ +#ifdef HAVE__CHSIZE_S +# define os_ftruncate(fd,size) _chsize_s(fd,size) +#elif defined(HAVE__CHSIZE) +# define os_ftruncate(fd,size) _chsize(fd,size) +#elif defined(HAVE_FTRUNCATE) +# define os_ftruncate(fd,size) ftruncate(fd,size) +#endif + +/* + * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit + * on the path length that it supports. Furthermore, we want to prefix the + * path name with \\?\ in order to let the Windows kernel know that + * we are not limited to PATH_MAX characters. Thus, we wrap all the functions + * which take filenames... + */ +#ifdef _WIN32 +# include <wchar.h> +typedef wchar_t *os_filename; +typedef wchar_t os_fopenflag; + +os_filename os_mangle_filename(const char *filename); +static inline void os_free_filename(os_filename filename) +{ + nasm_free(filename); +} + +# define os_fopen _wfopen +# define os_access _waccess + +/* + * On Win32/64, we have to use the _wstati64() function. Note that + * we can't use _wstat64() without depending on a needlessly new + * version os MSVCRT. + */ + +typedef struct _stati64 os_struct_stat; + +# define os_stat _wstati64 +# define os_fstat _fstati64 + +/* + * On Win32/64, freopen() and _wfreopen() fails when the mode string + * is with the letter 'b' that represents to set binary mode. On + * POSIX operating systems, the 'b' is ignored, without failure. + */ + +#include <io.h> +#include <fcntl.h> + +static inline void os_set_binary_mode(FILE *f) { + int ret = _setmode(_fileno(f), _O_BINARY); + + if (ret == -1) { + nasm_fatalf(ERR_NOFILE, "unable to open file: %s", + strerror(errno)); + } +} + +#else /* not _WIN32 */ + +typedef const char *os_filename; +typedef char os_fopenflag; + +static inline os_filename os_mangle_filename(const char *filename) +{ + return filename; +} +static inline void os_free_filename(os_filename filename) +{ + (void)filename; /* Nothing to do */ +} + +static inline void os_set_binary_mode(FILE *f) { + (void)f; +} + +# define os_fopen fopen + +#if defined(HAVE_FACCESSAT) && defined(AT_EACCESS) +static inline int os_access(os_filename pathname, int mode) +{ + return faccessat(AT_FDCWD, pathname, mode, AT_EACCESS); +} +# define os_access os_access +#elif defined(HAVE_ACCESS) +# define os_access access +#endif + +#ifdef HAVE_STRUCT_STAT +typedef struct stat os_struct_stat; +# ifdef HAVE_STAT +# define os_stat stat +# endif +# ifdef HAVE_FSTAT +# define os_fstat fstat +# endif +#else +struct dummy_struct_stat { + int st_mode; + int st_size; +}; +typedef struct dummy_struct_stat os_struct_stat; +#endif + +#endif /* Not _WIN32 */ + +#ifdef S_ISREG +/* all good */ +#elif defined(HAVE_S_ISREG) +/* exists, but not a macro */ +# define S_ISREG S_ISREG +#elif defined(S_IFMT) && defined(S_IFREG) +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#elif defined(_S_IFMT) && defined(_S_IFREG) +# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif + +#ifdef fileno +/* all good */ +#elif defined(HAVE_FILENO) +/* exists, but not a macro */ +# define fileno fileno +#elif defined(_fileno) || defined(HAVE__FILENO) +# define fileno _fileno +#endif + +#ifndef S_ISREG +# undef os_stat +# undef os_fstat +#endif + +/* Disable these functions if they don't support something we need */ +#ifndef fileno +# undef os_fstat +# undef os_ftruncate +# undef HAVE_MMAP +#endif + +/* + * If we don't have functional versions of these functions, + * stub them out so we don't need so many #ifndefs + */ +#ifndef os_stat +static inline int os_stat(os_filename osfname, os_struct_stat *st) +{ + (void)osfname; + (void)st; + return -1; +} +#endif + +#ifndef os_fstat +static inline int os_fstat(int fd, os_struct_stat *st) +{ + (void)fd; + (void)st; + return -1; +} +#endif + +#ifndef S_ISREG +static inline bool S_ISREG(int m) +{ + (void)m; + return false; +} +#endif + +#endif /* NASMLIB_FILE_H */ diff --git a/vere/ext/nasm/nasmlib/filename.c b/vere/ext/nasm/nasmlib/filename.c new file mode 100644 index 0000000..172ae0b --- /dev/null +++ b/vere/ext/nasm/nasmlib/filename.c @@ -0,0 +1,63 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" + +/* + * Add/modify a filename extension, assumed to be a period-delimited + * field at the very end of the filename. Returns a newly allocated + * string buffer. + */ +const char *filename_set_extension(const char *inname, const char *extension) +{ + const char *q = inname; + char *p; + size_t elen = strlen(extension); + size_t baselen; + + q = strrchrnul(inname, '.'); /* find extension or end of string */ + baselen = q - inname; + + p = nasm_malloc(baselen + elen + 1); + + memcpy(p, inname, baselen); + memcpy(p+baselen, extension, elen+1); + + return p; +} diff --git a/vere/ext/nasm/nasmlib/hashtbl.c b/vere/ext/nasm/nasmlib/hashtbl.c new file mode 100644 index 0000000..9a4c0b5 --- /dev/null +++ b/vere/ext/nasm/nasmlib/hashtbl.c @@ -0,0 +1,287 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * hashtbl.c + * + * Efficient dictionary hash table class. + */ + +#include "compiler.h" + +#include "nasm.h" +#include "hashtbl.h" + +#define HASH_MAX_LOAD 2 /* Higher = more memory-efficient, slower */ +#define HASH_INIT_SIZE 16 /* Initial size (power of 2, min 4) */ + +#define hash_calc(key,keylen) crc64b(CRC64_INIT, (key), (keylen)) +#define hash_calci(key,keylen) crc64ib(CRC64_INIT, (key), (keylen)) +#define hash_max_load(size) ((size) * (HASH_MAX_LOAD - 1) / HASH_MAX_LOAD) +#define hash_expand(size) ((size) << 1) +#define hash_mask(size) ((size) - 1) +#define hash_pos(hash, mask) ((hash) & (mask)) +#define hash_inc(hash, mask) ((((hash) >> 32) & (mask)) | 1) /* always odd */ +#define hash_pos_next(pos, inc, mask) (((pos) + (inc)) & (mask)) + +static void hash_init(struct hash_table *head) +{ + head->size = HASH_INIT_SIZE; + head->load = 0; + head->max_load = hash_max_load(head->size); + nasm_newn(head->table, head->size); +} + +/* + * Find an entry in a hash table. The key can be any binary object. + * + * On failure, if "insert" is non-NULL, store data in that structure + * which can be used to insert that node using hash_add(). + * See hash_add() for constraints on the uses of the insert object. + * + * On success, return a pointer to the "data" element of the hash + * structure. + */ +void **hash_findb(struct hash_table *head, const void *key, + size_t keylen, struct hash_insert *insert) +{ + struct hash_node *np = NULL; + struct hash_node *tbl = head->table; + uint64_t hash = hash_calc(key, keylen); + size_t mask = hash_mask(head->size); + size_t pos = hash_pos(hash, mask); + size_t inc = hash_inc(hash, mask); + + if (likely(tbl)) { + while ((np = &tbl[pos])->key) { + if (hash == np->hash && + keylen == np->keylen && + !memcmp(key, np->key, keylen)) + return &np->data; + pos = hash_pos_next(pos, inc, mask); + } + } + + /* Not found. Store info for insert if requested. */ + if (insert) { + insert->node.hash = hash; + insert->node.key = key; + insert->node.keylen = keylen; + insert->node.data = NULL; + insert->head = head; + insert->where = np; + } + return NULL; +} + +/* + * Same as hash_findb(), but for a C string. + */ +void **hash_find(struct hash_table *head, const char *key, + struct hash_insert *insert) +{ + return hash_findb(head, key, strlen(key)+1, insert); +} + +/* + * Same as hash_findb(), but for case-insensitive hashing. + */ +void **hash_findib(struct hash_table *head, const void *key, size_t keylen, + struct hash_insert *insert) +{ + struct hash_node *np = NULL; + struct hash_node *tbl = head->table; + uint64_t hash = hash_calci(key, keylen); + size_t mask = hash_mask(head->size); + size_t pos = hash_pos(hash, mask); + size_t inc = hash_inc(hash, mask); + + if (likely(tbl)) { + while ((np = &tbl[pos])->key) { + if (hash == np->hash && + keylen == np->keylen && + !nasm_memicmp(key, np->key, keylen)) + return &np->data; + pos = hash_pos_next(pos, inc, mask); + } + } + + /* Not found. Store info for insert if requested. */ + if (insert) { + insert->node.hash = hash; + insert->node.key = key; + insert->node.keylen = keylen; + insert->node.data = NULL; + insert->head = head; + insert->where = np; + } + return NULL; +} + +/* + * Same as hash_find(), but for case-insensitive hashing. + */ +void **hash_findi(struct hash_table *head, const char *key, + struct hash_insert *insert) +{ + return hash_findib(head, key, strlen(key)+1, insert); +} + +/* + * Insert node. Return a pointer to the "data" element of the newly + * created hash node. + * + * The following constraints apply: + * 1. A call to hash_add() invalidates all other outstanding hash_insert + * objects; attempting to use them causes a wild pointer reference. + * 2. The key provided must exactly match the key passed to hash_find*(), + * but it does not have to point to the same storage address. The key + * buffer provided to this function must not be freed for the lifespan + * of the hash. NULL will use the same pointer that was passed to + * hash_find*(). + */ +void **hash_add(struct hash_insert *insert, const void *key, void *data) +{ + struct hash_table *head = insert->head; + struct hash_node *np = insert->where; + + if (unlikely(!np)) { + hash_init(head); + /* The hash table is empty, so we don't need to iterate here */ + np = &head->table[hash_pos(insert->node.hash, hash_mask(head->size))]; + } + + /* + * Insert node. We can always do this, even if we need to + * rebalance immediately after. + */ + *np = insert->node; + np->data = data; + if (key) + np->key = key; + + if (unlikely(++head->load > head->max_load)) { + /* Need to expand the table */ + size_t newsize = hash_expand(head->size); + struct hash_node *newtbl; + size_t mask = hash_mask(newsize); + struct hash_node *op, *xp; + size_t i; + + nasm_newn(newtbl, newsize); + + /* Rebalance all the entries */ + for (i = 0, op = head->table; i < head->size; i++, op++) { + if (op->key) { + size_t pos = hash_pos(op->hash, mask); + size_t inc = hash_inc(op->hash, mask); + + while ((xp = &newtbl[pos])->key) + pos = hash_pos_next(pos, inc, mask); + + *xp = *op; + if (op == np) + np = xp; + } + } + nasm_free(head->table); + + head->table = newtbl; + head->size = newsize; + head->max_load = hash_max_load(newsize); + } + + return &np->data; +} + +/* + * Iterate over all members of a hash set. For the first call, iter + * should be as initialized by hash_iterator_init(). Returns a struct + * hash_node representing the current object, or NULL if we have + * reached the end of the hash table. + * + * Calling hash_add() will invalidate the iterator. + */ +const struct hash_node *hash_iterate(struct hash_iterator *iter) +{ + const struct hash_table *head = iter->head; + const struct hash_node *cp = iter->next; + const struct hash_node *ep = head->table + head->size; + + /* For an empty table, cp == ep == NULL */ + while (cp < ep) { + if (cp->key) { + iter->next = cp+1; + return cp; + } + cp++; + } + + iter->next = head->table; + return NULL; +} + +/* + * Free the hash itself. Doesn't free the data elements; use + * hash_iterate() to do that first, if needed. This function is normally + * used when the hash data entries are either freed separately, or + * compound objects which can't be freed in a single operation. + */ +void hash_free(struct hash_table *head) +{ + void *p = head->table; + memset(head, 0, sizeof *head); + nasm_free(p); +} + +/* + * Frees the hash *and* all data elements. This is applicable only in + * the case where the data element is a single allocation. If the + * second argument is false, the key string is part of the data + * allocation or belongs to an allocation which will be freed + * separately, if it is true the keys are also freed. + */ +void hash_free_all(struct hash_table *head, bool free_keys) +{ + struct hash_iterator it; + const struct hash_node *np; + + hash_for_each(head, it, np) { + if (np->data) + nasm_free(np->data); + if (free_keys && np->key) + nasm_free((void *)np->key); + } + + hash_free(head); +} diff --git a/vere/ext/nasm/nasmlib/ilog2.c b/vere/ext/nasm/nasmlib/ilog2.c new file mode 100644 index 0000000..cba2224 --- /dev/null +++ b/vere/ext/nasm/nasmlib/ilog2.c @@ -0,0 +1,2 @@ +#define ILOG2_C +#include "ilog2.h" diff --git a/vere/ext/nasm/nasmlib/md5c.c b/vere/ext/nasm/nasmlib/md5c.c new file mode 100644 index 0000000..79cf4e0 --- /dev/null +++ b/vere/ext/nasm/nasmlib/md5c.c @@ -0,0 +1,246 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#include "md5.h" + +#ifdef WORDS_LITTLEENDIAN +#define byteReverse(buf, len) /* Nothing */ +#else +static void byteReverse(unsigned char *buf, unsigned longs); + +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32_t t; + do { + t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32_t *) buf = t; + buf += 4; + } while (--longs); +} +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(MD5_CTX *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len) +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], MD5_CTX *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset((char *) ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} diff --git a/vere/ext/nasm/nasmlib/mmap.c b/vere/ext/nasm/nasmlib/mmap.c new file mode 100644 index 0000000..5fc5646 --- /dev/null +++ b/vere/ext/nasm/nasmlib/mmap.c @@ -0,0 +1,139 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "file.h" + +/* ----------------------------------------------------------------------- * + * Unix-style memory mapping, using mmap(). + * ----------------------------------------------------------------------- */ +#if defined(HAVE_FILENO) && defined(HAVE_MMAP) + +/* + * System page size + */ + +/* File scope since not all compilers like static data in inline functions */ +static size_t nasm_pagemask; + +static size_t get_pagemask(void) +{ + size_t ps = 0; + +# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) + ps = sysconf(_SC_PAGESIZE); +# elif defined(HAVE_GETPAGESIZE) + ps = getpagesize(); +# elif defined(PAGE_SIZE) + ps = PAGE_SIZE; +# endif + + nasm_pagemask = ps = is_power2(ps) ? (ps - 1) : 0; + return ps; +} + +static inline size_t pagemask(void) +{ + size_t pm = nasm_pagemask; + + if (unlikely(!pm)) + return get_pagemask(); + + return pm; +} + +/* + * Try to map an input file into memory + */ +const void *nasm_map_file(FILE *fp, off_t start, off_t len) +{ + const char *p; + off_t astart; /* Aligned start */ + size_t salign; /* Amount of start adjustment */ + size_t alen; /* Aligned length */ + const size_t page_mask = pagemask(); + + if (unlikely(!page_mask)) + return NULL; /* Page size undefined? */ + + if (unlikely(!len)) + return NULL; /* Mapping nothing... */ + + if (unlikely(len != (off_t)(size_t)len)) + return NULL; /* Address space insufficient */ + + astart = start & ~(off_t)page_mask; + salign = start - astart; + alen = (len + salign + page_mask) & ~page_mask; + + p = mmap(NULL, alen, PROT_READ, MAP_SHARED, fileno(fp), astart); + return unlikely(p == MAP_FAILED) ? NULL : p + salign; +} + +/* + * Unmap an input file + */ +void nasm_unmap_file(const void *p, size_t len) +{ + const size_t page_mask = pagemask(); + uintptr_t astart; + size_t salign; + size_t alen; + + if (unlikely(!page_mask)) + return; + + astart = (uintptr_t)p & ~(uintptr_t)page_mask; + salign = (uintptr_t)p - astart; + alen = (len + salign + page_mask) & ~page_mask; + + munmap((void *)astart, alen); +} + +/* ----------------------------------------------------------------------- * + * No memory map support at all + * XXX: Add a section with Windows support + * ----------------------------------------------------------------------- */ +#else + +const void *nasm_map_file(FILE *fp, off_t start, off_t len) +{ + (void)fp; (void)start; (void)len; + return NULL; +} + +void nasm_unmap_file(const void *p, size_t len) +{ + (void)p; (void)len; +} + +#endif diff --git a/vere/ext/nasm/nasmlib/nctype.c b/vere/ext/nasm/nasmlib/nctype.c new file mode 100644 index 0000000..f30f37e --- /dev/null +++ b/vere/ext/nasm/nasmlib/nctype.c @@ -0,0 +1,116 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "nctype.h" +#include <ctype.h> + +/* + * Table of tolower() results. This avoids function calls + * on some platforms. + */ +unsigned char nasm_tolower_tab[256]; + +static void tolower_tab_init(void) +{ + int i; + + for (i = 0; i < 256; i++) + nasm_tolower_tab[i] = tolower(i); +} + +/* + * Table of character type flags; some are simply <ctype.h>, + * some are NASM-specific. + */ + +uint16_t nasm_ctype_tab[256]; + +#if !defined(HAVE_ISCNTRL) && !defined(iscntrl) +# define iscntrl(x) ((x) < 32) +#endif +#if !defined(HAVE_ISASCII) && !defined(isascii) +# define isascii(x) ((x) < 128) +#endif + +static void ctype_tab_init(void) +{ + int i; + + for (i = 0; i < 256; i++) { + enum nasm_ctype ct = 0; + + if (iscntrl(i)) + ct |= NCT_CTRL; + + if (isascii(i)) + ct |= NCT_ASCII; + + if (isspace(i) && i != '\n') + ct |= NCT_SPACE; + + if (isalpha(i)) { + ct |= (nasm_tolower(i) == i) ? NCT_LOWER : NCT_UPPER; + ct |= NCT_ID|NCT_IDSTART; + } + + if (isdigit(i)) + ct |= NCT_DIGIT|NCT_ID; + + if (isxdigit(i)) + ct |= NCT_HEX; + + /* Non-ASCII character, but no ctype returned (e.g. Unicode) */ + if (!ct && !ispunct(i)) + ct |= NCT_ID|NCT_IDSTART; + + nasm_ctype_tab[i] = ct; + } + + nasm_ctype_tab['-'] |= NCT_MINUS; + nasm_ctype_tab['$'] |= NCT_DOLLAR|NCT_ID; + nasm_ctype_tab['_'] |= NCT_UNDER|NCT_ID|NCT_IDSTART; + nasm_ctype_tab['.'] |= NCT_ID|NCT_IDSTART; + nasm_ctype_tab['@'] |= NCT_ID|NCT_IDSTART; + nasm_ctype_tab['?'] |= NCT_ID|NCT_IDSTART; + nasm_ctype_tab['#'] |= NCT_ID; + nasm_ctype_tab['~'] |= NCT_ID; + nasm_ctype_tab['\''] |= NCT_QUOTE; + nasm_ctype_tab['\"'] |= NCT_QUOTE; + nasm_ctype_tab['`'] |= NCT_QUOTE; +} + +void nasm_ctype_init(void) +{ + tolower_tab_init(); + ctype_tab_init(); +} diff --git a/vere/ext/nasm/nasmlib/path.c b/vere/ext/nasm/nasmlib/path.c new file mode 100644 index 0000000..d228ed1 --- /dev/null +++ b/vere/ext/nasm/nasmlib/path.c @@ -0,0 +1,186 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * path.c - host operating system specific pathname manipulation functions + * + * This file is inherently nonportable ... please help adjusting it to + * any new platforms that may be necessary. + */ + +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" + +#if defined(__MSDOS__) || defined(__DOS__) || \ + defined(__WINDOWS__) || defined(_Windows) || \ + defined(__OS2__) || defined(_WIN16) || defined(WIN32) || defined(_WIN32) +/* MS-DOS/Windows and like operating systems */ +# define separators "/\\:" +# define cleandirend "/\\" +# define catsep '\\' +# define leaveonclean 2 /* Leave \\ at the start alone */ +# define curdir "." +#elif defined(unix) || defined(__unix) || defined(__unix__) || \ + defined(__UNIX__) || defined(__Unix__) || \ + defined(__MACH__) || defined(__BEOS__) +/* Unix and Unix-like operating systems and others using + * the equivalent syntax (slashes as only separators, no concept of volume) + * + * This must come after the __MSDOS__ section, since it seems that at + * least DJGPP defines __unix__ despite not being a Unix environment at all. + */ +# define separators "/" +# define cleandirend "/" +# define catsep '/' +# define leaveonclean 1 +# define curdir "." +#elif defined(Macintosh) || defined(macintosh) +/* MacOS classic */ +# define separators ":" +# define curdir ":" +# define catsep ':' +# define cleandirend ":" +# define leaveonclean 0 +# define leave_leading 1 +#elif defined(__VMS) +/* VMS * + * + * VMS filenames may have ;version at the end. Assume we should count that + * as part of the filename anyway. + */ +# define separators ":]" +# define curdir "[]" +#else +/* No idea what to do here, do nothing. Feel free to add new ones. */ +# define curdir "" +#endif + +/* + * This is an inline, because most compilers can greatly simplify this + * for a fixed string, like we have here. + */ +static inline bool ismatch(const char *charset, char ch) +{ + const char *p; + + for (p = charset; *p; p++) { + if (ch == *p) + return true; + } + + return false; +} + +static const char *first_filename_char(const char *path) +{ +#ifdef separators + const char *p = path + strlen(path); + + while (p > path) { + if (ismatch(separators, p[-1])) + return p; + p--; + } + + return p; +#else + return path; +#endif +} + +/* Return the filename portion of a PATH as a new string */ +char *nasm_basename(const char *path) +{ + return nasm_strdup(first_filename_char(path)); +} + +/* Return the directory name portion of a PATH as a new string */ +char *nasm_dirname(const char *path) +{ + const char *p = first_filename_char(path); + const char *p0 = p; + (void)p0; /* Don't warn if unused */ + + if (p == path) + return nasm_strdup(curdir); + +#ifdef cleandirend + while (p > path+leaveonclean) { + if (ismatch(cleandirend, p[-1])) + break; + p--; + } +#endif + +#ifdef leave_leading + /* If the directory contained ONLY separators, leave as-is */ + if (p == path+leaveonclean) + p = p0; +#endif + + return nasm_strndup(path, p-path); +} + +/* + * Concatenate a directory path and a filename. Note that this function + * currently does NOT handle the case where file itself contains + * directory components (except on Unix platforms, because it is trivial.) + */ +char *nasm_catfile(const char *dir, const char *file) +{ +#ifndef catsep + return nasm_strcat(dir, file); +#else + size_t dl = strlen(dir); + size_t fl = strlen(file); + char *p, *pp; + bool dosep = true; + + if (!dl || ismatch(separators, dir[dl-1])) { + /* No separator necessary */ + dosep = false; + } + + p = pp = nasm_malloc(dl + fl + dosep + 1); + + memcpy(pp, dir, dl); + pp += dl; + if (dosep) + *pp++ = catsep; + + memcpy(pp, file, fl+1); + + return p; +#endif +} diff --git a/vere/ext/nasm/nasmlib/perfhash.c b/vere/ext/nasm/nasmlib/perfhash.c new file mode 100644 index 0000000..acd3d28 --- /dev/null +++ b/vere/ext/nasm/nasmlib/perfhash.c @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "perfhash.h" +#include "hashtbl.h" /* For crc64i() */ + +int perfhash_find(const struct perfect_hash *hash, const char *str) +{ + uint32_t k1, k2; + uint64_t crc; + uint16_t ix; + + crc = crc64i(hash->crcinit, str); + k1 = (uint32_t)crc & hash->hashmask; + k2 = ((uint32_t)(crc >> 32) & hash->hashmask) + 1; + + ix = hash->hashvals[k1] + hash->hashvals[k2]; + + if (ix >= hash->tbllen || + !hash->strings[ix] || + nasm_stricmp(str, hash->strings[ix])) + return hash->errval; + + return hash->tbloffs + ix; +} diff --git a/vere/ext/nasm/nasmlib/perfhash.pl b/vere/ext/nasm/nasmlib/perfhash.pl new file mode 100755 index 0000000..0c885e8 --- /dev/null +++ b/vere/ext/nasm/nasmlib/perfhash.pl @@ -0,0 +1,357 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2017 The NASM Authors - All Rights Reserved +## See the file AUTHORS included with the NASM distribution for +## the specific copyright holders. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following +## conditions are met: +## +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above +## copyright notice, this list of conditions and the following +## disclaimer in the documentation and/or other materials provided +## with the distribution. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +## -------------------------------------------------------------------------- + +# +# Generate a perfect hash for general case-insensitive string-to-enum +# lookup. This generates an enum and the corresponding hash, but +# relies on a common function to parse the hash. +# +# Usage: +# perfhash.pl h foohash.dat foohash.h (to generate C header) +# perfhash.pl c foohash.dat foohash.c (to generate C source) +# + +use strict; + +require 'phash.ph'; + +sub basename($) { + my($s) = @_; + $s =~ s/^.*[^-[:alnum:]_\.]//; # Remove path component as best we can + return $s; +} + +sub intval($) { + my($s) = @_; + + if ($s =~ /^0/) { + return oct($s); # Handles octal or hexadecimal + } elsif ($s =~ /^\-(0.*)$/) { + return -oct($1); + } else { + return $s + 0; # Forcibly convert to number + } +} + +my($output, $infile, $outfile) = @ARGV; +my $me = basename($0); + +# The following special things are allowed in the input file: +# #<space> or ; begins a comment +# #include filename +# #name str +# The name of the hash +# #prefix str +# Defines the prefix before enum +# #guard str +# Defines the header guard string +# #special str [= value] +# Generate an enum value without a corresponding string; not capitalized. +# #header str +# Indicates the name of the .h file to include from the .c file +# #errval str +# Define the value to be returned if a string is not found +# (defaults to -1). This can be any constant C expression, +# including one of the enum values. +# +# Regular lines are just str [= value] +# +# Enumeration is generated in the order listed in the file, just as in C +# specifying a value causes the values to increase by 1 from that point on +# unless specified. + +my $name; +my $prefix; +my $guard; +my $hfile; + +my %strings = (); +my %specials = (); +my $next_value = 0; +my $errval = '-1'; + +my @incstack = (); +my @filenames = ($infile); +my @linenums = (0); +my $dd = undef; +my $err = 0; + +while (scalar(@filenames)) { + if (!defined($dd)) { + open($dd, '<', $filenames[-1]) + or die "$0: cannot open: $filenames[-1]: $!\n"; + } + + my $line = <$dd>; + if (!defined($line)) { + close($dd); + $dd = pop @incstack; + pop @filenames; + pop @linenums; + next; + } + + $linenums[-1]++; + + chomp $line; + $line =~ s/\s*(|\;.*|\#\s.*|\#)$//; # Remove comments and trailing space + $line =~ s/^\s+//; # Remove leading space + if ($line eq '') { + # Do nothing + } elsif ($line =~ /^\#name\s+([[:alnum:]_]+)$/) { + $name = $1; + } elsif ($line =~ /^\#prefix\s+([[:alnum:]_]+)$/) { + $prefix = $1; + } elsif ($line =~ /^\#guard\s+([[:alnum:]_]+)$/) { + $guard = $1; + } elsif ($line =~ /^\#errval\s+(\S.*)$/) { + $errval = $1; + } elsif ($line =~ /^\#header\s+(\"(.+)\"|\S+)$/) { + $hfile = ($2 ne '') ? $2 : $1; + } elsif ($line =~ /^\#include\s+(\"(.+)\"|\S+)$/) { + push @incstack, $dd; + push @filenames, (($2 ne '') ? $2 : $1); + push @linenums, 0; + undef $dd; # Open a new file + } elsif ($line =~ /^(|\#special\s+)(\S+)\s*(|=\s*(\-?(0[Xx][[:xdigit:]]+|0[0-7]*|[0-9]+)))$/) { + $next_value = intval($4) if ($4 ne ''); + if ($1 eq '') { + $strings{$2} = $next_value++; + } else { + $specials{$2} = $next_value++; + } + } else { + printf STDERR "%s:%d:%s syntax error: \"%s\"\n", + $filenames[-1], $linenums[-1], + (scalar(@incstack) == 1) ? '' : "(from $infile)", $line; + $err++; + } +} + +exit 1 if ($err); + +# Default name, prefix, and header guard name +if (!defined($name)) { + $name = basename($infile); + $name =~ s/(\..*)$//; # Strip extension, if any +} +if (!defined($prefix)) { + $prefix = "\U${name}\E_"; +} +if (!defined($hfile)) { + $hfile = $outfile; + $hfile =~ s/\.c$/\.h/; +} +if (!defined($guard)) { + $guard = basename($hfile); + $guard =~ s/[^[:alnum:]_]/_/g; + $guard =~ s/__+/_/g; + $guard = "\U$guard"; +} + +# Verify input. We can't have more than one constant with the same +# enumeration value, nor the same enumeration string. +if (scalar(keys(%strings)) == 0) { + die "$0: $infile: no strings to hash!\n"; +} + +my %enums; +my %enumvals; +my %stringbyval; +my $max_enum; +my $tbllen = 0; +my $tbloffs; +foreach my $s (keys(%strings)) { + my $es = "${prefix}\U${s}"; + $es =~ s/[^[:alnum:]_]/_/g; + $es =~ s/__+/_/g; + my $v = $strings{$s}; + $stringbyval{$v} = $s; + if (defined($enums{$es})) { + printf STDERR "%s: string \"%s\" duplicates existing enum %s\n", + $infile, $s, $es; + $err++; + } else { + $enums{$es} = $v; + } + if (defined($enumvals{$v})) { + printf STDERR "%s: string \"%s\" duplicates existing enum constant %d\n", $v; + $err++; + } else { + $enumvals{$v} = $es; + } + $max_enum = $v if (!defined($max_enum) || $v > $max_enum); + $tbloffs = $v if (!defined($tbloffs) || $v < $tbloffs); + $tbllen = $v+1 if (!defined($tbllen) || $v >= $tbllen); +} +foreach my $s (keys(%specials)) { + my $es = $prefix . $s; # No string mangling here + my $v = $specials{$s}; + if (defined($enums{$es})) { + printf STDERR "%s: special \"%s\" duplicates existing enum %s\n", + $infile, $s, $es; + $err++; + } else { + $enums{$es} = $v; + } + if (defined ($enumvals{$v})) { + printf STDERR "%s: special \"%s\" duplicates existing enum constant %d\n", $v; + $err++; + } else { + $enumvals{$v} = $es; + } + $max_enum = $v if ($v > $max_enum || !defined($max_enum)); +} + +$tbllen -= $tbloffs; +if ($tbllen > 65536) { + printf STDERR "%s: span of enumeration values too large\n"; + $err++; +} + +exit 1 if ($err); + +open(F, '>', $outfile) + or die "$0: cannot create: ${outfile}: $!\n"; + +if ($output eq 'h') { + print F "/*\n"; + print F " * This file is generated from $infile\n"; + print F " * by $me; do not edit.\n"; + print F " */\n"; + print F "\n"; + + print F "#ifndef $guard\n"; + print F "#define $guard 1\n\n"; + print F "#include \"perfhash.h\"\n\n"; + + my $c = '{'; + $next_value = 0; + print F "enum ${name} "; + foreach my $v (sort { $a <=> $b } keys(%enumvals)) { + my $s = $enumvals{$v}; + print F "$c\n $s"; + print F " = $v" if ($v != $next_value); + $next_value = $v + 1; + $c = ','; + } + print F "\n};\n\n"; + print F "extern const struct perfect_hash ${name}_hash;\n"; + printf F "extern const char * const %s_tbl[%d];\n", $name, $tbllen; + + print F "\nstatic inline enum ${name} ${name}_find(const char *str)\n"; + print F "{\n"; + print F " return perfhash_find(&${name}_hash, str);\n"; + print F "}\n"; + + print F "\nstatic inline const char * ${name}_name(enum ${name} x)\n"; + print F "{\n"; + printf F " size_t ix = (size_t)x - (%d);\n", $tbloffs; + printf F " if (ix >= %d)\n", $tbllen; + print F " return NULL;\n"; + print F " return ${name}_tbl[ix];\n"; + print F "}\n"; + + print F "\nstatic inline const char * ${name}_dname(enum ${name} x)\n"; + print F "{\n"; + print F " const char *y = ${name}_name(x);\n"; + print F " return y ? y : invalid_enum_str(x);\n"; + print F "}\n"; + + print F "\n#endif /* $guard */\n"; +} elsif ($output eq 'c') { + # The strings we hash must all be lower case, even if the string + # table doesn't contain them that way. + + my %lcstrings; + foreach my $s (keys(%strings)) { + my $ls = "\L$s"; + if (defined($lcstrings{$ls})) { + printf STDERR "%s: strings \"%s\" and \"%s\" differ only in case\n", + $infile, $s, $strings{$lcstrings{$s}}; + } else { + $lcstrings{$ls} = $strings{$s} - $tbloffs; + } + } + + my @hashinfo = gen_perfect_hash(\%lcstrings); + if (!@hashinfo) { + die "$0: no hash found\n"; + } + + # Paranoia... + verify_hash_table(\%lcstrings, \@hashinfo); + + my ($n, $sv, $g) = @hashinfo; + + die if ($n & ($n-1)); + + print F "/*\n"; + print F " * This file is generated from $infile\n"; + print F " * by $me; do not edit.\n"; + print F " */\n"; + print F "\n"; + + print F "#include \"$hfile\"\n\n"; + + printf F "const char * const %s_tbl[%d] = ", $name, $tbllen; + my $c = '{'; + for (my $i = $tbloffs; $i < $tbloffs+$tbllen; $i++) { + printf F "%s\n %s", $c, + defined($stringbyval{$i}) ? '"'.$stringbyval{$i}.'"' : 'NULL'; + $c = ','; + } + print F "\n};\n\n"; + + print F "#define INVALID_HASH_ENTRY (65536/3)\n\n"; + + printf F "static const int16_t %s_hashvals[%d] = ", $name, $n*2; + $c = '{'; + for (my $i = 0; $i < $n*2; $i++) { + my $h = ${$g}[$i]; + print F "$c\n ", defined($h) ? $h : 'INVALID_HASH_ENTRY'; + $c = ','; + } + print F "\n};\n\n"; + + print F "const struct perfect_hash ${name}_hash = {\n"; + printf F " UINT64_C(0x%08x%08x),\n", $$sv[0], $$sv[1]; # crcinit + printf F " UINT32_C(0x%x),\n", ($n-1) << 1; # hashmask + printf F " UINT32_C(%u),\n", $tbllen; # tbllen + printf F " %d,\n", $tbloffs; # tbloffs + printf F " (%s),\n", $errval; # errval + printf F " ${name}_hashvals,\n"; # hashvals + printf F " ${name}_tbl\n"; # strings + print F "};\n"; +} diff --git a/vere/ext/nasm/nasmlib/raa.c b/vere/ext/nasm/nasmlib/raa.c new file mode 100644 index 0000000..038f97a --- /dev/null +++ b/vere/ext/nasm/nasmlib/raa.c @@ -0,0 +1,198 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "nasmlib.h" +#include "raa.h" +#include "ilog2.h" + +/* + * Routines to manage a dynamic random access array of int64_ts which + * may grow in size to be more than the largest single malloc'able + * chunk. + */ + +#define RAA_LAYERSHIFT 11 /* 2^this many items per layer */ +#define RAA_LAYERSIZE ((size_t)1 << RAA_LAYERSHIFT) +#define RAA_LAYERMASK (RAA_LAYERSIZE-1) + +typedef struct RAA RAA; +typedef union RAA_UNION RAA_UNION; +typedef struct RAA_LEAF RAA_LEAF; +typedef struct RAA_BRANCH RAA_BRANCH; + +struct RAA { + /* Last position in this RAA */ + raaindex endposn; + + /* + * Number of layers below this one to get to the real data. 0 + * means this structure is a leaf, holding RAA_LAYERSIZE real + * data items; 1 and above mean it's a branch, holding + * RAA_LAYERSIZE pointers to the next level branch or leaf + * structures. + */ + unsigned int layers; + + /* + * Number of real data items spanned by one position in the + * `data' array at this level. This number is 0 trivially, for + * a leaf (level 0): for a level n branch it should be + * n*RAA_LAYERSHIFT. + */ + unsigned int shift; + + /* + * The actual data + */ + union RAA_UNION { + struct RAA_LEAF { + union intorptr data[RAA_LAYERSIZE]; + } l; + struct RAA_BRANCH { + struct RAA *data[RAA_LAYERSIZE]; + } b; + } u; +}; + +#define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF)) +#define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH)) + +static struct RAA *raa_init_layer(raaindex posn, unsigned int layers) +{ + struct RAA *r; + raaindex posmask; + + r = nasm_zalloc((layers == 0) ? LEAFSIZ : BRANCHSIZ); + r->shift = layers * RAA_LAYERSHIFT; + r->layers = layers; + posmask = ((raaindex)RAA_LAYERSIZE << r->shift) - 1; + r->endposn = posn | posmask; + return r; +} + +void raa_free(struct RAA *r) +{ + if (!r) + return; + + if (r->layers) { + struct RAA **p = r->u.b.data; + size_t i; + for (i = 0; i < RAA_LAYERSIZE; i++) + raa_free(*p++); + } + nasm_free(r); +} + +static const union intorptr *real_raa_read(struct RAA *r, raaindex posn) +{ + nasm_assert(posn <= (~(raaindex)0 >> 1)); + + if (unlikely(!r || posn > r->endposn)) + return NULL; /* Beyond the end */ + + while (r->layers) { + size_t l = (posn >> r->shift) & RAA_LAYERMASK; + r = r->u.b.data[l]; + if (!r) + return NULL; /* Not present */ + } + return &r->u.l.data[posn & RAA_LAYERMASK]; +} + +int64_t raa_read(struct RAA *r, raaindex pos) +{ + const union intorptr *ip; + + ip = real_raa_read(r, pos); + return ip ? ip->i : 0; +} + +void *raa_read_ptr(struct RAA *r, raaindex pos) +{ + const union intorptr *ip; + + ip = real_raa_read(r, pos); + return ip ? ip->p : NULL; +} + + +static struct RAA * +real_raa_write(struct RAA *r, raaindex posn, union intorptr value) +{ + struct RAA *result; + + nasm_assert(posn <= (~(raaindex)0 >> 1)); + + if (unlikely(!r)) { + /* Create a new top-level RAA */ + r = raa_init_layer(posn, ilog2_64(posn)/RAA_LAYERSHIFT); + } else { + while (unlikely(r->endposn < posn)) { + /* We need to add layers to an existing RAA */ + struct RAA *s = raa_init_layer(r->endposn, r->layers + 1); + s->u.b.data[0] = r; + r = s; + } + } + + result = r; + + while (r->layers) { + struct RAA **s; + size_t l = (posn >> r->shift) & RAA_LAYERMASK; + s = &r->u.b.data[l]; + if (unlikely(!*s)) + *s = raa_init_layer(posn, r->layers - 1); + r = *s; + } + r->u.l.data[posn & RAA_LAYERMASK] = value; + + return result; +} + +struct RAA *raa_write(struct RAA *r, raaindex posn, int64_t value) +{ + union intorptr ip; + + ip.i = value; + return real_raa_write(r, posn, ip); +} + +struct RAA *raa_write_ptr(struct RAA *r, raaindex posn, void *value) +{ + union intorptr ip; + + ip.p = value; + return real_raa_write(r, posn, ip); +} diff --git a/vere/ext/nasm/nasmlib/rbtree.c b/vere/ext/nasm/nasmlib/rbtree.c new file mode 100644 index 0000000..773338b --- /dev/null +++ b/vere/ext/nasm/nasmlib/rbtree.c @@ -0,0 +1,259 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * rbtree.c + * + * Simple implementation of a "left-leaning threaded red-black tree" + * with 64-bit integer keys. The search operation will return the + * highest node <= the key; only search and insert are supported, but + * additional standard llrbtree operations can be coded up at will. + * + * See http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf for + * information about left-leaning red-black trees. + * + * The "threaded" part means that left and right pointers that would + * otherwise be NULL are pointers to the in-order predecessor or + * successor node. The only pointers that are NULL are the very left- + * and rightmost, for which no corresponding side node exists. + * + * This, among other things, allows for efficient predecessor and + * successor operations without requiring dedicated space for a parent + * pointer. + * + * This implementation is robust for identical key values; such keys + * will not have their insertion order preserved, and after insertion + * of unrelated keys a lookup may return a different node for the + * duplicated key, but the prev/next operations will always enumerate + * all entries. + * + * The NULL pointers at the end are considered predecessor/successor + * pointers, so if the corresponding flags are clear it is always safe + * to access the pointed-to object without an explicit NULL pointer + * check. + */ + +#include "rbtree.h" +#include "nasmlib.h" + +struct rbtree *rb_search(const struct rbtree *tree, uint64_t key) +{ + const struct rbtree *best = NULL; + + if (tree) { + while (true) { + if (tree->key > key) { + if (tree->m.flags & RBTREE_NODE_PRED) + break; + tree = tree->m.left; + } else { + best = tree; + if (tree->key == key || (tree->m.flags & RBTREE_NODE_SUCC)) + break; + tree = tree->m.right; + } + } + } + return (struct rbtree *)best; +} + +struct rbtree *rb_search_exact(const struct rbtree *tree, uint64_t key) +{ + struct rbtree *rv; + + rv = rb_search(tree, key); + return (rv && rv->key == key) ? rv : NULL; +} + +/* Reds two left in a row? */ +static inline bool is_red_left_left(struct rbtree *h) +{ + return !(h->m.flags & RBTREE_NODE_PRED) && + !(h->m.left->m.flags & (RBTREE_NODE_BLACK|RBTREE_NODE_PRED)) && + !(h->m.left->m.left->m.flags & RBTREE_NODE_BLACK); +} + +/* Node to the right is red? */ +static inline bool is_red_right(struct rbtree *h) +{ + return !(h->m.flags & RBTREE_NODE_SUCC) && + !(h->m.right->m.flags & RBTREE_NODE_BLACK); +} + +/* Both the left and right hand nodes are red? */ +static inline bool is_red_both(struct rbtree *h) +{ + return !(h->m.flags & (RBTREE_NODE_PRED|RBTREE_NODE_SUCC)) + && !(h->m.left->m.flags & h->m.right->m.flags & RBTREE_NODE_BLACK); +} + +static inline struct rbtree *rotate_left(struct rbtree *h) +{ + struct rbtree *x = h->m.right; + enum rbtree_node_flags hf = h->m.flags; + enum rbtree_node_flags xf = x->m.flags; + + if (xf & RBTREE_NODE_PRED) { + h->m.right = x; + h->m.flags = (hf & RBTREE_NODE_PRED) | RBTREE_NODE_SUCC; + } else { + h->m.right = x->m.left; + h->m.flags = hf & RBTREE_NODE_PRED; + } + x->m.flags = (hf & RBTREE_NODE_BLACK) | (xf & RBTREE_NODE_SUCC); + x->m.left = h; + + return x; +} + +static inline struct rbtree *rotate_right(struct rbtree *h) +{ + struct rbtree *x = h->m.left; + enum rbtree_node_flags hf = h->m.flags; + enum rbtree_node_flags xf = x->m.flags; + + if (xf & RBTREE_NODE_SUCC) { + h->m.left = x; + h->m.flags = (hf & RBTREE_NODE_SUCC) | RBTREE_NODE_PRED; + } else { + h->m.left = x->m.right; + h->m.flags = hf & RBTREE_NODE_SUCC; + } + x->m.flags = (hf & RBTREE_NODE_BLACK) | (xf & RBTREE_NODE_PRED); + x->m.right = h; + + return x; +} + +static inline void color_flip(struct rbtree *h) +{ + h->m.flags ^= RBTREE_NODE_BLACK; + h->m.left->m.flags ^= RBTREE_NODE_BLACK; + h->m.right->m.flags ^= RBTREE_NODE_BLACK; +} + +static struct rbtree * +_rb_insert(struct rbtree *tree, struct rbtree *node); + +struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node) +{ + /* Initialize node as if it was the sole member of the tree */ + + nasm_zero(node->m); + node->m.flags = RBTREE_NODE_PRED|RBTREE_NODE_SUCC; + + if (unlikely(!tree)) + return node; + + return _rb_insert(tree, node); +} + +static struct rbtree * +_rb_insert(struct rbtree *tree, struct rbtree *node) +{ + /* Recursive part of the algorithm */ + + /* Red on both sides? */ + if (is_red_both(tree)) + color_flip(tree); + + if (node->key < tree->key) { + node->m.right = tree; /* Potential successor */ + if (tree->m.flags & RBTREE_NODE_PRED) { + node->m.left = tree->m.left; + tree->m.flags &= ~RBTREE_NODE_PRED; + tree->m.left = node; + } else { + tree->m.left = _rb_insert(tree->m.left, node); + } + } else { + node->m.left = tree; /* Potential predecessor */ + if (tree->m.flags & RBTREE_NODE_SUCC) { + node->m.right = tree->m.right; + tree->m.flags &= ~RBTREE_NODE_SUCC; + tree->m.right = node; + } else { + tree->m.right = _rb_insert(tree->m.right, node); + } + } + + if (is_red_right(tree)) + tree = rotate_left(tree); + + if (is_red_left_left(tree)) + tree = rotate_right(tree); + + return tree; +} + +struct rbtree *rb_first(const struct rbtree *tree) +{ + if (unlikely(!tree)) + return NULL; + + while (!(tree->m.flags & RBTREE_NODE_PRED)) + tree = tree->m.left; + + return (struct rbtree *)tree; +} + +struct rbtree *rb_last(const struct rbtree *tree) +{ + if (unlikely(!tree)) + return NULL; + + while (!(tree->m.flags & RBTREE_NODE_SUCC)) + tree = tree->m.right; + + return (struct rbtree *)tree; +} + +struct rbtree *rb_prev(const struct rbtree *node) +{ + struct rbtree *np = node->m.left; + + if (node->m.flags & RBTREE_NODE_PRED) + return np; + else + return rb_last(np); +} + +struct rbtree *rb_next(const struct rbtree *node) +{ + struct rbtree *np = node->m.right; + + if (node->m.flags & RBTREE_NODE_SUCC) + return np; + else + return rb_first(np); +} diff --git a/vere/ext/nasm/nasmlib/readnum.c b/vere/ext/nasm/nasmlib/readnum.c new file mode 100644 index 0000000..947bda5 --- /dev/null +++ b/vere/ext/nasm/nasmlib/readnum.c @@ -0,0 +1,179 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" + +#include "nctype.h" + +#include "nasmlib.h" +#include "error.h" +#include "nasm.h" /* For globalbits */ + +#define lib_isnumchar(c) (nasm_isalnum(c) || (c) == '$' || (c) == '_') + +static int radix_letter(char c) +{ + switch (c) { + case 'b': case 'B': + case 'y': case 'Y': + return 2; /* Binary */ + case 'o': case 'O': + case 'q': case 'Q': + return 8; /* Octal */ + case 'h': case 'H': + case 'x': case 'X': + return 16; /* Hexadecimal */ + case 'd': case 'D': + case 't': case 'T': + return 10; /* Decimal */ + default: + return 0; /* Not a known radix letter */ + } +} + +int64_t readnum(const char *str, bool *error) +{ + const char *r = str, *q; + int32_t pradix, sradix, radix; + int plen, slen, len; + uint64_t result, checklimit; + int digit, last; + bool warn = false; + int sign = 1; + + if (error) + *error = true; + + while (nasm_isspace(*r)) + r++; /* find start of number */ + + /* + * If the number came from make_tok_num (as a result of an %assign), it + * might have a '-' built into it (rather than in a preceding token). + */ + if (*r == '-') { + r++; + sign = -1; + } + + q = r; + + while (lib_isnumchar(*q)) + q++; /* find end of number */ + + len = q-r; + if (!len) { + /* Not numeric */ + return 0; + } + + /* + * Handle radix formats: + * + * 0<radix-letter><string> + * $<string> (hexadecimal) + * <string><radix-letter> + */ + pradix = sradix = 0; + plen = slen = 0; + + if (len > 2 && *r == '0' && (pradix = radix_letter(r[1])) != 0) + plen = 2; + else if (len > 1 && *r == '$') + pradix = 16, plen = 1; + + if (len > 1 && (sradix = radix_letter(q[-1])) != 0) + slen = 1; + + if (pradix > sradix) { + radix = pradix; + r += plen; + } else if (sradix > pradix) { + radix = sradix; + q -= slen; + } else { + /* Either decimal, or invalid -- if invalid, we'll trip up + further down. */ + radix = 10; + } + + /* + * `checklimit' must be 2**64 / radix. We can't do that in + * 64-bit arithmetic, which we're (probably) using, so we + * cheat: since we know that all radices we use are even, we + * can divide 2**63 by radix/2 instead. + */ + checklimit = UINT64_C(0x8000000000000000) / (radix >> 1); + + /* + * Calculate the highest allowable value for the last digit of a + * 64-bit constant... in radix 10, it is 6, otherwise it is 0 + */ + last = (radix == 10 ? 6 : 0); + + result = 0; + while (*r && r < q) { + if (*r != '_') { + if (*r < '0' || (*r > '9' && *r < 'A') + || (digit = numvalue(*r)) >= radix) { + return 0; + } + if (result > checklimit || + (result == checklimit && digit >= last)) { + warn = true; + } + + result = radix * result + digit; + } + r++; + } + + if (warn) { + /*! + *!number-overflow [on] numeric constant does not fit + *! covers warnings about numeric constants which + *! don't fit in 64 bits. + */ + nasm_warn(WARN_NUMBER_OVERFLOW, + "numeric constant %s does not fit in 64 bits", + str); + } + + if (error) + *error = false; + return result * sign; +} diff --git a/vere/ext/nasm/nasmlib/realpath.c b/vere/ext/nasm/nasmlib/realpath.c new file mode 100644 index 0000000..eaa148a --- /dev/null +++ b/vere/ext/nasm/nasmlib/realpath.c @@ -0,0 +1,133 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * realpath.c As system-independent as possible implementation of realpath() + */ + +#include "compiler.h" + +#include <errno.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif + +#include "nasmlib.h" + +#ifdef HAVE_CANONICALIZE_FILE_NAME + +/* + * GNU-specific, but avoids the realpath(..., NULL) + * portability problem if it exists. + */ +char *nasm_realpath(const char *rel_path) +{ + char *rp = canonicalize_file_name(rel_path); + return rp ? rp : nasm_strdup(rel_path); +} + +#elif defined(HAVE_REALPATH) + +/* + * POSIX.1-2008 defines realpath(..., NULL); POSIX.1-2001 doesn't guarantee + * that a NULL second argument is supported. + */ + +char *nasm_realpath(const char *rel_path) +{ + char *rp; + + rp = realpath(rel_path, NULL); + + /* Not all implementations of realpath() support a NULL second argument */ + if (!rp && errno == EINVAL) { + long path_max = -1; + char *rp; + +#if defined(HAVE_PATHCONF) && defined(_PC_PATH_MAX) + path_max = pathconf(rel_path, _PC_PATH_MAX); /* POSIX */ +#endif + + if (path_max < 0) { +#ifdef PATH_MAX + path_max = PATH_MAX; /* SUSv2 */ +#elif defined(MAXPATHLEN) + path_max = MAXPATHLEN; /* Solaris */ +#else + path_max = 65536; /* Crazily high, we hope */ +#endif + } + + rp = nasm_malloc(path_max); + + if (!realpath(rel_path, rp)) { + nasm_free(rp); + rp = NULL; + } else { + /* On some systems, pathconf() can return a very large value */ + + rp[path_max - 1] = '\0'; /* Just in case overrun is possible */ + rp = nasm_realloc(rp, strlen(rp) + 1); + } + } + + return rp ? rp : nasm_strdup(rel_path); +} + +#elif defined(HAVE__FULLPATH) + +/* + * win32/win64 API + */ + +char *nasm_realpath(const char *rel_path) +{ + char *rp = _fullpath(NULL, rel_path, 0); + return rp ? rp : nasm_strdup(rel_path); +} + +#else + +/* + * There is nothing we know how to do here, so hope it just works anyway. + */ + +char *nasm_realpath(const char *rel_path) +{ + return nasm_strdup(rel_path); +} + +#endif diff --git a/vere/ext/nasm/nasmlib/rlimit.c b/vere/ext/nasm/nasmlib/rlimit.c new file mode 100644 index 0000000..096879f --- /dev/null +++ b/vere/ext/nasm/nasmlib/rlimit.c @@ -0,0 +1,78 @@ + /* ----------------------------------------------------------------------- * + * + * Copyright 2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" +#include "nasmlib.h" + +#ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif + +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK) + +size_t nasm_get_stack_size_limit(void) +{ + struct rlimit rl; + + if (getrlimit(RLIMIT_STACK, &rl)) + return SIZE_MAX; + +# ifdef RLIM_SAVED_MAX + if (rl.rlim_cur == RLIM_SAVED_MAX) + rl.rlim_cur = rl.rlim_max; +# endif + + if ( +# ifdef RLIM_INFINITY + rl.rlim_cur >= RLIM_INFINITY || +# endif +# ifdef RLIM_SAVED_CUR + rl.rlim_cur == RLIM_SAVED_CUR || +# endif +# ifdef RLIM_SAVED_MAX + rl.rlim_cur == RLIM_SAVED_MAX || +# endif + (size_t)rl.rlim_cur != rl.rlim_cur) + return SIZE_MAX; + + return rl.rlim_cur; +} + +#else + +size_t nasm_get_stack_size_limit(void) +{ + return SIZE_MAX; +} + +#endif diff --git a/vere/ext/nasm/nasmlib/saa.c b/vere/ext/nasm/nasmlib/saa.c new file mode 100644 index 0000000..dcc2c01 --- /dev/null +++ b/vere/ext/nasm/nasmlib/saa.c @@ -0,0 +1,383 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" +#include "nasmlib.h" +#include "saa.h" + +/* Aggregate SAA components smaller than this */ +#define SAA_BLKSHIFT 16 +#define SAA_BLKLEN ((size_t)1 << SAA_BLKSHIFT) + +struct SAA *saa_init(size_t elem_len) +{ + struct SAA *s; + char *data; + + s = nasm_zalloc(sizeof(struct SAA)); + + if (elem_len >= SAA_BLKLEN) + s->blk_len = elem_len; + else + s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len); + + s->elem_len = elem_len; + s->length = s->blk_len; + data = nasm_malloc(s->blk_len); + s->nblkptrs = s->nblks = 1; + s->blk_ptrs = nasm_malloc(sizeof(char *)); + s->blk_ptrs[0] = data; + s->wblk = s->rblk = &s->blk_ptrs[0]; + + return s; +} + +void saa_free(struct SAA *s) +{ + char **p; + size_t n; + + for (p = s->blk_ptrs, n = s->nblks; n; p++, n--) + nasm_free(*p); + + nasm_free(s->blk_ptrs); + nasm_free(s); +} + +/* Add one allocation block to an SAA */ +static void saa_extend(struct SAA *s) +{ + size_t blkn = s->nblks++; + + if (blkn >= s->nblkptrs) { + size_t rindex = s->rblk - s->blk_ptrs; + size_t windex = s->wblk - s->blk_ptrs; + + s->nblkptrs <<= 1; + s->blk_ptrs = + nasm_realloc(s->blk_ptrs, s->nblkptrs * sizeof(char *)); + + s->rblk = s->blk_ptrs + rindex; + s->wblk = s->blk_ptrs + windex; + } + + s->blk_ptrs[blkn] = nasm_malloc(s->blk_len); + s->length += s->blk_len; +} + +void *saa_wstruct(struct SAA *s) +{ + void *p; + + nasm_assert((s->wpos % s->elem_len) == 0); + + if (s->wpos + s->elem_len > s->blk_len) { + nasm_assert(s->wpos == s->blk_len); + if (s->wptr + s->elem_len > s->length) + saa_extend(s); + s->wblk++; + s->wpos = 0; + } + + p = *s->wblk + s->wpos; + s->wpos += s->elem_len; + s->wptr += s->elem_len; + + if (s->wptr > s->datalen) + s->datalen = s->wptr; + + return p; +} + +void saa_wbytes(struct SAA *s, const void *data, size_t len) +{ + const char *d = data; + + while (len) { + size_t l = s->blk_len - s->wpos; + if (l > len) + l = len; + if (l) { + if (d) { + memcpy(*s->wblk + s->wpos, d, l); + d += l; + } else + memset(*s->wblk + s->wpos, 0, l); + s->wpos += l; + s->wptr += l; + len -= l; + + if (s->datalen < s->wptr) + s->datalen = s->wptr; + } + if (len) { + if (s->wptr >= s->length) + saa_extend(s); + s->wblk++; + s->wpos = 0; + } + } +} + +/* + * Writes a string, *including* the final null, to the specified SAA, + * and return the number of bytes written. + */ +size_t saa_wcstring(struct SAA *s, const char *str) +{ + size_t bytes = strlen(str) + 1; + + saa_wbytes(s, str, bytes); + + return bytes; +} + +void saa_rewind(struct SAA *s) +{ + s->rblk = s->blk_ptrs; + s->rpos = s->rptr = 0; +} + +void *saa_rstruct(struct SAA *s) +{ + void *p; + + if (s->rptr + s->elem_len > s->datalen) + return NULL; + + nasm_assert((s->rpos % s->elem_len) == 0); + + if (s->rpos + s->elem_len > s->blk_len) { + s->rblk++; + s->rpos = 0; + } + + p = *s->rblk + s->rpos; + s->rpos += s->elem_len; + s->rptr += s->elem_len; + + return p; +} + +const void *saa_rbytes(struct SAA *s, size_t * lenp) +{ + const void *p; + size_t len; + + if (s->rptr >= s->datalen) { + *lenp = 0; + return NULL; + } + + if (s->rpos >= s->blk_len) { + s->rblk++; + s->rpos = 0; + } + + len = *lenp; + if (len > s->datalen - s->rptr) + len = s->datalen - s->rptr; + if (len > s->blk_len - s->rpos) + len = s->blk_len - s->rpos; + + *lenp = len; + p = *s->rblk + s->rpos; + + s->rpos += len; + s->rptr += len; + + return p; +} + +void saa_rnbytes(struct SAA *s, void *data, size_t len) +{ + char *d = data; + + nasm_assert(s->rptr + len <= s->datalen); + + while (len) { + size_t l; + const void *p; + + l = len; + p = saa_rbytes(s, &l); + + memcpy(d, p, l); + d += l; + len -= l; + } +} + +/* Same as saa_rnbytes, except position the counter first */ +void saa_fread(struct SAA *s, size_t posn, void *data, size_t len) +{ + size_t ix; + + nasm_assert(posn + len <= s->datalen); + + if (likely(s->blk_len == SAA_BLKLEN)) { + ix = posn >> SAA_BLKSHIFT; + s->rpos = posn & (SAA_BLKLEN - 1); + } else { + ix = posn / s->blk_len; + s->rpos = posn % s->blk_len; + } + s->rptr = posn; + s->rblk = &s->blk_ptrs[ix]; + + saa_rnbytes(s, data, len); +} + +/* Same as saa_wbytes, except position the counter first */ +void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len) +{ + size_t ix; + size_t padding = 0; + + if (posn > s->datalen) { + padding = posn - s->datalen; + posn = s->datalen; + } + + if (likely(s->blk_len == SAA_BLKLEN)) { + ix = posn >> SAA_BLKSHIFT; + s->wpos = posn & (SAA_BLKLEN - 1); + } else { + ix = posn / s->blk_len; + s->wpos = posn % s->blk_len; + } + s->wptr = posn; + s->wblk = &s->blk_ptrs[ix]; + + if (!s->wpos) { + s->wpos = s->blk_len; + s->wblk--; + } + + if (padding) + saa_wbytes(s, NULL, padding); + + saa_wbytes(s, data, len); +} + +void saa_fpwrite(struct SAA *s, FILE * fp) +{ + const char *data; + size_t len; + + saa_rewind(s); + while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL) + nasm_write(data, len, fp); +} + +void saa_write8(struct SAA *s, uint8_t v) +{ + saa_wbytes(s, &v, 1); +} + +void saa_write16(struct SAA *s, uint16_t v) +{ + v = cpu_to_le16(v); + saa_wbytes(s, &v, 2); +} + +void saa_write32(struct SAA *s, uint32_t v) +{ + v = cpu_to_le32(v); + saa_wbytes(s, &v, 4); +} + +void saa_write64(struct SAA *s, uint64_t v) +{ + v = cpu_to_le64(v); + saa_wbytes(s, &v, 8); +} + +void saa_writeaddr(struct SAA *s, uint64_t v, size_t len) +{ + v = cpu_to_le64(v); + saa_wbytes(s, &v, len); +} + +/* write unsigned LEB128 value to SAA */ +void saa_wleb128u(struct SAA *psaa, int value) +{ + char temp[64], *ptemp; + uint8_t byte; + int len; + + ptemp = temp; + len = 0; + do { + byte = value & 127; + value >>= 7; + if (value != 0) /* more bytes to come */ + byte |= 0x80; + *ptemp = byte; + ptemp++; + len++; + } while (value != 0); + saa_wbytes(psaa, temp, len); +} + +/* write signed LEB128 value to SAA */ +void saa_wleb128s(struct SAA *psaa, int value) +{ + char temp[64], *ptemp; + uint8_t byte; + bool more, negative; + int size, len; + + ptemp = temp; + more = 1; + negative = (value < 0); + size = sizeof(int) * 8; + len = 0; + while (more) { + byte = value & 0x7f; + value >>= 7; + if (negative) + /* sign extend */ + value |= -(1 << (size - 7)); + /* sign bit of byte is second high order bit (0x40) */ + if ((value == 0 && !(byte & 0x40)) || + ((value == -1) && (byte & 0x40))) + more = 0; + else + byte |= 0x80; + *ptemp = byte; + ptemp++; + len++; + } + saa_wbytes(psaa, temp, len); +} diff --git a/vere/ext/nasm/nasmlib/string.c b/vere/ext/nasm/nasmlib/string.c new file mode 100644 index 0000000..4ee3ecb --- /dev/null +++ b/vere/ext/nasm/nasmlib/string.c @@ -0,0 +1,224 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" +#include "nasmlib.h" +#include "nctype.h" + +#ifndef nasm_stricmp +int nasm_stricmp(const char *s1, const char *s2) +{ + unsigned char c1, c2; + int d; + + while (1) { + c1 = nasm_tolower(*s1++); + c2 = nasm_tolower(*s2++); + d = c1-c2; + + if (d) + return d; + if (!c1) + break; + } + return 0; +} +#endif + +#ifndef nasm_strnicmp +int nasm_strnicmp(const char *s1, const char *s2, size_t n) +{ + unsigned char c1, c2; + int d; + + while (n--) { + c1 = nasm_tolower(*s1++); + c2 = nasm_tolower(*s2++); + d = c1-c2; + + if (d) + return d; + if (!c1) + break; + } + return 0; +} +#endif + +int nasm_memicmp(const char *s1, const char *s2, size_t n) +{ + unsigned char c1, c2; + int d; + + while (n--) { + c1 = nasm_tolower(*s1++); + c2 = nasm_tolower(*s2++); + d = c1-c2; + if (d) + return d; + } + return 0; +} + +#ifndef nasm_strsep +char *nasm_strsep(char **stringp, const char *delim) +{ + char *s = *stringp; + char *e; + + if (!s) + return NULL; + + e = strpbrk(s, delim); + if (e) + *e++ = '\0'; + + *stringp = e; + return s; +} +#endif + +/* skip leading spaces */ +char *nasm_skip_spaces(const char *p) +{ + if (p) + while (*p && nasm_isspace(*p)) + p++; + return (char *)p; +} + +/* skip leading non-spaces */ +char *nasm_skip_word(const char *p) +{ + if (p) + while (*p && !nasm_isspace(*p)) + p++; + return (char *)p; +} + +/* zap leading spaces with zero */ +char *nasm_zap_spaces_fwd(char *p) +{ + if (p) + while (*p && nasm_isspace(*p)) + *p++ = 0x0; + return p; +} + +/* zap spaces with zero in reverse order */ +char *nasm_zap_spaces_rev(char *p) +{ + if (p) + while (*p && nasm_isspace(*p)) + *p-- = 0x0; + return p; +} + +/* zap leading and trailing spaces */ +char *nasm_trim_spaces(char *p) +{ + p = nasm_zap_spaces_fwd(p); + nasm_zap_spaces_fwd(nasm_skip_word(p)); + + return p; +} + +/* + * return the word extracted from a stream + * or NULL if nothing left + */ +char *nasm_get_word(char *p, char **tail) +{ + char *word = nasm_skip_spaces(p); + char *next = nasm_skip_word(word); + + if (word && *word) { + if (*next) + *next++ = '\0'; + } else + word = next = NULL; + + /* NOTE: the tail may start with spaces */ + *tail = next; + + return word; +} + +/* + * Extract "opt=val" values from the stream and + * returns "opt" + * + * Exceptions: + * 1) If "=val" passed the NULL returned though + * you may continue handling the tail via "next" + * 2) If "=" passed the NULL is returned and "val" + * is set to NULL as well + */ +char *nasm_opt_val(char *p, char **val, char **next) +{ + char *q, *nxt; + + *val = *next = NULL; + + p = nasm_get_word(p, &nxt); + if (!p) + return NULL; + + q = strchr(p, '='); + if (q) { + if (q == p) + p = NULL; + *q++='\0'; + if (*q) { + *val = q; + } else { + q = nasm_get_word(q + 1, &nxt); + if (q) + *val = q; + } + } else { + q = nasm_skip_spaces(nxt); + if (q && *q == '=') { + q = nasm_get_word(q + 1, &nxt); + if (q) + *val = q; + } + } + + *next = nxt; + return p; +} diff --git a/vere/ext/nasm/nasmlib/strlist.c b/vere/ext/nasm/nasmlib/strlist.c new file mode 100644 index 0000000..449304b --- /dev/null +++ b/vere/ext/nasm/nasmlib/strlist.c @@ -0,0 +1,207 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * strlist.c - list of ordered strings, optionally made unique + */ + +#include "strlist.h" + +/* + * Create a string list. The list can be uniqizing or not. + */ +struct strlist *strlist_alloc(bool uniq) +{ + struct strlist *list = nasm_zalloc(sizeof(*list)); + list->tailp = &list->head; + list->uniq = uniq; + return list; +} + +/* + * Append a string to a string list. Return the entry pointer, which + * may be a pre-existing entry for a uniqizing list. + */ + +static const struct strlist_entry * +strlist_add_common(struct strlist *list, struct strlist_entry *e, + struct hash_insert *hi) +{ + e->offset = list->size; + e->next = NULL; + + *list->tailp = e; + list->tailp = &e->next; + list->nstr++; + list->size += e->size; + + if (list->uniq) + hash_add(hi, e->str, (void *)e); + + return e; +} + +const struct strlist_entry * +strlist_add(struct strlist *list, const char *str) +{ + struct strlist_entry *e; + struct hash_insert hi; + size_t size; + + if (!list) + return NULL; + + size = strlen(str) + 1; + if (list->uniq) { + void **dp = hash_findb(&list->hash, str, size, &hi); + if (dp) + return *dp; + } + + /* Structure already has char[1] as EOS */ + e = nasm_malloc(sizeof(*e) - 1 + size); + e->size = size; + memcpy(e->str, str, size); + + return strlist_add_common(list, e, &hi); +} + +/* + * printf() to a string list + */ +const struct strlist_entry * +strlist_vprintf(struct strlist *list, const char *fmt, va_list ap) +{ + /* clang miscompiles offsetin() unless e is initialized here */ + struct strlist_entry *e = NULL; + struct hash_insert hi; + + if (!list) + return NULL; + + e = nasm_vaxprintf(offsetin(*e, str), fmt, ap); + e->size = nasm_last_string_size(); + + if (list->uniq) { + void **dp = hash_findb(&list->hash, e->str, e->size, &hi); + if (dp) { + nasm_free(e); + return *dp; + } + } + + return strlist_add_common(list, e, &hi); +} + +const struct strlist_entry * +strlist_printf(struct strlist *list, const char *fmt, ...) +{ + va_list ap; + const struct strlist_entry *e; + + va_start(ap, fmt); + e = strlist_vprintf(list, fmt, ap); + va_end(ap); + + return e; +} + +/* + * Free a string list. Sets the pointed to pointer to NULL. + */ +void strlist_free(struct strlist **listp) +{ + struct strlist *list = *listp; + struct strlist_entry *e, *tmp; + + if (!list) + return; + + if (list->uniq) + hash_free(&list->hash); + + list_for_each_safe(e, tmp, list->head) + nasm_free(e); + + nasm_free(list); + *listp = NULL; +} + +/* + * Search the string list for an entry. If found, return the entry pointer. + * Only possible on a uniqizing list. + */ +const struct strlist_entry * +strlist_find(const struct strlist *list, const char *str) +{ + void **hf; + + nasm_assert(list->uniq); + + hf = hash_find((struct hash_table *)&list->hash, str, NULL); + return hf ? *hf : NULL; +} + +/* + * Produce a linearized buffer containing the whole list, in order; + * The character "sep" is the separator between strings; this is + * typically either 0 or '\n'. strlist_size() will give the size of + * the returned buffer. + */ +void *strlist_linearize(const struct strlist *list, char sep) +{ + const struct strlist_entry *sl; + char *buf = nasm_malloc(list->size); + char *p = buf; + + strlist_for_each(sl, list) { + p = mempcpy(p, sl->str, sl->size); + p[-1] = sep; + } + + return buf; +} + +/* + * Output a string list to a file. The separator can be any string. + */ +void strlist_write(const struct strlist *list, const char *sep, FILE *f) +{ + const struct strlist_entry *sl; + size_t seplen = strlen(sep); + + strlist_for_each(sl, list) { + fwrite(sl->str, 1, sl->size - 1, f); + fwrite(sep, 1, seplen, f); + } +} diff --git a/vere/ext/nasm/nasmlib/ver.c b/vere/ext/nasm/nasmlib/ver.c new file mode 100644 index 0000000..667dc88 --- /dev/null +++ b/vere/ext/nasm/nasmlib/ver.c @@ -0,0 +1,80 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#include "ver.h" +#include "version.h" + +/* This is printed when entering nasm -v */ +const char nasm_version[] = NASM_VER; +const char nasm_date[] = ""; +const char nasm_compile_options[] = "" +#ifdef DEBUG + " with -DDEBUG" +#endif + ; + +bool reproducible; /* Reproducible output */ + +/* These are used by some backends. For a reproducible build, + * these cannot contain version numbers. + */ +static const char * const _nasm_comment[2] = +{ + "The Netwide Assembler " NASM_VER, + "The Netwide Assembler" +}; + +static const char * const _nasm_signature[2] = { + "NASM " NASM_VER, + "NASM" +}; + +const char *nasm_comment(void) +{ + return _nasm_comment[reproducible]; +} + +size_t nasm_comment_len(void) +{ + return strlen(nasm_comment()); +} + +const char *nasm_signature(void) +{ + return _nasm_signature[reproducible]; +} + +size_t nasm_signature_len(void) +{ + return strlen(nasm_signature()); +} diff --git a/vere/ext/nasm/nasmlib/zerobuf.c b/vere/ext/nasm/nasmlib/zerobuf.c new file mode 100644 index 0000000..651c0fd --- /dev/null +++ b/vere/ext/nasm/nasmlib/zerobuf.c @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" +#include "nasmlib.h" + +/* Uninitialized -> all zero by C spec */ +const uint8_t zero_buffer[ZERO_BUF_SIZE]; |