Skip to content

Commit 48df2fc

Browse files
committed
[GOFF] Add writing text records to yaml2obj
Add support for writing text records to yaml2obj.
1 parent 6f26aa8 commit 48df2fc

File tree

7 files changed

+127
-4
lines changed

7 files changed

+127
-4
lines changed

Diff for: llvm/include/llvm/BinaryFormat/GOFF.h

+6
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ enum ESDAlignment : uint8_t {
157157
ESD_ALIGN_4Kpage = 12,
158158
};
159159

160+
enum TXTRecordStyle : uint8_t {
161+
TXT_TS_Byte = 0,
162+
TXT_TS_Structured = 1,
163+
TXT_TS_Unstructured = 2,
164+
};
165+
160166
enum ENDEntryPointRequest : uint8_t {
161167
END_EPR_None = 0,
162168
END_EPR_EsdidOffset = 1,

Diff for: llvm/include/llvm/ObjectYAML/GOFFYAML.h

+19
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace llvm {
2626
namespace GOFFYAML {
2727

2828
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_AMODE)
29+
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_TXTRECORDSTYLE)
2930
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ENDFLAGS)
3031

3132
// The GOFF format uses different kinds of logical records. The format imposes
@@ -65,6 +66,22 @@ struct ModuleHeader : public RecordBase {
6566
}
6667
};
6768

69+
struct Text : public RecordBase {
70+
Text() : RecordBase(Kind::Text) {}
71+
72+
GOFF_TXTRECORDSTYLE Style;
73+
uint32_t ESDID;
74+
uint32_t Offset;
75+
uint32_t TrueLength;
76+
uint16_t Encoding;
77+
uint16_t DataLength;
78+
std::optional<yaml::BinaryRef> Data;
79+
80+
static bool classof(const RecordBase *S) {
81+
return S->getKind() == Kind::Text;
82+
}
83+
};
84+
6885
struct EndOfModule : public RecordBase {
6986
EndOfModule() : RecordBase(Kind::EndOfModule) {}
7087

@@ -89,12 +106,14 @@ struct Object {
89106
} // end namespace llvm
90107

91108
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_AMODE)
109+
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_TXTRECORDSTYLE)
92110
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ENDFLAGS)
93111

94112
LLVM_YAML_IS_SEQUENCE_VECTOR(GOFFYAML::RecordPtr)
95113
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::RecordPtr)
96114

97115
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::ModuleHeader)
116+
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Text)
98117
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::EndOfModule)
99118
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Object)
100119

Diff for: llvm/lib/ObjectYAML/GOFFEmitter.cpp

