2 * $Id: unit.c,v 1.4 2007/07/22 13:33:26 khansen Exp $
4 * Revision 1.4 2007/07/22 13:33:26 khansen
5 * convert tabs to whitespaces
7 * Revision 1.3 2004/12/18 17:00:35 kenth
8 * improved error reporting slightly
10 * Revision 1.2 2004/12/16 13:20:07 kenth
13 * Revision 1.1 2004/06/30 07:56:00 kenth
19 * (C) 2004 Kent Hansen
21 * The XORcyst is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * The XORcyst is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with The XORcyst; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 #define SAFE_FREE(m) if ((m) != NULL) { free(m); m = NULL; }
43 /*---------------------------------------------------------------------------*/
46 #define get_1(f) (unsigned char)fgetc(fp)
47 /* Reads a short (big-endian) */
48 static unsigned short get_2(FILE *fp
)
50 unsigned short result
;
51 result
= get_1(fp
) << 8; /* High byte */
52 result
|= get_1(fp
); /* Low byte */
55 /* Reads a 24-bit integer (big-endian) */
56 static unsigned int get_3(FILE *fp
)
59 result
= get_2(fp
) << 8; /* High 16 bits */
60 result
|= get_1(fp
); /* Low byte */
63 /* Reads an int (big-endian) */
64 static unsigned int get_4(FILE *fp
)
67 /* Assumes little-endian machine!! */
68 result
= get_2(fp
) << 16; /* High 16 bits */
69 result
|= get_2(fp
); /* Low 16 bits */
72 /* Reads a string prepended by 8-bit length */
73 static char *get_str_8(FILE *fp
)
76 int len
= get_1(fp
) + 1;
77 s
= (char *)malloc(len
+ 1);
84 /* Reads a string prepended by 16-bit length */
85 static char *get_str_16(FILE *fp
)
88 int len
= get_2(fp
) + 1;
89 s
= (char *)malloc(len
+ 1);
96 #define get_bytes_8(f) (unsigned char *)get_str_8(f)
97 #define get_bytes_16(f) (unsigned char *)get_str_16(f)
99 /*--------------------------------------------------------------------------*/
102 * Reads a constant from file.
103 * @param fp File handle
104 * @param u Unit in which constant is loaded
105 * @param i Index of constant in unit's constant array
107 static void get_const(FILE *fp
, xasm_unit
*u
, int i
)
109 xasm_constant
*cnst
= &u
->constants
[i
];
110 cnst
->name
= get_str_8(fp
);
111 cnst
->type
= get_1(fp
);
112 switch (cnst
->type
) {
113 case XASM_INT_8
: cnst
->integer
= get_1(fp
); cnst
->type
= XASM_INTEGER_CONSTANT
; break;
114 case XASM_INT_16
: cnst
->integer
= get_2(fp
); cnst
->type
= XASM_INTEGER_CONSTANT
; break;
115 case XASM_INT_24
: cnst
->integer
= get_3(fp
); cnst
->type
= XASM_INTEGER_CONSTANT
; break;
116 case XASM_INT_32
: cnst
->integer
= get_4(fp
); cnst
->type
= XASM_INTEGER_CONSTANT
; break;
117 case XASM_STR_8
: cnst
->string
= get_str_8(fp
); cnst
->type
= XASM_STRING_CONSTANT
; break;
118 case XASM_STR_16
: cnst
->string
= get_str_16(fp
); cnst
->type
= XASM_STRING_CONSTANT
; break;
121 fprintf(stderr
, "%s(0x%lx): get_const(): bad constant type (%.2X)\n", u
->name
, ftell(fp
), cnst
->type
);
128 * Reads constant array from file.
129 * @param fp File handle
130 * @param u Unit whose constants array will be populated
132 static void get_constants(FILE *fp
, xasm_unit
*u
)
135 int count
= get_2(fp
);
137 u
->constants
= (xasm_constant
*)malloc(sizeof(xasm_constant
) * count
);
141 for (i
=0; i
<count
; i
++) {
144 u
->const_count
= count
;
148 * Reads imported symbol from file.
149 * @param fp File handle
151 * @param i External index
153 static void get_ext(FILE *fp
, xasm_unit
*u
, int i
)
155 xasm_external
*ext
= &u
->externals
[i
];
156 ext
->unit
= get_1(fp
);
157 ext
->name
= get_str_8(fp
);
162 * Reads imported symbol array from file.
163 * @param fp File handle
164 * @param u Unit whose externals array will be populated
166 static void get_externals(FILE *fp
, xasm_unit
*u
)
172 u
->externals
= (xasm_external
*)malloc(sizeof(xasm_external
) * count
);
176 for (i
=0; i
<count
; i
++) {
179 u
->ext_count
= count
;
183 * Reads an expression from file.
184 * @param fp File handle
185 * @param dest Pointer to pointer where expression should be stored
186 * @param u Owner unit
188 static void get_expr_recursive(FILE *fp
, xasm_expression
**dest
, xasm_unit
*u
)
191 xasm_expression
*exp
= (xasm_expression
*)malloc( sizeof(xasm_expression
) );
195 case XASM_INT_8
: exp
->integer
= get_1(fp
); exp
->type
= XASM_INTEGER_EXPRESSION
; break;
196 case XASM_INT_16
: exp
->integer
= get_2(fp
); exp
->type
= XASM_INTEGER_EXPRESSION
; break;
197 case XASM_INT_24
: exp
->integer
= get_3(fp
); exp
->type
= XASM_INTEGER_EXPRESSION
; break;
198 case XASM_INT_32
: exp
->integer
= get_4(fp
); exp
->type
= XASM_INTEGER_EXPRESSION
; break;
199 case XASM_STR_8
: exp
->string
= get_str_8(fp
); exp
->type
= XASM_STRING_EXPRESSION
; break;
200 case XASM_STR_16
: exp
->string
= get_str_16(fp
); exp
->type
= XASM_STRING_EXPRESSION
; break;
202 case XASM_LOCAL
: exp
->local_id
= get_2(fp
); exp
->type
= XASM_LOCAL_EXPRESSION
; break;
203 case XASM_EXTRN
: exp
->extrn_id
= get_2(fp
); exp
->type
= XASM_EXTERNAL_EXPRESSION
;break;
205 case XASM_PC
: ; exp
->type
= XASM_PC_EXPRESSION
; break;
223 get_expr_recursive(fp
, &exp
->op_expr
.lhs
, u
);
224 get_expr_recursive(fp
, &exp
->op_expr
.rhs
, u
);
225 exp
->op_expr
.operator = type
;
226 exp
->type
= XASM_OPERATOR_EXPRESSION
;
235 get_expr_recursive(fp
, &exp
->op_expr
.lhs
, u
);
236 exp
->op_expr
.rhs
= NULL
;
237 exp
->op_expr
.operator = type
;
238 exp
->type
= XASM_OPERATOR_EXPRESSION
;
242 fprintf(stderr
, "%s(0x%lx): get_expr(): invalid expression type (%.2X)\n", u
->name
, ftell(fp
), type
);
244 exp
->type
= XASM_INTEGER_EXPRESSION
;
253 * Reads expressions from file.
254 * @param fp File handle
255 * @param u Unit whose expressions array to populate
257 static void get_expressions(FILE *fp
, xasm_unit
*u
)
263 u
->expressions
= (xasm_expression
**)malloc(sizeof(xasm_expression
*) * count
);
265 u
->expressions
= NULL
;
267 for (i
=0; i
<count
; i
++) {
268 get_expr_recursive(fp
, &u
->expressions
[i
], u
);
270 u
->expr_count
= count
;
274 * Reads a segment from file.
275 * @param fp File handle
276 * @param seg Where to store segment
278 static void get_segment(FILE *fp
, xasm_segment
*seg
)
280 seg
->size
= get_3(fp
);
282 seg
->bytes
= (unsigned char *)malloc(seg
->size
);
283 if (seg
->bytes
!= NULL
) {
284 fread(seg
->bytes
, 1, seg
->size
, fp
);
291 /*--------------------------------------------------------------------------*/
294 * Reads a unit from file.
295 * @param filename Name of the unit
296 * @param u Pointer to struct to fill in
298 int xasm_unit_read(char *filename
, xasm_unit
*u
)
302 unsigned short magic
;
303 unsigned char version
;
306 fp
= fopen(filename
, "rb");
312 u
->dataseg
.bytes
= NULL
;
314 u
->codeseg
.bytes
= NULL
;
319 if (magic
!= XASM_MAGIC
) {
320 /* Error, bad magic number */
325 if (version
!= XASM_OBJ_VERSION
) {
326 /* Error, bad version */
330 get_constants(fp
, u
);
332 /* Read # of units explicitly imported from */
334 /* Read unit names */
335 for (i
=0; i
<count
; i
++) {
339 get_externals(fp
, u
);
340 get_segment(fp
, &u
->dataseg
);
341 get_segment(fp
, &u
->codeseg
);
342 get_expressions(fp
, u
);
350 /*--------------------------------------------------------------------------*/
353 * Finalizes a constant.
354 * @param c Constant to finalize
356 static void finalize_constant(xasm_constant
*c
)
358 if (c
->type
== XASM_STRING_CONSTANT
) {
359 SAFE_FREE(c
->string
);
365 * Finalizes an external.
366 * @param e External to finalize
368 static void finalize_external(xasm_external
*e
)
374 * Finalizes an expression.
375 * @param e Expression to finalize
377 static void finalize_expression(xasm_expression
*e
)
379 if (e
== NULL
) { return; }
381 case XASM_STRING_EXPRESSION
:
382 SAFE_FREE(e
->string
);
385 case XASM_OPERATOR_EXPRESSION
:
386 finalize_expression(e
->op_expr
.lhs
);
387 finalize_expression(e
->op_expr
.rhs
);
398 * Finalizes a bytecode segment.
399 * @param s Segment to finalize
401 static void finalize_segment(xasm_segment
*s
)
406 /*--------------------------------------------------------------------------*/
410 * @param u Unit to finalize
412 void xasm_unit_finalize(xasm_unit
*u
)
415 for (i
=0; i
<u
->const_count
; i
++) {
416 finalize_constant(&u
->constants
[i
]);
418 SAFE_FREE(u
->constants
);
420 for (i
=0; i
<u
->ext_count
; i
++) {
421 finalize_external(&u
->externals
[i
]);
423 SAFE_FREE(u
->externals
);
425 for (i
=0; i
<u
->expr_count
; i
++) {
426 finalize_expression(u
->expressions
[i
]);
428 SAFE_FREE(u
->expressions
);
430 finalize_segment(&u
->dataseg
);
431 finalize_segment(&u
->codeseg
);
435 * Gets string representation of an operator (OP_*, see objdef.h).
437 * @return String representation of operator
439 const char *xasm_operator_to_string(int op
)
442 case XASM_OP_PLUS
: return "+";
443 case XASM_OP_MINUS
: return "-";
444 case XASM_OP_MUL
: return "*";
445 case XASM_OP_DIV
: return "/";
446 case XASM_OP_MOD
: return "%";
447 case XASM_OP_SHL
: return "<<";
448 case XASM_OP_SHR
: return ">>";
449 case XASM_OP_AND
: return "&";
450 case XASM_OP_OR
: return "|";
451 case XASM_OP_XOR
: return "^";
452 case XASM_OP_EQ
: return "==";
453 case XASM_OP_NE
: return "!=";
454 case XASM_OP_LT
: return "<";
455 case XASM_OP_GT
: return ">";
456 case XASM_OP_LE
: return "<=";
457 case XASM_OP_GE
: return ">=";
458 case XASM_OP_NOT
: return "!";
459 case XASM_OP_NEG
: return "~";
460 case XASM_OP_LO
: return "<";
461 case XASM_OP_HI
: return ">";
462 case XASM_OP_UMINUS
: return "-";
463 case XASM_OP_BANK
: return "^";