Skip to content

Commit f2ecdeb

Browse files
committed
Add HLASM output and external references
Adds HLASM output and tests for it, per reviewer comment. Also adds external references, because it fits very well into the implementation.
1 parent e8cabda commit f2ecdeb

19 files changed

+395
-60
lines changed

llvm/include/llvm/MC/MCDirectives.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ enum MCSymbolAttr {
4848
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
4949
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
5050
MCSA_Memtag, ///< .memtag (ELF)
51+
52+
// Attributes specific for HLASM.
53+
MCSA_Code, ///< symbol is code (GOFF)
54+
MCSA_Data, ///< symbol is data (GOFF)
5155
};
5256

5357
enum MCDataRegionType {

llvm/include/llvm/MC/MCGOFFAttributes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ 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::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
89+
};
90+
8391
// Predefined GOFF class names.
8492
constexpr StringLiteral CLASS_CODE = "C_CODE64";
8593
constexpr StringLiteral CLASS_WSA = "C_WSA64";

llvm/include/llvm/MC/MCGOFFStreamer.h

Lines changed: 3 additions & 0 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

@@ -34,6 +35,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
3435

3536
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
3637
Align ByteAlignment) override {}
38+
39+
void emitExterns();
3740
};
3841

3942
} // end namespace llvm

llvm/include/llvm/MC/MCSymbolGOFF.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,21 @@ namespace llvm {
2323

2424
class MCSymbolGOFF : public MCSymbol {
2525
// Associated data area of the section. Needs to be emitted first.
26-
MCSectionGOFF *ADA;
26+
MCSectionGOFF *ADA = nullptr;
27+
28+
// Owner of the symbol if symbol is an external reference. External references
29+
// need a section, too, but adding them to a section would make the symbol
30+
// defined.
31+
MCSectionGOFF *Owner = nullptr;
2732

2833
GOFF::LDAttr LDAttributes;
34+
GOFF::ERAttr ERAttributes;
35+
36+
GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
2937

3038
enum SymbolFlags : uint16_t {
3139
SF_LD = 0x01, // LD attributes are set.
32-
// Leave place for EX attributes.
40+
SF_ER = 0x02, // ER attributes are set.
3341
SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
3442
SF_Weak = 0x08, // Symbol is weak.
3543
};
@@ -46,12 +54,25 @@ class MCSymbolGOFF : public MCSymbol {
4654
GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
4755
bool hasLDAttributes() const { return getFlags() & SF_LD; }
4856

57+
void setERAttributes(GOFF::ERAttr Attr) {
58+
modifyFlags(SF_ER, SF_ER);
59+
ERAttributes = Attr;
60+
}
61+
const GOFF::ERAttr &getERAttributes() const { return ERAttributes; }
62+
GOFF::ERAttr &getERAttributes() { return ERAttributes; }
63+
bool hasERAttributes() const { return getFlags() & SF_ER; }
64+
4965
void setADA(MCSectionGOFF *AssociatedDataArea) {
5066
ADA = AssociatedDataArea;
5167
AssociatedDataArea->RequiresNonZeroLength = true;
5268
}
5369
MCSectionGOFF *getADA() const { return ADA; }
5470

71+
void setOwner(MCSectionGOFF *Owner) {
72+
this->Owner = Owner;
73+
}
74+
MCSectionGOFF *getOwner() const { return Owner; }
75+
5576
bool isExternal() const { return IsExternal; }
5677
void setExternal(bool Value) const { IsExternal = Value; }
5778

@@ -64,6 +85,9 @@ class MCSymbolGOFF : public MCSymbol {
6485
void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
6586
bool isWeak() const { return getFlags() & SF_Weak; }
6687

88+
void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
89+
GOFF::ESDExecutable getCodeData() const { return CodeData; }
90+
6791
void initAttributes();
6892
};
6993
} // end namespace llvm

llvm/lib/MC/GOFFObjectWriter.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ 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.setBindingScope(Attr.BindingScope);
279+
}
269280
};
270281

