9 date 2007.07.22.13.33.26; author khansen; state Exp;
14 date 2004.12.18.17.00.35; author kenth; state Exp;
19 date 2004.12.16.13.20.07; author kenth; state Exp;
24 date 2004.06.30.07.56.00; author kenth; state Exp;
35 @convert tabs to whitespaces
39 * $Id: unit.c,v 1.3 2004/12/18 17:00:35 kenth Exp $
41 * Revision 1.3 2004/12/18 17:00:35 kenth
42 * improved error reporting slightly
44 * Revision 1.2 2004/12/16 13:20:07 kenth
47 * Revision 1.1 2004/06/30 07:56:00 kenth
53 * (C) 2004 Kent Hansen
55 * The XORcyst is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
57 * the Free Software Foundation; either version 2 of the License, or
58 * (at your option) any later version.
60 * The XORcyst is distributed in the hope that it will be useful,
61 * but WITHOUT ANY WARRANTY; without even the implied warranty of
62 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 * GNU General Public License for more details.
65 * You should have received a copy of the GNU General Public License
66 * along with The XORcyst; if not, write to the Free Software
67 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
75 #define SAFE_FREE(m) if ((m) != NULL) { free(m); m = NULL; }
77 /*---------------------------------------------------------------------------*/
80 #define get_1(f) (unsigned char)fgetc(fp)
81 /* Reads a short (big-endian) */
82 static unsigned short get_2(FILE *fp)
84 unsigned short result;
85 result = get_1(fp) << 8; /* High byte */
86 result |= get_1(fp); /* Low byte */
89 /* Reads a 24-bit integer (big-endian) */
90 static unsigned int get_3(FILE *fp)
93 result = get_2(fp) << 8; /* High 16 bits */
94 result |= get_1(fp); /* Low byte */
97 /* Reads an int (big-endian) */
98 static unsigned int get_4(FILE *fp)
101 /* Assumes little-endian machine!! */
102 result = get_2(fp) << 16; /* High 16 bits */
103 result |= get_2(fp); /* Low 16 bits */
106 /* Reads a string prepended by 8-bit length */
107 static char *get_str_8(FILE *fp)
111 int len = get_1(fp) + 1;
112 /* Allocate space for string */
113 s = (char *)malloc(len + 1);
115 /* Read string from file */
116 fread(s, 1, len, fp);
117 /* 0-terminate string */
120 /* Return the new string */
123 /* Reads a string prepended by 16-bit length */
124 static char *get_str_16(FILE *fp)
128 int len = get_2(fp) + 1;
129 /* Allocate space for string */
130 s = (char *)malloc(len + 1);
132 /* Read string from file */
133 fread(s, 1, len, fp);
135 /* Return the new string */
138 #define get_bytes_8(f) (unsigned char *)get_str_8(f)
139 #define get_bytes_16(f) (unsigned char *)get_str_16(f)
141 /*--------------------------------------------------------------------------*/
144 * Reads a constant from file.
145 * @@param fp File handle
146 * @@param u Unit in which constant is loaded
147 * @@param i Index of constant in unit's constant array
149 static void get_const(FILE *fp, unit *u, int i)
151 constant *cnst = &u->constants[i];
153 cnst->name = get_str_8(fp);
155 cnst->type = get_1(fp);
157 switch (cnst->type) {
158 case INT_8: cnst->integer = get_1(fp); cnst->type = INTEGER_CONSTANT; break;
159 case INT_16: cnst->integer = get_2(fp); cnst->type = INTEGER_CONSTANT; break;
160 case INT_24: cnst->integer = get_3(fp); cnst->type = INTEGER_CONSTANT; break;
161 case INT_32: cnst->integer = get_4(fp); cnst->type = INTEGER_CONSTANT; break;
162 case STR_8: cnst->string = get_str_8(fp); cnst->type = STRING_CONSTANT; break;
163 case STR_16: cnst->string = get_str_16(fp); cnst->type = STRING_CONSTANT; break;
166 /* Error, invalid type */
167 fprintf(stderr, "%s(0x%lx): get_const(): bad constant type (%.2X)\n", u->name, ftell(fp), cnst->type);
175 * Reads constant array from file.
176 * @@param fp File handle
177 * @@param u Unit whose constants array will be populated
179 static void get_constants(FILE *fp, unit *u)
182 /* Read the number of constants */
183 int count = get_2(fp);
184 /* Allocate the list */
186 u->constants = (constant *)malloc(sizeof(constant) * count);
192 for (i=0; i<count; i++) {
195 /* Set count field */
196 u->const_count = count;
200 * Reads imported symbol from file.
201 * @@param fp File handle
203 * @@param i External index
205 static void get_ext(FILE *fp, unit *u, int i)
207 external *ext = &u->externals[i];
209 ext->unit = get_1(fp);
211 ext->name = get_str_8(fp);
217 * Reads imported symbol array from file.
218 * @@param fp File handle
219 * @@param u Unit whose externals array will be populated
221 static void get_externals(FILE *fp, unit *u)
225 /* Read the number of imported symbols */
227 /* Allocate the list */
229 u->externals = (external *)malloc(sizeof(external) * count);
234 /* Read imported symbols */
235 for (i=0; i<count; i++) {
238 /* Set count field */
239 u->ext_count = count;
243 * Reads an expression from file.
244 * @@param fp File handle
245 * @@param dest Pointer to pointer where expression should be stored
246 * @@param u Owner unit
248 static void get_expr_recursive(FILE *fp, expression **dest, unit *u)
251 /* Allocate space for expression */
252 expression *exp = (expression *)malloc( sizeof(expression) );
254 /* Read expression type */
259 case INT_8: exp->integer = get_1(fp); exp->type = INTEGER_EXPRESSION; break;
260 case INT_16: exp->integer = get_2(fp); exp->type = INTEGER_EXPRESSION; break;
261 case INT_24: exp->integer = get_3(fp); exp->type = INTEGER_EXPRESSION; break;
262 case INT_32: exp->integer = get_4(fp); exp->type = INTEGER_EXPRESSION; break;
263 case STR_8: exp->string = get_str_8(fp); exp->type = STRING_EXPRESSION; break;
264 case STR_16: exp->string = get_str_16(fp); exp->type = STRING_EXPRESSION; break;
267 case LOCAL: exp->local_id = get_2(fp); exp->type = LOCAL_EXPRESSION; break;
268 case EXTRN: exp->extrn_id = get_2(fp); exp->type = EXTERNAL_EXPRESSION;break;
270 /* Current address */
271 case PC: ; exp->type = PC_EXPRESSION; break;
273 /* Arithmetic, binary */
290 get_expr_recursive(fp, &exp->op_expr.lhs, u);
291 get_expr_recursive(fp, &exp->op_expr.rhs, u);
292 exp->op_expr.operator = type;
293 exp->type = OPERATOR_EXPRESSION;
296 /* Arithmetic, unary */
303 get_expr_recursive(fp, &exp->op_expr.lhs, u);
304 exp->op_expr.rhs = NULL;
305 exp->op_expr.operator = type;
306 exp->type = OPERATOR_EXPRESSION;
310 fprintf(stderr, "%s(0x%lx): get_expr(): invalid expression type (%.2X)\n", u->name, ftell(fp), type);
312 exp->type = INTEGER_EXPRESSION;
318 /* Set result pointer */
323 * Reads expressions from file.
324 * @@param fp File handle
325 * @@param u Unit whose expressions array to populate
327 static void get_expressions(FILE *fp, unit *u)
331 /* Read the number of expressions */
333 /* Allocate the list */
335 u->expressions = (expression **)malloc(sizeof(expression *) * count);
338 u->expressions = NULL;
340 /* Read expressions */
341 for (i=0; i<count; i++) {
342 get_expr_recursive(fp, &u->expressions[i], u);
345 u->expr_count = count;
349 * Reads a segment from file.
350 * @@param fp File handle
351 * @@param seg Where to store segment
353 static void get_segment(FILE *fp, segment *seg)
356 seg->size = get_3(fp);
359 /* Allocate mem for bytecodes */
360 seg->bytes = (unsigned char *)malloc(seg->size);
361 if (seg->bytes != NULL) {
363 fread(seg->bytes, 1, seg->size, fp);
371 /*--------------------------------------------------------------------------*/
374 * Reads a unit from file.
375 * @@param filename Name of the unit
376 * @@param u Pointer to struct to fill in
378 int unit_read(char *filename, unit *u)
382 unsigned short magic;
383 unsigned char version;
387 /* Attempt to open file */
388 fp = fopen(filename, "rb");
390 /* Error, couldn't open it */
395 u->dataseg.bytes = NULL;
397 u->codeseg.bytes = NULL;
400 /* Read magic number */
402 /* Verify magic number */
403 if (magic != A_MAGIC) {
404 /* Error, bad magic number */
409 /* Verify version: should be 1.0 */
410 if (version != A_VERSION) {
411 /* Error, bad version */
414 /* Read exported constants */
415 get_constants(fp, u);
416 /* Read # of units explicitly imported from */
418 /* Read unit names */
419 for (i=0; i<count; i++) {
422 /* Read imported symbols */
423 get_externals(fp, u);
425 get_segment(fp, &u->dataseg);
427 get_segment(fp, &u->codeseg);
428 /* Read expressions */
429 get_expressions(fp, u);
438 /*--------------------------------------------------------------------------*/
441 * Finalizes a constant.
442 * @@param c Constant to finalize
444 static void finalize_constant(constant *c)
446 if (c->type == STRING_CONSTANT) {
447 SAFE_FREE(c->string);
453 * Finalizes an external.
454 * @@param e External to finalize
456 static void finalize_external(external *e)
462 * Finalizes an expression.
463 * @@param e Expression to finalize
465 static void finalize_expression(expression *e)
467 if (e == NULL) { return; }
469 case STRING_EXPRESSION:
470 SAFE_FREE(e->string);
473 case OPERATOR_EXPRESSION:
474 finalize_expression(e->op_expr.lhs);
475 finalize_expression(e->op_expr.rhs);
486 * Finalizes a bytecode segment.
487 * @@param s Segment to finalize
489 static void finalize_segment(segment *s)
494 /*--------------------------------------------------------------------------*/
498 * @@param u Unit to finalize
500 void unit_finalize(unit *u)
503 /* Finalize the constants */
504 for (i=0; i<u->const_count; i++) {
505 finalize_constant(&u->constants[i]);
507 SAFE_FREE(u->constants);
508 /* Finalize the externals */
509 for (i=0; i<u->ext_count; i++) {
510 finalize_external(&u->externals[i]);
512 SAFE_FREE(u->externals);
513 /* Finalize expressions */
514 for (i=0; i<u->expr_count; i++) {
515 finalize_expression(u->expressions[i]);
517 SAFE_FREE(u->expressions);
518 /* Finalize bytecode segments */
519 finalize_segment(&u->dataseg);
520 finalize_segment(&u->codeseg);
527 @improved error reporting slightly
532 * $Id: unit.c,v 1.2 2004/12/16 13:20:07 kenth Exp kenth $
536 unsigned short result;
537 result = get_1(fp) << 8; /* High byte */
538 result |= get_1(fp); /* Low byte */
543 result = get_2(fp) << 8; /* High 16 bits */
544 result |= get_1(fp); /* Low byte */
549 /* Assumes little-endian machine!! */
550 result = get_2(fp) << 16; /* High 16 bits */
551 result |= get_2(fp); /* Low 16 bits */
557 int len = get_1(fp) + 1;
558 /* Allocate space for string */
559 s = (char *)malloc(len + 1);
561 /* Read string from file */
562 fread(s, 1, len, fp);
563 /* 0-terminate string */
566 /* Return the new string */
572 int len = get_2(fp) + 1;
573 /* Allocate space for string */
574 s = (char *)malloc(len + 1);
576 /* Read string from file */
577 fread(s, 1, len, fp);
579 /* Return the new string */
583 constant *cnst = &u->constants[i];
585 cnst->name = get_str_8(fp);
587 cnst->type = get_1(fp);
589 switch (cnst->type) {
590 case INT_8: cnst->integer = get_1(fp); cnst->type = INTEGER_CONSTANT; break;
591 case INT_16: cnst->integer = get_2(fp); cnst->type = INTEGER_CONSTANT; break;
592 case INT_24: cnst->integer = get_3(fp); cnst->type = INTEGER_CONSTANT; break;
593 case INT_32: cnst->integer = get_4(fp); cnst->type = INTEGER_CONSTANT; break;
594 case STR_8: cnst->string = get_str_8(fp); cnst->type = STRING_CONSTANT; break;
595 case STR_16: cnst->string = get_str_16(fp); cnst->type = STRING_CONSTANT; break;
598 /* Error, invalid type */
599 fprintf(stderr, "%s(0x%lx): get_const(): bad constant type (%.2X)\n", u->name, ftell(fp), cnst->type);
607 /* Read the number of constants */
608 int count = get_2(fp);
609 /* Allocate the list */
611 u->constants = (constant *)malloc(sizeof(constant) * count);
617 for (i=0; i<count; i++) {
620 /* Set count field */
621 u->const_count = count;
624 external *ext = &u->externals[i];
626 ext->unit = get_1(fp);
628 ext->name = get_str_8(fp);
635 /* Read the number of imported symbols */
637 /* Allocate the list */
639 u->externals = (external *)malloc(sizeof(external) * count);
644 /* Read imported symbols */
645 for (i=0; i<count; i++) {
648 /* Set count field */
649 u->ext_count = count;
653 /* Allocate space for expression */
654 expression *exp = (expression *)malloc( sizeof(expression) );
656 /* Read expression type */
661 case INT_8: exp->integer = get_1(fp); exp->type = INTEGER_EXPRESSION; break;
662 case INT_16: exp->integer = get_2(fp); exp->type = INTEGER_EXPRESSION; break;
663 case INT_24: exp->integer = get_3(fp); exp->type = INTEGER_EXPRESSION; break;
664 case INT_32: exp->integer = get_4(fp); exp->type = INTEGER_EXPRESSION; break;
665 case STR_8: exp->string = get_str_8(fp); exp->type = STRING_EXPRESSION; break;
666 case STR_16: exp->string = get_str_16(fp); exp->type = STRING_EXPRESSION; break;
669 case LOCAL: exp->local_id = get_2(fp); exp->type = LOCAL_EXPRESSION; break;
670 case EXTRN: exp->extrn_id = get_2(fp); exp->type = EXTERNAL_EXPRESSION;break;
672 /* Current address */
673 case PC: ; exp->type = PC_EXPRESSION; break;
675 /* Arithmetic, binary */
692 get_expr_recursive(fp, &exp->op_expr.lhs, u);
693 get_expr_recursive(fp, &exp->op_expr.rhs, u);
694 exp->op_expr.operator = type;
695 exp->type = OPERATOR_EXPRESSION;
698 /* Arithmetic, unary */
705 get_expr_recursive(fp, &exp->op_expr.lhs, u);
706 exp->op_expr.rhs = NULL;
707 exp->op_expr.operator = type;
708 exp->type = OPERATOR_EXPRESSION;
712 fprintf(stderr, "%s(0x%lx): get_expr(): invalid expression type (%.2X)\n", u->name, ftell(fp), type);
714 exp->type = INTEGER_EXPRESSION;
720 /* Set result pointer */
726 /* Read the number of expressions */
728 /* Allocate the list */
730 u->expressions = (expression **)malloc(sizeof(expression *) * count);
733 u->expressions = NULL;
735 /* Read expressions */
736 for (i=0; i<count; i++) {
737 get_expr_recursive(fp, &u->expressions[i], u);
740 u->expr_count = count;
744 seg->size = get_3(fp);
747 /* Allocate mem for bytecodes */
748 seg->bytes = (unsigned char *)malloc(seg->size);
749 if (seg->bytes != NULL) {
751 fread(seg->bytes, 1, seg->size, fp);
761 unsigned short magic;
762 unsigned char version;
766 /* Attempt to open file */
767 fp = fopen(filename, "rb");
769 /* Error, couldn't open it */
774 u->dataseg.bytes = NULL;
776 u->codeseg.bytes = NULL;
779 /* Read magic number */
781 /* Verify magic number */
782 if (magic != A_MAGIC) {
783 /* Error, bad magic number */
788 /* Verify version: should be 1.0 */
789 if (version != A_VERSION) {
790 /* Error, bad version */
793 /* Read exported constants */
794 get_constants(fp, u);
795 /* Read # of units explicitly imported from */
797 /* Read unit names */
798 for (i=0; i<count; i++) {
801 /* Read imported symbols */
802 get_externals(fp, u);
804 get_segment(fp, &u->dataseg);
806 get_segment(fp, &u->codeseg);
807 /* Read expressions */
808 get_expressions(fp, u);
819 if (c->type == STRING_CONSTANT) {
820 SAFE_FREE(c->string);
828 if (e == NULL) { return; }
830 case STRING_EXPRESSION:
831 SAFE_FREE(e->string);
834 case OPERATOR_EXPRESSION:
835 finalize_expression(e->op_expr.lhs);
836 finalize_expression(e->op_expr.rhs);
850 /* Finalize the constants */
851 for (i=0; i<u->const_count; i++) {
852 finalize_constant(&u->constants[i]);
854 SAFE_FREE(u->constants);
855 /* Finalize the externals */
856 for (i=0; i<u->ext_count; i++) {
857 finalize_external(&u->externals[i]);
859 SAFE_FREE(u->externals);
860 /* Finalize expressions */
861 for (i=0; i<u->expr_count; i++) {
862 finalize_expression(u->expressions[i]);
864 SAFE_FREE(u->expressions);
865 /* Finalize bytecode segments */
866 finalize_segment(&u->dataseg);
867 finalize_segment(&u->codeseg);
878 * $Id: unit.c,v 1.1 2004/06/30 07:56:00 kenth Exp kenth $
882 printf("get_const(): bad type\n");
885 printf("get_expr: invalid expression type\n");
900 * @@param cnst Pointer to struct where constant will be loaded
903 static void get_const(FILE *fp, constant *cnst)
908 * @@param list Pointer to array where constants will be stored
909 * @@return Number of constants read
912 static int get_constants(FILE *fp, constant **list)
915 *list = (constant *)malloc(sizeof(constant) * count);
921 get_const(fp, &((*list)[i]));
924 /* Return the number of constants read */
928 * @@param ext Pointer to struct where external info will be stored
931 static void get_ext(FILE *fp, external *ext)
936 * @@param list Pointer to array where external infos will be stored
939 static int get_externals(FILE *fp, external **list)
942 *list = (external *)malloc(sizeof(external) * count);
948 get_ext(fp, &((*list)[i]));
951 /* Return the number of imported symbols read */
956 static void get_expr(FILE *fp, expression **dest)
959 get_expr(fp, &exp->op_expr.lhs);
960 get_expr(fp, &exp->op_expr.rhs);
963 get_expr(fp, &exp->op_expr.lhs);
968 * @@param list Pointer to array of pointers where expressions will be stored
969 * @@return Number of expressions read
972 static int get_expressions(FILE *fp, expression ***list)
975 *list = (expression **)malloc(sizeof(expression *) * count);
981 get_expr(fp, &((*list)[i]));
984 /* Return the number of expressions read */
988 u->const_count = get_constants(fp, &u->constants);
991 u->ext_count = get_externals(fp, &u->externals);
994 u->expr_count = get_expressions(fp, &u->expressions);