コード例 #1
0
   /*
     Takes a char pointer "key", variable "value", and "user_data" (not used), 
     and prints information about "value"
   */
static void
var_display_func( madparser* mp, 
                  gpointer   key,
                  gpointer   value,
                  gpointer   user_data ) {

  quatro* p   = (quatro*)user_data;
  FILE*  out  = (FILE*)(p->first_);
  GNode* expr = ((variable*)value)->expr_;
  
  fprintf( out, "Variable: %s; defined on line %d in file %s\n", ((variable*)value)->name_, ((variable*)value)->local_linenum_, ((variable*)value)->filename_ );
  fprintf( out, "Expression: ");
  expr_display( mp, out, expr, (GHashTable*)(p->third_), (GHashTable*)(p->fourth_) );
  fprintf( out, "\nValue: ");
  if ( ((expr_struct*)(expr->data))->kind_ == STRING_EXPR ) {
    fprintf( out, "\"%s\"", ((expr_struct*)(expr->data))->svalue_);
  } else if ( ((expr_struct*)(expr->data))->kind_ == STR_IDENT_EXPR ) {
    fprintf( out, "\"%s\"", ( (constant*)const_table_lookup( ((expr_struct*)(expr->data))->svalue_, (GHashTable*)(p->second_) ))->svalue_ );
  } else if ( ((expr_struct*)(expr->data))->kind_ == VAR_IDENT_EXPR ) {
    char* str = expr_is_string( mp, expr, (GHashTable*)(p->second_), (GHashTable*)(p->third_) );
    if ( str != NULL ) {
      fprintf( out, "\"%s\"", str);
    } else {
      fprintf( out, "%f", expr_evaluate( mp, expr, (GHashTable*)(p->third_), (GHashTable*)(p->fourth_) ) );
    }
  } else {
    fprintf( out, "%f", expr_evaluate( mp, expr, (GHashTable*)(p->third_), (GHashTable*)(p->fourth_) ) );
  }

  fprintf( out, "\n" );
}
コード例 #2
0
ファイル: node.c プロジェクト: cooljeanius/gcml2-0.7.1
const cml_atom *
cml_node_get_value(cml_node *mn)
{
    const cml_binding *bd;

    switch (mn->treetype)
    {
    case MN_DERIVED:
	assert(mn->expr != 0);
	cml_atom_init(&mn->value);
	expr_evaluate(mn->expr, &mn->value);
	return &mn->value;
	
    case MN_MENU:
    	if (!cml_node_is_radio(mn))
	    return 0;
	/* fall through */
    case MN_SYMBOL:
    	if ((bd = _cml_tx_get(mn->rulebase, mn)) == 0)
	{
	    cml_atom_init(&mn->value);
	    
	    if (cml_node_is_radio(mn->parent))
	    {
	    	mn->value.type = A_BOOLEAN;
		mn->value.value.tritval =
		    (cml_node_get_value(mn->parent)->value.node == mn
		    	? CML_Y : CML_N);
	    }
	    else if (!mn_eval_default_expr(mn, &mn->value))
	    {
    		/*
		 * Failed to set default value from expression,
		 * so use fallback defaults.
		 */
		cml_atom_init(&mn->value);  	/* zero value */
		
    	    	if (mn->value_type == A_NODE)
		{
		    mn->value.type = A_NODE;
		    mn->value.value.node = (mn->children == 0 ? 0 : mn->children->data);
		}
		else if (!mn->rulebase->cml1_default_vals)
		{
		    /* CML2 default value is a zero value of the right type */
		    mn->value.type = mn->value_type;
		}
		/* CML1 default is type A_NONE, i.e. a null */
	    }
	    return &mn->value;
    	}
	return &bd->value;

    case MN_UNKNOWN:
    case MN_EXPLANATION:
    	return 0;
    }
    return 0;
}
コード例 #3
0
ファイル: evaluate.c プロジェクト: NautiluX/geomview
void expr_evaluate_some(struct expression *e, expr_var v, double min, double max, int npoints, double *buffer)
{
  int i;
  for (i=0; i<npoints; i++) {
    expr_set_variable (e, v, min+(((max-min)*i)/(npoints-1)));
    buffer[i] = expr_evaluate(e);
  }
}
コード例 #4
0
ファイル: node.c プロジェクト: cooljeanius/gcml2-0.7.1
gboolean
mn_is_saveable(const cml_node *mn)
{
    cml_atom a;
    
    if (mn->saveability_expr == 0)
    	return cml_node_is_visible(mn);
    
    cml_atom_init(&a);
    expr_evaluate(mn->saveability_expr, &a);
    assert(a.type == A_BOOLEAN);
    return (a.value.tritval == CML_Y);
}
コード例 #5
0
ファイル: node.c プロジェクト: cooljeanius/gcml2-0.7.1
static gboolean
mn_eval_default_expr(cml_node *mn, cml_atom *val)
{
    if (mn->expr == 0)
    	return FALSE; /* no explicit expression for default value */
	
    cml_atom_init(val);
    expr_evaluate(mn->expr, val);
    
    if (basic_type(val->type) != basic_type(mn->value_type) &&
    	mn->value_type != A_NONE)
	return FALSE;
	
    return TRUE;
}
コード例 #6
0
ファイル: main.c プロジェクト: GraspSilv/compilers
int main( int argc, char *argv[] )
{
	printf("CSE 40243 Expression Compiler\n");
	printf("Enter an infix expression using the operators +-*/() ending with ;\n\n");

	if(yyparse()==0) {
		printf("parse successful: ");
		expr_print(parser_result);
		printf("\n");
		printf("evaluates to: %lg\n",expr_evaluate(parser_result));
		return 0;
	} else {
		printf("parse failed!\n");
		return 1;
	}
}
コード例 #7
0
ファイル: expr.c プロジェクト: DCPUTeam/DCPUToolchain
static void if_handle(state_t* state, match_t* match, bool* reprocess)
{
    list_t* result = ppparam_get(state);
    struct expr* expr = NULL;
    uint16_t value;
    bstring output;
    bool stopped_at_else;

    // Ensure the parameter format is correct.
    if (list_size(result) == 1 &&
            ((parameter_t*)list_get_at(result, 0))->type == EXPRESSION)
    {
        // Get the expression.
        expr = ((parameter_t*)list_get_at(result, 0))->expr;
        replace_state = state;
        value = expr_evaluate(expr, &if_define_replace, &dhalt_expression_exit_handler);
        replace_state = NULL;
        
        if (value)
        {
            output = skip_to_endif(state, true, &stopped_at_else);
            if (stopped_at_else)
                skip_to_endif(state, false, &stopped_at_else);
        }
        else
        {
            bassigncstr(output, "");
            skip_to_endif(state, true, &stopped_at_else);
            if (stopped_at_else)
            {
                output = skip_to_endif(state, false, &stopped_at_else);
            }
        }
        
        // print the output to the pre processor input
        ppimpl_printf(state, "%s", output->data);
    }
    else
        dhalt(ERR_PP_ASM_IF_PARAMETERS_INCORRECT, ppimpl_get_location(state));
    
    ppparam_free(result);
}
コード例 #8
0
ファイル: expr.c プロジェクト: DCPUTeam/DCPUToolchain
static uint16_t if_define_replace(bstring define)
{
    // Search through all of the defines to find one where
    // the name matches.
    size_t i = 0;
    match_t* match;
    struct expr* tree;
    for (i = 0; i < list_size(&replace_state->handlers); i++)
    {
        match = list_get_at(&replace_state->handlers, i);
        if (biseq(match->text.ref, define))
        {
            // Found a match.
            tree = expr_parse(match->userdata);
            if (tree == NULL)
                dhalt(ERR_PP_DEFINE_NOT_EXPRESSION, ppimpl_get_location(replace_state));
            return expr_evaluate(tree, &if_define_replace, &dhalt_expression_exit_handler);
        }
    }
    dhalt(ERR_PP_DEFINE_NOT_FOUND, ppimpl_get_location(replace_state));
    return 0;
}
コード例 #9
0
ファイル: node.c プロジェクト: cooljeanius/gcml2-0.7.1
gboolean
cml_node_is_visible(const cml_node *mn)
{
    cml_atom a;
    GList *iter;
    
    if (mn->visibility_expr == 0)
    	return TRUE;	/* default is to be visible always */
    
    cml_atom_init(&a);
    expr_evaluate(mn->visibility_expr, &a);
    if (a.value.tritval != CML_Y)
    	return FALSE;
    
    for (iter = mn->dependees ; iter != 0 ; iter = iter->next)
    {
    	cml_node *dep = (cml_node *)iter->data;
	
	if (!cml_node_is_visible(dep))
	    return FALSE;
    }

    return TRUE;    
}
コード例 #10
0
ファイル: assem.c プロジェクト: kierenj/DCPUToolchain
void process_line(struct ast_node_line* line)
{
	struct instruction_mapping* insttype;
	struct process_parameters_results ppresults;
	struct process_parameter_results dparam;
	struct ast_node_parameter* dcurrent;
	uint32_t dchrproc;
	uint16_t i, flimit, fchar, opos;

	// Change depending on the type of line.
	switch (line->type)
	{
		case type_keyword:
			switch (line->keyword)
			{
				case BOUNDARY:
					fprintf(stderr, ".BOUNDARY");

					// Emit safety boundary of 16 NULL words.
					for (i = 0; i < 16; i += 1)
						aout_emit(aout_create_raw(0));

					break;

				case FILL:
					fprintf(stderr, ".FILL");

					// Emit N words with value X
					flimit = expr_evaluate(line->keyword_data_expr_1, &ahalt_label_resolution_not_permitted, &ahalt_expression_exit_handler);
					fchar = expr_evaluate(line->keyword_data_expr_2, &ahalt_label_resolution_not_permitted, &ahalt_expression_exit_handler);
					for (i = 0; i < flimit; i++)
						aout_emit(aout_create_raw(fchar));

					break;

				case EXTENSION:
					fprintf(stderr, ".EXTENSION %s", line->keyword_data_string);

					// Emit extension metadata.
					aout_emit(aout_create_metadata_extension(bstr2cstr(line->keyword_data_string, '0')));

					break;

				case INCBIN:
					fprintf(stderr, ".INCBIN %s", line->keyword_data_string);

					// Emit binary include metadata.
					aout_emit(aout_create_metadata_incbin(bstr2cstr(line->keyword_data_string, '0')));

					break;

				case ORIGIN:
					opos = expr_evaluate(line->keyword_data_expr_1, &ahalt_label_resolution_not_permitted, &ahalt_expression_exit_handler);
					fprintf(stderr, ".ORIGIN 0x%04X", opos);

					// Emit origin set metadata.
					aout_emit(aout_create_metadata_origin(opos));

					break;

				case EXPORT:
					fprintf(stderr, ".EXPORT %s", line->keyword_data_string);

					// Emit export metadata.
					aout_emit(aout_create_metadata_export(bstr2cstr(line->keyword_data_string, '0')));

					break;

				case IMPORT:
					fprintf(stderr, ".IMPORT %s", line->keyword_data_string);

					// Emit export metadata.
					aout_emit(aout_create_metadata_import(bstr2cstr(line->keyword_data_string, '0')));

					break;

				default:
					fprintf(stderr, "\n");
					ahalt(ERR_UNSUPPORTED_KEYWORD, NULL);
			}

			fprintf(stderr, "\n");
			break;

		case type_instruction:

			// Check to see if this is DAT.
			if (strcmp(line->instruction->instruction, "DAT") == 0)
			{
				// Handle data.
				fprintf(stderr, "EMIT DAT");

				// Process parameters as data.
				reverse_parameters(line->instruction->parameters);
				dcurrent = line->instruction->parameters->last;

				while (dcurrent != NULL)
				{
					// Process parameter normally.
					dparam = process_parameter(dcurrent);

					// Output depending on what kind of parameter it was.
					if (dparam.v_label != NULL) // If this is a label, output something that we need to replace.
						aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(dparam.v_label)))));
					else if (dparam.v_raw != NULL) // If the raw field is not null, get each character and output it.
					{
						fprintf(stderr, " \"%s\"", dparam.v_raw->data);

						for (dchrproc = 0; dchrproc < blength(dparam.v_raw); dchrproc++)
							aout_emit(aout_create_raw(dparam.v_raw->data[dchrproc]));
					}
					else if (dparam.v_extra_used == true) // Just a single address.
						aout_emit(aout_create_expr(dparam.v_extra));
					else // Something that isn't handled by DAT.
					{
						fprintf(stderr, "\n");
						ahalt(ERR_DAT_UNSUPPORTED_PARAMETER, NULL);
					}

					dcurrent = dcurrent->prev;
				}
			}
			else
			{
				// Handle instruction.
				insttype = get_instruction_by_name(line->instruction->instruction);

				if (insttype == NULL)
					ahalt(ERR_UNKNOWN_OPCODE, line->instruction->instruction);

				fprintf(stderr, "EMIT %s", insttype->name);

				// Process parameters normally.
				ppresults = process_parameters(line->instruction->parameters);

				// Force the parameter value to be NXT if it's a label.
				if (ppresults.a_label != NULL) ppresults.a = NXT_LIT;

				if (ppresults.b_label != NULL) ppresults.b = NXT_LIT;

				if (ppresults.a_label != NULL && ppresults.a_label_bracketed) ppresults.a = NXT;

				if (ppresults.b_label != NULL && ppresults.b_label_bracketed) ppresults.b = NXT;

				// Output the initial opcode.
				if (insttype->opcode != OP_NONBASIC)
					aout_emit(aout_create_opcode(insttype->opcode, ppresults.a, ppresults.b));
				else
					aout_emit(aout_create_opcode(insttype->opcode, insttype->nbopcode, ppresults.a));

				// If the parameter is a label or requires an extra word, output them.
				if (ppresults.b_label != NULL)
					aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(ppresults.b_label)))));
				else if (ppresults.b_extra_used)
					aout_emit(aout_create_expr(ppresults.b_extra));

				if (ppresults.a_label != NULL)
					aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(ppresults.a_label)))));
				else if (ppresults.a_extra_used)
					aout_emit(aout_create_expr(ppresults.a_extra));

			}

			fprintf(stderr, "\n");
			break;

		case type_label:
			// Handle label definition.
			fprintf(stderr, ":%s\n", line->label->name);
			aout_emit(aout_create_label(line->label->name));
			break;
	}
}
コード例 #11
0
ファイル: section.c プロジェクト: RPG-7/lemberg
void section_write_elf(Elf *e, struct sect *sect, struct buffer *shstrtab_buf)
{
  unsigned i;

  struct buffer buf;

  Elf_Scn *scn;
  Elf_Data *data;
  Elf32_Shdr *shdr;

  buffer_init(&buf);
  
  for (i = 0; i < sect->size; i++)
	{
	  if (sect->type == SECT_XLATE)
		{			  
		  buffer_write(&buf, sect->data[i].type, 1);
		  switch (sect->data[i].type)
			{
			case TYPE_ALIGN:
			  buffer_write(&buf, sect->data[i].size, 1);
			  break;
			case TYPE_SIZE:
			  {
				struct reloc_info size = expr_evaluate(sect->data[i].raw);
				if (size.symbol != NULL) {
				  eprintf("Cannot relocate function size");;
				  exit(EXIT_FAILURE);
				}
				if ((size.intval > (1 << 15)) || (size.intval < 0)) {
				  eprintf("Invalid size %016llx", size.intval);
				  exit(EXIT_FAILURE);
				}
				buffer_write(&buf, size.intval, 4);
			  }
			  break;
			case 0x0:
			  /* nothing to dump for a nop */
			  break;
			case 0x1:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  break;
			case 0x2:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  break;
			case 0x4:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  break;
			case 0x8:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0x3:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  break;
			case 0x5:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  break;
			case 0x9:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0x6:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  break;
			case 0xA:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0xC:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0x7:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  break;
			case 0xB:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0xD:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0xE:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			case 0xF:
			  buffer_write(&buf, conv_asmop(sect->data[i].op[0].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[1].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[2].op, sect->name, buf.pos), 4);
			  buffer_write(&buf, conv_asmop(sect->data[i].op[3].op, sect->name, buf.pos), 4);
			  break;
			default:
			  eprintf("Invalid type for translated section");
			  exit(EXIT_FAILURE);
			}
		}
	  else if (sect->type == SECT_ZERO)
		{
		  unsigned j;
		  switch (sect->data[i].type)
			{
			case TYPE_ALIGN:
			case TYPE_ZERO:
			  for (j = 0; j < sect->data[i].size; j++)
				{
				  buffer_write(&buf, 0, 1);
				}
			  break;
			case TYPE_RAW:
			  {
				struct reloc_info raw = expr_evaluate(sect->data[i].raw);
				if (raw.symbol != NULL)
				  {
					eprintf("Cannot relocate in zero section");
					exit(EXIT_FAILURE);
				  }
				if (raw.intval != 0)
				  {
					eprintf("Cannot put non-zero data in zero section");
					exit(EXIT_FAILURE);
				  }
				buffer_write(&buf, raw.intval, sect->data[i].size);
			  }
			  break;
			default:
			  eprintf("Invalid type for zero section");
			  exit(EXIT_FAILURE);
			}
		}
	  else
		{
		  unsigned j;
		  switch (sect->data[i].type)
			{
			case TYPE_ALIGN:
			case TYPE_ZERO:
			  for (j = 0; j < sect->data[i].size; j++)
				{
				  buffer_write(&buf, 0, 1);
				}
			  break;
			case TYPE_RAW:
			  {
				struct reloc_info raw = expr_evaluate(sect->data[i].raw);
				if (raw.symbol != NULL)
				  {
					if (sect->data[i].size != 4)
					  {
						eprintf("Invalid size for relocated data: %d", sect->data[i].size);
						exit(EXIT_FAILURE);
					  }
					sym_addreloc(raw.symbol, sect->name, buf.pos,
								 R_LEMBERG_FULL, raw.intval);
					buffer_write(&buf, 0, sect->data[i].size);
				  }
				else
				  {
					buffer_write(&buf, raw.intval, sect->data[i].size);
				  }
			  }
			  break;
			default:
			  eprintf("Invalid type for raw section");
			  exit(EXIT_FAILURE);
			}
		}
	}

  scn = xelf_newscn(e);

  shdr = xelf32_getshdr(scn);
  shdr->sh_name = shstrtab_buf->pos;
  buffer_writestr(shstrtab_buf, sect->name);
  switch (sect->type)
	{
	case SECT_XLATE: 
	  shdr->sh_type = SHT_PROGBITS;
	  shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR | SHF_OS_NONCONFORMING;
	  shdr->sh_info = sect->pos;
	  break;
	case SECT_ZERO:
	  shdr->sh_type = SHT_NOBITS;
	  shdr->sh_flags = SHF_WRITE | SHF_ALLOC;
	  break;
	case SECT_RAW:
	  shdr->sh_type = SHT_PROGBITS;
	  shdr->sh_flags = SHF_WRITE | SHF_ALLOC;
	  break;
	default:
	  eprintf("Unknown section type");
	  exit(EXIT_FAILURE);
	}
  
  data = xelf_newdata(scn);
  data->d_align = sect->align;
  data->d_off = 0;
  data->d_type = ELF_T_BYTE;
  data->d_version = EV_CURRENT;
  data->d_buf = buf.data;
  data->d_size = buf.pos;
}
コード例 #12
0
ファイル: symtab.c プロジェクト: RPG-7/lemberg
Elf_Scn *symtab_write_elf(Elf *e, struct sect * sects,
						  struct buffer *strtab_buf, struct buffer *shstrtab_buf)
{
  unsigned i, k;
  struct sym_info *sym;
  Elf32_Sym esym;

