Skip to content

Commit 5aeabf2

Browse files
[XCOFF][obj2yaml] Support SymbolAlignmentAndType as 2 separate fields in YAML. (#76828)
XCOFF encodes a symbol type and alignment in a single 8-bit field. It is easier to read and write YAML files if the fields can be specified separately. This PR causes obj2yaml to write the fields separately and allows yaml2obj to read either the single combined field or the separate fields.
1 parent f407be3 commit 5aeabf2

File tree

8 files changed

+250
-39
lines changed

8 files changed

+250
-39
lines changed

llvm/include/llvm/ObjectYAML/XCOFFYAML.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ struct CsectAuxEnt : AuxSymbolEnt {
121121
// Common fields for both XCOFF32 and XCOFF64.
122122
std::optional<uint32_t> ParameterHashIndex;
123123
std::optional<uint16_t> TypeChkSectNum;
124+
std::optional<XCOFF::SymbolType> SymbolType;
125+
std::optional<uint8_t> SymbolAlignment;
126+
// The two previous values can be encoded as a single value.
124127
std::optional<uint8_t> SymbolAlignmentAndType;
125128
std::optional<XCOFF::StorageMappingClass> StorageMappingClass;
126129

@@ -237,6 +240,10 @@ template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> {
237240
static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value);
238241
};
239242

243+
template <> struct ScalarEnumerationTraits<XCOFF::SymbolType> {
244+
static void enumeration(IO &IO, XCOFF::SymbolType &Value);
245+
};
246+
240247
template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> {
241248
static void enumeration(IO &IO, XCOFF::CFileStringType &Type);
242249
};

llvm/lib/ObjectYAML/XCOFFEmitter.cpp

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/Support/raw_ostream.h"
2424

2525
using namespace llvm;
26+
using namespace llvm::object;
2627

2728
namespace {
2829

@@ -56,14 +57,14 @@ class XCOFFWriter {
5657
bool writeSymbols();
5758
void writeStringTable();
5859

59-
void writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);
60-
void writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);
61-
void writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);
62-
void writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
63-
void writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);
64-
void writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
65-
void writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);
66-
void writeAuxSymbol(const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
60+
bool writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);
61+
bool writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);
62+
bool writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);
63+
bool writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
64+
bool writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);
65+
bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
66+
bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);
67+
bool writeAuxSymbol(const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
6768

6869
XCOFFYAML::Object &Obj;
6970
bool Is64Bit = false;
@@ -181,7 +182,7 @@ bool XCOFFWriter::initStringTable() {
181182
StrTblBuilder.clear();
182183

183184
if (Obj.StrTbl.Strings) {
184-
// All specified strings should be added to the string table.
185+
// Add all specified strings to the string table.
185186
for (StringRef StringEnt : *Obj.StrTbl.Strings)
186187
StrTblBuilder.add(StringEnt);
187188

@@ -524,12 +525,44 @@ bool XCOFFWriter::writeRelocations() {
524525
return true;
525526
}
526527

527-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
528+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
529+
uint8_t SymAlignAndType = 0;
530+
if (AuxSym.SymbolAlignmentAndType) {
531+
if (AuxSym.SymbolType || AuxSym.SymbolAlignment) {
532+
ErrHandler("cannot specify SymbolType or SymbolAlignment if "
533+
"SymbolAlignmentAndType is specified");
534+
return false;
535+
}
536+
SymAlignAndType = *AuxSym.SymbolAlignmentAndType;
537+
} else {
538+
if (AuxSym.SymbolType) {
539+
uint8_t SymbolType = *AuxSym.SymbolType;
540+
if (SymbolType & ~XCOFFCsectAuxRef::SymbolTypeMask) {
541+
ErrHandler("symbol type must be less than " +
542+
Twine(1 + XCOFFCsectAuxRef::SymbolTypeMask));
543+
return false;
544+
}
545+
SymAlignAndType = SymbolType;
546+
}
547+
if (AuxSym.SymbolAlignment) {
548+
const uint8_t ShiftedSymbolAlignmentMask =
549+
XCOFFCsectAuxRef::SymbolAlignmentMask >>
550+
XCOFFCsectAuxRef::SymbolAlignmentBitOffset;
551+
552+
if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {
553+
ErrHandler("symbol alignment must be less than " +
554+
Twine(1 + ShiftedSymbolAlignmentMask));
555+
return false;
556+
}
557+
SymAlignAndType |= (*AuxSym.SymbolAlignment
558+
<< XCOFFCsectAuxRef::SymbolAlignmentBitOffset);
559+
}
560+
}
528561
if (Is64Bit) {
529562
W.write<uint32_t>(AuxSym.SectionOrLengthLo.value_or(0));
530563
W.write<uint32_t>(AuxSym.ParameterHashIndex.value_or(0));
531564
W.write<uint16_t>(AuxSym.TypeChkSectNum.value_or(0));
532-
W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.value_or(0));
565+
W.write<uint8_t>(SymAlignAndType);
533566
W.write<uint8_t>(AuxSym.StorageMappingClass.value_or(XCOFF::XMC_PR));
534567
W.write<uint32_t>(AuxSym.SectionOrLengthHi.value_or(0));
535568
W.write<uint8_t>(0);
@@ -538,23 +571,25 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
538571
W.write<uint32_t>(AuxSym.SectionOrLength.value_or(0));
539572
W.write<uint32_t>(AuxSym.ParameterHashIndex.value_or(0));
540573
W.write<uint16_t>(AuxSym.TypeChkSectNum.value_or(0));
541-
W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.value_or(0));
574+
W.write<uint8_t>(SymAlignAndType);
542575
W.write<uint8_t>(AuxSym.StorageMappingClass.value_or(XCOFF::XMC_PR));
543576
W.write<uint32_t>(AuxSym.StabInfoIndex.value_or(0));
544577
W.write<uint16_t>(AuxSym.StabSectNum.value_or(0));
545578
}
579+
return true;
546580
}
547581

