summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Nacke <kai.peter.nacke@ibm.com>2025-06-16 17:27:16 -0400
committerKai Nacke <kai.peter.nacke@ibm.com>2025-11-07 11:14:31 -0500
commit6261752c43e16feb0ac3b42915c8de943cc96601 (patch)
treef0f5dac86875bd7cb6840c4a13b08d78c934a5f6
parent80a53328392319cceb49702743cc93fa578aec6e (diff)
[GOFF] Emit symbols for functions.
A function entry is mapped to a LD symbol with an offset to the begin of the section.
-rw-r--r--llvm/include/llvm/MC/MCGOFFStreamer.h7
-rw-r--r--llvm/include/llvm/MC/MCSymbolGOFF.h22
-rw-r--r--llvm/lib/MC/CMakeLists.txt1
-rw-r--r--llvm/lib/MC/GOFFObjectWriter.cpp1
-rw-r--r--llvm/lib/MC/MCGOFFStreamer.cpp57
-rw-r--r--llvm/lib/MC/MCSymbolGOFF.cpp39
-rw-r--r--llvm/test/CodeGen/SystemZ/zos-section-1.ll34
7 files changed, 143 insertions, 18 deletions
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 8888d9e7bdbb..6fa6e6481347 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -28,9 +28,10 @@ public:
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 11d4df4aea63..b58b520cc5c4 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 @@ public:
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 @@ public:
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 70c4577aeec0..1388f130bb80 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 a3eaaa743039..b42ba148ef65 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 ad6397bce70f..c76e8cd1dc3c 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 000000000000..86de21b11bc0
--- /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 b98584df54d5..6caa8f4d607d 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