Skip to content

Commit 07fb14f

Browse files
committed
[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
1 parent f40ee6e commit 07fb14f

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ class AsmParser : public MCAsmParser {
177177

178178
/// Are we parsing ms-style inline assembly?
179179
bool ParsingMSInlineAsm = false;
180+
bool NeedParseFromRdata = false;
181+
int ParseRdataCnt = 0;
180182

181183
/// Did we already inform the user about inconsistent MD5 usage?
182184
bool ReportedInconsistentMD5 = false;
@@ -996,11 +998,65 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
996998

997999
getTargetParser().onBeginOfFile();
9981000

1001+
// Save begin location, check if have .rdata section, confirm where to begin
1002+
// parse. If have it and .rdata after .text, begin parse from .rdata, when go
1003+
// to Eof, jump to begin location and then continue parse.
1004+
SMLoc IDLoc_start = getTok().getLoc();
1005+
SMLoc IDLoc_rdata = getTok().getLoc();
1006+
StringRef IDVal;
1007+
bool HasParseText = false;
1008+
bool HasParseRdata = false;
1009+
while (Lexer.isNot(AsmToken::Eof)) {
1010+
while (Lexer.is(AsmToken::Space)) {
1011+
IDLoc_rdata = getTok().getLoc();
1012+
Lex();
1013+
}
1014+
if (Lexer.is(AsmToken::EndOfStatement) || Lexer.is(AsmToken::Integer) ||
1015+
Lexer.is(AsmToken::Dot) || Lexer.is(AsmToken::LCurly) ||
1016+
Lexer.is(AsmToken::RCurly) ||
1017+
(Lexer.is(AsmToken::Star) &&
1018+
getTargetParser().starIsStartOfStatement())) {
1019+
IDLoc_rdata = getTok().getLoc();
1020+
Lex();
1021+
} else if (!parseIdentifier(IDVal)) {
1022+
if (IDVal == ".rdata")
1023+
HasParseRdata = true;
1024+
if (IDVal == ".text")
1025+
HasParseText = true;
1026+
//.text section before .rdata section.
1027+
if (IDVal == ".rdata" && HasParseText == true) {
1028+
NeedParseFromRdata = true;
1029+
jumpToLoc(IDLoc_rdata);
1030+
Lex();
1031+
break;
1032+
}
1033+
if (IDVal == ".text" && HasParseRdata == true) {
1034+
break;
1035+
}
1036+
IDLoc_rdata = getTok().getLoc();
1037+
Lex();
1038+
} else {
1039+
IDLoc_rdata = getTok().getLoc();
1040+
Lex();
1041+
}
1042+
}
1043+
1044+
// If did not have .rdata section or .rdata before .text, jump to begin
1045+
// location and then parse.
1046+
if (NeedParseFromRdata == false) {
1047+
jumpToLoc(IDLoc_start);
1048+
Lex();
1049+
}
1050+
1051+
BeginParse:
9991052
// While we have input, parse each statement.
10001053
while (Lexer.isNot(AsmToken::Eof)) {
10011054
ParseStatementInfo Info(&AsmStrRewrites);
10021055
bool Parsed = parseStatement(Info, nullptr);
10031056

1057+
if (!Parsed && (ParseRdataCnt == 2)) {
1058+
break;
1059+
}
10041060
// If we have a Lexer Error we are on an Error Token. Load in Lexer Error
10051061
// for printing ErrMsg via Lex() only if no (presumably better) parser error
10061062
// exists.
@@ -1016,6 +1072,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
10161072
eatToEndOfStatement();
10171073
}
10181074

1075+
// Because when we parse from .rdata, what before .rdata would be skipped and
1076+
// not be parsed, so need to go to begin location until once again parse
1077+
// .rdata section.
1078+
if (NeedParseFromRdata == true) {
1079+
jumpToLoc(IDLoc_start);
1080+
Lex();
1081+
goto BeginParse;
1082+
}
1083+
10191084
getTargetParser().onEndOfFile();
10201085
printPendingErrors();
10211086

@@ -2003,6 +2068,15 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
20032068
// manner, or at least have a default behavior that's shared between
20042069
// all targets and platforms.
20052070

2071+
// Prevent parsing .rdata section twice.
2072+
if (IDVal == ".rdata") {
2073+
ParseRdataCnt++;
2074+
}
2075+
if (NeedParseFromRdata == true && ParseRdataCnt == 2) {
2076+
NeedParseFromRdata = false;
2077+
return false;
2078+
}
2079+
20062080
getTargetParser().flushPendingInstructions(getStreamer());
20072081

20082082
ParseStatus TPDirectiveReturn = getTargetParser().parseDirective(ID);

0 commit comments

Comments
 (0)