From 2b99eb315cea3e75a6ecc49571d75d9371669116 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Mon, 16 Jun 2025 17:27:16 -0400 Subject: [PATCH 1/2] [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 | 19 ++++++- llvm/lib/MC/CMakeLists.txt | 1 + llvm/lib/MC/GOFFObjectWriter.cpp | 1 + llvm/lib/MC/MCGOFFStreamer.cpp | 58 ++++++++++++++++++++++ llvm/lib/MC/MCSymbolGOFF.cpp | 38 ++++++++++++++ llvm/test/CodeGen/SystemZ/zos-section-1.ll | 34 ++++++++----- 7 files changed, 140 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 366d7dc08c679..968bef044d175 100644 --- a/llvm/include/llvm/MC/MCGOFFStreamer.h +++ b/llvm/include/llvm/MC/MCGOFFStreamer.h @@ -30,9 +30,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 {} void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override {} diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h index d8c570d2de240..b9295d3690803 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) { @@ -48,6 +52,17 @@ class MCSymbolGOFF : public MCSymbol { } MCSectionGOFF *getADA() const { return ADA; } + 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(); + static bool classof(const MCSymbol *S) { return S->isGOFF(); } }; } // end namespace llvm diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index d662c42c522fc..85e857d3fb406 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -55,6 +55,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 214533b99688e..c7fa2e99f6625 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -329,6 +329,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 b7021915e7b70..451acf3b5d781 100644 --- a/llvm/lib/MC/MCGOFFStreamer.cpp +++ b/llvm/lib/MC/MCGOFFStreamer.cpp @@ -15,8 +15,11 @@ #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" +#include "llvm/Support/Casting.h" using namespace llvm; @@ -41,6 +44,61 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { MCObjectStreamer::changeSection(Section, Subsection); } +void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { + MCObjectStreamer::emitLabel(Symbol, Loc); + cast(Symbol)->initAttributes(); +} + +bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym, + MCSymbolAttr Attribute) { + auto *Symbol = cast(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 &&MAB, std::unique_ptr &&OW, diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp new file mode 100644 index 0000000000000..6d07d6a54a233 --- /dev/null +++ b/llvm/lib/MC/MCSymbolGOFF.cpp @@ -0,0 +1,38 @@ +//===- 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/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +void MCSymbolGOFF::initAttributes() { + if (hasLDAttributes()) + return; + + if (isDefined()) { + MCSectionGOFF &Section = cast(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::LINKAGE, GOFF::AMODE, 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 f20a8faf848f596e56ded0189cf98cfeb8921b94 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Tue, 17 Jun 2025 10:35:12 -0400 Subject: [PATCH 2/2] Fix formatting --- llvm/include/llvm/MC/MCSymbolGOFF.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h index b9295d3690803..7612a06e7d738 100644 --- a/llvm/include/llvm/MC/MCSymbolGOFF.h +++ b/llvm/include/llvm/MC/MCSymbolGOFF.h @@ -28,10 +28,10 @@ class MCSymbolGOFF : public MCSymbol { GOFF::LDAttr LDAttributes; enum SymbolFlags : uint16_t { - 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. + 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: