Skip to content

[SystemZ] Add indirect reference bit XATTR REFERENCE(INDIRECT) for indirect symbol handling support#183441

Merged
amy-kwan merged 2 commits intomainfrom
users/amy-kwan/indirectsymbols-1
Feb 27, 2026
Merged

[SystemZ] Add indirect reference bit XATTR REFERENCE(INDIRECT) for indirect symbol handling support#183441
amy-kwan merged 2 commits intomainfrom
users/amy-kwan/indirectsymbols-1

Conversation

@amy-kwan
Copy link
Member

This is the first of three patches aimed to support indirect symbol handling for the SystemZ backend. This PR introduces a GOFF:ERAttr to represent indirect references, handles indirect symbols within setSymbolAttribute() by setting the indirect reference bit, and also updates the HLASM streamer to emit XATTR REFERENCE(INDIRECT) and various other combinations.

@llvmbot
Copy link
Member

llvmbot commented Feb 26, 2026

@llvm/pr-subscribers-llvm-mc

@llvm/pr-subscribers-backend-systemz

Author: Amy Kwan (amy-kwan)

Changes

This is the first of three patches aimed to support indirect symbol handling for the SystemZ backend. This PR introduces a GOFF:ERAttr to represent indirect references, handles indirect symbols within setSymbolAttribute() by setting the indirect reference bit, and also updates the HLASM streamer to emit XATTR REFERENCE(INDIRECT) and various other combinations.


Full diff: https://github.com/llvm/llvm-project/pull/183441.diff

