Example #1
0
//deletes a statement and all of its pointers
void stmt_delete(struct stmt *s){
	if(!s) return;
	decl_delete(s->decl);
	expr_delete(s->init_expr);
	expr_delete(s->expr);
	expr_delete(s->next_expr);
	stmt_delete(s->body);
	stmt_delete(s->else_body);

	free(s);
}
Example #2
0
void expr_delete( struct expr *e )
{
	/* Careful: Stop on null pointer. */
	if(!e) return;
	expr_delete(e->next);
	expr_delete(e->left);
	expr_delete(e->right);
	if (e->name) free(e->name);
	if (e->string_literal) free(e->string_literal);
	free ( e );
}
Example #3
0
void decl_delete( struct decl *d )
{
	if (!d) return;
	free( d-> name );
	type_delete( d->type );
	expr_delete( d->value );
	stmt_delete( d->code );
	decl_delete( d->next );
	free( d );
}
Example #4
0
void expr_delete(struct expr* e)
{
	// Handle the expression components.
	switch (e->type)
	{
		case EXPR_NUMBER:
			// Don't need to free any children components.
			break;
		case EXPR_LABEL:
			// Need to free the bstring.
			bdestroy((bstring)e->data);
			break;
		case EXPR_EXPR:
			// Need to free each child expression recursively.
			expr_delete(e->a);
			expr_delete(e->b);
			break;
	}

	// Free the expression itself.
	free(e);
}
Example #5
0
static void
destructor(stmt_ty *sp)
{
    stmt_command_ty *this;

    trace(("destructor(sp = %08X)\n{\n", sp));
    /* assert(sp); */
    /* assert(sp->method == &method); */
    this = (stmt_command_ty *)sp;

    expr_list_destructor(&this->args);
    expr_list_destructor(&this->flags);
    if (this->input)
        expr_delete(this->input);
    expr_position_destructor(&this->pos);

    trace(("}\n"));
}
Example #6
0
//recursively delete an expression tree
void expr_delete(struct expr *e){
	if(!e) return;
	expr_delete(e->left);
	expr_delete(e->right);
	free(e);
}
Example #7
0
uint16_t aout_write(FILE* out, bool relocatable, bool intermediate)
{
	struct aout_byte* current_outer;
	struct aout_byte* current_inner;
	struct lprov_entry* linker_provided = NULL;
	struct lprov_entry* linker_required = NULL;
	struct lprov_entry* linker_adjustment = NULL;
	struct lprov_entry* linker_section = NULL;
	struct lprov_entry* linker_output = NULL;
	struct lprov_entry* linker_temp = NULL;
	uint32_t mem_index, out_index;
	uint16_t inst;
	BFILE* temp = NULL;
	bstring bname, ename;
	uint16_t eaddr;
	bool did_find;
	bool shown_expr_warning = false;
	bool has_output = false;

	// Initialize out our extension table.
	code_offset += textn_init(start);

	// If relocatable, initialize out our relocation table.
	if (relocatable)
		code_offset += treloc_init(start);

	// First go through and evaluate all expressions that need to be.
	current_outer = start;
	out_index = code_offset;
	while (current_outer != NULL)
	{
		if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN)
		{
			// Adjust memory address.
			out_index = current_outer->opcode;
		}
		else if (current_outer->type == AOUT_TYPE_METADATA_SECTION)
		{
			assert(current_outer->label != NULL);

			// We're exporting the current address as the beginning
			// of a section.
			if (!intermediate)
				ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL);

			// Check to make sure outputs haven't previously been emitted.
			if (has_output)
				ahalt(ERR_OUTPUT_BEFORE_SECTION, NULL);

			// Create linker entry.
			linker_temp = lprov_create(current_outer->label, out_index);
			linker_temp->next = linker_section;
			linker_section = linker_temp;
			printd(LEVEL_VERBOSE, "LINK SECTION %s -> 0x%04X\n", current_outer->label, out_index);
		}
		else if (current_outer->type == AOUT_TYPE_METADATA_OUTPUT)
		{
			assert(current_outer->label != NULL);

			// We're exporting the current address as the beginning
			// of a section.
			if (!intermediate)
				ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL);

			// Create linker entry.
			has_output = true;
			linker_temp = lprov_create(current_outer->label, out_index);
			linker_temp->next = linker_output;
			linker_output = linker_temp;
			printd(LEVEL_VERBOSE, "LINK OUTPUT 0x%04X -> %s\n", out_index, current_outer->label);
		}
		else if (current_outer->type == AOUT_TYPE_METADATA_EXPORT)
		{
			assert(current_outer->label != NULL);

			// We're exporting the address of this label in the
			// object table.
			if (!intermediate)
				ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL);

			// Resolve label position.
			ename = bfromcstr(current_outer->label);
			eaddr = aout_get_label_address(ename);
			bdestroy(ename);

			// Create linker entry.
			linker_temp = lprov_create(current_outer->label, eaddr);
			linker_temp->next = linker_provided;
			linker_provided = linker_temp;
			printd(LEVEL_VERBOSE, "LINK REPLACE %s -> 0x%04X\n", current_outer->label, eaddr);
		}
		else if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->expr != NULL)
		{
			if (current_outer->expr->type != EXPR_LABEL)
			{
				// This is either just a number or a more complicated expression, so
				// evaluate it using the preprocessor expression engine.
				if ((relocatable || intermediate) && !shown_expr_warning)
				{
					printd(LEVEL_WARNING, "warning: expressions will not be adjusted at link or relocation time.\n");
					printd(LEVEL_WARNING, "		ensure labels are not used as part of expressions.\n");
					shown_expr_warning = true;
				}
				current_outer->raw_used = true;
				current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler);
				expr_delete(current_outer->expr);
				current_outer->expr = NULL;
			}
			else
			{
				// If this is just a label, we can handle it directly (this allows
				// us to handle imported labels in intermediate code).
				current_inner = start;
				mem_index = code_offset;
				did_find = false;

				// Search for .IMPORT directives first.
				while (current_inner != NULL)
				{
					if (current_inner->type == AOUT_TYPE_METADATA_ORIGIN)
					{
						// Adjust memory address.
						mem_index = current_inner->opcode;
					}
					else if (current_inner->type == AOUT_TYPE_METADATA_IMPORT)
					{
						// An imported label (we don't need to adjust
						// memory index because the existance of this type
						// of entry doesn't affect executable size).
						if (!intermediate)
							ahalt(ERR_NOT_GENERATING_INTERMEDIATE_CODE, NULL);

						assert(current_outer->expr->data != NULL);
						if (strcmp(current_inner->label, ((bstring)current_outer->expr->data)->data) == 0)
						{
							// We don't actually know our position yet;
							// that will be handled by the linker!
							current_outer->raw = 0xFFFF;
							expr_delete(current_outer->expr);
							current_outer->expr = NULL;
							linker_temp = lprov_create(current_inner->label, out_index);
							linker_temp->next = linker_required;
							linker_required = linker_temp;
							printd(LEVEL_VERBOSE, "LINK REPLACE 0x%04X -> %s\n", out_index, current_inner->label);
							did_find = true;
							break;
						}
					}

					// Goto next.
					current_inner = current_inner->next;
				}

				// If it wasn't found in the .IMPORT directives, try searching
				// labels directly using the expression engine.
				if (!did_find)
				{
					// Replace the label position.
					current_outer->raw_used = true;
					current_outer->raw = expr_evaluate(current_outer->expr, &aout_get_label_address, &ahalt_expression_exit_handler);
					expr_delete(current_outer->expr);
					current_outer->expr = NULL;
					did_find = true;

					// We also need to add this entry to the adjustment
					// table for the linker since it also needs to adjust
					// internal label jumps in files when it concatenates
					// all of the object code together.
					linker_temp = lprov_create(NULL, out_index);
					linker_temp->next = linker_adjustment;
					linker_adjustment = linker_temp;
					printd(LEVEL_VERBOSE, "LINK ADJUST 0x%04X\n", out_index);
				}
			}
		}

		if (current_outer->type == AOUT_TYPE_NORMAL && current_outer->label == NULL)
			out_index += 1;

		current_outer = current_outer->next;
	}

	// If intermediate, we need to write out our linker table
	// as the absolute first thing in the file.
	if (intermediate)
	{
		fwrite(ldata_objfmt, 1, strlen(ldata_objfmt) + 1, out);
		objfile_save(out, linker_provided, linker_required, linker_adjustment, linker_section, linker_output);

		// Adjust the "true origin" for .ORIGIN directivies because
		// the linker table won't exist in the final result when
		// linked.
		true_origin = (uint16_t)ftell(out);
	}

	// Write out our extension table.
	textn_write(out);

	// If relocatable, write out our relocation table.
	if (relocatable)
		treloc_write(out);

	// Now write to the file.
	current_outer = start;

	while (current_outer != NULL)
	{
		if (current_outer->type == AOUT_TYPE_METADATA_ORIGIN)
		{
			// Adjust origin.
			fseek(out, true_origin + current_outer->opcode * 2 /* double because the number is in words, not bytes */, SEEK_SET);
		}
		else if (current_outer->type == AOUT_TYPE_METADATA_INCBIN)
		{
			// Include binary file.
			bname = ppfind_locate(bautofree(bfromcstr(current_outer->label)));

			if (bname == NULL)
				ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label);

			temp = bfopen((const char*)(bname->data), "rb");

			if (temp == NULL)
				ahalt(ERR_UNABLE_TO_INCBIN, current_outer->label);

			// Copy binary data.
			while (!bfeof(temp))
			{
				// TODO: This could be faster if we didn't do it character
				// by character.
				fputc(bfgetc(temp), out);
			}

			// Finalize.
			bfclose(temp);
			bdestroy(bname);
		}
		else if (current_outer->type == AOUT_TYPE_NORMAL)
		{
			// Update the debugging symbol.
			dbgfmt_update_symbol_list(&current_outer->symbols, (uint16_t)((ftell(out) - true_origin) / 2));

			// Normal output.
			if (current_outer->raw_used == true)
			{
				inst = current_outer->raw;
				iwrite(&inst, out);
			}
			else if (current_outer->label == NULL)
			{
				inst = INSTRUCTION_CREATE(current_outer->opcode, current_outer->a, current_outer->b);
				iwrite(&inst, out);
			}
		}

		// Goto next in linked list.
		current_outer = current_outer->next;
	}

	fflush(out);

	return (uint16_t)((ftell(out) - true_origin) / 2);
}