-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[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 6 commits
6261752
194ba3a
c19957c
2fa73af
43dcc13
ee1434b
214d716
1f43993
9c35da1
b75d2cb
28a99e3
063b271
7fa4651
6537834
f07556a
126ad82
9fd32ac
8b71056
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,24 @@ 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; | ||
| 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. | ||
| }; | ||
uweigand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| public: | ||
|
|
@@ -39,14 +51,46 @@ 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 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; } | ||
|
|
||
| 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,11 +11,14 @@ | |
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #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/MCSymbolGOFF.h" | ||
| #include "llvm/MC/TargetRegistry.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
@@ -37,6 +40,85 @@ 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_Code: | ||
| Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE); | ||
| break; | ||
| 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; | ||
| 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 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, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| //===- 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() { | ||
|
||
| // 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()); | ||
| 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}); | ||
| } | ||
| } | ||
|
||
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 two duplicate the semantics of
MCSA_ELF_TypeFunctionandMCSA_ELF_TypeObjectin a sense. I'm wondering if we can hook into that (already existing) common code logic ...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.
Changed, now using
MCSA_ELF_TypeFunction/MCSA_ELF_TypeObject. It's indeed very similar.