@@ -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