| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /* ----------------------------------------------------------------------- *
- *
- * 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;
- /* Seek beyond the end of the existing array not supported */
- nasm_assert(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--;
- }
- 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);
- }
|