Reactos

[ASMPP] Improve handling of rip relative addressing

+72 -8
+72 -8
sdk/tools/asmpp/asmpp.cpp
··· 296 296 // FIXME: use context? 297 297 unsigned int g_label_number = 0; 298 298 299 - vector<string> g_identifiers; 299 + bool g_processing_jmp = false; 300 + 301 + enum class IDTYPE 302 + { 303 + Memory, 304 + Register, 305 + Label, 306 + Constant, 307 + Macro, 308 + Instruction, 309 + String, 310 + Unknown 311 + }; 312 + 313 + struct IDENTIFIER 314 + { 315 + string Name; 316 + IDTYPE Type; 317 + }; 318 + 319 + vector<IDENTIFIER> g_identifiers; 320 + 321 + static 322 + void 323 + add_identifier(Token& tok, IDTYPE type) 324 + { 325 + g_identifiers.push_back(IDENTIFIER{ tok.str(), type }); 326 + //fprintf(stderr, "Added id: '%s'\n", tok.str().c_str()); 327 + } 300 328 301 329 void 302 330 add_mem_id(Token& tok) 303 331 { 304 - g_identifiers.push_back(tok.str()); 305 - //fprintf(stderr, "Added mem id: '%s'\n", tok.str().c_str()); 332 + add_identifier(tok, IDTYPE::Memory); 306 333 } 307 334 308 335 bool 309 336 is_mem_id(Token& tok) 310 337 { 311 - for (auto id : g_identifiers) 338 + for (IDENTIFIER& identifier : g_identifiers) 312 339 { 313 - if (id == tok.str()) 340 + if (identifier.Name == tok.str()) 314 341 { 315 - return true; 342 + return identifier.Type == IDTYPE::Memory; 316 343 } 317 344 } 318 345 319 - return false; 346 + return true; 320 347 } 321 348 322 349 bool ··· 587 614 case TOKEN_TYPE::Operator: 588 615 if (tok.str() == ",") 589 616 return index; 617 + return translate_token(tokens, index, macro_params); 590 618 591 619 case TOKEN_TYPE::Identifier: 592 620 index = translate_token(tokens, index, macro_params); 593 - if (is_mem_id(tok)) 621 + if (is_mem_id(tok) && 622 + !is_string_in_list(macro_params, tok.str()) && 623 + !g_processing_jmp) 594 624 { 595 625 printf("[rip]"); 596 626 } ··· 604 634 return index; 605 635 } 606 636 637 + static 638 + bool 639 + is_jmp_or_call(const Token& tok) 640 + { 641 + const char* inst_list[] = { 642 + "jmp", "call", "ja", "jae", "jb", "jbe", "jc", "jcxz", "je", "jecxz", "jg", "jge", 643 + "jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng", "jnge", "jnl", "jnle", 644 + "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe", "jpo", "jrcxz", "js", "jz", "loop", "loope", 645 + "loopne", "loopnz", "loopz" 646 + }; 647 + 648 + for (const char* inst : inst_list) 649 + { 650 + if (iequals(tok.str(), inst)) 651 + { 652 + return true; 653 + } 654 + } 655 + 656 + return false; 657 + } 658 + 607 659 size_t translate_instruction(TokenList& tokens, size_t index, const vector<string>& macro_params) 608 660 { 661 + // Check for jump/call instructions 662 + if (is_jmp_or_call(tokens[index])) 663 + { 664 + g_processing_jmp = true; 665 + } 666 + 609 667 // Translate the instruction itself 610 668 index = translate_token(tokens, index, macro_params); 611 669 ··· 624 682 { 625 683 case TOKEN_TYPE::Comment: 626 684 case TOKEN_TYPE::NewLine: 685 + g_processing_jmp = false; 627 686 return index; 628 687 629 688 case TOKEN_TYPE::WhiteSpace: ··· 637 696 } 638 697 } 639 698 699 + g_processing_jmp = false; 640 700 return index; 641 701 } 642 702 ··· 891 951 { 892 952 printf("%s:", tok.str().c_str()); 893 953 } 954 + add_identifier(tok, IDTYPE::Label); 894 955 return index + 2; 895 956 } 896 957 ··· 912 973 case TOKEN_TYPE::KW_EQU: 913 974 //printf("%s%s", tok.str().c_str(), tok1.str().c_str()); 914 975 printf("#define %s ", tok.str().c_str()); 976 + add_identifier(tok, IDTYPE::Constant); 915 977 return translate_expression(tokens, index + 3, macro_params); 916 978 917 979 case TOKEN_TYPE::KW_TEXTEQU: ··· 921 983 922 984 string textdef = tok4.str(); 923 985 printf("#define %s %s", tok.str().c_str(), textdef.substr(1, textdef.size() - 2).c_str()); 986 + add_identifier(tok, IDTYPE::Constant); 924 987 return index + 5; 925 988 } 926 989 ··· 940 1003 #endif 941 1004 index += 2; 942 1005 } 1006 + add_identifier(tok, IDTYPE::Label); 943 1007 break; 944 1008 } 945 1009