Skip to content

Commit dcc86c6

Browse files
committed
[Mips] Fix clang integrated assembler generates incorrect relocations for mips32
Save begin location, check if have .rdata section, confirm where to begin parse. If have it and .rdata section after .text section, begin parse from .rdata, when go to Eof, jump to begin location and then continue parse. If did not have .rdata section or .rdata before .text, jump to begin location and then parse.
1 parent 0289ae5 commit dcc86c6

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
@@ -178,6 +178,8 @@ class AsmParser : public MCAsmParser {
178178

179179
/// Are we parsing ms-style inline assembly?
180180
bool ParsingMSInlineAsm = false;
181+
bool NeedParseFromRdata = false;
182+
int ParseRdataCnt = 0;
181183

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

9981000
getTargetParser().onBeginOfFile();
9991001

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

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

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

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

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

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

0 commit comments

Comments
 (0)