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
);