[llvm-branch-commits] [llvm] [SystemZ] Emit external aliases required for indirect symbol handling support (PR #183442)

Amy Kwan via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Feb 25 21:53:19 PST 2026


https://github.com/amy-kwan updated https://github.com/llvm/llvm-project/pull/183442

>From ac321c25acb736f2d2f10964b0959470468ec5cd Mon Sep 17 00:00:00 2001
From: Amy Kwan <amy.kwan1 at ibm.com>
Date: Wed, 25 Feb 2026 13:52:01 -0500
Subject: [PATCH] [SystemZ] Emit external aliases required for indirect symbol
 handling support

This is the second of three patches aimed to support indirect symbol handling for
the SystemZ backend. An external name is added for both MC sections and symbols
and makes the relevant printers and writers utilize the external name when present.
Furthermore, the ALIAS HLASM instruction is emitted after every XATTR instruction.
---
 llvm/include/llvm/MC/MCSectionGOFF.h          |  8 +++++
 llvm/include/llvm/MC/MCSymbolGOFF.h           |  9 +++++
 llvm/lib/MC/GOFFObjectWriter.cpp              | 35 +++++++++++--------
 llvm/lib/MC/MCAsmInfoGOFF.cpp                 |  6 ++++
 .../MCTargetDesc/SystemZHLASMAsmStreamer.cpp  |  4 +++
 .../MCTargetDesc/SystemZTargetStreamer.h      | 17 +++++++++
 6 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 2136148368fbd..288f9038bb65e 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -27,6 +27,8 @@ namespace llvm {
 class MCExpr;
 
 class LLVM_ABI MCSectionGOFF final : public MCSection {
+  StringRef ExternalName; // Alternate external name.
+
   // Parent of this section. Implies that the parent is emitted first.
   MCSectionGOFF *Parent;
 
@@ -115,6 +117,12 @@ class LLVM_ABI MCSectionGOFF final : public MCSection {
   bool requiresNonZeroLength() const { return RequiresNonZeroLength; }
 
   void setName(StringRef SectionName) { Name = SectionName; }
+
+  bool hasExternalName() const { return !ExternalName.empty(); }
+  void setExternalName(StringRef Name) { ExternalName = Name; }
+  StringRef getExternalName() const {
+    return hasExternalName() ? ExternalName : getName();
+  }
 };
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 449307217d531..8bbd53f824f1e 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -23,6 +23,9 @@
 namespace llvm {
 
 class MCSymbolGOFF : public MCSymbol {
+
+  StringRef ExternalName; // Alternate external name.
+
   // Associated data area of the section. Needs to be emitted first.
   MCSectionGOFF *ADA = nullptr;
 
@@ -48,6 +51,12 @@ class MCSymbolGOFF : public MCSymbol {
   bool isExternal() const { return IsExternal; }
   void setExternal(bool Value) const { IsExternal = Value; }
 
+  bool hasExternalName() const { return !ExternalName.empty(); }
+  void setExternalName(StringRef Name) { ExternalName = Name; }
+  StringRef getExternalName() const {
+    return hasExternalName() ? ExternalName : getName();
+  }
+
   void setHidden(bool Value = true) {
     modifyFlags(Value ? SF_Hidden : 0, SF_Hidden);
   }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index a619328c09fa3..9319a377ca10b 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -315,13 +315,13 @@ GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isSD()) {
-    GOFFSymbol SD(Section.getName(), Section.getOrdinal(),
+    GOFFSymbol SD(Section.getExternalName(), Section.getOrdinal(),
                   Section.getSDAttributes());
     writeSymbol(SD);
   }
 
   if (Section.isED()) {
-    GOFFSymbol ED(Section.getName(), Section.getOrdinal(),
+    GOFFSymbol ED(Section.getExternalName(), Section.getOrdinal(),
                   Section.getParent()->getOrdinal(), Section.getEDAttributes());
     ED.SectionLength = Asm.getSectionAddressSize(Section);
     writeSymbol(ED);
@@ -329,8 +329,9 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 
   if (Section.isPR()) {
     MCSectionGOFF *Parent = Section.getParent();
-    GOFFSymbol PR(Section.getName(), Section.getOrdinal(), Parent->getOrdinal(),
-                  Parent->getEDAttributes(), Section.getPRAttributes());
+    GOFFSymbol PR(Section.getExternalName(), Section.getOrdinal(),
+                  Parent->getOrdinal(), Parent->getEDAttributes(),
+                  Section.getPRAttributes());
     PR.SectionLength = Asm.getSectionAddressSize(Section);
     if (Section.requiresNonZeroLength()) {
       // We cannot have a zero-length section for data.  If we do,
@@ -347,8 +348,8 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 
 void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
   MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(Symbol.getSection());
-  GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(), Section.getOrdinal(),
-                Section.getEDAttributes().NameSpace,
+  GOFFSymbol LD(Symbol.getExternalName(), Symbol.getIndex(),
+                Section.getOrdinal(), Section.getEDAttributes().NameSpace,
                 GOFF::LDAttr{false, Symbol.getCodeData(),
                              Symbol.getBindingStrength(), Symbol.getLinkage(),
                              GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
@@ -359,7 +360,8 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
 }
 
 void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
-  GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(), RootSD->getOrdinal(),
+  GOFFSymbol ER(Symbol.getExternalName(), Symbol.getIndex(),
+                RootSD->getOrdinal(),
                 GOFF::ERAttr{Symbol.isIndirect(), Symbol.getCodeData(),
                              Symbol.getBindingStrength(), Symbol.getLinkage(),
                              GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
@@ -695,25 +697,26 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
       Asm->reportError(
           Fixup.getLoc(),
           Twine("symbol ")
-              .concat(A.getName())
+              .concat(A.getExternalName())
               .concat(" must be defined for a relative immediate relocation"));
       return;
     }
     if (&A.getSection() != PSection) {
+      MCSectionGOFF &GOFFSection = static_cast<MCSectionGOFF &>(A.getSection());
       Asm->reportError(Fixup.getLoc(),
                        Twine("relative immediate relocation section mismatch: ")
-                           .concat(A.getSection().getName())
+                           .concat(GOFFSection.getExternalName())
                            .concat(" of symbol ")
-                           .concat(A.getName())
+                           .concat(A.getExternalName())
                            .concat(" <-> ")
-                           .concat(PSection->getName()));
+                           .concat(PSection->getExternalName()));
       return;
     }
     if (B) {
       Asm->reportError(
           Fixup.getLoc(),
           Twine("subtractive symbol ")
-              .concat(B->getName())
+              .concat(B->getExternalName())
               .concat(" not supported for a relative immediate relocation"));
       return;
     }
@@ -767,9 +770,11 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
     default:
       Con = "(unknown)";
     }
-    dbgs() << "Reloc " << N << ": " << Con << " Rptr: " << Sym->getName()
-           << " Pptr: " << PSection->getName() << " Offset: " << FixupOffset
-           << " Fixed Imm: " << FixedValue << "\n";
+    dbgs() << "Reloc " << N << ": " << Con
+           << " Rptr: " << Sym->getExternalName()
+           << " Pptr: " << PSection->getExternalName()
+           << " Offset: " << FixupOffset << " Fixed Imm: " << FixedValue
+           << "\n";
   };
   (void)DumpReloc;
 
diff --git a/llvm/lib/MC/MCAsmInfoGOFF.cpp b/llvm/lib/MC/MCAsmInfoGOFF.cpp
index 4dc33943609db..721d62fab512d 100644
--- a/llvm/lib/MC/MCAsmInfoGOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoGOFF.cpp
@@ -124,6 +124,8 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section,
   case GOFF::ESD_ST_SectionDefinition: {
     OS << Sec.getName() << " CSECT\n";
     Sec.Emitted = true;
+    if (Sec.hasExternalName())
+      OS << Sec.getName() << " ALIAS \"" << Sec.getExternalName() << "\"\n";
     break;
   }
   case GOFF::ESD_ST_ElementDefinition: {
@@ -134,6 +136,8 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section,
                 GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0,
                 Sec.EDAttributes.FillByteValue, StringRef());
       Sec.Emitted = true;
+      if (Sec.hasExternalName())
+        OS << Sec.getName() << " ALIAS \"" << Sec.getExternalName() << "\"\n";
     } else
       OS << Sec.getName() << " CATTR\n";
     break;
@@ -151,6 +155,8 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section,
                 Sec.PRAttributes.Executable, Sec.PRAttributes.BindingScope);
       ED->Emitted = true;
       Sec.Emitted = true;
+      if (Sec.hasExternalName())
+        OS << Sec.getName() << " ALIAS \"" << Sec.getExternalName() << "\"\n";
     } else
       OS << ED->getName() << " CATTR PART(" << Sec.getName() << ")\n";
     break;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index bb49ab85ad126..52e3e950cbb0c 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -263,6 +263,8 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
     emitXATTR(OS, Sym->getName(), Sym->isIndirect(), Sym->getLinkage(),
               Sym->getCodeData(), Sym->getBindingScope());
     EmitEOL();
+    if (Sym->hasExternalName())
+      OS << Sym->getName() << " ALIAS \"" << Sym->getExternalName() << "\"\n";
   }
 
   if (EmitLabelAndEntry) {
@@ -373,6 +375,8 @@ void SystemZHLASMAsmStreamer::finishImpl() {
     emitXATTR(OS, Sym.getName(), Sym.isIndirect(), Sym.getLinkage(),
               Sym.getCodeData(), Sym.getBindingScope());
     EmitEOL();
+    if (Sym.hasExternalName())
+      OS << Sym.getName() << " ALIAS \"" << Sym.getExternalName() << "\"\n";
   }
 
   // Finish the assembly output.
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 4f9a4a0a97ed8..878600a67edbc 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -13,8 +13,10 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/Support/FormattedStream.h"
 #include <map>
 #include <utility>
@@ -58,6 +60,9 @@ class SystemZTargetStreamer : public MCTargetStreamer {
 
   virtual void emitMachine(StringRef CPUOrCommand) {};
 
+  virtual void emitExternalName(MCSymbol *Sym, StringRef Name) {}
+  virtual void emitExternalName(MCSection *Sec, StringRef Name) {}
+
   virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
                                            const MCSymbol *Lo) {
     return nullptr;
@@ -69,6 +74,12 @@ class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
   SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
   const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
                                    const MCSymbol *Lo) override;
+  virtual void emitExternalName(MCSymbol *Sym, StringRef Name) override {
+    static_cast<MCSymbolGOFF *>(Sym)->setExternalName(Name);
+  }
+  virtual void emitExternalName(MCSection *Sec, StringRef Name) override {
+    static_cast<MCSectionGOFF *>(Sec)->setExternalName(Name);
+  }
 };
 
 class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
@@ -80,6 +91,12 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
   SystemZHLASMAsmStreamer &getHLASMStreamer();
   const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
                                    const MCSymbol *Lo) override;
+  virtual void emitExternalName(MCSymbol *Sym, StringRef Name) override {
+    static_cast<MCSymbolGOFF *>(Sym)->setExternalName(Name);
+  }
+  virtual void emitExternalName(MCSection *Sec, StringRef Name) override {
+    static_cast<MCSectionGOFF *>(Sec)->setExternalName(Name);
+  }
 };
 
 class SystemZTargetELFStreamer : public SystemZTargetStreamer {



More information about the llvm-branch-commits mailing list