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]); }
//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); } } }