+22-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class LogicalRecord : public raw_svector_ostream {
147147

148148
class GOFFState {
149149
void writeHeader(const GOFFYAML::ModuleHeader &ModHdr);
150+
void writeText(const GOFFYAML::Text &Txt);
150151
void writeEnd(const GOFFYAML::EndOfModule &EndMod);
151152

152153
void reportError(const Twine &Msg) {
@@ -184,6 +185,24 @@ void GOFFState::writeHeader(const GOFFYAML::ModuleHeader &ModHdr) {
184185
LR << *ModHdr.Properties; // Module properties.
185186
}
186187

188+
void GOFFState::writeText(const GOFFYAML::Text &Txt) {
189+
// See https://www.ibm.com/docs/en/zos/3.1.0?topic=grf-text-record.
190+
GW.newRecord(GOFF::RT_TXT);
191+
LogicalRecord LR(GW);
192+
LR << binaryBe(uint8_t(Txt.Style)) // Text record style.
193+
<< binaryBe(
194+
Txt.ESDID) // ESDID of the element/part to which this data belongs.
195+
<< zeros(4) // Reserved.
196+
<< binaryBe(Txt.Offset) // Starting offset from element/part.
197+
<< binaryBe(Txt.TrueLength) // True length if encoded.
198+
<< binaryBe(Txt.Encoding) // Encoding.
199+
<< binaryBe(Txt.DataLength); // Total length of data.
200+
if (Txt.Data)
201+
LR << *Txt.Data; // Data.
202+
else
203+
LR << zeros(Txt.DataLength);
204+
}
205+
187206
void GOFFState::writeEnd(const GOFFYAML::EndOfModule &EndMod) {
188207
// See https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-end-module-record.
189208
SmallString<16> EntryName;
@@ -211,12 +230,14 @@ bool GOFFState::writeObject() {
211230
case GOFFYAML::RecordBase::Kind::ModuleHeader:
212231
writeHeader(*static_cast<const GOFFYAML::ModuleHeader *>(Rec));
213232
break;
233+
case GOFFYAML::RecordBase::Kind::Text:
234+
writeText(*static_cast<const GOFFYAML::Text *>(Rec));
235+
break;
214236
case GOFFYAML::RecordBase::Kind::EndOfModule:
215237
writeEnd(*static_cast<const GOFFYAML::EndOfModule *>(Rec));
216238
break;
217239
case GOFFYAML::RecordBase::Kind::RelocationDirectory:
218240
case GOFFYAML::RecordBase::Kind::Symbol:
219-
case GOFFYAML::RecordBase::Kind::Text:
220241
case GOFFYAML::RecordBase::Kind::DeferredLength:
221242
llvm_unreachable("not yet implemented");
222243
}

Diff for: llvm/lib/ObjectYAML/GOFFYAML.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ void ScalarEnumerationTraits<GOFFYAML::GOFF_AMODE>::enumeration(
3030
IO.enumFallback<Hex8>(Value);
3131
}
3232

33+
void ScalarEnumerationTraits<GOFFYAML::GOFF_TXTRECORDSTYLE>::enumeration(
34+
IO &IO, GOFFYAML::GOFF_TXTRECORDSTYLE &Value) {
35+
#define ECase(X) IO.enumCase(Value, #X, GOFF::TXT_##X)
36+
ECase(TS_Byte);
37+
ECase(TS_Structured);
38+
ECase(TS_Unstructured);
39+
#undef ECase
40+
IO.enumFallback<Hex8>(Value);
41+
}
42+
3343
void ScalarEnumerationTraits<GOFFYAML::GOFF_ENDFLAGS>::enumeration(
3444
IO &IO, GOFFYAML::GOFF_ENDFLAGS &Value) {
3545
#define ECase(X) IO.enumCase(Value, #X, unsigned(GOFF::END_##X) << 6)
@@ -48,6 +58,16 @@ void MappingTraits<GOFFYAML::ModuleHeader>::mapping(
4858
IO.mapOptional("Properties", ModHdr.Properties);
4959
}
5060

61+
void MappingTraits<GOFFYAML::Text>::mapping(IO &IO, GOFFYAML::Text &Txt) {
62+
IO.mapOptional("TextStyle", Txt.Style, GOFF::TXT_TS_Byte);
63+
IO.mapOptional("ESDID", Txt.ESDID, 0);
64+
IO.mapOptional("Offset", Txt.Offset, 0);
65+
IO.mapOptional("TrueLength", Txt.TrueLength, 0);
66+
IO.mapOptional("TextEncoding", Txt.Encoding, 0);
67+
IO.mapOptional("DataLength", Txt.DataLength, 0);
68+
IO.mapOptional("Data", Txt.Data);
69+
}
70+
5171
void MappingTraits<GOFFYAML::EndOfModule>::mapping(IO &IO,
5272
GOFFYAML::EndOfModule &End) {
5373
IO.mapOptional("Flags", End.Flags, 0);
@@ -65,12 +85,15 @@ void CustomMappingTraits<GOFFYAML::RecordPtr>::inputOne(
6585
GOFFYAML::ModuleHeader ModHdr;
6686
IO.mapRequired("ModuleHeader", ModHdr);
6787
Elem = std::make_unique<GOFFYAML::ModuleHeader>(std::move(ModHdr));
88+
} else if (Key == "Text") {
89+
GOFFYAML::Text Txt;
90+
IO.mapRequired("Text", Txt);
91+
Elem = std::make_unique<GOFFYAML::Text>(std::move(Txt));
6892
} else if (Key == "End") {
6993
GOFFYAML::EndOfModule End;
7094
IO.mapRequired("End", End);
7195
Elem = std::make_unique<GOFFYAML::EndOfModule>(std::move(End));
72-
} else if (Key == "RelocationDirectory" || Key == "Symbol" || Key == "Text" ||
73-
Key == "Length")
96+
} else if (Key == "RelocationDirectory" || Key == "Symbol" || Key == "Length")
7497
IO.setError(Twine("not yet implemented ").concat(Key));
7598
else
7699
IO.setError(Twine("unknown record type name ").concat(Key));
@@ -83,12 +106,14 @@ void CustomMappingTraits<GOFFYAML::RecordPtr>::output(
83106
IO.mapRequired("ModuleHeader",
84107
*static_cast<GOFFYAML::ModuleHeader *>(Elem.get()));
85108
break;
109+
case GOFFYAML::RecordBase::Kind::Text:
110+
IO.mapRequired("Text", *static_cast<GOFFYAML::Text *>(Elem.get()));
111+
break;
86112
case GOFFYAML::RecordBase::Kind::EndOfModule:
87113
IO.mapRequired("End", *static_cast<GOFFYAML::EndOfModule *>(Elem.get()));
88114
break;
89115
case GOFFYAML::RecordBase::Kind::RelocationDirectory:
90116
case GOFFYAML::RecordBase::Kind::Symbol:
91-
case GOFFYAML::RecordBase::Kind::Text:
92117
case GOFFYAML::RecordBase::Kind::DeferredLength:
93118
llvm_unreachable("not yet implemented");
94119
}

Diff for: llvm/test/tools/yaml2obj/GOFF/text-default.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s
2+
3+
## Verify that the GOFF text record is correctly written with all fields
4+
## having a default value.
5+
6+
# CHECK: 03 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
8+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
11+
12+
# CHECK-EMPTY:
13+
14+
--- !GOFF
15+
- Text:

Diff for: llvm/test/tools/yaml2obj/GOFF/text-only.yaml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s
2+
3+
## Verify that the GOFF text record is correct, with all fields having a
4+
## value. No other record is written.
5+
6+
# CHECK: 03 10 00 01 00 00 00 2a 00 00 00 00 00 00 00 01
7+
# CHECK-NEXT: 00 00 02 00 00 01 00 0a a0 b0 c0 d0 e0 f0 10 20
8+
# CHECK-NEXT: 30 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
11+
12+
# CHECK-EMPTY:
13+
14+
--- !GOFF
15+
- Text:
16+
TextStyle: TS_Structured
17+
ESDID: 42
18+
Offset: 1
19+
TrueLength: 512
20+
TextEncoding: 1
21+
DataLength: 10
22+
Data: a0b0c0d0e0f010203040

Diff for: llvm/test/tools/yaml2obj/GOFF/text-style-const.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s
2+
3+
## Verify that the text style can be given as a constant.
4+
5+
# CHECK: 03 10 00 0a 00 00 00 00 00 00 00 00 00 00 00 00
6+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
8+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
9+
# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10+
11+
# CHECK-EMPTY:
12+
13+
--- !GOFF
14+
- Text:
15+
TextStyle: 0xA

0 commit comments

Comments
 (0)