271282
class GOFFWriter {
@@ -279,6 +290,7 @@ class GOFFWriter {
279290

280291
void defineSectionSymbols(const MCSectionGOFF &Section);
281292
void defineLabel(const MCSymbolGOFF &Symbol);
293+
void defineExtern(const MCSymbolGOFF &Symbol);
282294
void defineSymbols();
283295

284296
public:
@@ -332,6 +344,12 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
332344
writeSymbol(LD);
333345
}
334346

347+
void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
348+
GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(),
349+
Symbol.getOwner()->getOrdinal(), Symbol.getERAttributes());
350+
writeSymbol(ER);
351+
}
352+
335353
void GOFFWriter::defineSymbols() {
336354
unsigned Ordinal = 0;
337355
// Process all sections.
@@ -349,6 +367,9 @@ void GOFFWriter::defineSymbols() {
349367
if (Symbol.hasLDAttributes()) {
350368
Symbol.setIndex(++Ordinal);
351369
defineLabel(Symbol);
370+
} else if (Symbol.hasERAttributes()) {
371+
Symbol.setIndex(++Ordinal);
372+
defineExtern(Symbol);
352373
}
353374
}
354375
}

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_Code:
778+
case MCSA_Data:
779+
// Only for HLASM.
777780
return false;
778781
case MCSA_Memtag:
779782
OS << "\t.memtag\t";

llvm/lib/MC/MCELFStreamer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
151151
case MCSA_IndirectSymbol:
152152
case MCSA_Exported:
153153
case MCSA_WeakAntiDep:
154+
case MCSA_Code:
155+
case MCSA_Data:
154156
return false;
155157

156158
case MCSA_NoDeadStrip:

llvm/lib/MC/MCGOFFStreamer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "llvm/MC/MCGOFFStreamer.h"
14+
#include "llvm/BinaryFormat/GOFF.h"
1415
#include "llvm/MC/MCAsmBackend.h"
1516
#include "llvm/MC/MCAssembler.h"
1617
#include "llvm/MC/MCCodeEmitter.h"
@@ -75,6 +76,12 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
7576
case MCSA_Memtag:
7677
return false;
7778

79+
case MCSA_Code:
80+
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
81+
break;
82+
case MCSA_Data:
83+
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
84+
break;
7885
case MCSA_Global:
7986
Symbol->setExternal(true);
8087
break;
@@ -94,6 +101,18 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
94101
return true;
95102
}
96103

104+
void MCGOFFStreamer::emitExterns() {
105+
for (auto &Symbol : getAssembler().symbols()) {
106+
if (Symbol.isTemporary())
107+
continue;
108+
if (Symbol.isRegistered()) {
109+
auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
110+
Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
111+
Sym.initAttributes();
112+
}
113+
}
114+
}
115+
97116
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
98117
std::unique_ptr<MCAsmBackend> &&MAB,
99118
std::unique_ptr<MCObjectWriter> &&OW,

llvm/lib/MC/MCMachOStreamer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
299299
case MCSA_Exported:
300300
case MCSA_Memtag:
301301
case MCSA_WeakAntiDep:
302+
case MCSA_Code:
303+
case MCSA_Data:
302304
return false;
303305

304306
case MCSA_Global:

llvm/lib/MC/MCSymbolGOFF.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,35 @@
1313
using namespace llvm;
1414

1515
void MCSymbolGOFF::initAttributes() {
16-
if (hasLDAttributes())
16+
// Temporary labels are not emitted into the object file.
17+
if (isTemporary())
1718
return;
1819

20+
// Do not initialize the attributes multiple times.
21+
if (hasLDAttributes() || hasERAttributes())
22+
return;
23+
24+
GOFF::ESDBindingScope BindingScope =
25+
isExternal()
26+
? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
27+
: GOFF::ESD_BSC_Section;
28+
GOFF::ESDBindingStrength BindingStrength =
29+
isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
30+
: GOFF::ESDBindingStrength::ESD_BST_Strong;
31+
1932
if (isDefined()) {
2033
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
21-
GOFF::ESDBindingScope BindingScope =
22-
isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
23-
: GOFF::ESD_BSC_Library)
24-
: GOFF::ESD_BSC_Section;
25-
GOFF::ESDBindingStrength BindingStrength =
26-
isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
27-
: GOFF::ESDBindingStrength::ESD_BST_Strong;
2834
if (Section.isED()) {
29-
setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, BindingStrength,
35+
setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength,
3036
GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
3137
BindingScope});
3238
} else if (Section.isPR()) {
3339
// For data symbols, the attributes are already determind in TLOFI.
3440
// TODO Does it make sense to it to here?
3541
} else
3642
llvm_unreachable("Unexpected section type for label");
43+
} else {
44+
setERAttributes(GOFF::ERAttr{CodeData, BindingStrength,
45+
GOFF::ESD_LT_XPLink, BindingScope});
3746
}
38-
// TODO Handle external symbol.
3947
}

0 commit comments

Comments
 (0)