-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[GOFF] Emit symbols for functions. #144437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6261752
194ba3a
c19957c
2fa73af
43dcc13
ee1434b
214d716
1f43993
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,12 +23,19 @@ namespace llvm { | |
|
|
||
| class MCSymbolGOFF : public MCSymbol { | ||
| // Associated data area of the section. Needs to be emitted first. | ||
| MCSectionGOFF *ADA; | ||
| 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_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. | ||
| }; | ||
|
|
||
| public: | ||
|
|
@@ -39,14 +46,43 @@ 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; } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need a non-const getter at all here? |
||
| 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; } | ||
|
|
||
| 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 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 | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,17 +11,35 @@ | |
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #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" | ||
| #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()); | ||
| } | ||
|
|
@@ -37,6 +55,82 @@ 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_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: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for .globl; .local; .weak, does the last directive win? MCELFStreamer.cpp reports warnings/errors.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, currently the last directive wins. I'll check the MCELFStreamer implementation. |
||
| case MCSA_WeakReference: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MCSA_WeakReference is used by AsmPrinter::emitGlobalAlias - ensure that GOFF has such a test. |
||
| Symbol->setExternal(true); | ||
| Symbol->setWeak(); | ||
| break; | ||
| case MCSA_Hidden: | ||
| Symbol->setHidden(true); | ||
| break; | ||
| } | ||
|
|
||
| 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.initAttributes(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| MCStreamer *llvm::createGOFFStreamer(MCContext &Context, | ||
| std::unique_ptr<MCAsmBackend> &&MAB, | ||
| std::unique_ptr<MCObjectWriter> &&OW, | ||
|
|
@@ -45,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)) {} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above fields
CodeDataandLinkageas well as the new flagsSF_HiddenandSF_Weakduplicate information already present in theLDAttributesorERAttributesfield. This should be avoided - what does it mean if the two places disagree?Not sure what the right fix is; either we can create and maintain the proper attribute structure at all times, or if not, maybe we should not have the attributes in
MCSymbolGOFFat all (only those other fields), and simply generate the proper attributes structure only where it is needed to write out the symbol.