  Elf_Scn *scn, *relscn, *tmpscn;
  Elf_Data *data, *reldata;
  Elf32_Shdr *shdr, *relshdr;

  struct buffer buf;
  struct buffer *relbuf;

  struct sect *s;

  buffer_init(&buf);

  esym.st_name = 0;
  esym.st_value = 0;
  esym.st_size = 0;
  esym.st_info = 0;
  esym.st_other = 0;
  esym.st_shndx = 0;
  buffer_writemem(&buf, &esym, sizeof(esym));

  relbuf = malloc(0);
  for (s = sects, k = 0; s != NULL; s = s->next, k++)
	{
	  relbuf = realloc(relbuf, (k+1)*sizeof(struct buffer));
	  buffer_init(&relbuf[k]);
	}

  for (i = 0; i < SYMTAB_SIZE; i++)
    {
      for (sym = symtab[i]; sym != NULL; sym = sym->next)
        {
          if (sym->symbol[0] != '.' || sym->relocs != NULL)
            {
			  struct reloc_info size;
			  int type = STT_NOTYPE;
			  int bind = STB_LOCAL;
			  if (!sym->defined || sym->bind == SYM_BIND_GLOBAL)
				{
				  bind = STB_GLOBAL;
				}

			  esym.st_name = strtab_buf->pos;
			  buffer_writestr(strtab_buf, sym->symbol);

			  esym.st_value = sym->addr;
			  
			  size = expr_evaluate(sym->size);
			  if (size.symbol != NULL) {
				eprintf("Cannot relocate symbol size");
				exit(EXIT_FAILURE);
			  }
			  esym.st_size = size.intval;

			  if (strcmp(sym->type, "@function") == 0)
				type = STT_FUNC;
			  if (strcmp(sym->type, "@object") == 0)
				type = STT_OBJECT;
			  esym.st_info = ELF32_ST_INFO(bind, type);

			  esym.st_other = ELF32_ST_VISIBILITY(STV_DEFAULT);

			  tmpscn = section_find(e, sym->section, shstrtab_buf);
			  if (tmpscn == NULL && sym->section != NULL)
				tmpscn = section_find(e, pile_name(pile_match(sym->section)), shstrtab_buf);
			  esym.st_shndx = tmpscn != NULL ? elf_ndxscn(tmpscn) : 0;

			  if (sym->relocs != NULL) {
				struct sym_reloc_info *r;
				for (r = sym->relocs; r != NULL; r = r->next) {
				  Elf32_Rela rel;
				  rel.r_offset = r->addr;
				  rel.r_info = ELF32_R_INFO(buf.pos/sizeof(esym), r->type);
				  rel.r_addend = r->addend;
				  for (s = sects, k = 0; s != NULL; s = s->next, k++)
					{
					  if (strcmp(s->name, r->sect) == 0)
						{
						  buffer_writemem(&relbuf[k], &rel, sizeof(rel));
						}
					}
				}
			  }

			  buffer_writemem(&buf, &esym, sizeof(esym));
			}
        }
    }

