[llvm] [GOFF] Emit symbols for functions. (PR #144437)
Kai Nacke via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 4 11:55:38 PST 2025
https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/144437
>From 6261752c43e16feb0ac3b42915c8de943cc96601 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 16 Jun 2025 17:27:16 -0400
Subject: [PATCH 01/18] [GOFF] Emit symbols for functions.
A function entry is mapped to a LD symbol with an offset to the begin of the section.
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 7 +--
llvm/include/llvm/MC/MCSymbolGOFF.h | 22 ++++++++-
llvm/lib/MC/CMakeLists.txt | 1 +
llvm/lib/MC/GOFFObjectWriter.cpp | 1 +
llvm/lib/MC/MCGOFFStreamer.cpp | 57 ++++++++++++++++++++++
llvm/lib/MC/MCSymbolGOFF.cpp | 39 +++++++++++++++
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 34 ++++++++-----
7 files changed, 143 insertions(+), 18 deletions(-)
create mode 100644 llvm/lib/MC/MCSymbolGOFF.cpp
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 8888d9e7bdbb3..6fa6e6481347f 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -28,9 +28,10 @@ class MCGOFFStreamer : public MCObjectStreamer {
GOFFObjectWriter &getWriter();
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return false;
- }
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
};
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 11d4df4aea634..b58b520cc5c49 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -28,7 +28,10 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::LDAttr LDAttributes;
enum SymbolFlags : uint16_t {
- SF_LD = 0x01, // LD attributes are set.
+ SF_LD = 0x01, // LD attributes are set.
+ // Leave place for EX attributes.
+ SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
+ SF_Weak = 0x08, // Symbol is weak.
};
public:
@@ -39,7 +42,8 @@ class MCSymbolGOFF : public MCSymbol {
modifyFlags(SF_LD, SF_LD);
LDAttributes = Attr;
}
- GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
+ const GOFF::LDAttr &getLDAttributes() const { return LDAttributes; }
+ GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
bool hasLDAttributes() const { return getFlags() & SF_LD; }
void setADA(MCSectionGOFF *AssociatedDataArea) {
@@ -47,6 +51,20 @@ class MCSymbolGOFF : public MCSymbol {
AssociatedDataArea->RequiresNonZeroLength = true;
}
MCSectionGOFF *getADA() const { return ADA; }
+
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) const { IsExternal = Value; }
+
+ void setHidden(bool Value = true) {
+ modifyFlags(Value ? SF_Hidden : 0, SF_Hidden);
+ }
+ bool isHidden() const { return getFlags() & SF_Hidden; }
+ bool isExported() const { return !isHidden(); }
+
+ void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
+ bool isWeak() const { return getFlags() & SF_Weak; }
+
+ void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 70c4577aeec0a..1388f130bb806 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMMC
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
+ MCSymbolGOFF.cpp
MCSymbolXCOFF.cpp
MCTargetOptions.cpp
MCTargetOptionsCommandFlags.cpp
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index a3eaaa743039d..b42ba148ef65b 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -328,6 +328,7 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
Section.getEDAttributes().NameSpace, Symbol.getLDAttributes());
if (Symbol.getADA())
LD.ADAEsdId = Symbol.getADA()->getOrdinal();
+ LD.Offset = Asm.getSymbolOffset(Symbol);
writeSymbol(LD);
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index ad6397bce70f0..c76e8cd1dc3c8 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -15,7 +15,9 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCGOFFObjectWriter.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
@@ -37,6 +39,61 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
}
}
+void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCObjectStreamer::emitLabel(Symbol, Loc);
+ static_cast<MCSymbolGOFF *>(Symbol)->initAttributes();
+}
+
+bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
+ auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
+ switch (Attribute) {
+ case MCSA_Invalid:
+ case MCSA_Cold:
+ case MCSA_ELF_TypeFunction:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeObject:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
+ case MCSA_ELF_TypeGnuUniqueObject:
+ case MCSA_LGlobal:
+ case MCSA_Extern:
+ case MCSA_Exported:
+ case MCSA_IndirectSymbol:
+ case MCSA_Internal:
+ case MCSA_LazyReference:
+ case MCSA_NoDeadStrip:
+ case MCSA_SymbolResolver:
+ case MCSA_AltEntry:
+ case MCSA_PrivateExtern:
+ case MCSA_Protected:
+ case MCSA_Reference:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_WeakAntiDep:
+ case MCSA_Memtag:
+ return false;
+
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_Local:
+ Symbol->setExternal(false);
+ break;
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ Symbol->setExternal(true);
+ Symbol->setWeak();
+ break;
+ case MCSA_Hidden:
+ Symbol->setHidden(true);
+ break;
+ }
+
+ return true;
+}
+
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
new file mode 100644
index 0000000000000..86de21b11bc0a
--- /dev/null
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -0,0 +1,39 @@
+//===- MCSymbolGOFF.cpp - GOFF Symbol Representation ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSymbolGOFF.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+void MCSymbolGOFF::initAttributes() {
+ if (hasLDAttributes())
+ return;
+
+ if (isDefined()) {
+ MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
+ GOFF::ESDBindingScope BindingScope =
+ isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
+ : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ GOFF::ESDBindingStrength BindingStrength =
+ isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+ if (Section.isED()) {
+ setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, BindingStrength,
+ GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
+ BindingScope});
+ } else if (Section.isPR()) {
+ // For data symbols, the attributes are already determind in TLOFI.
+ // TODO Does it make sense to it to here?
+ } else
+ llvm_unreachable("Unexpected section type for label");
+ }
+ // TODO Handle external symbol.
+}
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index b98584df54d5a..6caa8f4d607de 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -104,26 +104,34 @@ entry:
; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type LD.
+; The name is me.
+; CHECK-NEXT: 000320 03 00 00 02 [[ME:00 00 00 09]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000360 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000320 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000370 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
; Text record for the section .&ppa2.
-; CHECK: 0003c0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000410 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the ADA section test#S.
-; CHECK: 000410 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000460 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section B_IDRL.
-; CHECK: 000460 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0004b0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 0004b0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>From 194ba3a6efd669d3737efa033e767a45bd6f756e Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 29 Oct 2025 13:19:28 -0400
Subject: [PATCH 02/18] Add HLASM output and external references
Adds HLASM output and tests for it, per reviewer comment.
Also adds external references, because it fits very well
into the implementation.
---
llvm/include/llvm/MC/MCDirectives.h | 4 +
llvm/include/llvm/MC/MCGOFFAttributes.h | 8 +
llvm/include/llvm/MC/MCGOFFStreamer.h | 3 +
llvm/include/llvm/MC/MCSymbolGOFF.h | 28 +++-
llvm/lib/MC/GOFFObjectWriter.cpp | 21 +++
llvm/lib/MC/MCAsmStreamer.cpp | 3 +
llvm/lib/MC/MCELFStreamer.cpp | 2 +
llvm/lib/MC/MCGOFFStreamer.cpp | 19 +++
llvm/lib/MC/MCMachOStreamer.cpp | 2 +
llvm/lib/MC/MCSymbolGOFF.cpp | 28 ++--
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 158 +++++++++++++++++-
.../MCTargetDesc/SystemZHLASMAsmStreamer.h | 7 +-
.../MCTargetDesc/SystemZTargetStreamer.cpp | 17 +-
.../MCTargetDesc/SystemZTargetStreamer.h | 7 +-
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 23 +++
llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 52 ++++--
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 34 ++--
llvm/test/CodeGen/SystemZ/zos-symbol-1.ll | 37 ++++
19 files changed, 395 insertions(+), 60 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index f8b7e05b3719b..f69144367c8e7 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,6 +48,10 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
+
+ // Attributes specific for HLASM.
+ MCSA_Code, ///< symbol is code (GOFF)
+ MCSA_Data, ///< symbol is data (GOFF)
};
enum MCDataRegionType {
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index c996f0cae2c69..1631d59462935 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -80,6 +80,14 @@ struct PRAttr {
uint32_t SortKey = 0;
};
+// Attributes for ER symbols.
+struct ERAttr {
+ GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+ GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
+ GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+ GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+};
+
// Predefined GOFF class names.
constexpr StringLiteral CLASS_CODE = "C_CODE64";
constexpr StringLiteral CLASS_WSA = "C_WSA64";
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 6fa6e6481347f..3d13ddf216aa3 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -14,6 +14,7 @@
namespace llvm {
class GOFFObjectWriter;
+class MCSymbolGOFF;
class MCGOFFStreamer : public MCObjectStreamer {
@@ -34,6 +35,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
+
+ void emitExterns();
};
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index b58b520cc5c49..58305a00ec235 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -23,13 +23,21 @@ namespace llvm {
class MCSymbolGOFF : public MCSymbol {
// Associated data area of the section. Needs to be emitted first.
- MCSectionGOFF *ADA;
+ MCSectionGOFF *ADA = nullptr;
+
+ // Owner of the symbol if symbol is an external reference. External references
+ // need a section, too, but adding them to a section would make the symbol
+ // defined.
+ MCSectionGOFF *Owner = nullptr;
GOFF::LDAttr LDAttributes;
+ GOFF::ERAttr ERAttributes;
+
+ GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
enum SymbolFlags : uint16_t {
SF_LD = 0x01, // LD attributes are set.
- // Leave place for EX attributes.
+ SF_ER = 0x02, // ER attributes are set.
SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
SF_Weak = 0x08, // Symbol is weak.
};
@@ -46,12 +54,25 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
bool hasLDAttributes() const { return getFlags() & SF_LD; }
+ void setERAttributes(GOFF::ERAttr Attr) {
+ modifyFlags(SF_ER, SF_ER);
+ ERAttributes = Attr;
+ }
+ const GOFF::ERAttr &getERAttributes() const { return ERAttributes; }
+ GOFF::ERAttr &getERAttributes() { return ERAttributes; }
+ bool hasERAttributes() const { return getFlags() & SF_ER; }
+
void setADA(MCSectionGOFF *AssociatedDataArea) {
ADA = AssociatedDataArea;
AssociatedDataArea->RequiresNonZeroLength = true;
}
MCSectionGOFF *getADA() const { return ADA; }
+ void setOwner(MCSectionGOFF *Owner) {
+ this->Owner = Owner;
+ }
+ MCSectionGOFF *getOwner() const { return Owner; }
+
bool isExternal() const { return IsExternal; }
void setExternal(bool Value) const { IsExternal = Value; }
@@ -64,6 +85,9 @@ class MCSymbolGOFF : public MCSymbol {
void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
bool isWeak() const { return getFlags() & SF_Weak; }
+ void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
+ GOFF::ESDExecutable getCodeData() const { return CodeData; }
+
void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index b42ba148ef65b..51f95813eabc8 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -266,6 +266,17 @@ class GOFFSymbol {
BehavAttrs.setBindingScope(Attr.BindingScope);
BehavAttrs.setAlignment(EDAttr.Alignment);
}
+
+ GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
+ const GOFF::ERAttr &Attr)
+ : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+ SymbolType(GOFF::ESD_ST_ExternalReference),
+ NameSpace(GOFF::ESD_NS_NormalName) {
+ BehavAttrs.setExecutable(Attr.Executable);
+ BehavAttrs.setBindingStrength(Attr.BindingStrength);
+ BehavAttrs.setLinkageType(Attr.Linkage);
+ BehavAttrs.setBindingScope(Attr.BindingScope);
+ }
};
class GOFFWriter {
@@ -279,6 +290,7 @@ class GOFFWriter {
void defineSectionSymbols(const MCSectionGOFF &Section);
void defineLabel(const MCSymbolGOFF &Symbol);
+ void defineExtern(const MCSymbolGOFF &Symbol);
void defineSymbols();
public:
@@ -332,6 +344,12 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
writeSymbol(LD);
}
+void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
+ GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(),
+ Symbol.getOwner()->getOrdinal(), Symbol.getERAttributes());
+ writeSymbol(ER);
+}
+
void GOFFWriter::defineSymbols() {
unsigned Ordinal = 0;
// Process all sections.
@@ -349,6 +367,9 @@ void GOFFWriter::defineSymbols() {
if (Symbol.hasLDAttributes()) {
Symbol.setIndex(++Ordinal);
defineLabel(Symbol);
+ } else if (Symbol.hasERAttributes()) {
+ Symbol.setIndex(++Ordinal);
+ defineExtern(Symbol);
}
}
}
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 885fa55b65d50..60e3757f60fed 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -774,6 +774,9 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Assemblers currently do not support a .cold directive.
case MCSA_Exported:
// Non-AIX assemblers currently do not support exported visibility.
+ case MCSA_Code:
+ case MCSA_Data:
+ // Only for HLASM.
return false;
case MCSA_Memtag:
OS << "\t.memtag\t";
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 1bc1b92610871..4d4148c506b4f 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -151,6 +151,8 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_IndirectSymbol:
case MCSA_Exported:
case MCSA_WeakAntiDep:
+ case MCSA_Code:
+ case MCSA_Data:
return false;
case MCSA_NoDeadStrip:
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index c76e8cd1dc3c8..62a9117fe895f 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCGOFFStreamer.h"
+#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -75,6 +76,12 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
+ case MCSA_Code:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
+ break;
+ case MCSA_Data:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
@@ -94,6 +101,18 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
return true;
}
+void MCGOFFStreamer::emitExterns() {
+ for (auto &Symbol : getAssembler().symbols()) {
+ if (Symbol.isTemporary())
+ continue;
+ if (Symbol.isRegistered()) {
+ auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
+ Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
+ Sym.initAttributes();
+ }
+ }
+}
+
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 2b7a248e6d109..da148f81012f7 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -299,6 +299,8 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Exported:
case MCSA_Memtag:
case MCSA_WeakAntiDep:
+ case MCSA_Code:
+ case MCSA_Data:
return false;
case MCSA_Global:
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 86de21b11bc0a..5e248dea033a4 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -13,20 +13,26 @@
using namespace llvm;
void MCSymbolGOFF::initAttributes() {
- if (hasLDAttributes())
+ // Temporary labels are not emitted into the object file.
+ if (isTemporary())
return;
+ // Do not initialize the attributes multiple times.
+ if (hasLDAttributes() || hasERAttributes())
+ return;
+
+ GOFF::ESDBindingScope BindingScope =
+ isExternal()
+ ? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ GOFF::ESDBindingStrength BindingStrength =
+ isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+
if (isDefined()) {
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
- GOFF::ESDBindingScope BindingScope =
- isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
- : GOFF::ESD_BSC_Library)
- : GOFF::ESD_BSC_Section;
- GOFF::ESDBindingStrength BindingStrength =
- isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong;
if (Section.isED()) {
- setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, BindingStrength,
+ setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength,
GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
BindingScope});
} else if (Section.isPR()) {
@@ -34,6 +40,8 @@ void MCSymbolGOFF::initAttributes() {
// TODO Does it make sense to it to here?
} else
llvm_unreachable("Unexpected section type for label");
+ } else {
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength,
+ GOFF::ESD_LT_XPLink, BindingScope});
}
- // TODO Handle external symbol.
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 72bb37265259e..8553f8bc14f56 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -8,12 +8,19 @@
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCGOFFAttributes.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Signals.h"
#include <sstream>
using namespace llvm;
+void SystemZHLASMAsmStreamer::visitUsedSymbol(const MCSymbol &Sym) {
+ Assembler->registerSymbol(Sym);
+}
+
void SystemZHLASMAsmStreamer::EmitEOL() {
// Comments are emitted on a new line before the instruction.
if (IsVerboseAsm)
@@ -183,17 +190,132 @@ void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
EmitEOL();
}
+static void emitXATTR(raw_ostream &OS, StringRef Name,
+ GOFF::ESDLinkageType Linkage,
+ GOFF::ESDExecutable Executable,
+ GOFF::ESDBindingScope BindingScope) {
+ llvm::ListSeparator Sep(",");
+ 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") << ")";
+ if (BindingScope != GOFF::ESD_BSC_Unspecified) {
+ OS << Sep << "SCOPE(";
+ switch (BindingScope) {
+ case GOFF::ESD_BSC_Section:
+ OS << "SECTION";
+ break;
+ case GOFF::ESD_BSC_Module:
+ OS << "MODULE";
+ break;
+ case GOFF::ESD_BSC_Library:
+ OS << "LIBRARY";
+ break;
+ case GOFF::ESD_BSC_ImportExport:
+ OS << "EXPORT";
+ break;
+ default:
+ break;
+ }
+ OS << ')';
+ }
+ OS << '\n';
+}
+
+static bool sameNameAsCSECT(MCSymbolGOFF *Sym) {
+ if (Sym->hasLDAttributes() && Sym->isInSection()) {
+ MCSectionGOFF &ED = static_cast<MCSectionGOFF &>(Sym->getSection());
+ return Sym->getName() == ED.getParent()->getName();
+ }
+ return false;
+}
+
void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCSymbolGOFF *Sym = static_cast<MCSymbolGOFF *>(Symbol);
+
+ MCStreamer::emitLabel(Sym, Loc);
+ Sym->initAttributes();
+
+ // Emit ENTRY statement only if not implied by CSECT.
+ bool EmitEntry = !sameNameAsCSECT(Sym);
+
+ if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
+ GOFF::LDAttr &LD = Sym->getLDAttributes();
+ if (EmitEntry) {
+ OS << " ENTRY " << Sym->getName();
+ EmitEOL();
+ }
- MCStreamer::emitLabel(Symbol, Loc);
+ emitXATTR(OS, Sym->getName(), LD.Linkage, LD.Executable, LD.BindingScope);
+ EmitEOL();
+ }
- Symbol->print(OS, MAI);
// TODO Need to adjust this based on Label type
- OS << " DS 0H";
- // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
- // moved to HLASM syntax.
- // OS << MAI->getLabelSuffix();
- EmitEOL();
+ if (EmitEntry) {
+ OS << Sym->getName() << " DS 0H";
+ // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
+ // moved to HLASM syntax.
+ // OS << MAI->getLabelSuffix();
+ EmitEOL();
+ }
+}
+
+bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
+ auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
+ switch (Attribute) {
+ case MCSA_Invalid:
+ case MCSA_Cold:
+ case MCSA_ELF_TypeFunction:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeObject:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
+ case MCSA_ELF_TypeGnuUniqueObject:
+ case MCSA_LGlobal:
+ case MCSA_Extern:
+ case MCSA_Exported:
+ case MCSA_IndirectSymbol:
+ case MCSA_Internal:
+ case MCSA_LazyReference:
+ case MCSA_NoDeadStrip:
+ case MCSA_SymbolResolver:
+ case MCSA_AltEntry:
+ case MCSA_PrivateExtern:
+ case MCSA_Protected:
+ case MCSA_Reference:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_WeakAntiDep:
+ case MCSA_Memtag:
+ return false;
+
+ case MCSA_Code:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
+ break;
+ case MCSA_Data:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
+ break;
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_Local:
+ Symbol->setExternal(false);
+ break;
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ Symbol->setExternal(true);
+ Symbol->setWeak();
+ break;
+ case MCSA_Hidden:
+ Symbol->setHidden(true);
+ break;
+ }
+
+ return true;
}
void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
@@ -276,6 +398,7 @@ void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
assert(getCurrentSectionOnly() &&
"Cannot emit contents before setting section!");
+ MCStreamer::emitValueImpl(Value, Size, Loc);
OS << " DC ";
emitHLASMValueImpl(Value, Size, true);
EmitEOL();
@@ -285,3 +408,24 @@ void SystemZHLASMAsmStreamer::emitEnd() {
OS << " END";
EmitEOL();
}
+
+void SystemZHLASMAsmStreamer::emitExterns() {
+ for (auto &Symbol : getAssembler().symbols()) {
+ if (Symbol.isTemporary())
+ continue;
+ if (Symbol.isRegistered()) {
+ auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
+ Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
+ Sym.initAttributes();
+ GOFF::ERAttr &ER = Sym.getERAttributes();
+ OS << " "
+ << (ER.BindingStrength == GOFF::ESDBindingStrength::ESD_BST_Weak
+ ? "WXTRN"
+ : "EXTRN")
+ << " " << Sym.getName();
+ EmitEOL();
+ emitXATTR(OS, Sym.getName(), ER.Linkage, ER.Executable, ER.BindingScope);
+ EmitEOL();
+ }
+ }
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
index 93b1ac4d901aa..81cfdad472244 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -28,6 +28,7 @@
#include "llvm/Support/FormattedStream.h"
namespace llvm {
+class MCSymbolGOFF;
class SystemZHLASMAsmStreamer final : public MCStreamer {
constexpr static size_t InstLimit = 80;
@@ -100,14 +101,13 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
/// @name MCStreamer Interface
/// @{
+ void visitUsedSymbol(const MCSymbol &Sym) override;
void changeSection(MCSection *Section, uint32_t Subsection) override;
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc) override;
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return false;
- }
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
@@ -123,6 +123,7 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
/// @}
void emitEnd();
+ void emitExterns();
};
} // namespace llvm
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index 1a3e373f25374..d25c77e21d9f8 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -15,6 +15,7 @@
#include "SystemZTargetStreamer.h"
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCGOFFStreamer.h"
#include "llvm/MC/MCObjectFileInfo.h"
using namespace llvm;
@@ -38,12 +39,12 @@ SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() {
return static_cast<SystemZHLASMAsmStreamer &>(getStreamer());
}
-void SystemZTargetHLASMStreamer::emitExtern(StringRef Sym) {
- getStreamer().emitRawText(Twine(" EXTRN ") + Twine(Sym));
-}
-
void SystemZTargetHLASMStreamer::emitEnd() { getHLASMStreamer().emitEnd(); }
+void SystemZTargetHLASMStreamer::emitExterns() {
+ getHLASMStreamer().emitExterns();
+}
+
// HLASM statements can only perform a single operation at a time
const MCExpr *SystemZTargetHLASMStreamer::createWordDiffExpr(
MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
@@ -66,3 +67,11 @@ const MCExpr *SystemZTargetGOFFStreamer::createWordDiffExpr(
MCSymbolRefExpr::create(Lo, Ctx), Ctx),
MCConstantExpr::create(1, Ctx), Ctx);
}
+
+MCGOFFStreamer &SystemZTargetGOFFStreamer::getGOFFStreamer() {
+ return static_cast<MCGOFFStreamer &>(getStreamer());
+}
+
+void SystemZTargetGOFFStreamer::emitExterns() {
+ getGOFFStreamer().emitExterns();
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 3fc09bc8c683a..31433cc9739c6 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -20,6 +20,7 @@
#include <utility>
namespace llvm {
+class MCGOFFStreamer;
class SystemZHLASMAsmStreamer;
class SystemZTargetStreamer : public MCTargetStreamer {
@@ -57,8 +58,8 @@ class SystemZTargetStreamer : public MCTargetStreamer {
virtual void emitMachine(StringRef CPUOrCommand) {};
- virtual void emitExtern(StringRef Str) {};
virtual void emitEnd() {};
+ virtual void emitExterns() {};
virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) {
@@ -69,6 +70,8 @@ class SystemZTargetStreamer : public MCTargetStreamer {
class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
+ MCGOFFStreamer &getGOFFStreamer();
+ void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
@@ -80,8 +83,8 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: SystemZTargetStreamer(S), OS(OS) {}
SystemZHLASMAsmStreamer &getHLASMStreamer();
- void emitExtern(StringRef Sym) override;
void emitEnd() override;
+ void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index e31d7c6a86476..87ff2f0353161 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -26,6 +26,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionELF.h"
@@ -1112,6 +1113,22 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
if (TT.isOSzOS()) {
emitADASection();
emitIDRLSection(M);
+ // Emit EXTRN declarations.
+ OutStreamer->pushSection();
+ for (auto &GO : M.global_objects()) {
+ if (GO.isDeclaration()) {
+ MCSymbol *Sym = TM.getSymbol(&GO);
+ OutStreamer->emitSymbolAttribute(
+ Sym, GO.hasExternalWeakLinkage() ? MCSA_WeakReference : MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
+ : MCSA_Data);
+ }
+ }
+ OutStreamer->switchSection(
+ static_cast<MCSectionGOFF *>(getObjFileLowering().getTextSection())
+ ->getParent());
+ getTargetStreamer()->emitExterns();
+ OutStreamer->popSection();
}
emitAttributes(M);
// Emit the END instruction in case of HLASM output. This must be the last
@@ -1570,6 +1587,9 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
+ // TODO Mark as OS linkage.
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
// Create symbol and assign to class field for use in PPA1.
PPA2Sym = OutContext.createTempSymbol("PPA2", false);
@@ -1734,6 +1754,9 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() {
OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca");
}
OutStreamer->emitInt32(DSAAndFlags);
+
+ // Functions denote CODE.
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Code);
}
AsmPrinter::emitFunctionEntryLabel();
diff --git a/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll b/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
index b28f0dd17599a..43ac737b29778 100644
--- a/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple s390x-ibm-zos < %s | FileCheck %s
+; RUN: llc -mtriple s390x-ibm-zos -emit-gnuas-syntax-on-zos=false < %s | FileCheck %s
define signext i32 @_Z9computeitv() personality ptr @__zos_cxx_personality_v2 {
ret i32 0
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 6caa8f4d607de..0e6619157261d 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -104,34 +104,50 @@ entry:
; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type ER.
+; The name is CELQSTRT.
+; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+
; ESD record, type LD.
; The name is me.
-; CHECK-NEXT: 000320 03 00 00 02 [[ME:00 00 00 09]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000360 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+; CHECK-NEXT: 000370 03 00 00 02 [[ME:00 00 00 0a]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 0003b0 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+
+; ESD record, type ER.
+; The name is other.
+; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000370 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000380 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000410 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
; Text record for the section .&ppa2.
-; CHECK: 000410 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0004b0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the ADA section test#S.
-; CHECK: 000460 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000500 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section B_IDRL.
-; CHECK: 0004b0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000550 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0005a0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index 0f608c1206b96..bf3fd8234eb33 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -147,29 +147,37 @@ source_filename = "test.ll"
; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 0004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type ER.
+; The name is CELQSTRT.
+; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000500 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK-NEXT: 000550 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section .&ppa2.
-; CHECK: 000550 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0005a0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section data.
; Length is 4, and the content is 0x2a = 42.
-; CHECK: 0005a0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+; CHECK: 0005f0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000600 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
; There is no text record for section bss!
; Text record for the section B_IDRL.
-; CHECK: 0005f0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000600 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000640 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000690 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
new file mode 100644
index 0000000000000..eaae1b7bbcfd2
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
@@ -0,0 +1,37 @@
+; RUN: llc <%s --mtriple s390x-ibm-zos -emit-gnuas-syntax-on-zos=false | FileCheck %s
+
+declare extern_weak void @other1(...)
+declare void @other2(...)
+
+define internal void @me1() {
+entry:
+ ret void
+}
+
+define hidden void @me2() {
+entry:
+ tail call void @other1()
+ ret void
+}
+
+define default void @me3() {
+entry:
+ tail call void @other2()
+ ret void
+}
+
+; CHECK: ENTRY me1
+; CHECK-NEXT: me1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(SECTION)
+
+; CHECK: ENTRY me2
+; CHECK-NEXT: me2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(LIBRARY)
+
+; CHECK: ENTRY me3
+; CHECK-NEXT: me3 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+
+; CHECK: EXTRN CELQSTRT
+; CHECK-NEXT: CELQSTRT XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: WXTRN other1
+; CHECK-NEXT: other1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: EXTRN other2
+; CHECK-NEXT: other2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
\ No newline at end of file
>From c19957c59feabbcfb36107f019e915acb6787050 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 3 Nov 2025 17:36:29 -0500
Subject: [PATCH 03/18] Fix some formatting issues.
---
llvm/include/llvm/MC/MCSymbolGOFF.h | 4 +---
llvm/lib/MC/MCSymbolGOFF.cpp | 4 ++--
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 5 +++--
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 58305a00ec235..301be80a8b575 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -68,9 +68,7 @@ class MCSymbolGOFF : public MCSymbol {
}
MCSectionGOFF *getADA() const { return ADA; }
- void setOwner(MCSectionGOFF *Owner) {
- this->Owner = Owner;
- }
+ void setOwner(MCSectionGOFF *Owner) { this->Owner = Owner; }
MCSectionGOFF *getOwner() const { return Owner; }
bool isExternal() const { return IsExternal; }
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 5e248dea033a4..33c7d658038bd 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -41,7 +41,7 @@ void MCSymbolGOFF::initAttributes() {
} else
llvm_unreachable("Unexpected section type for label");
} else {
- setERAttributes(GOFF::ERAttr{CodeData, BindingStrength,
- GOFF::ESD_LT_XPLink, BindingScope});
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
+ BindingScope});
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 87ff2f0353161..0a02397ab100b 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1118,8 +1118,9 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
for (auto &GO : M.global_objects()) {
if (GO.isDeclaration()) {
MCSymbol *Sym = TM.getSymbol(&GO);
- OutStreamer->emitSymbolAttribute(
- Sym, GO.hasExternalWeakLinkage() ? MCSA_WeakReference : MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
+ ? MCSA_WeakReference
+ : MCSA_Global);
OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
: MCSA_Data);
}
>From 2fa73af9d9f9fc87c939e175f90343aa8738d638 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 15:46:26 -0500
Subject: [PATCH 04/18] ER symbols also need to set AMODE
---
llvm/include/llvm/MC/MCGOFFAttributes.h | 1 +
llvm/lib/MC/GOFFObjectWriter.cpp | 1 +
llvm/lib/MC/MCSymbolGOFF.cpp | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 4 ++--
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 2 +-
5 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 1631d59462935..e771f36f35346 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -85,6 +85,7 @@ struct ERAttr {
GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+ GOFF::ESDAmode Amode;
GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
};
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 51f95813eabc8..07aecf13bce37 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -275,6 +275,7 @@ class GOFFSymbol {
BehavAttrs.setExecutable(Attr.Executable);
BehavAttrs.setBindingStrength(Attr.BindingStrength);
BehavAttrs.setLinkageType(Attr.Linkage);
+ BehavAttrs.setAmode(Attr.Amode);
BehavAttrs.setBindingScope(Attr.BindingScope);
}
};
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 33c7d658038bd..2d067155d45aa 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -42,6 +42,6 @@ void MCSymbolGOFF::initAttributes() {
llvm_unreachable("Unexpected section type for label");
} else {
setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
- BindingScope});
+ GOFF::ESD_AMODE_64, BindingScope});
}
}
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 0e6619157261d..728686127bacd 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -109,7 +109,7 @@ entry:
; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; ESD record, type LD.
@@ -125,7 +125,7 @@ entry:
; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
; Text record for the code section C_CODE64.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index bf3fd8234eb33..d3a0d75acba88 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -152,7 +152,7 @@ source_filename = "test.ll"
; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; Text record for the code section C_CODE64.
>From 43dcc134f279af6836a635748c8db084f420a92f Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 17:49:56 -0500
Subject: [PATCH 05/18] Add linkage attribute
---
llvm/include/llvm/MC/MCDirectives.h | 4 ++--
llvm/include/llvm/MC/MCSymbolGOFF.h | 4 ++++
llvm/lib/MC/MCELFStreamer.cpp | 3 +++
llvm/lib/MC/MCGOFFStreamer.cpp | 6 ++++++
llvm/lib/MC/MCMachOStreamer.cpp | 2 ++
llvm/lib/MC/MCSymbolGOFF.cpp | 7 +++----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 2 +-
9 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index f69144367c8e7..39ecadb9cd029 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,10 +48,10 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
-
- // Attributes specific for HLASM.
MCSA_Code, ///< symbol is code (GOFF)
MCSA_Data, ///< symbol is data (GOFF)
+ MCSA_OSLinkage, ///< symbol uses OS linkage (GOFF)
+ MCSA_XPLinkage, ///< symbol uses XP linkage (GOFF)
};
enum MCDataRegionType {
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 301be80a8b575..f1397a6b3822c 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -34,6 +34,7 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::ERAttr ERAttributes;
GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
+ GOFF::ESDLinkageType Linkage = GOFF::ESDLinkageType::ESD_LT_XPLink;
enum SymbolFlags : uint16_t {
SF_LD = 0x01, // LD attributes are set.
@@ -86,6 +87,9 @@ class MCSymbolGOFF : public MCSymbol {
void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
GOFF::ESDExecutable getCodeData() const { return CodeData; }
+ void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
+ GOFF::ESDLinkageType getLinkage() const { return Linkage; }
+
void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 4d4148c506b4f..a296977f7ae98 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
@@ -153,6 +154,8 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_WeakAntiDep:
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
return false;
case MCSA_NoDeadStrip:
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 62a9117fe895f..8450f7cfb5381 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -82,6 +82,12 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Data:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
+ case MCSA_OSLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
+ break;
+ case MCSA_XPLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index da148f81012f7..3b0acd71e2057 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -301,6 +301,8 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_WeakAntiDep:
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
return false;
case MCSA_Global:
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 2d067155d45aa..345572418ecd8 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -32,16 +32,15 @@ void MCSymbolGOFF::initAttributes() {
if (isDefined()) {
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
if (Section.isED()) {
- setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength,
- GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
- BindingScope});
+ setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength, Linkage,
+ GOFF::ESD_AMODE_64, BindingScope});
} else if (Section.isPR()) {
// For data symbols, the attributes are already determind in TLOFI.
// TODO Does it make sense to it to here?
} else
llvm_unreachable("Unexpected section type for label");
} else {
- setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, Linkage,
GOFF::ESD_AMODE_64, BindingScope});
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 0a02397ab100b..193e6ef6d1e64 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1589,7 +1589,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
- // TODO Mark as OS linkage.
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
// Create symbol and assign to class field for use in PPA1.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 728686127bacd..cae371b07d0eb 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -110,7 +110,7 @@ entry:
; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000360 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; ESD record, type LD.
; The name is me.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index d3a0d75acba88..f59bace65ca73 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -153,7 +153,7 @@ source_filename = "test.ll"
; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000540 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
>From ee1434b325d46403b98cb1c369b69be04db22a08 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 18:02:27 -0500
Subject: [PATCH 06/18] Update the asm output for the linkage type
---
llvm/lib/MC/MCAsmStreamer.cpp | 2 ++
.../Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 6 ++++++
llvm/test/CodeGen/SystemZ/zos-symbol-1.ll | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 60e3757f60fed..18db8ef99c2cf 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -776,6 +776,8 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Non-AIX assemblers currently do not support exported visibility.
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
// Only for HLASM.
return false;
case MCSA_Memtag:
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 8553f8bc14f56..7294d0a12b7ce 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -299,6 +299,12 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Data:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
+ case MCSA_OSLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
+ break;
+ case MCSA_XPLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
index eaae1b7bbcfd2..bd4361aaafdcb 100644
--- a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
@@ -30,7 +30,7 @@ entry:
; CHECK-NEXT: me3 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK: EXTRN CELQSTRT
-; CHECK-NEXT: CELQSTRT XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: CELQSTRT XATTR LINKAGE(OS),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK-NEXT: WXTRN other1
; CHECK-NEXT: other1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK-NEXT: EXTRN other2
>From 214d716d483c6536c56fb45138bbca035b25c846 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 19 Nov 2025 13:37:36 -0500
Subject: [PATCH 07/18] Replace MCSA_Code/Data
Use MCSA_ELF_TypeFunction/TypeObject instead.
---
llvm/include/llvm/MC/MCDirectives.h | 2 --
llvm/lib/MC/MCAsmStreamer.cpp | 2 --
llvm/lib/MC/MCELFStreamer.cpp | 2 --
llvm/lib/MC/MCGOFFStreamer.cpp | 6 ++----
llvm/lib/MC/MCMachOStreamer.cpp | 2 --
.../SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 6 ++----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 9 +++++----
7 files changed, 9 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index 39ecadb9cd029..3b9c4670399c9 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,8 +48,6 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
- MCSA_Code, ///< symbol is code (GOFF)
- MCSA_Data, ///< symbol is data (GOFF)
MCSA_OSLinkage, ///< symbol uses OS linkage (GOFF)
MCSA_XPLinkage, ///< symbol uses XP linkage (GOFF)
};
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 18db8ef99c2cf..7ff570c7df402 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -774,8 +774,6 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Assemblers currently do not support a .cold directive.
case MCSA_Exported:
// Non-AIX assemblers currently do not support exported visibility.
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
// Only for HLASM.
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index a296977f7ae98..13a7f6d999e61 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -152,8 +152,6 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_IndirectSymbol:
case MCSA_Exported:
case MCSA_WeakAntiDep:
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
return false;
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 8450f7cfb5381..81472ba5e4de6 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -51,9 +51,7 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
switch (Attribute) {
case MCSA_Invalid:
case MCSA_Cold:
- case MCSA_ELF_TypeFunction:
case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeObject:
case MCSA_ELF_TypeTLS:
case MCSA_ELF_TypeCommon:
case MCSA_ELF_TypeNoType:
@@ -76,10 +74,10 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
- case MCSA_Code:
+ case MCSA_ELF_TypeFunction:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
break;
- case MCSA_Data:
+ case MCSA_ELF_TypeObject:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
case MCSA_OSLinkage:
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 3b0acd71e2057..b8e7772f4e16f 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -299,8 +299,6 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Exported:
case MCSA_Memtag:
case MCSA_WeakAntiDep:
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
return false;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 7294d0a12b7ce..ac0dd84fe9941 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -268,9 +268,7 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
switch (Attribute) {
case MCSA_Invalid:
case MCSA_Cold:
- case MCSA_ELF_TypeFunction:
case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeObject:
case MCSA_ELF_TypeTLS:
case MCSA_ELF_TypeCommon:
case MCSA_ELF_TypeNoType:
@@ -293,10 +291,10 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
- case MCSA_Code:
+ case MCSA_ELF_TypeFunction:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
break;
- case MCSA_Data:
+ case MCSA_ELF_TypeObject:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
case MCSA_OSLinkage:
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 193e6ef6d1e64..b895ae9546e5a 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1121,8 +1121,9 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
? MCSA_WeakReference
: MCSA_Global);
- OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
- : MCSA_Data);
+ OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO)
+ ? MCSA_ELF_TypeFunction
+ : MCSA_ELF_TypeObject);
}
}
OutStreamer->switchSection(
@@ -1588,7 +1589,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
- OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_ELF_TypeFunction);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
@@ -1757,7 +1758,7 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() {
OutStreamer->emitInt32(DSAAndFlags);
// Functions denote CODE.
- OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Code);
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
}
AsmPrinter::emitFunctionEntryLabel();
>From 1f4399374acfb1b4cd5a7995af0ce9d4205c2230 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 19 Nov 2025 16:36:30 -0500
Subject: [PATCH 08/18] Remove owner from MCSymbolGOFF
It's only needed on the binary object path, pushing the section into the GOFFObjectWriter is enough.
---
llvm/include/llvm/MC/MCGOFFObjectWriter.h | 6 +++++
llvm/include/llvm/MC/MCGOFFStreamer.h | 2 ++
llvm/include/llvm/MC/MCSymbolGOFF.h | 8 -------
llvm/lib/MC/GOFFObjectWriter.cpp | 12 +++++-----
llvm/lib/MC/MCGOFFStreamer.cpp | 22 +++++++++++++------
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 1 -
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 ----
7 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index ec07637dd2847..90887b296d46f 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -14,6 +14,7 @@
namespace llvm {
class MCObjectWriter;
+class MCSectionGOFF;
class raw_pwrite_stream;
class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
@@ -37,11 +38,16 @@ class GOFFObjectWriter : public MCObjectWriter {
// The stream used to write the GOFF records.
raw_pwrite_stream &OS;
+ // The RootSD section.
+ MCSectionGOFF *RootSD = nullptr;
+
public:
GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
raw_pwrite_stream &OS);
~GOFFObjectWriter() override;
+ void setRootSD(MCSectionGOFF *RootSD) { this->RootSD = RootSD; }
+
// Implementation of the MCObjectWriter interface.
void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue) override {}
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 3d13ddf216aa3..622fca0c5e70f 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -25,6 +25,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
~MCGOFFStreamer() override;
+ void finishImpl() override;
+
void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
GOFFObjectWriter &getWriter();
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index f1397a6b3822c..61a5db3d83540 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -25,11 +25,6 @@ class MCSymbolGOFF : public MCSymbol {
// Associated data area of the section. Needs to be emitted first.
MCSectionGOFF *ADA = nullptr;
- // Owner of the symbol if symbol is an external reference. External references
- // need a section, too, but adding them to a section would make the symbol
- // defined.
- MCSectionGOFF *Owner = nullptr;
-
GOFF::LDAttr LDAttributes;
GOFF::ERAttr ERAttributes;
@@ -69,9 +64,6 @@ class MCSymbolGOFF : public MCSymbol {
}
MCSectionGOFF *getADA() const { return ADA; }
- void setOwner(MCSectionGOFF *Owner) { this->Owner = Owner; }
- MCSectionGOFF *getOwner() const { return Owner; }
-
bool isExternal() const { return IsExternal; }
void setExternal(bool Value) const { IsExternal = Value; }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 07aecf13bce37..860d0a50ccb35 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -283,6 +283,7 @@ class GOFFSymbol {
class GOFFWriter {
GOFFOstream OS;
MCAssembler &Asm;
+ MCSectionGOFF *RootSD;
void writeHeader();
void writeSymbol(const GOFFSymbol &Symbol);
@@ -295,13 +296,14 @@ class GOFFWriter {
void defineSymbols();
public:
- GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm);
+ GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD);
uint64_t writeObject();
};
} // namespace
-GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
- : OS(OS), Asm(Asm) {}
+GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
+ MCSectionGOFF *RootSD)
+ : OS(OS), Asm(Asm), RootSD(RootSD) {}
void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
if (Section.isSD()) {
@@ -347,7 +349,7 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(),
- Symbol.getOwner()->getOrdinal(), Symbol.getERAttributes());
+ RootSD->getOrdinal(), Symbol.getERAttributes());
writeSymbol(ER);
}
@@ -546,7 +548,7 @@ GOFFObjectWriter::GOFFObjectWriter(
GOFFObjectWriter::~GOFFObjectWriter() = default;
uint64_t GOFFObjectWriter::writeObject() {
- uint64_t Size = GOFFWriter(OS, *Asm).writeObject();
+ uint64_t Size = GOFFWriter(OS, *Asm, RootSD).writeObject();
return Size;
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 81472ba5e4de6..e462864b55054 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -18,13 +18,28 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCGOFFObjectWriter.h"
+#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
+MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> MAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
+ std::move(Emitter)) {}
+
MCGOFFStreamer::~MCGOFFStreamer() = default;
+void MCGOFFStreamer::finishImpl() {
+ getWriter().setRootSD(static_cast<MCSectionGOFF *>(
+ getContext().getObjectFileInfo()->getTextSection())
+ ->getParent());
+ MCObjectStreamer::finishImpl();
+}
+
GOFFObjectWriter &MCGOFFStreamer::getWriter() {
return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
}
@@ -111,7 +126,6 @@ void MCGOFFStreamer::emitExterns() {
continue;
if (Symbol.isRegistered()) {
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
- Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
Sym.initAttributes();
}
}
@@ -125,9 +139,3 @@ MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
new MCGOFFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
return S;
}
-llvm::MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
- std::unique_ptr<MCAsmBackend> MAB,
- std::unique_ptr<MCObjectWriter> OW,
- std::unique_ptr<MCCodeEmitter> Emitter)
- : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
- std::move(Emitter)) {}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index ac0dd84fe9941..fe2470e374352 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -419,7 +419,6 @@ void SystemZHLASMAsmStreamer::emitExterns() {
continue;
if (Symbol.isRegistered()) {
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
- Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
Sym.initAttributes();
GOFF::ERAttr &ER = Sym.getERAttributes();
OS << " "
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index b895ae9546e5a..cddda67e91674 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1114,7 +1114,6 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
emitADASection();
emitIDRLSection(M);
// Emit EXTRN declarations.
- OutStreamer->pushSection();
for (auto &GO : M.global_objects()) {
if (GO.isDeclaration()) {
MCSymbol *Sym = TM.getSymbol(&GO);
@@ -1126,9 +1125,6 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
: MCSA_ELF_TypeObject);
}
}
- OutStreamer->switchSection(
- static_cast<MCSectionGOFF *>(getObjFileLowering().getTextSection())
- ->getParent());
getTargetStreamer()->emitExterns();
OutStreamer->popSection();
}
>From 9c35da10f0e210ed7aac4ec6ef3e03bd4bc4c260 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 21 Nov 2025 18:15:07 -0500
Subject: [PATCH 09/18] Remove LDAttr/ERAttr and initAttributes.
---
llvm/include/llvm/MC/MCSymbolGOFF.h | 30 +++---------
.../CodeGen/TargetLoweringObjectFileImpl.cpp | 7 +--
llvm/lib/MC/MCGOFFStreamer.cpp | 9 ----
llvm/lib/MC/MCSymbolGOFF.cpp | 46 ++++++++++---------
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 25 +++++-----
5 files changed, 48 insertions(+), 69 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 61a5db3d83540..7e9765330e1c3 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -25,38 +25,22 @@ class MCSymbolGOFF : public MCSymbol {
// Associated data area of the section. Needs to be emitted first.
MCSectionGOFF *ADA = nullptr;
- GOFF::LDAttr LDAttributes;
- GOFF::ERAttr ERAttributes;
-
GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
GOFF::ESDLinkageType Linkage = GOFF::ESDLinkageType::ESD_LT_XPLink;
enum SymbolFlags : uint16_t {
- SF_LD = 0x01, // LD attributes are set.
- SF_ER = 0x02, // ER attributes are set.
- SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
- SF_Weak = 0x08, // Symbol is weak.
+ SF_Hidden = 0x01, // Symbol is hidden, aka not exported.
+ SF_Weak = 0x02, // Symbol is weak.
};
public:
MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary)
: MCSymbol(Name, IsTemporary) {}
- void setLDAttributes(GOFF::LDAttr Attr) {
- modifyFlags(SF_LD, SF_LD);
- LDAttributes = Attr;
- }
- const GOFF::LDAttr &getLDAttributes() const { return LDAttributes; }
- GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
- bool hasLDAttributes() const { return getFlags() & SF_LD; }
-
- void setERAttributes(GOFF::ERAttr Attr) {
- modifyFlags(SF_ER, SF_ER);
- ERAttributes = Attr;
- }
- const GOFF::ERAttr &getERAttributes() const { return ERAttributes; }
- GOFF::ERAttr &getERAttributes() { return ERAttributes; }
- bool hasERAttributes() const { return getFlags() & SF_ER; }
+ GOFF::LDAttr getLDAttributes() const;
+ bool hasLDAttributes() const;
+ GOFF::ERAttr getERAttributes() const;
+ bool hasERAttributes() const;
void setADA(MCSectionGOFF *AssociatedDataArea) {
ADA = AssociatedDataArea;
@@ -81,8 +65,6 @@ class MCSymbolGOFF : public MCSymbol {
void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
GOFF::ESDLinkageType getLinkage() const { return Linkage; }
-
- void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ae681b9aebdfb..5edbc4caf3fae 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2788,9 +2788,10 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
// Initialize the label for the text section.
MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
getContext().getOrCreateSymbol(RootSD->getName()));
- TextLD->setLDAttributes(GOFF::LDAttr{
- false, GOFF::ESD_EXE_CODE, GOFF::ESD_BST_Strong, GOFF::ESD_LT_XPLink,
- GOFF::ESD_AMODE_64, GOFF::ESD_BSC_Section});
+ TextLD->setCodeData(GOFF::ESD_EXE_CODE);
+ TextLD->setLinkage(GOFF::ESD_LT_XPLink);
+ TextLD->setExternal(false);
+ TextLD->setWeak(false);
TextLD->setADA(ADAPR);
TextSection->setBeginSymbol(TextLD);
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index e462864b55054..2fc50b0c3f11b 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -57,7 +57,6 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCObjectStreamer::emitLabel(Symbol, Loc);
- static_cast<MCSymbolGOFF *>(Symbol)->initAttributes();
}
bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
@@ -121,14 +120,6 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
}
void MCGOFFStreamer::emitExterns() {
- for (auto &Symbol : getAssembler().symbols()) {
- if (Symbol.isTemporary())
- continue;
- if (Symbol.isRegistered()) {
- auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
- Sym.initAttributes();
- }
- }
}
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 345572418ecd8..cd55c759614ef 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -12,14 +12,13 @@
using namespace llvm;
-void MCSymbolGOFF::initAttributes() {
- // Temporary labels are not emitted into the object file.
- if (isTemporary())
- return;
+bool MCSymbolGOFF::hasLDAttributes() const {
+ return !isTemporary() && isDefined() &&
+ static_cast<MCSectionGOFF &>(getSection()).isED();
+}
- // Do not initialize the attributes multiple times.
- if (hasLDAttributes() || hasERAttributes())
- return;
+GOFF::LDAttr MCSymbolGOFF::getLDAttributes() const {
+ assert(hasLDAttributes() && "Symbol does not have LD attributes");
GOFF::ESDBindingScope BindingScope =
isExternal()
@@ -28,19 +27,24 @@ void MCSymbolGOFF::initAttributes() {
GOFF::ESDBindingStrength BindingStrength =
isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
: GOFF::ESDBindingStrength::ESD_BST_Strong;
+ return GOFF::LDAttr{false, CodeData, BindingStrength,
+ Linkage, GOFF::ESD_AMODE_64, BindingScope};
+}
+
+bool MCSymbolGOFF::hasERAttributes() const {
+ return !isTemporary() && !isDefined() && isExternal();
+}
+
+GOFF::ERAttr MCSymbolGOFF::getERAttributes() const {
+ assert(hasERAttributes() && "Symbol does not have ER attributes");
- if (isDefined()) {
- MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
- if (Section.isED()) {
- setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength, Linkage,
- GOFF::ESD_AMODE_64, BindingScope});
- } else if (Section.isPR()) {
- // For data symbols, the attributes are already determind in TLOFI.
- // TODO Does it make sense to it to here?
- } else
- llvm_unreachable("Unexpected section type for label");
- } else {
- setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, Linkage,
- GOFF::ESD_AMODE_64, BindingScope});
- }
+ GOFF::ESDBindingScope BindingScope =
+ isExternal()
+ ? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ GOFF::ESDBindingStrength BindingStrength =
+ isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+ return GOFF::ERAttr{CodeData, BindingStrength, Linkage, GOFF::ESD_AMODE_64,
+ BindingScope};
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index fe2470e374352..b44cea33bd3ba 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -236,13 +236,12 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCSymbolGOFF *Sym = static_cast<MCSymbolGOFF *>(Symbol);
MCStreamer::emitLabel(Sym, Loc);
- Sym->initAttributes();
// Emit ENTRY statement only if not implied by CSECT.
bool EmitEntry = !sameNameAsCSECT(Sym);
if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
- GOFF::LDAttr &LD = Sym->getLDAttributes();
+ GOFF::LDAttr LD = Sym->getLDAttributes();
if (EmitEntry) {
OS << " ENTRY " << Sym->getName();
EmitEOL();
@@ -419,16 +418,18 @@ void SystemZHLASMAsmStreamer::emitExterns() {
continue;
if (Symbol.isRegistered()) {
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
- Sym.initAttributes();
- GOFF::ERAttr &ER = Sym.getERAttributes();
- OS << " "
- << (ER.BindingStrength == GOFF::ESDBindingStrength::ESD_BST_Weak
- ? "WXTRN"
- : "EXTRN")
- << " " << Sym.getName();
- EmitEOL();
- emitXATTR(OS, Sym.getName(), ER.Linkage, ER.Executable, ER.BindingScope);
- EmitEOL();
+ if (Sym.hasERAttributes()) {
+ GOFF::ERAttr ER = Sym.getERAttributes();
+ OS << " "
+ << (ER.BindingStrength == GOFF::ESDBindingStrength::ESD_BST_Weak
+ ? "WXTRN"
+ : "EXTRN")
+ << " " << Sym.getName();
+ EmitEOL();
+ emitXATTR(OS, Sym.getName(), ER.Linkage, ER.Executable,
+ ER.BindingScope);
+ EmitEOL();
+ }
}
}
}
>From b75d2cb5b92cb59adc6b00b496adc218f40d0fdb Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 26 Nov 2025 13:42:03 -0500
Subject: [PATCH 10/18] Fix formatting
---
llvm/lib/MC/GOFFObjectWriter.cpp | 4 ++--
llvm/lib/MC/MCGOFFStreamer.cpp | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 860d0a50ccb35..2e1bc49938dd6 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -348,8 +348,8 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
}
void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
- GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(),
- RootSD->getOrdinal(), Symbol.getERAttributes());
+ GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(), RootSD->getOrdinal(),
+ Symbol.getERAttributes());
writeSymbol(ER);
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 2fc50b0c3f11b..fddf553b28b5a 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -119,8 +119,7 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
return true;
}
-void MCGOFFStreamer::emitExterns() {
-}
+void MCGOFFStreamer::emitExterns() {}
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
>From 28a99e3d2cb5dc255aeea282830e2602b742cdf4 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 10:10:25 -0500
Subject: [PATCH 11/18] Centralize setting of symbol attributes
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 4 +
llvm/lib/MC/MCGOFFStreamer.cpp | 83 ++++++++++---------
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 58 +------------
3 files changed, 51 insertions(+), 94 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 622fca0c5e70f..348194eb14697 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -16,6 +16,10 @@ namespace llvm {
class GOFFObjectWriter;
class MCSymbolGOFF;
+namespace goff {
+bool setSymbolAttribute(MCSymbolGOFF *Symbol, MCSymbolAttr Attribute);
+}
+
class MCGOFFStreamer : public MCObjectStreamer {
public:
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index fddf553b28b5a..d77d252df8728 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -24,44 +24,9 @@
using namespace llvm;
-MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
- std::unique_ptr<MCAsmBackend> MAB,
- std::unique_ptr<MCObjectWriter> OW,
- std::unique_ptr<MCCodeEmitter> Emitter)
- : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
- std::move(Emitter)) {}
-
-MCGOFFStreamer::~MCGOFFStreamer() = default;
-
-void MCGOFFStreamer::finishImpl() {
- getWriter().setRootSD(static_cast<MCSectionGOFF *>(
- getContext().getObjectFileInfo()->getTextSection())
- ->getParent());
- MCObjectStreamer::finishImpl();
-}
-
-GOFFObjectWriter &MCGOFFStreamer::getWriter() {
- return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
-}
-
-void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
- // Make sure that all section are registered in the correct order.
- SmallVector<MCSectionGOFF *> Sections;
- for (auto *S = static_cast<MCSectionGOFF *>(Section); S; S = S->getParent())
- Sections.push_back(S);
- while (!Sections.empty()) {
- auto *S = Sections.pop_back_val();
- MCObjectStreamer::changeSection(S, Sections.empty() ? Subsection : 0);
- }
-}
-
-void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
- MCObjectStreamer::emitLabel(Symbol, Loc);
-}
-
-bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
- MCSymbolAttr Attribute) {
- auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
+namespace llvm {
+namespace goff {
+bool setSymbolAttribute(MCSymbolGOFF *Symbol, MCSymbolAttr Attribute) {
switch (Attribute) {
case MCSA_Invalid:
case MCSA_Cold:
@@ -118,6 +83,48 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
return true;
}
+} // namespace goff
+} // namespace llvm
+
+MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> MAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
+ std::move(Emitter)) {}
+
+MCGOFFStreamer::~MCGOFFStreamer() = default;
+
+void MCGOFFStreamer::finishImpl() {
+ getWriter().setRootSD(static_cast<MCSectionGOFF *>(
+ getContext().getObjectFileInfo()->getTextSection())
+ ->getParent());
+ MCObjectStreamer::finishImpl();
+}
+
+GOFFObjectWriter &MCGOFFStreamer::getWriter() {
+ return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
+}
+
+void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
+ // Make sure that all section are registered in the correct order.
+ SmallVector<MCSectionGOFF *> Sections;
+ for (auto *S = static_cast<MCSectionGOFF *>(Section); S; S = S->getParent())
+ Sections.push_back(S);
+ while (!Sections.empty()) {
+ auto *S = Sections.pop_back_val();
+ MCObjectStreamer::changeSection(S, Sections.empty() ? Subsection : 0);
+ }
+}
+
+void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCObjectStreamer::emitLabel(Symbol, Loc);
+}
+
+bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
+ return goff::setSymbolAttribute(static_cast<MCSymbolGOFF *>(Sym), Attribute);
+}
void MCGOFFStreamer::emitExterns() {}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index b44cea33bd3ba..49a6bf6611798 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -10,6 +10,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCGOFFAttributes.h"
+#include "llvm/MC/MCGOFFStreamer.h"
#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Signals.h"
@@ -263,62 +264,7 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
- auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
- switch (Attribute) {
- case MCSA_Invalid:
- case MCSA_Cold:
- case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeTLS:
- case MCSA_ELF_TypeCommon:
- case MCSA_ELF_TypeNoType:
- case MCSA_ELF_TypeGnuUniqueObject:
- case MCSA_LGlobal:
- case MCSA_Extern:
- case MCSA_Exported:
- case MCSA_IndirectSymbol:
- case MCSA_Internal:
- case MCSA_LazyReference:
- case MCSA_NoDeadStrip:
- case MCSA_SymbolResolver:
- case MCSA_AltEntry:
- case MCSA_PrivateExtern:
- case MCSA_Protected:
- case MCSA_Reference:
- case MCSA_WeakDefinition:
- case MCSA_WeakDefAutoPrivate:
- case MCSA_WeakAntiDep:
- case MCSA_Memtag:
- return false;
-
- case MCSA_ELF_TypeFunction:
- Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
- break;
- case MCSA_ELF_TypeObject:
- Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
- break;
- case MCSA_OSLinkage:
- Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
- break;
- case MCSA_XPLinkage:
- Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
- break;
- case MCSA_Global:
- Symbol->setExternal(true);
- break;
- case MCSA_Local:
- Symbol->setExternal(false);
- break;
- case MCSA_Weak:
- case MCSA_WeakReference:
- Symbol->setExternal(true);
- Symbol->setWeak();
- break;
- case MCSA_Hidden:
- Symbol->setHidden(true);
- break;
- }
-
- return true;
+ return goff::setSymbolAttribute(static_cast<MCSymbolGOFF *>(Sym), Attribute);
}
void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
>From 063b271b1a7611a37030e19c46d649b7965e6c36 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 13:38:14 -0500
Subject: [PATCH 12/18] Remove unused emitExterns()
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 2 --
llvm/lib/MC/MCGOFFStreamer.cpp | 2 --
.../lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp | 4 ----
llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h | 1 -
4 files changed, 9 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 348194eb14697..77a06de51f3f9 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -41,8 +41,6 @@ class MCGOFFStreamer : public MCObjectStreamer {
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
-
- void emitExterns();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index d77d252df8728..880bbcc069f90 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -126,8 +126,6 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
return goff::setSymbolAttribute(static_cast<MCSymbolGOFF *>(Sym), Attribute);
}
-void MCGOFFStreamer::emitExterns() {}
-
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index d25c77e21d9f8..52bae0d6fdfd1 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -71,7 +71,3 @@ const MCExpr *SystemZTargetGOFFStreamer::createWordDiffExpr(
MCGOFFStreamer &SystemZTargetGOFFStreamer::getGOFFStreamer() {
return static_cast<MCGOFFStreamer &>(getStreamer());
}
-
-void SystemZTargetGOFFStreamer::emitExterns() {
- getGOFFStreamer().emitExterns();
-}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 31433cc9739c6..529aabe57e3e6 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -71,7 +71,6 @@ class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
MCGOFFStreamer &getGOFFStreamer();
- void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
>From 7fa4651ce58774e52135d92fd296f0fb1af4d823 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 14:26:32 -0500
Subject: [PATCH 13/18] Completely remove attributes from MCSymbolGOFF
---
llvm/include/llvm/MC/MCSymbolGOFF.h | 4 +--
llvm/lib/MC/GOFFObjectWriter.cpp | 15 ++++++--
llvm/lib/MC/MCSymbolGOFF.cpp | 34 ++++---------------
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 15 +++-----
4 files changed, 26 insertions(+), 42 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 7e9765330e1c3..de26d2f031987 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -37,9 +37,7 @@ class MCSymbolGOFF : public MCSymbol {
MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary)
: MCSymbol(Name, IsTemporary) {}
- GOFF::LDAttr getLDAttributes() const;
bool hasLDAttributes() const;
- GOFF::ERAttr getERAttributes() const;
bool hasERAttributes() const;
void setADA(MCSectionGOFF *AssociatedDataArea) {
@@ -65,6 +63,8 @@ class MCSymbolGOFF : public MCSymbol {
void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
GOFF::ESDLinkageType getLinkage() const { return Linkage; }
+
+ GOFF::ESDBindingScope getBindingScope() const;
};
} // end namespace llvm
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 2e1bc49938dd6..02e7666af1d1f 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -340,7 +340,13 @@ 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, Symbol.getLDAttributes());
+ Section.getEDAttributes().NameSpace,
+ GOFF::LDAttr{false, Symbol.getCodeData(),
+ Symbol.isWeak()
+ ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong,
+ Symbol.getLinkage(), GOFF::ESD_AMODE_64,
+ Symbol.getBindingScope()});
if (Symbol.getADA())
LD.ADAEsdId = Symbol.getADA()->getOrdinal();
LD.Offset = Asm.getSymbolOffset(Symbol);
@@ -349,7 +355,12 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(), RootSD->getOrdinal(),
- Symbol.getERAttributes());
+ GOFF::ERAttr{Symbol.getCodeData(),
+ Symbol.isWeak()
+ ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong,
+ 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 cd55c759614ef..9b69bb8f8e0a7 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -12,39 +12,17 @@
using namespace llvm;
+GOFF::ESDBindingScope MCSymbolGOFF::getBindingScope() const {
+ return isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
+ : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+}
+
bool MCSymbolGOFF::hasLDAttributes() const {
return !isTemporary() && isDefined() &&
static_cast<MCSectionGOFF &>(getSection()).isED();
}
-GOFF::LDAttr MCSymbolGOFF::getLDAttributes() const {
- assert(hasLDAttributes() && "Symbol does not have LD attributes");
-
- GOFF::ESDBindingScope BindingScope =
- isExternal()
- ? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
- : GOFF::ESD_BSC_Section;
- GOFF::ESDBindingStrength BindingStrength =
- isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong;
- return GOFF::LDAttr{false, CodeData, BindingStrength,
- Linkage, GOFF::ESD_AMODE_64, BindingScope};
-}
-
bool MCSymbolGOFF::hasERAttributes() const {
return !isTemporary() && !isDefined() && isExternal();
}
-
-GOFF::ERAttr MCSymbolGOFF::getERAttributes() const {
- assert(hasERAttributes() && "Symbol does not have ER attributes");
-
- GOFF::ESDBindingScope BindingScope =
- isExternal()
- ? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
- : GOFF::ESD_BSC_Section;
- GOFF::ESDBindingStrength BindingStrength =
- isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong;
- return GOFF::ERAttr{CodeData, BindingStrength, Linkage, GOFF::ESD_AMODE_64,
- BindingScope};
-}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 49a6bf6611798..adb7d56a9f269 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -242,13 +242,13 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
bool EmitEntry = !sameNameAsCSECT(Sym);
if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
- GOFF::LDAttr LD = Sym->getLDAttributes();
if (EmitEntry) {
OS << " ENTRY " << Sym->getName();
EmitEOL();
}
- emitXATTR(OS, Sym->getName(), LD.Linkage, LD.Executable, LD.BindingScope);
+ emitXATTR(OS, Sym->getName(), Sym->getLinkage(), Sym->getCodeData(),
+ Sym->getBindingScope());
EmitEOL();
}
@@ -365,15 +365,10 @@ void SystemZHLASMAsmStreamer::emitExterns() {
if (Symbol.isRegistered()) {
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
if (Sym.hasERAttributes()) {
- GOFF::ERAttr ER = Sym.getERAttributes();
- OS << " "
- << (ER.BindingStrength == GOFF::ESDBindingStrength::ESD_BST_Weak
- ? "WXTRN"
- : "EXTRN")
- << " " << Sym.getName();
+ OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
EmitEOL();
- emitXATTR(OS, Sym.getName(), ER.Linkage, ER.Executable,
- ER.BindingScope);
+ emitXATTR(OS, Sym.getName(), Sym.getLinkage(), Sym.getCodeData(),
+ Sym.getBindingScope());
EmitEOL();
}
}
>From 653783442d341d956f12dcd640db017621e86c4e Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 14:45:18 -0500
Subject: [PATCH 14/18] Remove left-over popSection()
---
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index cddda67e91674..08cfa5acb414f 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1126,7 +1126,6 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
}
}
getTargetStreamer()->emitExterns();
- OutStreamer->popSection();
}
emitAttributes(M);
// Emit the END instruction in case of HLASM output. This must be the last
>From f07556ac9320b6435b6e8bd3aa300ee4f8113be4 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 15:19:07 -0500
Subject: [PATCH 15/18] Simplify the implementation by moving some code into
finishImpl()
---
.../SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 11 +++++------
.../SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h | 3 +--
.../SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp | 6 ------
.../SystemZ/MCTargetDesc/SystemZTargetStreamer.h | 5 -----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 ----
llvm/test/CodeGen/SystemZ/zos-symbol-1.ll | 3 ++-
6 files changed, 8 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index adb7d56a9f269..349f7d777e9d3 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -353,12 +353,7 @@ void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
EmitEOL();
}
-void SystemZHLASMAsmStreamer::emitEnd() {
- OS << " END";
- EmitEOL();
-}
-
-void SystemZHLASMAsmStreamer::emitExterns() {
+void SystemZHLASMAsmStreamer::finishImpl() {
for (auto &Symbol : getAssembler().symbols()) {
if (Symbol.isTemporary())
continue;
@@ -373,4 +368,8 @@ void SystemZHLASMAsmStreamer::emitExterns() {
}
}
}
+
+ // Finish the assembly output.
+ OS << " END";
+ EmitEOL();
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
index 81cfdad472244..1eb358d45e0f4 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -122,8 +122,7 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
bool Parens = false);
/// @}
- void emitEnd();
- void emitExterns();
+ void finishImpl() override;
};
} // namespace llvm
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index 52bae0d6fdfd1..2127b7aa24c21 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -39,12 +39,6 @@ SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() {
return static_cast<SystemZHLASMAsmStreamer &>(getStreamer());
}
-void SystemZTargetHLASMStreamer::emitEnd() { getHLASMStreamer().emitEnd(); }
-
-void SystemZTargetHLASMStreamer::emitExterns() {
- getHLASMStreamer().emitExterns();
-}
-
// HLASM statements can only perform a single operation at a time
const MCExpr *SystemZTargetHLASMStreamer::createWordDiffExpr(
MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 529aabe57e3e6..fc2bcee17cf81 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -58,9 +58,6 @@ class SystemZTargetStreamer : public MCTargetStreamer {
virtual void emitMachine(StringRef CPUOrCommand) {};
- virtual void emitEnd() {};
- virtual void emitExterns() {};
-
virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) {
return nullptr;
@@ -82,8 +79,6 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: SystemZTargetStreamer(S), OS(OS) {}
SystemZHLASMAsmStreamer &getHLASMStreamer();
- void emitEnd() override;
- void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 08cfa5acb414f..9469d6841d6aa 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1125,12 +1125,8 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
: MCSA_ELF_TypeObject);
}
}
- getTargetStreamer()->emitExterns();
}
emitAttributes(M);
- // Emit the END instruction in case of HLASM output. This must be the last
- // instruction in the source file.
- getTargetStreamer()->emitEnd();
}
void SystemZAsmPrinter::emitADASection() {
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
index bd4361aaafdcb..6768da0da7cfc 100644
--- a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
@@ -34,4 +34,5 @@ entry:
; CHECK-NEXT: WXTRN other1
; CHECK-NEXT: other1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK-NEXT: EXTRN other2
-; CHECK-NEXT: other2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
\ No newline at end of file
+; CHECK-NEXT: other2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: END
>From 126ad826f294ab1fac5c8a7f82debc4eedd4d97b Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 28 Nov 2025 15:43:23 -0500
Subject: [PATCH 16/18] Move loop to AsmPrinter
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 15 +++++++++++++++
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 12 ------------
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3aa245b7f3f1e..85f49d6953361 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2937,6 +2937,21 @@ bool AsmPrinter::doFinalization(Module &M) {
}
}
+ // Emit symbol attributes for declarations (GOFF only).
+ if (TM.getTargetTriple().isOSBinFormatGOFF()) {
+ for (auto &GO : M.global_objects()) {
+ if (GO.isDeclaration()) {
+ MCSymbol *Sym = TM.getSymbol(&GO);
+ OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
+ ? MCSA_WeakReference
+ : MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO)
+ ? MCSA_ELF_TypeFunction
+ : MCSA_ELF_TypeObject);
+ }
+ }
+ }
+
// Allow the target to emit any magic that it wants at the end of the file,
// after everything else has gone out.
emitEndOfAsmFile(M);
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 9469d6841d6aa..31c57a63e5c87 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1113,18 +1113,6 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
if (TT.isOSzOS()) {
emitADASection();
emitIDRLSection(M);
- // Emit EXTRN declarations.
- for (auto &GO : M.global_objects()) {
- if (GO.isDeclaration()) {
- MCSymbol *Sym = TM.getSymbol(&GO);
- OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
- ? MCSA_WeakReference
- : MCSA_Global);
- OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO)
- ? MCSA_ELF_TypeFunction
- : MCSA_ELF_TypeObject);
- }
- }
}
emitAttributes(M);
}
>From 9fd32acf391de1c7ee26ea21b46043fecb300778 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 3 Dec 2025 09:14:48 -0500
Subject: [PATCH 17/18] Address most review comments
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 6 --
llvm/include/llvm/MC/MCSymbolGOFF.h | 14 +++-
llvm/lib/MC/GOFFObjectWriter.cpp | 12 +---
llvm/lib/MC/MCGOFFStreamer.cpp | 68 +------------------
llvm/lib/MC/MCSymbolGOFF.cpp | 64 +++++++++++++++--
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 2 +-
.../MCTargetDesc/SystemZTargetStreamer.cpp | 4 --
.../MCTargetDesc/SystemZTargetStreamer.h | 1 -
8 files changed, 76 insertions(+), 95 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 77a06de51f3f9..886efe10d45df 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -16,10 +16,6 @@ namespace llvm {
class GOFFObjectWriter;
class MCSymbolGOFF;
-namespace goff {
-bool setSymbolAttribute(MCSymbolGOFF *Symbol, MCSymbolAttr Attribute);
-}
-
class MCGOFFStreamer : public MCObjectStreamer {
public:
@@ -35,8 +31,6 @@ class MCGOFFStreamer : public MCObjectStreamer {
GOFFObjectWriter &getWriter();
- void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
-
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index de26d2f031987..0a39d04ad3c8d 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -14,6 +14,7 @@
#define LLVM_MC_MCSYMBOLGOFF_H
#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCGOFFAttributes.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSymbol.h"
@@ -64,7 +65,18 @@ class MCSymbolGOFF : public MCSymbol {
void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
GOFF::ESDLinkageType getLinkage() const { return Linkage; }
- GOFF::ESDBindingScope getBindingScope() const;
+ GOFF::ESDBindingScope getBindingScope() const {
+ return isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
+ : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ }
+
+ GOFF::ESDBindingStrength getBindingStrength() const {
+ return isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+ }
+
+ bool setSymbolAttribute(MCSymbolAttr Attribute);
};
} // end namespace llvm
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 02e7666af1d1f..66e0cf5bc178a 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -342,11 +342,8 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(), Section.getOrdinal(),
Section.getEDAttributes().NameSpace,
GOFF::LDAttr{false, Symbol.getCodeData(),
- Symbol.isWeak()
- ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong,
- Symbol.getLinkage(), GOFF::ESD_AMODE_64,
- Symbol.getBindingScope()});
+ Symbol.getBindingStrength(), Symbol.getLinkage(),
+ GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
if (Symbol.getADA())
LD.ADAEsdId = Symbol.getADA()->getOrdinal();
LD.Offset = Asm.getSymbolOffset(Symbol);
@@ -355,10 +352,7 @@ 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.isWeak()
- ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong,
+ GOFF::ERAttr{Symbol.getCodeData(), Symbol.getBindingStrength(),
Symbol.getLinkage(), GOFF::ESD_AMODE_64,
Symbol.getBindingScope()});
writeSymbol(ER);
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 880bbcc069f90..51580e0063207 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -24,68 +24,6 @@
using namespace llvm;
-namespace llvm {
-namespace goff {
-bool setSymbolAttribute(MCSymbolGOFF *Symbol, MCSymbolAttr Attribute) {
- switch (Attribute) {
- case MCSA_Invalid:
- case MCSA_Cold:
- case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeTLS:
- case MCSA_ELF_TypeCommon:
- case MCSA_ELF_TypeNoType:
- case MCSA_ELF_TypeGnuUniqueObject:
- case MCSA_LGlobal:
- case MCSA_Extern:
- case MCSA_Exported:
- case MCSA_IndirectSymbol:
- case MCSA_Internal:
- case MCSA_LazyReference:
- case MCSA_NoDeadStrip:
- case MCSA_SymbolResolver:
- case MCSA_AltEntry:
- case MCSA_PrivateExtern:
- case MCSA_Protected:
- case MCSA_Reference:
- case MCSA_WeakDefinition:
- case MCSA_WeakDefAutoPrivate:
- case MCSA_WeakAntiDep:
- case MCSA_Memtag:
- return false;
-
- case MCSA_ELF_TypeFunction:
- Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
- break;
- case MCSA_ELF_TypeObject:
- Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
- break;
- case MCSA_OSLinkage:
- Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
- break;
- case MCSA_XPLinkage:
- Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
- break;
- case MCSA_Global:
- Symbol->setExternal(true);
- break;
- case MCSA_Local:
- Symbol->setExternal(false);
- break;
- case MCSA_Weak:
- case MCSA_WeakReference:
- Symbol->setExternal(true);
- Symbol->setWeak();
- break;
- case MCSA_Hidden:
- Symbol->setHidden(true);
- break;
- }
-
- return true;
-}
-} // namespace goff
-} // namespace llvm
-
MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW,
@@ -117,13 +55,9 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
}
}
-void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
- MCObjectStreamer::emitLabel(Symbol, Loc);
-}
-
bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
- return goff::setSymbolAttribute(static_cast<MCSymbolGOFF *>(Sym), Attribute);
+ return static_cast<MCSymbolGOFF *>(Sym)->setSymbolAttribute(Attribute);
}
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 9b69bb8f8e0a7..c2622e1bf3667 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -12,12 +12,6 @@
using namespace llvm;
-GOFF::ESDBindingScope MCSymbolGOFF::getBindingScope() const {
- return isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
- : GOFF::ESD_BSC_Library)
- : GOFF::ESD_BSC_Section;
-}
-
bool MCSymbolGOFF::hasLDAttributes() const {
return !isTemporary() && isDefined() &&
static_cast<MCSectionGOFF &>(getSection()).isED();
@@ -26,3 +20,61 @@ bool MCSymbolGOFF::hasLDAttributes() const {
bool MCSymbolGOFF::hasERAttributes() const {
return !isTemporary() && !isDefined() && isExternal();
}
+
+bool MCSymbolGOFF::setSymbolAttribute(MCSymbolAttr Attribute) {
+ switch (Attribute) {
+ case MCSA_Invalid:
+ case MCSA_Cold:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
+ case MCSA_ELF_TypeGnuUniqueObject:
+ case MCSA_LGlobal:
+ case MCSA_Extern:
+ case MCSA_Exported:
+ case MCSA_IndirectSymbol:
+ case MCSA_Internal:
+ case MCSA_LazyReference:
+ case MCSA_NoDeadStrip:
+ case MCSA_SymbolResolver:
+ case MCSA_AltEntry:
+ case MCSA_PrivateExtern:
+ case MCSA_Protected:
+ case MCSA_Reference:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_WeakAntiDep:
+ case MCSA_Memtag:
+ return false;
+
+ case MCSA_ELF_TypeFunction:
+ setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
+ break;
+ case MCSA_ELF_TypeObject:
+ setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
+ break;
+ case MCSA_OSLinkage:
+ setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
+ break;
+ case MCSA_XPLinkage:
+ setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
+ break;
+ case MCSA_Global:
+ setExternal(true);
+ break;
+ case MCSA_Local:
+ setExternal(false);
+ break;
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ setExternal(true);
+ setWeak();
+ break;
+ case MCSA_Hidden:
+ setHidden(true);
+ break;
+ }
+
+ return true;
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 349f7d777e9d3..3f7228bbdcbbf 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -264,7 +264,7 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
- return goff::setSymbolAttribute(static_cast<MCSymbolGOFF *>(Sym), Attribute);
+ return static_cast<MCSymbolGOFF *>(Sym)->setSymbolAttribute(Attribute);
}
void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index 2127b7aa24c21..eeaa7382ad761 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -61,7 +61,3 @@ const MCExpr *SystemZTargetGOFFStreamer::createWordDiffExpr(
MCSymbolRefExpr::create(Lo, Ctx), Ctx),
MCConstantExpr::create(1, Ctx), Ctx);
}
-
-MCGOFFStreamer &SystemZTargetGOFFStreamer::getGOFFStreamer() {
- return static_cast<MCGOFFStreamer &>(getStreamer());
-}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index fc2bcee17cf81..4f9a4a0a97ed8 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -67,7 +67,6 @@ class SystemZTargetStreamer : public MCTargetStreamer {
class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
- MCGOFFStreamer &getGOFFStreamer();
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
>From 8b710565e25b9c8989e48bf2727edc0cb5045e44 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 4 Dec 2025 14:55:10 -0500
Subject: [PATCH 18/18] Remove hasLDAttributes() and hasERAttributes()
Just inline and simplify the expressions.
---
llvm/include/llvm/MC/MCSymbolGOFF.h | 3 ---
llvm/lib/MC/GOFFObjectWriter.cpp | 6 ++++--
llvm/lib/MC/MCSymbolGOFF.cpp | 9 --------
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 21 ++++++++++---------
4 files changed, 15 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 0a39d04ad3c8d..7108f7ebd2b2d 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -38,9 +38,6 @@ class MCSymbolGOFF : public MCSymbol {
MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary)
: MCSymbol(Name, IsTemporary) {}
- bool hasLDAttributes() const;
- bool hasERAttributes() const;
-
void setADA(MCSectionGOFF *AssociatedDataArea) {
ADA = AssociatedDataArea;
AssociatedDataArea->RequiresNonZeroLength = true;
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 66e0cf5bc178a..d966021475abb 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -372,10 +372,12 @@ void GOFFWriter::defineSymbols() {
if (Sym.isTemporary())
continue;
auto &Symbol = static_cast<const MCSymbolGOFF &>(Sym);
- if (Symbol.hasLDAttributes()) {
+ bool IsDefined = Symbol.isDefined();
+ if (IsDefined &&
+ static_cast<MCSectionGOFF &>(Symbol.getSection()).isED()) {
Symbol.setIndex(++Ordinal);
defineLabel(Symbol);
- } else if (Symbol.hasERAttributes()) {
+ } else if (!IsDefined) {
Symbol.setIndex(++Ordinal);
defineExtern(Symbol);
}
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index c2622e1bf3667..2ed15e3fc9c94 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -12,15 +12,6 @@
using namespace llvm;
-bool MCSymbolGOFF::hasLDAttributes() const {
- return !isTemporary() && isDefined() &&
- static_cast<MCSectionGOFF &>(getSection()).isED();
-}
-
-bool MCSymbolGOFF::hasERAttributes() const {
- return !isTemporary() && !isDefined() && isExternal();
-}
-
bool MCSymbolGOFF::setSymbolAttribute(MCSymbolAttr Attribute) {
switch (Attribute) {
case MCSA_Invalid:
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 3f7228bbdcbbf..ddc897b0e8393 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -226,9 +226,9 @@ static void emitXATTR(raw_ostream &OS, StringRef Name,
}
static bool sameNameAsCSECT(MCSymbolGOFF *Sym) {
- if (Sym->hasLDAttributes() && Sym->isInSection()) {
+ if (!Sym->isTemporary() && Sym->isDefined() && Sym->isInSection()) {
MCSectionGOFF &ED = static_cast<MCSectionGOFF &>(Sym->getSection());
- return Sym->getName() == ED.getParent()->getName();
+ return ED.isED() && Sym->getName() == ED.getParent()->getName();
}
return false;
}
@@ -241,7 +241,8 @@ void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
// Emit ENTRY statement only if not implied by CSECT.
bool EmitEntry = !sameNameAsCSECT(Sym);
- if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
+ if (!Sym->isTemporary() && Sym->isDefined() &&
+ static_cast<MCSectionGOFF &>(Sym->getSection()).isED()) {
if (EmitEntry) {
OS << " ENTRY " << Sym->getName();
EmitEOL();
@@ -358,14 +359,14 @@ void SystemZHLASMAsmStreamer::finishImpl() {
if (Symbol.isTemporary())
continue;
if (Symbol.isRegistered()) {
+ if (Symbol.isDefined())
+ continue;
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
- if (Sym.hasERAttributes()) {
- OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
- EmitEOL();
- emitXATTR(OS, Sym.getName(), Sym.getLinkage(), Sym.getCodeData(),
- Sym.getBindingScope());
- EmitEOL();
- }
+ OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
+ EmitEOL();
+ emitXATTR(OS, Sym.getName(), Sym.getLinkage(), Sym.getCodeData(),
+ Sym.getBindingScope());
+ EmitEOL();
}
}
More information about the llvm-commits
mailing list