Skip to content

Commit 37545b8

Browse files
authored
[GOFF] Emit symbols for functions. (#144437)
A function entry is mapped to a LD symbol with an offset to the begin of the section. HLASM syntax is emitted accordingly.
1 parent fea987b commit 37545b8

23 files changed

+398
-82
lines changed

llvm/include/llvm/MC/MCDirectives.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ enum MCSymbolAttr {
4848
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
4949
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
5050
MCSA_Memtag, ///< .memtag (ELF)
51+
MCSA_OSLinkage, ///< symbol uses OS linkage (GOFF)
52+
MCSA_XPLinkage, ///< symbol uses XP linkage (GOFF)
5153
};
5254

5355
enum MCDataRegionType {

llvm/include/llvm/MC/MCGOFFAttributes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ struct PRAttr {
8080
uint32_t SortKey = 0;
8181
};
8282

83+
// Attributes for ER symbols.
84+
struct ERAttr {
85+
GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
86+
GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
87+
GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
88+
GOFF::ESDAmode Amode;
89+
GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
90+
};
91+
8392
// Predefined GOFF class names.
8493
constexpr StringLiteral CLASS_CODE = "C_CODE64";
8594
constexpr StringLiteral CLASS_WSA = "C_WSA64";

llvm/include/llvm/MC/MCGOFFObjectWriter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace llvm {
1616
class MCObjectWriter;
17+
class MCSectionGOFF;
1718
class raw_pwrite_stream;
1819

1920
class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
@@ -37,11 +38,16 @@ class GOFFObjectWriter : public MCObjectWriter {
3738
// The stream used to write the GOFF records.
3839
raw_pwrite_stream &OS;
3940

41+
// The RootSD section.
42+
MCSectionGOFF *RootSD = nullptr;
43+
4044
public:
4145
GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
4246
raw_pwrite_stream &OS);
4347
~GOFFObjectWriter() override;
4448

49+
void setRootSD(MCSectionGOFF *RootSD) { this->RootSD = RootSD; }
50+
4551
// Implementation of the MCObjectWriter interface.
4652
void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
4753
MCValue Target, uint64_t &FixedValue) override {}

llvm/include/llvm/MC/MCGOFFStreamer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace llvm {
1616
class GOFFObjectWriter;
17+
class MCSymbolGOFF;
1718

1819
class MCGOFFStreamer : public MCObjectStreamer {
1920

@@ -24,13 +25,14 @@ class MCGOFFStreamer : public MCObjectStreamer {
2425

2526
~MCGOFFStreamer() override;
2627

28+
void finishImpl() override;
29+
2730
void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
2831

2932
GOFFObjectWriter &getWriter();
3033

31-
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
32-
return false;
33-
}
34+
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
35+
3436
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3537
Align ByteAlignment) override {}
3638
};

llvm/include/llvm/MC/MCSymbolGOFF.h

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_MC_MCSYMBOLGOFF_H
1515

1616
#include "llvm/BinaryFormat/GOFF.h"
17+
#include "llvm/MC/MCDirectives.h"
1718
#include "llvm/MC/MCGOFFAttributes.h"
1819
#include "llvm/MC/MCSectionGOFF.h"
1920
#include "llvm/MC/MCSymbol.h"
@@ -23,30 +24,61 @@ namespace llvm {
2324

2425
class MCSymbolGOFF : public MCSymbol {
2526
// Associated data area of the section. Needs to be emitted first.
26-
MCSectionGOFF *ADA;
27+
MCSectionGOFF *ADA = nullptr;
2728

28-
GOFF::LDAttr LDAttributes;
29+
GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
30+
GOFF::ESDLinkageType Linkage = GOFF::ESDLinkageType::ESD_LT_XPLink;
2931

3032
enum SymbolFlags : uint16_t {
31-
SF_LD = 0x01, // LD attributes are set.
33+
SF_Hidden = 0x01, // Symbol is hidden, aka not exported.
34+
SF_Weak = 0x02, // Symbol is weak.
3235
};
3336

3437
public:
3538
MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary)
3639
: MCSymbol(Name, IsTemporary) {}
3740

38-
void setLDAttributes(GOFF::LDAttr Attr) {
39-
modifyFlags(SF_LD, SF_LD);
40-
LDAttributes = Attr;
41-
}
42-
GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
43-
bool hasLDAttributes() const { return getFlags() & SF_LD; }
44-
4541
void setADA(MCSectionGOFF *AssociatedDataArea) {
4642
ADA = AssociatedDataArea;
4743
AssociatedDataArea->RequiresNonZeroLength = true;
4844
}
4945
MCSectionGOFF *getADA() const { return ADA; }
46+
47+
bool isExternal() const { return IsExternal; }
48+
void setExternal(bool Value) const { IsExternal = Value; }
49+
50+
void setHidden(bool Value = true) {
51+
modifyFlags(Value ? SF_Hidden : 0, SF_Hidden);
52+
}
53+
bool isHidden() const { return getFlags() & SF_Hidden; }
54+
bool isExported() const { return !isHidden(); }
55+
56+
void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
57+
bool isWeak() const { return getFlags() & SF_Weak; }
58+
59+
void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
60+
GOFF::ESDExecutable getCodeData() const { return CodeData; }
61+
62+
void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
63+
GOFF::ESDLinkageType getLinkage() const { return Linkage; }
64+
65+
GOFF::ESDBindingScope getBindingScope() const {
66+
return (isExternal() || !isDefined()) ? isExported()
67+
? GOFF::ESD_BSC_ImportExport
68+
: GOFF::ESD_BSC_Library
69+
: GOFF::ESD_BSC_Section;
70+
}
71+
72+
GOFF::ESDBindingStrength getBindingStrength() const {
73+
return isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
74+
: GOFF::ESDBindingStrength::ESD_BST_Strong;
75+
}
76+
77+
bool setSymbolAttribute(MCSymbolAttr Attribute);
78+
79+
bool isInEDSection() const {
80+
return isInSection() && static_cast<MCSectionGOFF &>(getSection()).isED();
81+
}
5082
};
5183
} // end namespace llvm
5284

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,9 +2788,10 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
27882788
// Initialize the label for the text section.
27892789
MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
27902790
getContext().getOrCreateSymbol(RootSD->getName()));
2791-
TextLD->setLDAttributes(GOFF::LDAttr{
2792-
false, GOFF::ESD_EXE_CODE, GOFF::ESD_BST_Strong, GOFF::ESD_LT_XPLink,
2793-
GOFF::ESD_AMODE_64, GOFF::ESD_BSC_Section});
2791+
TextLD->setCodeData(GOFF::ESD_EXE_CODE);
2792+
TextLD->setLinkage(GOFF::ESD_LT_XPLink);
2793+
TextLD->setExternal(false);
2794+
TextLD->setWeak(false);
27942795
TextLD->setADA(ADAPR);
27952796
TextSection->setBeginSymbol(TextLD);
27962797
}