5 Files Affected:

  • (modified) llvm/include/llvm/MC/MCGOFFAttributes.h (+1)
  • (modified) llvm/include/llvm/MC/MCSymbolGOFF.h (+6)
  • (modified) llvm/lib/MC/GOFFObjectWriter.cpp (+4-3)
  • (modified) llvm/lib/MC/MCSymbolGOFF.cpp (+3-1)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp (+24-9)
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index b1c6d73e41f9f..9787ef4c916a9 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -82,6 +82,7 @@ struct PRAttr {
 
 // Attributes for ER symbols.
 struct ERAttr {
+  bool IsIndirectReference = false;
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 310cc4db9a7e2..15193c8379d14 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -32,6 +32,7 @@ class MCSymbolGOFF : public MCSymbol {
   enum SymbolFlags : uint16_t {
     SF_Hidden = 0x01, // Symbol is hidden, aka not exported.
     SF_Weak = 0x02,   // Symbol is weak.
+    SF_Indirect = 0x4, // Symbol referenced indirectly.
   };
 
 public:
@@ -53,6 +54,11 @@ class MCSymbolGOFF : public MCSymbol {
   bool isHidden() const { return getFlags() & SF_Hidden; }
   bool isExported() const { return !isHidden(); }
 
+  void setIndirect(bool Value = true) {
+    modifyFlags(Value ? SF_Indirect : 0, SF_Indirect);
+  }
+  bool isIndirect() const { return getFlags() & SF_Indirect; }
+
   void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
   bool isWeak() const { return getFlags() & SF_Weak; }
 
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index cbe9c7eb2fac1..a619328c09fa3 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -278,6 +278,7 @@ class GOFFSymbol {
     BehavAttrs.setLinkageType(Attr.Linkage);
     BehavAttrs.setAmode(Attr.Amode);
     BehavAttrs.setBindingScope(Attr.BindingScope);
+    BehavAttrs.setIndirectReference(Attr.IsIndirectReference);
   }
 };
 
@@ -359,9 +360,9 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
 
 void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
   GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(), RootSD->getOrdinal(),
-                GOFF::ERAttr{Symbol.getCodeData(), Symbol.getBindingStrength(),
-                             Symbol.getLinkage(), GOFF::ESD_AMODE_64,
-                             Symbol.getBindingScope()});
+                GOFF::ERAttr{Symbol.isIndirect(), Symbol.getCodeData(),
+                             Symbol.getBindingStrength(), Symbol.getLinkage(),
+                             GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
   writeSymbol(ER);
 }
 
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 00479d22232ff..b6a25c3a24d94 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -24,7 +24,6 @@ bool MCSymbolGOFF::setSymbolAttribute(MCSymbolAttr Attribute) {
   case MCSA_LGlobal:
   case MCSA_Extern:
   case MCSA_Exported:
-  case MCSA_IndirectSymbol:
   case MCSA_Internal:
   case MCSA_LazyReference:
   case MCSA_Local:
@@ -40,6 +39,9 @@ bool MCSymbolGOFF::setSymbolAttribute(MCSymbolAttr Attribute) {
   case MCSA_Memtag:
     return false;
 
+  case MCSA_IndirectSymbol:
+    setIndirect(true);
+    break;
   case MCSA_ELF_TypeFunction:
     setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
     break;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 8a559e1ab261b..bb49ab85ad126 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -193,7 +193,7 @@ void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
   EmitEOL();
 }
 
-static void emitXATTR(raw_ostream &OS, StringRef Name,
+static void emitXATTR(raw_ostream &OS, StringRef Name, bool IsIndirectReference,
                       GOFF::ESDLinkageType Linkage,
                       GOFF::ESDExecutable Executable,
                       GOFF::ESDBindingScope BindingScope) {
@@ -201,9 +201,25 @@ static void emitXATTR(raw_ostream &OS, StringRef Name,
   OS << Name << " XATTR ";
   OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
      << ")";
-  if (Executable != GOFF::ESD_EXE_Unspecified)
-    OS << Sep << "REFERENCE("
-       << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA") << ")";
+
+  const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
+  if (NotUnspecified || IsIndirectReference) {
+    OS << Sep << "REFERENCE(";
+    bool RequiresComma = false;
+
+    if (NotUnspecified) {
+      OS << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
+      RequiresComma = true;
+    }
+
+    if (IsIndirectReference) {
+      if (RequiresComma)
+        OS << ",";
+      OS << "INDIRECT";
+    }
+
+    OS << ")";
+  }
   if (BindingScope != GOFF::ESD_BSC_Unspecified) {
     OS << Sep << "SCOPE(";
     switch (BindingScope) {
@@ -224,7 +240,6 @@ static void emitXATTR(raw_ostream &OS, StringRef Name,
     }
     OS << ')';
   }
-  OS << '\n';
 }
 
 void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
@@ -245,8 +260,8 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
       EmitEOL();
     }
 
-    emitXATTR(OS, Sym->getName(), Sym->getLinkage(), Sym->getCodeData(),
-              Sym->getBindingScope());
+    emitXATTR(OS, Sym->getName(), Sym->isIndirect(), Sym->getLinkage(),
+              Sym->getCodeData(), Sym->getBindingScope());
     EmitEOL();
   }
 
@@ -355,8 +370,8 @@ void SystemZHLASMAsmStreamer::finishImpl() {
     auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
     OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
     EmitEOL();
-    emitXATTR(OS, Sym.getName(), Sym.getLinkage(), Sym.getCodeData(),
-              Sym.getBindingScope());
+    emitXATTR(OS, Sym.getName(), Sym.isIndirect(), Sym.getLinkage(),
+              Sym.getCodeData(), Sym.getBindingScope());
     EmitEOL();
   }
 

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@amy-kwan amy-kwan changed the title [SystemZ] Add indirect reference bit XATTR REFERNECE(INDIRECT) for indirect symbol handling support [SystemZ] Add indirect reference bit XATTR REFERENCE(INDIRECT) for indirect symbol handling support Feb 26, 2026
…direct symbol handling support

This is the first of three patches aimed to support indirect symbol handling for
the SystemZ backend. This PR introduces a `GOFF:ERAttr` to represent indirect
references, handles indirect symbols within `setSymbolAttribute()` by setting
the indirect reference bit, and also updates the HLASM streamer to emit
`XATTR REFERENCE(INDIRECT)` and various other combinations.
@amy-kwan amy-kwan force-pushed the users/amy-kwan/indirectsymbols-1 branch from 69e9313 to ad410c6 Compare February 26, 2026 05:52
Copy link
Member

@uweigand uweigand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Copy link
Member

@redstar redstar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the ListSeparator, otherwise LGTM.

const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
if (NotUnspecified || IsIndirectReference) {
OS << Sep << "REFERENCE(";
bool RequiresComma = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use

llvm::ListSeparator SepRef(",");

instead. This encapsulates the boolean logic.

Comment on lines +210 to +213
if (NotUnspecified) {
OS << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
RequiresComma = true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With SepRef, this becomes

Suggested change
if (NotUnspecified) {
OS << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
RequiresComma = true;
}
if (NotUnspecified)
OS << SepRef << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");

@amy-kwan amy-kwan requested a review from redstar February 26, 2026 20:55
@amy-kwan amy-kwan merged commit 11a92a9 into main Feb 27, 2026
10 checks passed
@amy-kwan amy-kwan deleted the users/amy-kwan/indirectsymbols-1 branch February 27, 2026 16:12
@llvm-ci
Copy link

llvm-ci commented Feb 27, 2026

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/42032

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: types/TestDoubleTypes.py (239 of 3395)
PASS: lldb-shell :: Recognizer/registration-unique.test (240 of 3395)
PASS: lldb-api :: functionalities/postmortem/elf-core/TestLinuxCore.py (241 of 3395)
PASS: lldb-api :: types/TestDoubleTypesExpr.py (242 of 3395)
PASS: lldb-api :: tools/lldb-server/commandline/TestStubSetSID.py (243 of 3395)
PASS: lldb-api :: functionalities/thread/concurrent_events/TestConcurrentSignalDelayBreak.py (244 of 3395)
PASS: lldb-api :: functionalities/thread/ignore_suspended/TestIgnoreSuspendedThread.py (245 of 3395)
PASS: lldb-api :: functionalities/tail_call_frames/ambiguous_tail_call_seq1/TestAmbiguousTailCallSeq1.py (246 of 3395)
PASS: lldb-api :: lang/c/bitfields/TestBitfields.py (247 of 3395)
PASS: lldb-api :: commands/process/detach-resumes/TestDetachResumes.py (248 of 3395)
FAIL: lldb-api :: tools/lldb-dap/evaluate/TestDAP_evaluate.py (249 of 3395)
******************** TEST 'lldb-api :: tools/lldb-dap/evaluate/TestDAP_evaluate.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib --cmake-build-type Release -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/evaluate -p TestDAP_evaluate.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 23.0.0git (https://github.com/llvm/llvm-project.git revision 11a92a9305a79548449731e3be989a3ffaa8ae53)
  clang revision 11a92a9305a79548449731e3be989a3ffaa8ae53
  llvm revision 11a92a9305a79548449731e3be989a3ffaa8ae53
Skipping the following test categories: libc++, msvcstl, dsym, pdb, gmodules, debugserver, objc

--
Command Output (stderr):
--
Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/tools/lldb-dap/evaluate
runCmd: settings clear --all

output: 

runCmd: settings set symbols.enable-external-lookup false

output: 

runCmd: settings set target.inherit-tcc true

output: 

runCmd: settings set target.disable-aslr false

output: 

runCmd: settings set target.detach-on-error false

output: 


amy-kwan added a commit that referenced this pull request Feb 27, 2026
… support (#183442)

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.

Depends on #183441.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Feb 27, 2026
…ol handling support (#183442)

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.

Depends on llvm/llvm-project#183441.
sujianIBM pushed a commit to sujianIBM/llvm-project that referenced this pull request Mar 5, 2026
…direct symbol handling support (llvm#183441)

This is the first of three patches aimed to support indirect symbol
handling for the SystemZ backend. This PR introduces a `GOFF:ERAttr` to
represent indirect references, handles indirect symbols within
`setSymbolAttribute()` by setting the indirect reference bit, and also
updates the HLASM streamer to emit `XATTR REFERENCE(INDIRECT)` and
various other combinations.
sujianIBM pushed a commit to sujianIBM/llvm-project that referenced this pull request Mar 5, 2026
… support (llvm#183442)

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.

Depends on llvm#183441.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:SystemZ llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants