コード例 #1
0
ファイル: parser.c プロジェクト: mnemnion/imp
int parse_line(struct prog_info *pi, char *line) 
{
	char *ptr=NULL;
	int k;
	int flag=0, i;
	int global_label = False;
	char temp[LINEBUFFER_LENGTH];
	struct label *label = NULL;
	struct macro_call *macro_call;

	while(IS_HOR_SPACE(*line)) line++;			/* At first remove leading spaces / tabs */
	if(IS_END_OR_COMMENT(*line))				/* Skip comment line or empty line */
		return(True);
								/* Filter out .stab debugging information */
								/* .stabs sometimes contains colon : symbol - might be interpreted as label */
	if(*line == '.') {					/* minimal slowdown of existing code */
		if(strncmp(temp,".stabs ",7) == 0 ) {		/* compiler output is always lower case */
			strcpy(temp,line);			/* TODO : Do we need this temp variable ? Please check */
			return parse_stabs( pi, temp );
		}
		if(strncmp(temp,".stabn ",7) == 0 ) {
			strcpy(temp,line);
			return parse_stabn( pi, temp );
		}
	}
								/* Meta information translation */
	ptr=line;
	k=0;
	while((ptr=strchr(ptr, '%')) != NULL) {
		if(!strncmp(ptr, "%MINUTE%", 8) ) {		/* Replacement always shorter than tag -> no length check */
			k=strftime(ptr,3,"%M", localtime(&pi->time));
			strcpy(ptr+k,ptr+8); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%HOUR%", 6) ) {			
			k=strftime(ptr,3,"%H", localtime(&pi->time));
			strcpy(ptr+k,ptr+6); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%DAY%", 5) ) {
			k=strftime(ptr,3,"%d", localtime(&pi->time));
			strcpy(ptr+k,ptr+5); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%MONTH%", 7) ) {
			k=strftime(ptr,3,"%m", localtime(&pi->time));
			strcpy(ptr+k,ptr+7); 
			ptr+=k;
			continue;
		}
		if(!strncmp(ptr, "%YEAR%", 6) ) {
			k=strftime(ptr,5,"%Y", localtime(&pi->time));
			strcpy(ptr+k,ptr+6); 
			ptr+=k;
			continue;
		}
		ptr++;
	}

//	if(pi->pass == PASS_2)		// TODO : Test
//		strcpy(pi->list_line, line);

	strcpy(pi->fi->scratch,line);

	for(i = 0; IS_LABEL(pi->fi->scratch[i]) || (pi->fi->scratch[i] == ':'); i++)
		if(pi->fi->scratch[i] == ':') {	/* it is a label */
			pi->fi->scratch[i] = '\0';
			if(pi->pass == PASS_1) {
				for(macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) {
					for(label = pi->macro_call->first_label; label; label = label->next) {
						if(!nocase_strcmp(label->name, &pi->fi->scratch[0])) {
							print_msg(pi, MSGTYPE_ERROR, "Can't redefine local label %s", &pi->fi->scratch[0]);
							break;
						}
					}
				}
				if(test_label(pi,&pi->fi->scratch[0],"Can't redefine label %s")!=NULL) 
					break;
				if(test_variable(pi,&pi->fi->scratch[0],"%s have already been defined as a .SET variable")!=NULL) 
					break;
				if(test_constant(pi,&pi->fi->scratch[0],"%s has already been defined as a .EQU constant")!=NULL) 
					break;
				label = malloc(sizeof(struct label));
				if(!label) {
					print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
					return(False);
				}
				label->next = NULL;
				label->name = malloc(strlen(&pi->fi->scratch[0]) + 1);
				if(!label->name) {
					print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
					return(False);
				}
				strcpy(label->name, &pi->fi->scratch[0]);
				switch(pi->segment) {
					case SEGMENT_CODE:
						label->value = pi->cseg_addr;
						break;
					case SEGMENT_DATA:
						label->value = pi->dseg_addr;
						break;
					case SEGMENT_EEPROM:
						label->value = pi->eseg_addr;
						break;
				}
				if(pi->macro_call && !global_label) {
					if(pi->macro_call->last_label)
						pi->macro_call->last_label->next = label;
				  	else
						pi->macro_call->first_label = label;
				  	pi->macro_call->last_label = label;
				} else {
					if(pi->last_label)
				  		pi->last_label->next = label;
					else
						pi->first_label = label;
					pi->last_label = label;
				}
			} 
			i++;
			while(IS_HOR_SPACE(pi->fi->scratch[i]) && !IS_END_OR_COMMENT(pi->fi->scratch[i])) i++;
			if(IS_END_OR_COMMENT(pi->fi->scratch[i])) {
				if((pi->pass == PASS_2) && pi->list_on) { // Diff tilpassing
					fprintf(pi->list_file, "          %s\n", pi->list_line);
					pi->list_line = NULL;
				}
				return(True);
			}
			strcpy(pi->fi->scratch, &pi->fi->scratch[i]);
			break;
		}

#if 0
	if(pi->fi->scratch[0] == '.') {
#else
	if((pi->fi->scratch[0] == '.') || (pi->fi->scratch[0] == '#')) {
#endif
		pi->fi->label = label;
		flag = parse_directive(pi);
		if((pi->pass == PASS_2) && pi->list_on && pi->list_line) { // Diff tilpassing 
  			fprintf(pi->list_file, "          %s\n", pi->list_line);
			pi->list_line = NULL;
		}
		return(flag);
	} else {
		return parse_mnemonic(pi);
	}
}


/*
 * Get the next token, and terminate the last one.
 * Termination identifier is specified.
 */

char *get_next_token(char *data, int term)
{
	int i = 0, j, anti_comma = False;
	switch(term) {
		case TERM_END:
//			while(!IS_END_OR_COMMENT(data[i])) i++; 	Problems with 2. operand == ';'
			while( ((data[i] != ',') || anti_comma) && !(((data[i] == ';') && !anti_comma) || IS_ENDLINE(data[i])) ) {
				if((data[i] == '\'') || (data[i] == '"')) 
					anti_comma = anti_comma ? False : True;
				i++;
			}
			break;
		case TERM_SPACE:
			while(!IS_HOR_SPACE(data[i]) && !IS_END_OR_COMMENT(data[i])) i++;
			break;
		case TERM_DASH:
			while((data[i] != '-') && !IS_END_OR_COMMENT(data[i])) i++;
			break;
		case TERM_COLON:
			while((data[i] != ':') && !IS_ENDLINE(data[i])) i++;
			break;
		case TERM_DOUBLEQUOTE:
			while((data[i] != '"') && !IS_ENDLINE(data[i])) i++;
			break;
		case TERM_COMMA:
			while(((data[i] != ',') || anti_comma) && !(((data[i] == ';') && !anti_comma) || IS_ENDLINE(data[i])) ) {
				if((data[i] == '\'') || (data[i] == '"')) 
					anti_comma = anti_comma ? False : True;
				i++;
			}
			break;
		case TERM_EQUAL:
			while((data[i] != '=') && !IS_END_OR_COMMENT(data[i])) i++;
			break;
	}
	if(IS_END_OR_COMMENT(data[i])) {
		data[i--] = '\0';
		while(IS_HOR_SPACE(data[i])) data[i--] = '\0';
		return(0);
	}
	j = i - 1;
	while(IS_HOR_SPACE(data[j])) data[j--] = '\0';
	data[i++] = '\0';
	while(IS_HOR_SPACE(data[i]) && !IS_END_OR_COMMENT(data[i])) i++;
	if(IS_END_OR_COMMENT(data[i]))
		return(0);
	return(&data[i]);
}
コード例 #2
0
ファイル: disasm.c プロジェクト: Gurgel100/Kernel
//Disassembler
void disasm(void *cmd)
{
	uint8_t *Byte;
	bool Prefix[__LAST_PREFIX];
	bool Prefixs = false;
	REX_t REX;
	REX.Valid = false;
	Byte = cmd;

	//Ausgabevariablen
	char *tmp;

	bool wgo = true;
	while(wgo)
	{
		switch(*Byte)
		{
			//Nach Prefixe suchen
			//Gruppe 1
			case 0xF0:
				Prefix[LOCK] = true;
				Prefixs = true;
			break;
			case 0xF2:
				Prefix[REPNE] = true;
				Prefixs = true;
			break;
			case 0xF3:
				Prefix[REP] = true;
				Prefixs = true;
			break;

			//Gruppe 2
			case 0x2E:
				Prefix[CS] = true;
				Prefixs = true;
			break;
			case 0x36:
				Prefix[SS] = true;
				Prefixs = true;
			break;
			case 0x3E:
				Prefix[DS] = true;
				Prefixs = true;
			break;
			case 0x26:
				Prefix[ES] = true;
				Prefixs = true;
			break;
			case 0x64:
				Prefix[FS] = true;
				Prefixs = true;
			break;
			case 0x65:
				Prefix[GS] = true;
				Prefixs = true;
			break;
			/*case 0x2E:
				Prefix[BNT] = true;
				Prefixs = true;
			break;
			case 0x3E:
				Prefix[BT] = true;
				Prefixs = true;
			break;*/

			//Gruppe 3
			case 0x66:
				Prefix[OP_SIZE_OV] = true;
				Prefixs = true;
			break;

			//Gruppe 4
			case 0x67:
				Prefix[ADDR_SIZE_OV] = true;
				Prefixs = true;
			break;
			default:
				wgo = false;
				Byte--;		//Fix, weil Byte++ immer ausgeführt wird
			break;
		}
		Byte++;
	}

	//REX erkennen (0x4X, für X = eine Zahl)
	if((*Byte >> 4) & 0xF == 4)
	{
		REX.W = (*Byte >> 3) & 1;
		REX.R = (*Byte >> 2) & 1;
		REX.X = (*Byte >> 1) & 1;
		REX.B = *Byte & 1;
		REX.Valid = true;
		Byte++;
	}

	char *Prfx;
	Prfx = "";
	if(Prefixs)
	{
		if(Prefix[LOCK])
			Prfx = "lock";
		else if(Prefix[REP])
			Prfx = "repe";
		else if(Prefix[REPNE])
			Prfx = "repne";
	}

	ModR_M_t *ModRM = 0;
	OpcodeDB_t Opcode = OpcodeToMnemonic[*Byte++];
	char *out;
	if(Opcode.flags & F_VALID == 0)
	{
		printf("(bad)");
		return;
	}
	if(Opcode.flags & 0b1110 == F_STRUCT)
	{
		if(Opcode.flags & (1 << 5))	//Mod.RM is used to identify
		{
			OpcodeDB_t *rOpcode = Opcode.data.ext;
			ModRM = Byte++;
			OpcodeDB_t sOpcode = rOpcode[ModRM->REG >> 3];
			if(sOpcode.flags & F_VALID == 0)
			{
				printf("(bad)");
				return;
			}
			if(sOpcode.flags & (1 << 5))
			{
				if(sOpcode.flags & 0b1110 == F_MONIC)
					out = parse_mnemonic(sOpcode, ModRM);
			}
		}
	}