llvm/lib/MC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMMC
5050
MCSubtargetInfo.cpp
5151
MCSymbol.cpp
5252
MCSymbolELF.cpp
53+
MCSymbolGOFF.cpp
5354
MCSymbolXCOFF.cpp
5455
MCTargetOptions.cpp
5556
MCTargetOptionsCommandFlags.cpp

llvm/lib/MC/GOFFObjectWriter.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,24 @@ class GOFFSymbol {
266266
BehavAttrs.setBindingScope(Attr.BindingScope);
267267
BehavAttrs.setAlignment(EDAttr.Alignment);
268268
}
269+
270+
GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
271+
const GOFF::ERAttr &Attr)
272+
: Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
273+
SymbolType(GOFF::ESD_ST_ExternalReference),
274+
NameSpace(GOFF::ESD_NS_NormalName) {
275+
BehavAttrs.setExecutable(Attr.Executable);
276+
BehavAttrs.setBindingStrength(Attr.BindingStrength);
277+
BehavAttrs.setLinkageType(Attr.Linkage);
278+
BehavAttrs.setAmode(Attr.Amode);
279+
BehavAttrs.setBindingScope(Attr.BindingScope);
280+
}
269281
};
270282

271283
class GOFFWriter {
272284
GOFFOstream OS;
273285
MCAssembler &Asm;
286+
MCSectionGOFF *RootSD;
274287

275288
void writeHeader();
276289
void writeSymbol(const GOFFSymbol &Symbol);
@@ -279,16 +292,18 @@ class GOFFWriter {
279292

280293
void defineSectionSymbols(const MCSectionGOFF &Section);
281294
void defineLabel(const MCSymbolGOFF &Symbol);
295+
void defineExtern(const MCSymbolGOFF &Symbol);
282296
void defineSymbols();
283297

284298
public:
285-
GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm);
299+
GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm, MCSectionGOFF *RootSD);
286300
uint64_t writeObject();
287301
};
288302
} // namespace
289303

