[llvm] [Mips] Fix clang integrated assembler generates incorrect relocations… (PR #83115)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 02:10:23 PST 2024


https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/83115

>From 33a29c98ab9a7cc8a73629c9260eee11276bbbef Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Tue, 27 Feb 2024 04:34:27 -0500
Subject: [PATCH] [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
---
 .../Target/Mips/AsmParser/MipsAsmParser.cpp   | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 36aab383da68d2..279216b7cb8160 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -149,6 +149,7 @@ class MipsAsmParser : public MCTargetAsmParser {
                        // directive.
   bool IsLittleEndian;
   bool IsPicEnabled;
+  bool HasParseRdata;
   bool IsCpRestoreSet;
   int CpRestoreOffset;
   unsigned GPReg;
@@ -555,6 +556,7 @@ class MipsAsmParser : public MCTargetAsmParser {
     IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
 
     IsCpRestoreSet = false;
+    HasParseRdata = false;
     CpRestoreOffset = -1;
     GPReg = ABI.GetGlobalPtr();
 
@@ -2920,11 +2922,45 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
         (Res.getSymA()->getSymbol().isELF() &&
          cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
              ELF::STB_LOCAL);
+
     // For O32, "$"-prefixed symbols are recognized as temporary while
     // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
     // manually.
     if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L"))
       IsLocalSym = true;
+    else {
+      if (HasParseRdata == false) {
+        StringRef CurrentASMContent = StringRef(IDLoc.getPointer());
+
+        // Get local symbol name LocalSymbol from "la $number, localsymbolname\n
+        // ... "
+        size_t NewlineIndex = CurrentASMContent.find_first_of('\n');
+        size_t CommaIndex = CurrentASMContent.find_first_of(',');
+        size_t SymbolLength = NewlineIndex - CommaIndex - 2;
+        StringRef LocalSymbol =
+            CurrentASMContent.take_front(NewlineIndex).take_back(SymbolLength);
+
+        // Get and check if ".rdata" section exist.
+        size_t RdataIndex = CurrentASMContent.find(".rdata");
+        if (RdataIndex != StringRef::npos) {
+          StringRef Rdata = CurrentASMContent.substr(RdataIndex);
+
+          // Check if rdata section contain local symbol.
+          if (1 == Rdata.contains(LocalSymbol)) {
+            // Check if "LocalSymbol:" exist.
+            size_t A = Rdata.find(LocalSymbol);
+            size_t B = Rdata.find(':', A);
+            if (B - A == LocalSymbol.size()) {
+              IsLocalSym = true;
+              LLVM_DEBUG(dbgs()
+                         << DEBUG_TYPE << ": Has definition of local symbol "
+                         << LocalSymbol << " after 'la' instruction"
+                         << "\n");
+            }
+          }
+        }
+      }
+    }
     bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
 
     // The case where the result register is $25 is somewhat special. If the
@@ -8073,6 +8109,7 @@ bool MipsAsmParser::parseDirectiveTpRelWord() {
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return Error(getLexer().getLoc(),
                 "unexpected token, expected end of statement");
+  HasParseRdata = true;
   Parser.Lex(); // Eat EndOfStatement token.
   return false;
 }



More information about the llvm-commits mailing list