548-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
582+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
549583
assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32");
550584
W.write<uint64_t>(AuxSym.OffsetToExceptionTbl.value_or(0));
551585
W.write<uint32_t>(AuxSym.SizeOfFunction.value_or(0));
552586
W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.value_or(0));
553587
W.write<uint8_t>(0);
554588
W.write<uint8_t>(XCOFF::AUX_EXCEPT);
589+
return true;
555590
}
556591

557-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
592+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
558593
if (Is64Bit) {
559594
W.write<uint64_t>(AuxSym.PtrToLineNum.value_or(0));
560595
W.write<uint32_t>(AuxSym.SizeOfFunction.value_or(0));
@@ -568,9 +603,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
568603
W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.value_or(0));
569604
W.OS.write_zeros(2);
570605
}
606+
return true;
571607
}
572608

573-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
609+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
574610
StringRef FileName = AuxSym.FileNameOrString.value_or("");
575611
if (nameShouldBeInStringTable(FileName)) {
576612
W.write<int32_t>(0);
@@ -586,9 +622,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
586622
} else {
587623
W.OS.write_zeros(3);
588624
}
625+
return true;
589626
}
590627

591-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
628+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
592629
if (Is64Bit) {
593630
W.write<uint32_t>(AuxSym.LineNum.value_or(0));
594631
W.OS.write_zeros(13);
@@ -599,9 +636,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
599636
W.write<uint16_t>(AuxSym.LineNumLo.value_or(0));
600637
W.OS.write_zeros(12);
601638
}
639+
return true;
602640
}
603641

604-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
642+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
605643
if (Is64Bit) {
606644
W.write<uint64_t>(AuxSym.LengthOfSectionPortion.value_or(0));
607645
W.write<uint64_t>(AuxSym.NumberOfRelocEnt.value_or(0));
@@ -613,34 +651,36 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
613651
W.write<uint32_t>(AuxSym.NumberOfRelocEnt.value_or(0));
614652
W.OS.write_zeros(6);
615653
}
654+
return true;
616655
}
617656

618-
void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {
657+
bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {
619658
assert(!Is64Bit && "can't write the stat auxiliary symbol for XCOFF64");
620659
W.write<uint32_t>(AuxSym.SectionLength.value_or(0));
621660
W.write<uint16_t>(AuxSym.NumberOfRelocEnt.value_or(0));
622661
W.write<uint16_t>(AuxSym.NumberOfLineNum.value_or(0));
623662
W.OS.write_zeros(10);
663+
return true;
624664
}
625665

626-
void XCOFFWriter::writeAuxSymbol(
666+
bool XCOFFWriter::writeAuxSymbol(
627667
const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {
628668
if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get()))
629-
writeAuxSymbol(*AS);
669+
return writeAuxSymbol(*AS);
630670
else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get()))
631-
writeAuxSymbol(*AS);
671+
return writeAuxSymbol(*AS);
632672
else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get()))
633-
writeAuxSymbol(*AS);
673+
return writeAuxSymbol(*AS);
634674
else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get()))
635-
writeAuxSymbol(*AS);
675+
return writeAuxSymbol(*AS);
636676
else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get()))
637-
writeAuxSymbol(*AS);
677+
return writeAuxSymbol(*AS);
638678
else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get()))
639-
writeAuxSymbol(*AS);
679+
return writeAuxSymbol(*AS);
640680
else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get()))
641-
writeAuxSymbol(*AS);
642-
else
643-
llvm_unreachable("unknown auxiliary symbol type");
681+
return writeAuxSymbol(*AS);
682+
llvm_unreachable("unknown auxiliary symbol type");
683+
return false;
644684
}
645685