  scn = xelf_newscn(e);

  shdr = xelf32_getshdr(scn);
  shdr->sh_name = shstrtab_buf->pos;
  buffer_writestr(shstrtab_buf, ".symtab");
  shdr->sh_type = SHT_SYMTAB;
  shdr->sh_flags = 0;

  data = xelf_newdata(scn);
  data->d_align = 4;
  data->d_off = 0;
  data->d_type = ELF_T_SYM;
  data->d_version = EV_CURRENT;
  data->d_buf = buf.data;
  data->d_size = buf.pos;

  for (s = sects, k = 0; s != NULL; s = s->next, k++)
	{
	  if (relbuf[k].pos > 0)
		{
		  char *relname;

		  relscn = xelf_newscn(e);
	  
		  relshdr = xelf32_getshdr(relscn);
		  relshdr->sh_name = shstrtab_buf->pos;
		  relname = malloc(strlen(s->name)+6);
		  strcpy(relname, ".rela");
		  strcat(relname, s->name);
		  buffer_writestr(shstrtab_buf, relname);

		  relshdr->sh_type = SHT_RELA;
		  shdr->sh_flags = 0;

		  reldata = xelf_newdata(relscn);
		  reldata->d_align = 4;
		  reldata->d_off = 0;
		  reldata->d_type = ELF_T_RELA;
		  reldata->d_version = EV_CURRENT;
		  reldata->d_buf = relbuf[k].data;
		  reldata->d_size = relbuf[k].pos;

		  relshdr->sh_link = elf_ndxscn(scn);
		  
		  tmpscn = section_find(e, s->name, shstrtab_buf);
		  relshdr->sh_info = tmpscn != NULL ? elf_ndxscn(tmpscn) : 0;
		}
	}

