diff options
author | Kai Nacke <kai.peter.nacke@ibm.com> | 2025-06-26 11:52:14 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-26 11:52:14 -0400 |
commit | 33872f12187b352b63e1749652cb18e678fc4f29 (patch) | |
tree | 9a3c587a187d4641ed7080e5384ef925463b8372 /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | 6bdfecaea837a07d034b1598a3af38c6f64044f4 (diff) | |
download | llvm-33872f12187b352b63e1749652cb18e678fc4f29.zip llvm-33872f12187b352b63e1749652cb18e678fc4f29.tar.gz llvm-33872f12187b352b63e1749652cb18e678fc4f29.tar.bz2 |
[GOFF] Add writing of section symbols (#133799)
Unlike other formats, the GOFF object file format uses a 2 dimensional structure
to define the location of data. For example, the equivalent of the ELF .text
section is made up of a Section Definition (SD) and a class (Element Definition;
ED). The name of the SD symbol depends on the application, while the class has
the predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively.
Data can be placed into this structure in 2 ways. First, the data (in a text
record) can be associated with an ED symbol. To refer to data, a Label
Definition (LD) is used to give an offset into the data a name. When binding,
the whole data is pulled into the resulting executable, and the addresses
given by the LD symbols are resolved.
The alternative is to use a Part Definition (PR). In this case, the data (in
a text record) is associated with the part. When binding, only the data of
referenced PRs is pulled into the resulting binary.
Both approaches are used. SD, ED, and PR elements are modeled by nested
MCSectionGOFF instances, while LD elements are associated with MCSymbolGOFF
instances.
At the binary level, a record called "External Symbol Definition" (ESD) is used. The
ESD has a type (SD, ED, PR, LD), and depending on the type a different subset of
the fields is used.
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index c804a17..5454cd4 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -19,6 +19,7 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/BinaryFormat/GOFF.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/CodeGen/BasicBlockSectionUtils.h" @@ -47,6 +48,7 @@ #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionGOFF.h" @@ -56,6 +58,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCSymbolGOFF.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" #include "llvm/ProfileData/InstrProf.h" @@ -64,6 +67,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Triple.h" @@ -2775,6 +2779,29 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( //===----------------------------------------------------------------------===// TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default; +void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) { + // Construct the default names for the root SD and the ADA PR symbol. + StringRef FileName = sys::path::stem(M.getSourceFileName()); + if (FileName.size() > 1 && FileName.starts_with('<') && + FileName.ends_with('>')) + FileName = FileName.substr(1, FileName.size() - 2); + DefaultRootSDName = Twine(FileName).concat("#C").str(); + DefaultADAPRName = Twine(FileName).concat("#S").str(); + MCSectionGOFF *RootSD = + static_cast<MCSectionGOFF *>(TextSection)->getParent(); + MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection); + RootSD->setName(DefaultRootSDName); + ADAPR->setName(DefaultADAPRName); + // Initialize the label for the text section. + MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>( + getContext().getOrCreateSymbol(RootSD->getName())); + TextLD->setLDAttributes(GOFF::LDAttr{ + false, GOFF::ESD_EXE_CODE, GOFF::ESD_BST_Strong, GOFF::ESD_LT_XPLink, + GOFF::ESD_AMODE_64, GOFF::ESD_BSC_Section}); + TextLD->setADA(ADAPR); + TextSection->setBeginSymbol(TextLD); +} + MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { return SelectSectionForGlobal(GO, Kind, TM); @@ -2783,15 +2810,56 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { std::string Name = ".gcc_exception_table." + F.getName().str(); - return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 0); + + MCSectionGOFF *WSA = getContext().getGOFFSection( + SectionKind::getMetadata(), GOFF::CLASS_WSA, + GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Fullword, 0}, + static_cast<MCSectionGOFF *>(TextSection)->getParent()); + return getContext().getGOFFSection(SectionKind::getData(), Name, + GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, + GOFF::ESD_LT_XPLink, + GOFF::ESD_BSC_Section, 0}, + WSA); } MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { auto *Symbol = TM.getSymbol(GO); - if (Kind.isBSS()) - return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(), - nullptr, 0); - return getContext().getObjectFileInfo()->getTextSection(); + if (Kind.isBSS() || Kind.isData()) { + GOFF::ESDBindingScope PRBindingScope = + GO->hasExternalLinkage() + ? (GO->hasDefaultVisibility() ? GOFF::ESD_BSC_ImportExport + : GOFF::ESD_BSC_Library) + : GOFF::ESD_BSC_Section; + GOFF::ESDBindingScope SDBindingScope = + PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section + : GOFF::ESD_BSC_Unspecified; + MaybeAlign Alignment; + if (auto *F = dyn_cast<Function>(GO)) + Alignment = F->getAlign(); + else if (auto *V = dyn_cast<GlobalVariable>(GO)) + Alignment = V->getAlign(); + GOFF::ESDAlignment Align = + Alignment ? static_cast<GOFF::ESDAlignment>(Log2(*Alignment)) + : GOFF::ESD_ALIGN_Doubleword; + MCSectionGOFF *SD = getContext().getGOFFSection( + SectionKind::getMetadata(), Symbol->getName(), + GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}); + MCSectionGOFF *ED = getContext().getGOFFSection( + SectionKind::getMetadata(), GOFF::CLASS_WSA, + GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0}, + SD); + return getContext().getGOFFSection(Kind, Symbol->getName(), + GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, + GOFF::ESD_LT_XPLink, + PRBindingScope, 0}, + ED); + } + return TextSection; } |