From 07fb14f3ff582693d9646263fc2770667b0f38bc Mon Sep 17 00:00:00 2001 From: Ying Huang Date: Wed, 3 Apr 2024 04:21:44 -0400 Subject: [PATCH] [MC] Fix clang integrated assembler generates incorrect relocations for mips32 Modify asm scan starting point to ensure scaning .rdata section before .text section. Save begin location, check if have .rdata section, confirm where to begin parse. If have it and .rdata after .text, begin parse from .rdata, when go to Eof, jump to begin location and then continue parse. If did not have .rdata or .rdata is before .text, jump to begin location and then parse. Fix #65020 --- llvm/lib/MC/MCParser/AsmParser.cpp | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 8e508dbdb1c69..4e64d00d63540 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -177,6 +177,8 @@ class AsmParser : public MCAsmParser { /// Are we parsing ms-style inline assembly? bool ParsingMSInlineAsm = false; + bool NeedParseFromRdata = false; + int ParseRdataCnt = 0; /// Did we already inform the user about inconsistent MD5 usage? bool ReportedInconsistentMD5 = false; @@ -996,11 +998,65 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { getTargetParser().onBeginOfFile(); + // Save begin location, check if have .rdata section, confirm where to begin + // parse. If have it and .rdata after .text, begin parse from .rdata, when go + // to Eof, jump to begin location and then continue parse. + SMLoc IDLoc_start = getTok().getLoc(); + SMLoc IDLoc_rdata = getTok().getLoc(); + StringRef IDVal; + bool HasParseText = false; + bool HasParseRdata = false; + while (Lexer.isNot(AsmToken::Eof)) { + while (Lexer.is(AsmToken::Space)) { + IDLoc_rdata = getTok().getLoc(); + Lex(); + } + if (Lexer.is(AsmToken::EndOfStatement) || Lexer.is(AsmToken::Integer) || + Lexer.is(AsmToken::Dot) || Lexer.is(AsmToken::LCurly) || + Lexer.is(AsmToken::RCurly) || + (Lexer.is(AsmToken::Star) && + getTargetParser().starIsStartOfStatement())) { + IDLoc_rdata = getTok().getLoc(); + Lex(); + } else if (!parseIdentifier(IDVal)) { + if (IDVal == ".rdata") + HasParseRdata = true; + if (IDVal == ".text") + HasParseText = true; + //.text section before .rdata section. + if (IDVal == ".rdata" && HasParseText == true) { + NeedParseFromRdata = true; + jumpToLoc(IDLoc_rdata); + Lex(); + break; + } + if (IDVal == ".text" && HasParseRdata == true) { + break; + } + IDLoc_rdata = getTok().getLoc(); + Lex(); + } else { + IDLoc_rdata = getTok().getLoc(); + Lex(); + } + } + + // If did not have .rdata section or .rdata before .text, jump to begin + // location and then parse. + if (NeedParseFromRdata == false) { + jumpToLoc(IDLoc_start); + Lex(); + } + +BeginParse: // While we have input, parse each statement. while (Lexer.isNot(AsmToken::Eof)) { ParseStatementInfo Info(&AsmStrRewrites); bool Parsed = parseStatement(Info, nullptr); + if (!Parsed && (ParseRdataCnt == 2)) { + break; + } // If we have a Lexer Error we are on an Error Token. Load in Lexer Error // for printing ErrMsg via Lex() only if no (presumably better) parser error // exists. @@ -1016,6 +1072,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { eatToEndOfStatement(); } + // Because when we parse from .rdata, what before .rdata would be skipped and + // not be parsed, so need to go to begin location until once again parse + // .rdata section. + if (NeedParseFromRdata == true) { + jumpToLoc(IDLoc_start); + Lex(); + goto BeginParse; + } + getTargetParser().onEndOfFile(); printPendingErrors(); @@ -2003,6 +2068,15 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // manner, or at least have a default behavior that's shared between // all targets and platforms. + // Prevent parsing .rdata section twice. + if (IDVal == ".rdata") { + ParseRdataCnt++; + } + if (NeedParseFromRdata == true && ParseRdataCnt == 2) { + NeedParseFromRdata = false; + return false; + } + getTargetParser().flushPendingInstructions(getStreamer()); ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);