  return scn;
}
コード例 #13
0
ファイル: assem.c プロジェクト: jathd/DCPUToolchain
void process_line(struct ast_node_line* line)
{
    struct instruction_mapping* insttype;
    struct process_parameters_results ppresults;
    struct process_parameter_results dparam;
    struct ast_node_parameter* dcurrent;
    uint32_t dchrproc;
    uint16_t i, flimit, fchar, opos;
    struct aout_byte* result = NULL;
    struct dbg_sym* newsym;

    // Change depending on the type of line.
    switch (line->type)
    {
        case type_keyword:
            switch (line->keyword)
            {
                case SYMBOL:
                    printd(LEVEL_VERBOSE, ".SYMBOL %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit debugging symbol.
                    list_append(&newsyms, dbgfmt_create_symbol(DBGFMT_SYMBOL_STRING, dbgfmt_create_symbol_string(line->keyword_data_string, DBGFMT_UNDETERMINED)));

                    break;

                case SECTION:
                    printd(LEVEL_VERBOSE, ".SECTION %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit section metadata.
                    aout_emit(aout_create_metadata_section(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case OUTPUT:
                    printd(LEVEL_VERBOSE, ".OUTPUT %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit output metadata.
                    aout_emit(aout_create_metadata_output(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case BOUNDARY:
                    printd(LEVEL_VERBOSE, ".BOUNDARY");

                    // Emit safety boundary of 16 NULL words.
                    for (i = 0; i < 16; i += 1)
                        aout_emit(aout_create_raw(0));

                    break;

                case FILL:
                    printd(LEVEL_VERBOSE, ".FILL");

                    if (line->keyword_data_expr_1 == NULL || line->keyword_data_expr_2 == NULL)
                    {
                        if (line->keyword_data_string != NULL)
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, line->keyword_data_string->data);
                        else
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, "");
                    }

                    // Emit N words with value X
                    flimit = expr_evaluate(line->keyword_data_expr_1, &dhalt_label_resolution_not_permitted, &dhalt_expression_exit_handler);
                    fchar = expr_evaluate(line->keyword_data_expr_2, &dhalt_label_resolution_not_permitted, &dhalt_expression_exit_handler);
                    for (i = 0; i < flimit; i++)
                        aout_emit(aout_create_raw(fchar));

                    break;

                case EXTENSION:
                    printd(LEVEL_VERBOSE, ".EXTENSION %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit extension metadata.
                    aout_emit(aout_create_metadata_extension(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case INCBIN:
                    printd(LEVEL_VERBOSE, ".INCBIN %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit binary include metadata.
                    aout_emit(aout_create_metadata_incbin(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case ORIGIN:
                    if (line->keyword_data_expr_1 == NULL)
                    {
                        if (line->keyword_data_string != NULL)
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, line->keyword_data_string->data);
                        else
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, "");
                    }

                    opos = expr_evaluate(line->keyword_data_expr_1, &dhalt_label_resolution_not_permitted, &dhalt_expression_exit_handler);
                    printd(LEVEL_VERBOSE, ".ORIGIN 0x%04X", opos);

                    // Emit origin set metadata.
                    aout_emit(aout_create_metadata_origin(opos));

                    break;

                case SEEK:
                    if (line->keyword_data_expr_1 == NULL)
                    {
                        if (line->keyword_data_string != NULL)
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, line->keyword_data_string->data);
                        else
                            dhalt(ERR_LABEL_RESOLUTION_NOT_PERMITTED, "");
                    }

                    opos = expr_evaluate(line->keyword_data_expr_1, &dhalt_label_resolution_not_permitted, &dhalt_expression_exit_handler);
                    printd(LEVEL_VERBOSE, ".SEEK 0x%04X", opos);

                    // Emit seek metadata.
                    aout_emit(aout_create_metadata_seek(opos));

                    break;

                case EXPORT:
                    printd(LEVEL_VERBOSE, ".EXPORT %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit export metadata.
                    aout_emit(aout_create_metadata_export(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case IMPORT:
                    printd(LEVEL_VERBOSE, ".IMPORT %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit import metadata.
                    aout_emit(aout_create_metadata_import(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case IMPORT_OPTIONAL:
                    printd(LEVEL_VERBOSE, ".IMPORT OPTIONAL %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit import metadata.
                    aout_emit(aout_create_metadata_import_optional(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                case JUMP:
                    if (line->keyword_data_string == NULL)
                        printd(LEVEL_VERBOSE, ".JUMP <table>");
                    else
                        printd(LEVEL_VERBOSE, ".JUMP %s", bstr2cstr(line->keyword_data_string, '0'));

                    // Emit jump metadata.
                    if (line->keyword_data_string == NULL)
                        aout_emit(aout_create_metadata_jump(NULL));
                    else
                        aout_emit(aout_create_metadata_jump(bstr2cstr(line->keyword_data_string, '0')));

                    break;

                default:
                    printd(LEVEL_VERBOSE, "?? UNKNOWN KEYWORD\n");
                    dhalt(ERR_UNSUPPORTED_KEYWORD, NULL);
            }

            printd(LEVEL_VERBOSE, "\n");
            break;

        case type_instruction:

            // Check to see if this is DAT.
            if (strcmp(line->instruction->instruction, "DAT") == 0)
            {
                // Handle data.
                printd(LEVEL_VERBOSE, "EMIT DAT");

                // Process parameters as data.
                reverse_parameters(line->instruction->parameters);
                dcurrent = line->instruction->parameters->last;

                while (dcurrent != NULL)
                {
                    // Process parameter normally.
                    dparam = process_parameter(dcurrent);

                    // Output depending on what kind of parameter it was.
                    if (dparam.v_label != NULL) // If this is a label, output something that we need to replace.
                        aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(dparam.v_label)))));
                    else if (dparam.v_raw != NULL) // If the raw field is not null, get each character and output it.
                    {
                        printd(LEVEL_VERBOSE, " \"%s\"", dparam.v_raw->data);

                        for (dchrproc = 0; dchrproc < (uint32_t)blength(dparam.v_raw); dchrproc++)
                            aout_emit(aout_create_raw(dparam.v_raw->data[dchrproc]));
                    }
                    else if (dparam.v_extra_used == true) // Just a single address.
                        aout_emit(aout_create_expr(dparam.v_extra));
                    else // Something that isn't handled by DAT.
                    {
                        printd(LEVEL_VERBOSE, "\n");
                        dhalt(ERR_DAT_UNSUPPORTED_PARAMETER, NULL);
                    }

                    dcurrent = dcurrent->prev;
                }
            }
            else
            {
                // Handle instruction.
                insttype = get_instruction_by_name(line->instruction->instruction);

                if (insttype == NULL)
                    dhalt(ERR_UNKNOWN_OPCODE, line->instruction->instruction);

                printd(LEVEL_VERBOSE, "EMIT %s", insttype->name);

                // Check parameter count.
                if (line->instruction->parameters == NULL && strcmp(line->instruction->instruction, "RFI") == 0)
                {
                    // Handle RFI (which can accept no parameters).
                    result = aout_emit(aout_create_opcode(insttype->opcode, insttype->nbopcode, 0x21 /* 0 literal */));
                    printd(LEVEL_VERBOSE, "\n");
                    break;
                }
                else if (line->instruction->parameters == NULL)
                {
                    // Halt and error.
                    dhalt(ERR_INVALID_PARAMETER_COUNT, NULL);
                }

                // Process parameters normally.
                ppresults = process_parameters(line->instruction->parameters);

                // Force the parameter value to be NXT if it's a label.
                if (ppresults.a_label != NULL) ppresults.a = NXT_LIT;
                if (ppresults.b_label != NULL) ppresults.b = NXT_LIT;
                if (ppresults.a_label != NULL && ppresults.a_label_bracketed) ppresults.a = NXT;
                if (ppresults.b_label != NULL && ppresults.b_label_bracketed) ppresults.b = NXT;

                // Check for relative addressing.
                if ((insttype->opcode == OP_ADD || insttype->opcode == OP_SUB ||
                        insttype->opcode == OP_MUL || insttype->opcode == OP_DIV) && ppresults.a == PC)
                {
                    // Warn about relative addressing portability.
                    dwarn(WARN_RELATIVE_PC_ADDRESSING, NULL);
                }

                // Output the initial opcode.
                if (insttype->opcode != OP_NONBASIC)
                    result = aout_emit(aout_create_opcode(insttype->opcode, ppresults.a, ppresults.b));
                else
                    result = aout_emit(aout_create_opcode(insttype->opcode, insttype->nbopcode, ppresults.a));

                // If the parameter is a label or requires an extra word, output them.
                if (ppresults.b_label != NULL)
                    aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(ppresults.b_label)))));
                else if (ppresults.b_extra_used)
                    aout_emit(aout_create_expr(ppresults.b_extra));

                if (ppresults.a_label != NULL)
                    aout_emit(aout_create_expr(expr_new_label(bautofree(bfromcstr(ppresults.a_label)))));
                else if (ppresults.a_extra_used)
                    aout_emit(aout_create_expr(ppresults.a_extra));

            }

            printd(LEVEL_VERBOSE, "\n");
            break;

        case type_label:
            // Handle label definition.
            list_append(&newsyms, dbgfmt_create_symbol(DBGFMT_SYMBOL_LABEL, dbgfmt_create_symbol_label(bfromcstr(line->label->name), DBGFMT_UNDETERMINED)));
            printd(LEVEL_VERBOSE, ":%s\n", line->label->name);
            aout_emit(aout_create_label(line->label->name));
            break;

        default:
            assert(false);
    }

    // If we can associate debugging symbols with this instruction...
    if (result != NULL)
    {
        // While the new symbols list is not empty, copy those symbols
        // into the output and associate.
        while (list_size(&newsyms) > 0)
        {
            newsym = list_extract_at(&newsyms, 0);
            printd(LEVEL_DEBUG, "Debugging custom symbol: %i\n", newsym->length);
            list_append(&result->symbols, newsym);
            list_append(assem_dbg_symbols, newsym);
        }

        // If the line information is provided, output
        // debugging symbols.
        if (line != NULL && line->file != NULL)
        {
            // Output a file / line number debugging symbol here.
            newsym = dbgfmt_create_symbol(DBGFMT_SYMBOL_LINE, dbgfmt_create_symbol_line(line->file, line->line, DBGFMT_UNDETERMINED));
            list_append(&result->symbols, newsym);
            list_append(assem_dbg_symbols, newsym);

            printd(LEVEL_DEBUG, "Debugging symbol: %i %s\n", line->line, line->file->data);
        }

        // If the higher-language line information is
        // provided, output debugging symbols.
        if (line != NULL && line->ufile != NULL)
        {
            // Output a file / line number debugging symbol here.
            newsym = dbgfmt_create_symbol(DBGFMT_SYMBOL_LINE, dbgfmt_create_symbol_line(line->ufile, line->uline, DBGFMT_UNDETERMINED));
            list_append(&result->symbols, newsym);
            list_append(assem_dbg_symbols, newsym);

            printd(LEVEL_DEBUG, "High-level debugging symbol: %i %s\n", line->uline, line->ufile->data);
        }
    }
}
コード例 #14
0
ファイル: aout.c プロジェクト: Beliaar/DCPUToolchain
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);
}