646686
bool XCOFFWriter::writeSymbols() {
@@ -698,7 +738,8 @@ bool XCOFFWriter::writeSymbols() {
698738
} else {
699739
for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
700740
YamlSym.AuxEntries) {
701-
writeAuxSymbol(AuxSym);
741+
if (!writeAuxSymbol(AuxSym))
742+
return false;
702743
}
703744
// Pad with zeros.
704745
if (NumOfAuxSym > YamlSym.AuxEntries.size())

llvm/lib/ObjectYAML/XCOFFYAML.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ void ScalarEnumerationTraits<XCOFF::StorageMappingClass>::enumeration(
127127
#undef ECase
128128
}
129129

130+
void ScalarEnumerationTraits<XCOFF::SymbolType>::enumeration(
131+
IO &IO, XCOFF::SymbolType &Value) {
132+
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
133+
ECase(XTY_ER);
134+
ECase(XTY_SD);
135+
ECase(XTY_LD);
136+
ECase(XTY_CM);
137+
#undef ECase
138+
IO.enumFallback<Hex8>(Value);
139+
}
140+
130141
void ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType>::enumeration(
131142
IO &IO, XCOFFYAML::AuxSymbolType &Type) {
132143
#define ECase(X) IO.enumCase(Type, #X, XCOFFYAML::X)
@@ -229,6 +240,8 @@ static void auxSymMapping(IO &IO, XCOFFYAML::CsectAuxEnt &AuxSym, bool Is64) {
229240
IO.mapOptional("ParameterHashIndex", AuxSym.ParameterHashIndex);
230241
IO.mapOptional("TypeChkSectNum", AuxSym.TypeChkSectNum);
231242
IO.mapOptional("SymbolAlignmentAndType", AuxSym.SymbolAlignmentAndType);
243+
IO.mapOptional("SymbolType", AuxSym.SymbolType);
244+
IO.mapOptional("SymbolAlignment", AuxSym.SymbolAlignment);
232245
IO.mapOptional("StorageMappingClass", AuxSym.StorageMappingClass);
233246
if (Is64) {
234247
IO.mapOptional("SectionOrLengthLo", AuxSym.SectionOrLengthLo);
@@ -350,7 +363,8 @@ void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
350363
IO.mapOptional("AuxEntries", S.AuxEntries);
351364
}
352365

353-
void MappingTraits<XCOFFYAML::StringTable>::mapping(IO &IO, XCOFFYAML::StringTable &Str) {
366+
void MappingTraits<XCOFFYAML::StringTable>::mapping(
367+
IO &IO, XCOFFYAML::StringTable &Str) {
354368
IO.mapOptional("ContentSize", Str.ContentSize);
355369
IO.mapOptional("Length", Str.Length);
356370
IO.mapOptional("Strings", Str.Strings);

llvm/test/tools/obj2yaml/XCOFF/aix.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
# CHECK32-NEXT: - Type: AUX_CSECT
5757
# CHECK32-NEXT: ParameterHashIndex: 0
5858
# CHECK32-NEXT: TypeChkSectNum: 0
59-
# CHECK32-NEXT: SymbolAlignmentAndType: 0
59+
# CHECK32-NEXT: SymbolType: XTY_ER
60+
# CHECK32-NEXT: SymbolAlignment: 0
6061
# CHECK32-NEXT: StorageMappingClass: XMC_PR
6162
# CHECK32-NEXT: SectionOrLength: 0
6263
# CHECK32-NEXT: StabInfoIndex: 0
@@ -71,7 +72,8 @@
7172
# CHECK32-NEXT: - Type: AUX_CSECT
7273
# CHECK32-NEXT: ParameterHashIndex: 0
7374
# CHECK32-NEXT: TypeChkSectNum: 0
74-
# CHECK32-NEXT: SymbolAlignmentAndType: 0
75+
# CHECK32-NEXT: SymbolType: XTY_ER
76+
# CHECK32-NEXT: SymbolAlignment: 0
7577
# CHECK32-NEXT: StorageMappingClass: XMC_PR
7678
# CHECK32-NEXT: SectionOrLength: 0
7779
# CHECK32-NEXT: StabInfoIndex: 0
@@ -128,7 +130,8 @@
128130
# CHECK64-NEXT: - Type: AUX_CSECT
129131
# CHECK64-NEXT: ParameterHashIndex: 0
130132
# CHECK64-NEXT: TypeChkSectNum: 0
131-
# CHECK64-NEXT: SymbolAlignmentAndType: 0
133+
# CHECK64-NEXT: SymbolType: XTY_ER
134+
# CHECK64-NEXT: SymbolAlignment: 0
132135
# CHECK64-NEXT: StorageMappingClass: XMC_PR
133136
# CHECK64-NEXT: SectionOrLengthLo: 0
134137
# CHECK64-NEXT: SectionOrLengthHi: 0
@@ -142,7 +145,8 @@
142145
# CHECK64-NEXT: - Type: AUX_CSECT
143146
# CHECK64-NEXT: ParameterHashIndex: 0
144147
# CHECK64-NEXT: TypeChkSectNum: 0
145-
# CHECK64-NEXT: SymbolAlignmentAndType: 0
148+
# CHECK64-NEXT: SymbolType: XTY_ER
149+
# CHECK64-NEXT: SymbolAlignment: 0
146150
# CHECK64-NEXT: StorageMappingClass: XMC_PR
147151
# CHECK64-NEXT: SectionOrLengthLo: 0
148152
# CHECK64-NEXT: SectionOrLengthHi: 0

llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
# CHECK32-NEXT: - Type: AUX_CSECT
3535
# CHECK32-NEXT: ParameterHashIndex: 1
3636
# CHECK32-NEXT: TypeChkSectNum: 2
37-
# CHECK32-NEXT: SymbolAlignmentAndType: 41
37+
# CHECK32-NEXT: SymbolType: XTY_SD
38+
# CHECK32-NEXT: SymbolAlignment: 5
3839
# CHECK32-NEXT: StorageMappingClass: XMC_PR
3940
# CHECK32-NEXT: SectionOrLength: 3
4041
# CHECK32-NEXT: StabInfoIndex: 4
@@ -54,7 +55,8 @@
5455
# CHECK32-NEXT: - Type: AUX_CSECT
5556
# CHECK32-NEXT: ParameterHashIndex: 1
5657
# CHECK32-NEXT: TypeChkSectNum: 2
57-
# CHECK32-NEXT: SymbolAlignmentAndType: 17
58+
# CHECK32-NEXT: SymbolType: XTY_SD
59+
# CHECK32-NEXT: SymbolAlignment: 2
5860
# CHECK32-NEXT: StorageMappingClass: XMC_PR
5961
# CHECK32-NEXT: SectionOrLength: 4
6062
# CHECK32-NEXT: StabInfoIndex: 5
@@ -174,7 +176,8 @@ Symbols:
174176
# CHECK64-NEXT: - Type: AUX_CSECT
175177
# CHECK64-NEXT: ParameterHashIndex: 1
176178
# CHECK64-NEXT: TypeChkSectNum: 2
177-
# CHECK64-NEXT: SymbolAlignmentAndType: 41
179+
# CHECK64-NEXT: SymbolType: XTY_SD
180+
# CHECK64-NEXT: SymbolAlignment: 5
178181
# CHECK64-NEXT: StorageMappingClass: XMC_PR
179182
# CHECK64-NEXT: SectionOrLengthLo: 3
180183
# CHECK64-NEXT: SectionOrLengthHi: 4
@@ -196,7 +199,8 @@ Symbols:
196199
# CHECK64-NEXT: - Type: AUX_CSECT
197200
# CHECK64-NEXT: ParameterHashIndex: 1
198201
# CHECK64-NEXT: TypeChkSectNum: 2
199-
# CHECK64-NEXT: SymbolAlignmentAndType: 17
202+
# CHECK64-NEXT: SymbolType: XTY_SD
203+
# CHECK64-NEXT: SymbolAlignment: 2
200204
# CHECK64-NEXT: StorageMappingClass: XMC_PR
201205
# CHECK64-NEXT: SectionOrLengthLo: 3
202206
# CHECK64-NEXT: SectionOrLengthHi: 4

0 commit comments

Comments
 (0)