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