1 /*
2 * Data (and LEB128) bytecode
3 *
4 * Copyright (C) 2001-2007 Peter Johnson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include "util.h"
28
29 #include "libyasm-stdint.h"
30 #include "coretype.h"
31
32 #include "errwarn.h"
33 #include "intnum.h"
34 #include "expr.h"
35 #include "value.h"
36
37 #include "bytecode.h"
38 #include "arch.h"
39
40
41 struct yasm_dataval {
42 /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;
43
44 enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128, DV_RESERVE }
45 type;
46
47 union {
48 yasm_value val;
49 struct {
50 /*@only@*/ unsigned char *contents;
51 unsigned long len;
52 } raw;
53 } data;
54
55 /* number of times data is repeated, NULL=1. */
56 /*@only@*/ /*@null@*/ yasm_expr *multiple;
57 };
58
59 typedef struct bytecode_data {
60 /* converted data (linked list) */
61 yasm_datavalhead datahead;
62
63 int item_size;
64 } bytecode_data;
65
66 static void bc_data_destroy(void *contents);
67 static void bc_data_print(const void *contents, FILE *f, int indent_level);
68 static void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
69 static int bc_data_item_size(yasm_bytecode *bc);
70 static int bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
71 void *add_span_data);
72 static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp,
73 unsigned char *bufstart, void *d,
74 yasm_output_value_func output_value,
75 /*@null@*/ yasm_output_reloc_func output_reloc);
76
77 static const yasm_bytecode_callback bc_data_callback = {
78 bc_data_destroy,
79 bc_data_print,
80 bc_data_finalize,
81 bc_data_item_size,
82 bc_data_calc_len,
83 yasm_bc_expand_common,
84 bc_data_tobytes,
85 0
86 };
87
88
89 static void
bc_data_destroy(void * contents)90 bc_data_destroy(void *contents)
91 {
92 bytecode_data *bc_data = (bytecode_data *)contents;
93 yasm_dvs_delete(&bc_data->datahead);
94 yasm_xfree(contents);
95 }
96
97 static void
bc_data_print(const void * contents,FILE * f,int indent_level)98 bc_data_print(const void *contents, FILE *f, int indent_level)
99 {
100 const bytecode_data *bc_data = (const bytecode_data *)contents;
101 fprintf(f, "%*s_Data_\n", indent_level, "");
102 fprintf(f, "%*sElements:\n", indent_level+1, "");
103 yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
104 }
105
106 static void
bc_data_finalize(yasm_bytecode * bc,yasm_bytecode * prev_bc)107 bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
108 {
109 bytecode_data *bc_data = (bytecode_data *)bc->contents;
110 yasm_dataval *dv;
111 yasm_intnum *intn;
112
113 /* Convert values from simple expr to value. */
114 STAILQ_FOREACH(dv, &bc_data->datahead, link) {
115 switch (dv->type) {
116 case DV_VALUE:
117 if (yasm_value_finalize(&dv->data.val, prev_bc)) {
118 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
119 N_("data expression too complex"));
120 return;
121 }
122 break;
123 case DV_ULEB128:
124 case DV_SLEB128:
125 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0);
126 if (!intn) {
127 yasm_error_set(YASM_ERROR_NOT_CONSTANT,
128 N_("LEB128 requires constant values"));
129 return;
130 }
131 /* Warn for negative values in unsigned environment.
132 * This could be an error instead: the likelihood this is
133 * desired is very low!
134 */
135 if (yasm_intnum_sign(intn) == -1 && dv->type == DV_ULEB128)
136 yasm_warn_set(YASM_WARN_GENERAL,
137 N_("negative value in unsigned LEB128"));
138 break;
139 default:
140 break;
141 }
142 if (dv->multiple) {
143 yasm_value val;
144 if (yasm_value_finalize_expr(&val, dv->multiple, prev_bc, 0))
145 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
146 N_("multiple expression too complex"));
147 else if (val.rel)
148 yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
149 N_("multiple expression not absolute"));
150 dv->multiple = val.abs;
151 }
152 }
153 }
154
155 static int
bc_data_item_size(yasm_bytecode * bc)156 bc_data_item_size(yasm_bytecode *bc)
157 {
158 bytecode_data *bc_data = (bytecode_data *)bc->contents;
159 return bc_data->item_size;
160 }
161
162 static int
bc_data_calc_len(yasm_bytecode * bc,yasm_bc_add_span_func add_span,void * add_span_data)163 bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
164 void *add_span_data)
165 {
166 bytecode_data *bc_data = (bytecode_data *)bc->contents;
167 yasm_dataval *dv;
168 yasm_intnum *intn;
169 unsigned long len = 0;
170 unsigned long multiple;
171
172 /* Count up element sizes, rounding up string length. */
173 STAILQ_FOREACH(dv, &bc_data->datahead, link) {
174 switch (dv->type) {
175 case DV_EMPTY:
176 len = 0;
177 break;
178 case DV_VALUE:
179 len = dv->data.val.size/8;
180 break;
181 case DV_RAW:
182 len = dv->data.raw.len;
183 break;
184 case DV_ULEB128:
185 case DV_SLEB128:
186 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0);
187 if (!intn)
188 yasm_internal_error(N_("non-constant in data_tobytes"));
189 len = yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128);
190 break;
191 case DV_RESERVE:
192 len = dv->data.val.size/8;
193 break;
194 }
195
196 if (!yasm_dv_get_multiple(dv, &multiple))
197 len *= multiple;
198
199 bc->len += len;
200 }
201
202 return 0;
203 }
204
205 static int
bc_data_tobytes(yasm_bytecode * bc,unsigned char ** bufp,unsigned char * bufstart,void * d,yasm_output_value_func output_value,yasm_output_reloc_func output_reloc)206 bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp,
207 unsigned char *bufstart, void *d,
208 yasm_output_value_func output_value,
209 /*@unused@*/ yasm_output_reloc_func output_reloc)
210 {
211 bytecode_data *bc_data = (bytecode_data *)bc->contents;
212 yasm_dataval *dv;
213 yasm_intnum *intn;
214 unsigned int val_len;
215 unsigned long multiple, i;
216
217 STAILQ_FOREACH(dv, &bc_data->datahead, link) {
218 if (yasm_dv_get_multiple(dv, &multiple) || multiple == 0)
219 continue;
220 switch (dv->type) {
221 case DV_EMPTY:
222 break;
223 case DV_VALUE:
224 val_len = dv->data.val.size/8;
225 for (i=0; i<multiple; i++) {
226 if (output_value(&dv->data.val, *bufp, val_len,
227 (unsigned long)(*bufp-bufstart), bc, 1,
228 d))
229 return 1;
230 *bufp += val_len;
231 }
232 break;
233 case DV_RAW:
234 for (i=0; i<multiple; i++) {
235 memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len);
236 *bufp += dv->data.raw.len;
237 }
238 break;
239 case DV_ULEB128:
240 case DV_SLEB128:
241 intn = yasm_expr_get_intnum(&dv->data.val.abs, 234);
242 if (!intn)
243 yasm_internal_error(N_("non-constant in data_tobytes"));
244 for (i=0; i<multiple; i++) {
245 *bufp +=
246 yasm_intnum_get_leb128(intn, *bufp,
247 dv->type == DV_SLEB128);
248 }
249 case DV_RESERVE:
250 val_len = dv->data.val.size/8;
251 for (i=0; i<multiple; i++) {
252 memset(*bufp, 0, val_len);
253 *bufp += val_len;
254 }
255 break;
256 }
257 }
258
259 return 0;
260 }
261
262 yasm_bytecode *
yasm_bc_create_data(yasm_datavalhead * datahead,unsigned int size,int append_zero,yasm_arch * arch,unsigned long line)263 yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
264 int append_zero, yasm_arch *arch, unsigned long line)
265 {
266 bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data));
267 yasm_bytecode *bc = yasm_bc_create_common(&bc_data_callback, data, line);
268 yasm_dataval *dv, *dv2, *dvo;
269 yasm_intnum *intn;
270 unsigned long len = 0, rlen, i;
271
272
273 yasm_dvs_initialize(&data->datahead);
274 data->item_size = size;
275
276 /* Prescan input data for length, etc. Careful: this needs to be
277 * precisely paired with the second loop.
278 */
279 STAILQ_FOREACH(dv, datahead, link) {
280 if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
281 /* Flush previous data */
282 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
283 STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
284 len = 0;
285 }
286 switch (dv->type) {
287 case DV_EMPTY:
288 break;
289 case DV_VALUE:
290 case DV_ULEB128:
291 case DV_SLEB128:
292 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0);
293 if (intn && dv->type == DV_VALUE && (arch || size == 1))
294 len += size;
295 else if (intn && dv->type == DV_ULEB128)
296 len += yasm_intnum_size_leb128(intn, 0);
297 else if (intn && dv->type == DV_SLEB128)
298 len += yasm_intnum_size_leb128(intn, 1);
299 else {
300 if (len > 0) {
301 /* Create bytecode for all previous len */
302 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
303 STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
304 len = 0;
305 }
306
307 /* Create bytecode for this value */
308 dvo = yasm_xmalloc(sizeof(yasm_dataval));
309 STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
310 dvo->multiple = dv->multiple;
311 }
312 break;
313 case DV_RAW:
314 rlen = dv->data.raw.len;
315 /* find count, rounding up to nearest multiple of size */
316 rlen = (rlen + size - 1) / size;
317 len += rlen*size;
318 break;
319 case DV_RESERVE:
320 len += size;
321 break;
322 }
323
324 if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
325 /* Flush this data */
326 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
327 STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
328 dvo->multiple = dv->multiple;
329 len = 0;
330 }
331
332 if (append_zero)
333 len++;
334 }
335
336 /* Create final dataval for any trailing length */
337 if (len > 0) {
338 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
339 STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
340 }
341
342 /* Second iteration: copy data and delete input datavals. */
343 dv = STAILQ_FIRST(datahead);
344 dvo = STAILQ_FIRST(&data->datahead);
345 len = 0;
346 while (dv && dvo) {
347 if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
348 dvo = STAILQ_NEXT(dvo, link);
349 len = 0;
350 }
351 switch (dv->type) {
352 case DV_EMPTY:
353 break;
354 case DV_VALUE:
355 case DV_ULEB128:
356 case DV_SLEB128:
357 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0);
358 if (intn && dv->type == DV_VALUE && (arch || size == 1)) {
359 if (size == 1)
360 yasm_intnum_get_sized(intn,
361 &dvo->data.raw.contents[len],
362 1, 8, 0, 0, 1);
363 else
364 yasm_arch_intnum_tobytes(arch, intn,
365 &dvo->data.raw.contents[len],
366 size, size*8, 0, bc, 1);
367 yasm_value_delete(&dv->data.val);
368 len += size;
369 } else if (intn && dv->type == DV_ULEB128) {
370 len += yasm_intnum_get_leb128(intn,
371 &dvo->data.raw.contents[len],
372 0);
373 yasm_value_delete(&dv->data.val);
374 } else if (intn && dv->type == DV_SLEB128) {
375 len += yasm_intnum_get_leb128(intn,
376 &dvo->data.raw.contents[len],
377 1);
378 yasm_value_delete(&dv->data.val);
379 } else {
380 if (len > 0)
381 dvo = STAILQ_NEXT(dvo, link);
382 dvo->type = dv->type;
383 dvo->data.val = dv->data.val; /* structure copy */
384 dvo->data.val.size = size*8; /* remember size */
385 dvo = STAILQ_NEXT(dvo, link);
386 len = 0;
387 }
388 break;
389 case DV_RAW:
390 rlen = dv->data.raw.len;
391 memcpy(&dvo->data.raw.contents[len], dv->data.raw.contents,
392 rlen);
393 yasm_xfree(dv->data.raw.contents);
394 len += rlen;
395 /* pad with 0's to nearest multiple of size */
396 rlen %= size;
397 if (rlen > 0) {
398 rlen = size-rlen;
399 for (i=0; i<rlen; i++)
400 dvo->data.raw.contents[len++] = 0;
401 }
402 break;
403 case DV_RESERVE:
404 memset(&dvo->data.raw.contents[len], 0, size);
405 len += size;
406 break;
407 }
408
409 if (dv->multiple && dv->type != DV_EMPTY && len > 0) {
410 dvo = STAILQ_NEXT(dvo, link);
411 len = 0;
412 }
413
414 if (append_zero)
415 dvo->data.raw.contents[len++] = 0;
416 dv2 = STAILQ_NEXT(dv, link);
417 yasm_xfree(dv);
418 dv = dv2;
419 }
420
421 return bc;
422 }
423
424 yasm_bytecode *
yasm_bc_create_leb128(yasm_datavalhead * datahead,int sign,unsigned long line)425 yasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line)
426 {
427 yasm_dataval *dv;
428
429 /* Convert all values into LEB type, error on strings/raws */
430 STAILQ_FOREACH(dv, datahead, link) {
431 switch (dv->type) {
432 case DV_VALUE:
433 dv->type = sign ? DV_SLEB128 : DV_ULEB128;
434 break;
435 case DV_RAW:
436 yasm_error_set(YASM_ERROR_VALUE,
437 N_("LEB128 does not allow string constants"));
438 break;
439 default:
440 break;
441 }
442 }
443
444 return yasm_bc_create_data(datahead, 0, 0, 0, line);
445 }
446
447 yasm_dataval *
yasm_dv_create_expr(yasm_expr * e)448 yasm_dv_create_expr(yasm_expr *e)
449 {
450 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
451
452 retval->type = DV_VALUE;
453 yasm_value_initialize(&retval->data.val, e, 0);
454 retval->multiple = NULL;
455
456 return retval;
457 }
458
459 yasm_dataval *
yasm_dv_create_raw(unsigned char * contents,unsigned long len)460 yasm_dv_create_raw(unsigned char *contents, unsigned long len)
461 {
462 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
463
464 retval->type = DV_RAW;
465 retval->data.raw.contents = contents;
466 retval->data.raw.len = len;
467 retval->multiple = NULL;
468
469 return retval;
470 }
471
472 yasm_dataval *
yasm_dv_create_reserve(void)473 yasm_dv_create_reserve(void)
474 {
475 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
476
477 retval->type = DV_RESERVE;
478 retval->multiple = NULL;
479
480 return retval;
481 }
482
483 yasm_value *
yasm_dv_get_value(yasm_dataval * dv)484 yasm_dv_get_value(yasm_dataval *dv)
485 {
486 if (dv->type != DV_VALUE)
487 return NULL;
488 return &dv->data.val;
489 }
490
491 void
yasm_dv_set_multiple(yasm_dataval * dv,yasm_expr * e)492 yasm_dv_set_multiple(yasm_dataval *dv, yasm_expr *e)
493 {
494 if (dv->multiple)
495 dv->multiple = yasm_expr_create_tree( dv->multiple, YASM_EXPR_MUL, e,
496 e->line);
497 else
498 dv->multiple = e;
499 }
500
501 int
yasm_dv_get_multiple(yasm_dataval * dv,unsigned long * multiple)502 yasm_dv_get_multiple(yasm_dataval *dv, unsigned long *multiple)
503 {
504 /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
505
506 *multiple = 1;
507 if (dv->multiple) {
508 num = yasm_expr_get_intnum(&dv->multiple, 0);
509 if (!num) {
510 yasm_error_set(YASM_ERROR_VALUE,
511 N_("could not determine multiple"));
512 return 1;
513 }
514 if (yasm_intnum_sign(num) < 0) {
515 yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
516 return 1;
517 }
518 *multiple = yasm_intnum_get_uint(num);
519 }
520 return 0;
521 }
522
523 void
yasm_dvs_delete(yasm_datavalhead * headp)524 yasm_dvs_delete(yasm_datavalhead *headp)
525 {
526 yasm_dataval *cur, *next;
527
528 cur = STAILQ_FIRST(headp);
529 while (cur) {
530 next = STAILQ_NEXT(cur, link);
531 switch (cur->type) {
532 case DV_VALUE:
533 yasm_value_delete(&cur->data.val);
534 break;
535 case DV_RAW:
536 yasm_xfree(cur->data.raw.contents);
537 break;
538 default:
539 break;
540 }
541 if (cur->multiple)
542 yasm_expr_destroy(cur->multiple);
543 yasm_xfree(cur);
544 cur = next;
545 }
546 STAILQ_INIT(headp);
547 }
548
549 yasm_dataval *
yasm_dvs_append(yasm_datavalhead * headp,yasm_dataval * dv)550 yasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv)
551 {
552 if (dv) {
553 STAILQ_INSERT_TAIL(headp, dv, link);
554 return dv;
555 }
556 return (yasm_dataval *)NULL;
557 }
558
559 void
yasm_dvs_print(const yasm_datavalhead * head,FILE * f,int indent_level)560 yasm_dvs_print(const yasm_datavalhead *head, FILE *f, int indent_level)
561 {
562 yasm_dataval *cur;
563 unsigned long i;
564
565 STAILQ_FOREACH(cur, head, link) {
566 fprintf(f, "%*sMultiple=", indent_level, "");
567 if (!cur->multiple)
568 fprintf(f, "nil (1)");
569 else
570 yasm_expr_print(cur->multiple, f);
571 switch (cur->type) {
572 case DV_EMPTY:
573 fprintf(f, "%*sEmpty\n", indent_level, "");
574 break;
575 case DV_VALUE:
576 fprintf(f, "%*sValue:\n", indent_level, "");
577 yasm_value_print(&cur->data.val, f, indent_level+1);
578 break;
579 case DV_RAW:
580 fprintf(f, "%*sLength=%lu\n", indent_level, "",
581 cur->data.raw.len);
582 fprintf(f, "%*sBytes=[", indent_level, "");
583 for (i=0; i<cur->data.raw.len; i++)
584 fprintf(f, "0x%02x, ", cur->data.raw.contents[i]);
585 fprintf(f, "]\n");
586 break;
587 case DV_ULEB128:
588 fprintf(f, "%*sULEB128 value:\n", indent_level, "");
589 yasm_value_print(&cur->data.val, f, indent_level+1);
590 break;
591 case DV_SLEB128:
592 fprintf(f, "%*sSLEB128 value:\n", indent_level, "");
593 yasm_value_print(&cur->data.val, f, indent_level+1);
594 break;
595 case DV_RESERVE:
596 fprintf(f, "%*sReserved\n", indent_level, "");
597 break;
598 }
599 }
600 }
601