1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
38 /* Aggregate SAA components smaller than this */
39 #define SAA_BLKSHIFT 16
40 #define SAA_BLKLEN ((size_t)1 << SAA_BLKSHIFT)
42 struct SAA *saa_init(size_t elem_len)
47 s = nasm_zalloc(sizeof(struct SAA));
49 if (elem_len >= SAA_BLKLEN)
50 s->blk_len = elem_len;
52 s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
54 s->elem_len = elem_len;
55 s->length = s->blk_len;
56 data = nasm_malloc(s->blk_len);
57 s->nblkptrs = s->nblks = 1;
58 s->blk_ptrs = nasm_malloc(sizeof(char *));
59 s->blk_ptrs[0] = data;
60 s->wblk = s->rblk = &s->blk_ptrs[0];
65 void saa_free(struct SAA *s)
70 for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
73 nasm_free(s->blk_ptrs);
77 /* Add one allocation block to an SAA */
78 static void saa_extend(struct SAA *s)
80 size_t blkn = s->nblks++;
82 if (blkn >= s->nblkptrs) {
83 size_t rindex = s->rblk - s->blk_ptrs;
84 size_t windex = s->wblk - s->blk_ptrs;
88 nasm_realloc(s->blk_ptrs, s->nblkptrs * sizeof(char *));
90 s->rblk = s->blk_ptrs + rindex;
91 s->wblk = s->blk_ptrs + windex;
94 s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
95 s->length += s->blk_len;
98 void *saa_wstruct(struct SAA *s)
102 if (s->wpos % s->elem_len)
103 nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
104 "misaligned wpos in saa_wstruct");
106 if (s->wpos + s->elem_len > s->blk_len) {
107 if (s->wpos != s->blk_len)
108 nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
109 "unfilled block in saa_wstruct");
111 if (s->wptr + s->elem_len > s->length)
117 p = *s->wblk + s->wpos;
118 s->wpos += s->elem_len;
119 s->wptr += s->elem_len;
121 if (s->wptr > s->datalen)
122 s->datalen = s->wptr;
127 void saa_wbytes(struct SAA *s, const void *data, size_t len)
129 const char *d = data;
132 size_t l = s->blk_len - s->wpos;
137 memcpy(*s->wblk + s->wpos, d, l);
140 memset(*s->wblk + s->wpos, 0, l);
145 if (s->datalen < s->wptr)
146 s->datalen = s->wptr;
149 if (s->wptr >= s->length)
157 void saa_rewind(struct SAA *s)
159 s->rblk = s->blk_ptrs;
160 s->rpos = s->rptr = 0;
163 void *saa_rstruct(struct SAA *s)
167 if (s->rptr + s->elem_len > s->datalen)
170 if (s->rpos % s->elem_len)
171 nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
172 "misaligned rpos in saa_rstruct");
174 if (s->rpos + s->elem_len > s->blk_len) {
179 p = *s->rblk + s->rpos;
180 s->rpos += s->elem_len;
181 s->rptr += s->elem_len;
186 const void *saa_rbytes(struct SAA *s, size_t * lenp)
191 if (s->rptr >= s->datalen) {
196 if (s->rpos >= s->blk_len) {
202 if (len > s->datalen - s->rptr)
203 len = s->datalen - s->rptr;
204 if (len > s->blk_len - s->rpos)
205 len = s->blk_len - s->rpos;
208 p = *s->rblk + s->rpos;
216 void saa_rnbytes(struct SAA *s, void *data, size_t len)
220 if (s->rptr + len > s->datalen) {
221 nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
222 "overrun in saa_rnbytes");
231 p = saa_rbytes(s, &l);
239 /* Same as saa_rnbytes, except position the counter first */
240 void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
244 if (posn + len > s->datalen) {
245 nasm_malloc_error(ERR_PANIC | ERR_NOFILE, "overrun in saa_fread");
249 if (likely(s->blk_len == SAA_BLKLEN)) {
250 ix = posn >> SAA_BLKSHIFT;
251 s->rpos = posn & (SAA_BLKLEN - 1);
253 ix = posn / s->blk_len;
254 s->rpos = posn % s->blk_len;
257 s->rblk = &s->blk_ptrs[ix];
259 saa_rnbytes(s, data, len);
262 /* Same as saa_wbytes, except position the counter first */
263 void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
267 if (posn > s->datalen) {
268 /* Seek beyond the end of the existing array not supported */
269 nasm_malloc_error(ERR_PANIC | ERR_NOFILE, "overrun in saa_fwrite");
273 if (likely(s->blk_len == SAA_BLKLEN)) {
274 ix = posn >> SAA_BLKSHIFT;
275 s->wpos = posn & (SAA_BLKLEN - 1);
277 ix = posn / s->blk_len;
278 s->wpos = posn % s->blk_len;
281 s->wblk = &s->blk_ptrs[ix];
284 s->wpos = s->blk_len;
288 saa_wbytes(s, data, len);
291 void saa_fpwrite(struct SAA *s, FILE * fp)
297 while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
298 fwrite(data, 1, len, fp);
301 void saa_write8(struct SAA *s, uint8_t v)
303 saa_wbytes(s, &v, 1);
306 #ifdef WORDS_LITTEENDIAN
308 void saa_write16(struct SAA *s, uint16_t v)
310 saa_wbytes(s, &v, 2);
313 void saa_write32(struct SAA *s, uint32_t v)
315 saa_wbytes(s, &v, 4);
318 void saa_write64(struct SAA *s, uint64_t v)
320 saa_wbytes(s, &v, 8);
323 void saa_writeaddr(struct SAA *s, uint64_t v, size_t len)
325 saa_wbytes(s, &v, len);
328 #else /* not WORDS_LITTLEENDIAN */
330 void saa_write16(struct SAA *s, uint16_t v)
339 void saa_write32(struct SAA *s, uint32_t v)
350 void saa_write64(struct SAA *s, uint64_t v)
365 void saa_writeaddr(struct SAA *s, uint64_t v, size_t len)
378 saa_wbytes(s, &v, len);
381 #endif /* WORDS_LITTLEENDIAN */
383 /* write unsigned LEB128 value to SAA */
384 void saa_wleb128u(struct SAA *psaa, int value)
386 char temp[64], *ptemp;
395 if (value != 0) /* more bytes to come */
400 } while (value != 0);
401 saa_wbytes(psaa, temp, len);
404 /* write signed LEB128 value to SAA */
405 void saa_wleb128s(struct SAA *psaa, int value)
407 char temp[64], *ptemp;
414 negative = (value < 0);
415 size = sizeof(int) * 8;
422 value |= -(1 << (size - 7));
423 /* sign bit of byte is second high order bit (0x40) */
424 if ((value == 0 && !(byte & 0x40)) ||
425 ((value == -1) && (byte & 0x40)))
433 saa_wbytes(psaa, temp, len);