Skip to content

Commit 33a29c9

Browse files
committed
[Mips] Fix clang integrated assembler generates incorrect relocations for mips32
When mips asm parse instruction la, check whether .rdata section was accessed and parsed, if it was not, then check the following statement, check if local symbol(eg "hello:") was in .rdata section, if it was in it, IsLocalSym is true. Fix #65020
1 parent f40ee6e commit 33a29c9

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class MipsAsmParser : public MCTargetAsmParser {
149149
// directive.
150150
bool IsLittleEndian;
151151
bool IsPicEnabled;
152+
bool HasParseRdata;
152153
bool IsCpRestoreSet;
153154
int CpRestoreOffset;
154155
unsigned GPReg;
@@ -555,6 +556,7 @@ class MipsAsmParser : public MCTargetAsmParser {
555556
IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
556557

557558
IsCpRestoreSet = false;
559+
HasParseRdata = false;
558560
CpRestoreOffset = -1;
559561
GPReg = ABI.GetGlobalPtr();
560562

@@ -2920,11 +2922,45 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
29202922
(Res.getSymA()->getSymbol().isELF() &&
29212923
cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
29222924
ELF::STB_LOCAL);
2925+
29232926
// For O32, "$"-prefixed symbols are recognized as temporary while
29242927
// .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
29252928
// manually.
29262929
if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L"))
29272930
IsLocalSym = true;
2931+
else {
2932+
if (HasParseRdata == false) {
2933+
StringRef CurrentASMContent = StringRef(IDLoc.getPointer());
2934+
2935+
// Get local symbol name LocalSymbol from "la $number, localsymbolname\n
2936+
// ... "
2937+
size_t NewlineIndex = CurrentASMContent.find_first_of('\n');
2938+
size_t CommaIndex = CurrentASMContent.find_first_of(',');
2939+
size_t SymbolLength = NewlineIndex - CommaIndex - 2;
2940+
StringRef LocalSymbol =
2941+
CurrentASMContent.take_front(NewlineIndex).take_back(SymbolLength);
2942+
2943+
// Get and check if ".rdata" section exist.
2944+
size_t RdataIndex = CurrentASMContent.find(".rdata");
2945+
if (RdataIndex != StringRef::npos) {
2946+
StringRef Rdata = CurrentASMContent.substr(RdataIndex);
2947+
2948+
// Check if rdata section contain local symbol.
2949+
if (1 == Rdata.contains(LocalSymbol)) {
2950+
// Check if "LocalSymbol:" exist.
2951+
size_t A = Rdata.find(LocalSymbol);
2952+
size_t B = Rdata.find(':', A);
2953+
if (B - A == LocalSymbol.size()) {
2954+
IsLocalSym = true;
2955+
LLVM_DEBUG(dbgs()
2956+
<< DEBUG_TYPE << ": Has definition of local symbol "
2957+
<< LocalSymbol << " after 'la' instruction"
2958+
<< "\n");
2959+
}
2960+
}
2961+
}
2962+
}
2963+
}
29282964
bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
29292965

29302966
// The case where the result register is $25 is somewhat special. If the
@@ -8073,6 +8109,7 @@ bool MipsAsmParser::parseDirectiveTpRelWord() {
80738109
if (getLexer().isNot(AsmToken::EndOfStatement))
80748110
return Error(getLexer().getLoc(),
80758111
"unexpected token, expected end of statement");
8112+
HasParseRdata = true;
80768113
Parser.Lex(); // Eat EndOfStatement token.
80778114
return false;
80788115
}

0 commit comments

Comments
 (0)