290-
GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
291-
: OS(OS), Asm(Asm) {}
304+
GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
305+
MCSectionGOFF *RootSD)
306+
: OS(OS), Asm(Asm), RootSD(RootSD) {}
292307

293308
void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
294309
if (Section.isSD()) {
@@ -325,12 +340,24 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
325340
void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
326341
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(Symbol.getSection());
327342
GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(), Section.getOrdinal(),
328-
Section.getEDAttributes().NameSpace, Symbol.getLDAttributes());
343+
Section.getEDAttributes().NameSpace,
344+
GOFF::LDAttr{false, Symbol.getCodeData(),
345+
Symbol.getBindingStrength(), Symbol.getLinkage(),
346+
GOFF::ESD_AMODE_64, Symbol.getBindingScope()});
329347
if (Symbol.getADA())
330348
LD.ADAEsdId = Symbol.getADA()->getOrdinal();
349+
LD.Offset = Asm.getSymbolOffset(Symbol);
331350
writeSymbol(LD);
332351
}
333352

353+
void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
354+
GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(), RootSD->getOrdinal(),
355+
GOFF::ERAttr{Symbol.getCodeData(), Symbol.getBindingStrength(),
356+
Symbol.getLinkage(), GOFF::ESD_AMODE_64,
357+
Symbol.getBindingScope()});
358+
writeSymbol(ER);
359+
}
360+
334361
void GOFFWriter::defineSymbols() {
335362
unsigned Ordinal = 0;
336363
// Process all sections.
@@ -345,7 +372,10 @@ void GOFFWriter::defineSymbols() {
345372
if (Sym.isTemporary())
346373
continue;
347374
auto &Symbol = static_cast<const MCSymbolGOFF &>(Sym);
348-
if (Symbol.hasLDAttributes()) {
375+
if (!Symbol.isDefined()) {
376+
Symbol.setIndex(++Ordinal);
377+
defineExtern(Symbol);
378+
} else if (Symbol.isInEDSection()) {
349379
Symbol.setIndex(++Ordinal);
350380
defineLabel(Symbol);
351381
}
@@ -523,7 +553,7 @@ GOFFObjectWriter::GOFFObjectWriter(
523553
GOFFObjectWriter::~GOFFObjectWriter() = default;
524554

525555
uint64_t GOFFObjectWriter::writeObject() {
526-
uint64_t Size = GOFFWriter(OS, *Asm).writeObject();
556+
uint64_t Size = GOFFWriter(OS, *Asm, RootSD).writeObject();
527557
return Size;
528558
}
529559

llvm/lib/MC/MCAsmInfoGOFF.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ using namespace llvm;
2121

2222
MCAsmInfoGOFF::MCAsmInfoGOFF() {
2323
Data64bitsDirective = "\t.quad\t";
24-
HasDotTypeDotSizeDirective = false;
24+
WeakRefDirective = "WXTRN";
2525
PrivateGlobalPrefix = "L#";
2626
PrivateLabelPrefix = "L#";
2727
ZeroDirective = "\t.space\t";

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,9 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
774774
// Assemblers currently do not support a .cold directive.
775775
case MCSA_Exported:
776776
// Non-AIX assemblers currently do not support exported visibility.
777+
case MCSA_OSLinkage:
778+
case MCSA_XPLinkage:
779+
// Only for HLASM.
777780
return false;
778781
case MCSA_Memtag:
779782
OS << "\t.memtag\t";

0 commit comments

Comments
 (0)