diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h --- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h +++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h @@ -82,6 +82,110 @@ std::vector Relocations; }; +enum AuxSymbolType : uint8_t { + AUX_EXCEPT = 255, + AUX_FCN = 254, + AUX_SYM = 253, + AUX_FILE = 252, + AUX_CSECT = 251, + AUX_SECT = 250, + AUX_STAT = 249 +}; + +struct AuxSymbolEnt { + AuxSymbolType Type; + + explicit AuxSymbolEnt(AuxSymbolType T) : Type(T) {} + virtual ~AuxSymbolEnt(); +}; + +struct FileAuxEnt : AuxSymbolEnt { + Optional FileNameOrString; + Optional FileStringType; + + FileAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FILE) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_FILE; + } +}; + +struct CsectAuxEnt : AuxSymbolEnt { + // Only for XCOFF32. + Optional SectionOrLength; + Optional StabInfoIndex; + Optional StabSectNum; + // Only for XCOFF64. + Optional SectionOrLengthLo; + Optional SectionOrLengthHi; + // Common fields for both XCOFF32 and XCOFF64. + Optional ParameterHashIndex; + Optional TypeChkSectNum; + Optional SymbolAlignmentAndType; + Optional StorageMappingClass; + + CsectAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_CSECT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_CSECT; + } +}; + +struct FunctionAuxEnt : AuxSymbolEnt { + Optional OffsetToExceptionTbl; // Only for XCOFF32. + Optional PtrToLineNum; + Optional SizeOfFunction; + Optional SymIdxOfNextBeyond; + + FunctionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FCN) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_FCN; + } +}; + +struct ExcpetionAuxEnt : AuxSymbolEnt { + Optional OffsetToExceptionTbl; + Optional SizeOfFunction; + Optional SymIdxOfNextBeyond; + + ExcpetionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_EXCEPT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_EXCEPT; + } +}; // Only for XCOFF64. + +struct BlockAuxEnt : AuxSymbolEnt { + // Only for XCOFF32. + Optional LineNumHi; + Optional LineNumLo; + // Only for XCOFF64. + Optional LineNum; + + BlockAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_SYM) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_SYM; + } +}; + +struct SectAuxEntForDWARF : AuxSymbolEnt { + Optional LengthOfSectionPortion; + Optional NumberOfRelocEnt; + + SectAuxEntForDWARF() : AuxSymbolEnt(AuxSymbolType::AUX_SECT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_SECT; + } +}; + +struct SectAuxEntForStat : AuxSymbolEnt { + Optional SectionLength; + Optional NumberOfRelocEnt; + Optional NumberOfLineNum; + + SectAuxEntForStat() : AuxSymbolEnt(AuxSymbolType::AUX_STAT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_STAT; + } +}; // Only for XCOFF32. + struct Symbol { StringRef SymbolName; llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent. @@ -89,7 +193,8 @@ Optional SectionIndex; llvm::yaml::Hex16 Type; XCOFF::StorageClass StorageClass; - uint8_t NumberOfAuxEntries; + Optional NumberOfAuxEntries; + std::vector> AuxEntries; }; struct StringTable { @@ -114,6 +219,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol) LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation) LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section) +LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr) namespace llvm { namespace yaml { @@ -126,6 +232,18 @@ static void enumeration(IO &IO, XCOFF::StorageClass &Value); }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value); +}; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, XCOFF::CFileStringType &Type); +}; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, XCOFFYAML::AuxSymbolType &Type); +}; + template <> struct MappingTraits { static void mapping(IO &IO, XCOFFYAML::FileHeader &H); }; @@ -134,6 +252,10 @@ static void mapping(IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr); }; +template <> struct MappingTraits> { + static void mapping(IO &IO, std::unique_ptr &AuxSym); +}; + template <> struct MappingTraits { static void mapping(IO &IO, XCOFFYAML::Symbol &S); }; diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp --- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp +++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp @@ -47,6 +47,7 @@ bool initRelocations(uint64_t &CurrentOffset); bool initStringTable(); bool assignAddressesAndIndices(); + void writeFileHeader(); void writeAuxFileHeader(); void writeSectionHeader(); @@ -55,6 +56,15 @@ bool writeSymbols(); void writeStringTable(); + void writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym); + void writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym); + void writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym); + void writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym); + void writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym); + void writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym); + void writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym); + void writeAuxSymbol(const std::unique_ptr &AuxSym); + XCOFFYAML::Object &Obj; bool Is64Bit = false; support::endian::Writer W; @@ -190,12 +200,23 @@ } } } else { - for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) { + for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) { if (nameShouldBeInStringTable(YamlSym.SymbolName)) StrTblBuilder.add(YamlSym.SymbolName); } } + // Check if the file name in the File Auxiliary Entry should be added to the + // string table. + for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) { + for (const std::unique_ptr &AuxSym : + YamlSym.AuxEntries) { + if (auto AS = dyn_cast(AuxSym.get())) + if (nameShouldBeInStringTable(AS->FileNameOrString.getValueOr(""))) + StrTblBuilder.add(AS->FileNameOrString.getValueOr("")); + } + } + StrTblBuilder.finalize(); size_t StrTblSize = StrTblBuilder.getSize(); @@ -216,9 +237,21 @@ InitFileHdr.NumberOfSections = Obj.Sections.size(); InitFileHdr.NumberOfSymTableEntries = Obj.Symbols.size(); - for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) + for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) { + uint32_t AuxCount = YamlSym.AuxEntries.size(); + if (YamlSym.NumberOfAuxEntries && *YamlSym.NumberOfAuxEntries < AuxCount) { + ErrHandler("specified NumberOfAuxEntries " + + Twine(static_cast(*YamlSym.NumberOfAuxEntries)) + + " is less than the actual number " + "of auxiliary entries " + + Twine(AuxCount)); + return false; + } + YamlSym.NumberOfAuxEntries = + YamlSym.NumberOfAuxEntries.getValueOr(AuxCount); // Add the number of auxiliary symbols to the total number. - InitFileHdr.NumberOfSymTableEntries += YamlSym.NumberOfAuxEntries; + InitFileHdr.NumberOfSymTableEntries += *YamlSym.NumberOfAuxEntries; + } // Calculate SymbolTableOffset for the file header. if (InitFileHdr.NumberOfSymTableEntries) { @@ -491,6 +524,125 @@ return true; } +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) { + if (Is64Bit) { + W.write(AuxSym.SectionOrLengthLo.getValueOr(0)); + W.write(AuxSym.ParameterHashIndex.getValueOr(0)); + W.write(AuxSym.TypeChkSectNum.getValueOr(0)); + W.write(AuxSym.SymbolAlignmentAndType.getValueOr(0)); + W.write(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR)); + W.write(AuxSym.SectionOrLengthHi.getValueOr(0)); + W.write(0); + W.write(XCOFF::AUX_CSECT); + } else { + W.write(AuxSym.SectionOrLength.getValueOr(0)); + W.write(AuxSym.ParameterHashIndex.getValueOr(0)); + W.write(AuxSym.TypeChkSectNum.getValueOr(0)); + W.write(AuxSym.SymbolAlignmentAndType.getValueOr(0)); + W.write(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR)); + W.write(AuxSym.StabInfoIndex.getValueOr(0)); + W.write(AuxSym.StabSectNum.getValueOr(0)); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) { + assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32"); + W.write(AuxSym.OffsetToExceptionTbl.getValueOr(0)); + W.write(AuxSym.SizeOfFunction.getValueOr(0)); + W.write(AuxSym.SymIdxOfNextBeyond.getValueOr(0)); + W.write(0); + W.write(XCOFF::AUX_EXCEPT); +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) { + if (Is64Bit) { + W.write(AuxSym.PtrToLineNum.getValueOr(0)); + W.write(AuxSym.SizeOfFunction.getValueOr(0)); + W.write(AuxSym.SymIdxOfNextBeyond.getValueOr(0)); + W.write(0); + W.write(XCOFF::AUX_FCN); + } else { + W.write(AuxSym.OffsetToExceptionTbl.getValueOr(0)); + W.write(AuxSym.SizeOfFunction.getValueOr(0)); + W.write(AuxSym.PtrToLineNum.getValueOr(0)); + W.write(AuxSym.SymIdxOfNextBeyond.getValueOr(0)); + W.OS.write_zeros(2); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) { + StringRef FileName = AuxSym.FileNameOrString.getValueOr(""); + if (nameShouldBeInStringTable(FileName)) { + W.write(0); + W.write(StrTblBuilder.getOffset(FileName)); + } else { + writeName(FileName, W); + } + W.OS.write_zeros(XCOFF::FileNamePadSize); + W.write(AuxSym.FileStringType.getValueOr(XCOFF::XFT_FN)); + if (Is64Bit) { + W.OS.write_zeros(2); + W.write(XCOFF::AUX_FILE); + } else { + W.OS.write_zeros(3); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) { + if (Is64Bit) { + W.write(AuxSym.LineNum.getValueOr(0)); + W.OS.write_zeros(13); + W.write(XCOFF::AUX_SYM); + } else { + W.OS.write_zeros(2); + W.write(AuxSym.LineNumHi.getValueOr(0)); + W.write(AuxSym.LineNumLo.getValueOr(0)); + W.OS.write_zeros(12); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) { + if (Is64Bit) { + W.write(AuxSym.LengthOfSectionPortion.getValueOr(0)); + W.write(AuxSym.NumberOfRelocEnt.getValueOr(0)); + W.write(0); + W.write(XCOFF::AUX_SECT); + } else { + W.write(AuxSym.LengthOfSectionPortion.getValueOr(0)); + W.OS.write_zeros(4); + W.write(AuxSym.NumberOfRelocEnt.getValueOr(0)); + W.OS.write_zeros(6); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) { + assert(!Is64Bit && "can't write the stat auxiliary symbol for XCOFF64"); + W.write(AuxSym.SectionLength.getValueOr(0)); + W.write(AuxSym.NumberOfRelocEnt.getValueOr(0)); + W.write(AuxSym.NumberOfLineNum.getValueOr(0)); + W.OS.write_zeros(10); +} + +void XCOFFWriter::writeAuxSymbol( + const std::unique_ptr &AuxSym) { + if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast(AuxSym.get())) + writeAuxSymbol(*AS); + else + llvm_unreachable("unknown auxiliary symbol type"); +} + bool XCOFFWriter::writeSymbols() { int64_t PaddingSize = (uint64_t)InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset); @@ -533,16 +685,25 @@ } W.write(YamlSym.Type); W.write(YamlSym.StorageClass); - W.write(YamlSym.NumberOfAuxEntries); - - // Now output the auxiliary entry. - for (uint8_t I = 0, E = YamlSym.NumberOfAuxEntries; I < E; ++I) { - // TODO: Auxiliary entry is not supported yet. - // The auxiliary entries for a symbol follow its symbol table entry. The - // length of each auxiliary entry is the same as a symbol table entry (18 - // bytes). The format and quantity of auxiliary entries depend on the - // storage class (n_sclass) and type (n_type) of the symbol table entry. - W.OS.write_zeros(XCOFF::SymbolTableEntrySize); + + uint8_t NumOfAuxSym = YamlSym.NumberOfAuxEntries.getValueOr(0); + W.write(NumOfAuxSym); + + if (!NumOfAuxSym && !YamlSym.AuxEntries.size()) + continue; + + // Now write auxiliary entries. + if (!YamlSym.AuxEntries.size()) { + W.OS.write_zeros(XCOFF::SymbolTableEntrySize * NumOfAuxSym); + } else { + for (const std::unique_ptr &AuxSym : + YamlSym.AuxEntries) { + writeAuxSymbol(AuxSym); + } + // Pad with zeros. + if (NumOfAuxSym > YamlSym.AuxEntries.size()) + W.OS.write_zeros(XCOFF::SymbolTableEntrySize * + (NumOfAuxSym - YamlSym.AuxEntries.size())); } } return true; diff --git a/llvm/lib/ObjectYAML/XCOFFYAML.cpp b/llvm/lib/ObjectYAML/XCOFFYAML.cpp --- a/llvm/lib/ObjectYAML/XCOFFYAML.cpp +++ b/llvm/lib/ObjectYAML/XCOFFYAML.cpp @@ -19,6 +19,8 @@ Object::Object() { memset(&Header, 0, sizeof(Header)); } +AuxSymbolEnt::~AuxSymbolEnt() = default; + } // namespace XCOFFYAML namespace yaml { @@ -98,6 +100,56 @@ #undef ECase } +void ScalarEnumerationTraits::enumeration( + IO &IO, XCOFF::StorageMappingClass &Value) { +#define ECase(X) IO.enumCase(Value, #X, XCOFF::X) + ECase(XMC_PR); + ECase(XMC_RO); + ECase(XMC_DB); + ECase(XMC_GL); + ECase(XMC_XO); + ECase(XMC_SV); + ECase(XMC_SV64); + ECase(XMC_SV3264); + ECase(XMC_TI); + ECase(XMC_TB); + ECase(XMC_RW); + ECase(XMC_TC0); + ECase(XMC_TC); + ECase(XMC_TD); + ECase(XMC_DS); + ECase(XMC_UA); + ECase(XMC_BS); + ECase(XMC_UC); + ECase(XMC_TL); + ECase(XMC_UL); + ECase(XMC_TE); +#undef ECase +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, XCOFFYAML::AuxSymbolType &Type) { +#define ECase(X) IO.enumCase(Type, #X, XCOFFYAML::X) + ECase(AUX_EXCEPT); + ECase(AUX_FCN); + ECase(AUX_SYM); + ECase(AUX_FILE); + ECase(AUX_CSECT); + ECase(AUX_SECT); + ECase(AUX_STAT); +#undef ECase +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, XCOFF::CFileStringType &Type) { +#define ECase(X) IO.enumCase(Type, #X, XCOFF::X) + ECase(XFT_FN); + ECase(XFT_CT); + ECase(XFT_CV); + ECase(XFT_CD); +#undef ECase +} + struct NSectionFlags { NSectionFlags(IO &) : Flags(XCOFF::SectionTypeFlags(0)) {} NSectionFlags(IO &, uint32_t C) : Flags(XCOFF::SectionTypeFlags(C)) {} @@ -173,6 +225,107 @@ IO.mapOptional("Relocations", Sec.Relocations); } +static void auxSymMapping(IO &IO, XCOFFYAML::CsectAuxEnt &AuxSym, bool Is64) { + IO.mapOptional("ParameterHashIndex", AuxSym.ParameterHashIndex); + IO.mapOptional("TypeChkSectNum", AuxSym.TypeChkSectNum); + IO.mapOptional("SymbolAlignmentAndType", AuxSym.SymbolAlignmentAndType); + IO.mapOptional("StorageMappingClass", AuxSym.StorageMappingClass); + if (Is64) { + IO.mapOptional("SectionOrLengthLo", AuxSym.SectionOrLengthLo); + IO.mapOptional("SectionOrLengthHi", AuxSym.SectionOrLengthHi); + } else { + IO.mapOptional("SectionOrLength", AuxSym.SectionOrLength); + IO.mapOptional("StabInfoIndex", AuxSym.StabInfoIndex); + IO.mapOptional("StabSectNum", AuxSym.StabSectNum); + } +} + +static void auxSymMapping(IO &IO, XCOFFYAML::FileAuxEnt &AuxSym) { + IO.mapOptional("FileNameOrString", AuxSym.FileNameOrString); + IO.mapOptional("FileStringType", AuxSym.FileStringType); +} + +static void auxSymMapping(IO &IO, XCOFFYAML::BlockAuxEnt &AuxSym, bool Is64) { + if (Is64) { + IO.mapOptional("LineNum", AuxSym.LineNum); + } else { + IO.mapOptional("LineNumHi", AuxSym.LineNumHi); + IO.mapOptional("LineNumLo", AuxSym.LineNumLo); + } +} + +static void auxSymMapping(IO &IO, XCOFFYAML::FunctionAuxEnt &AuxSym, + bool Is64) { + if (!Is64) + IO.mapOptional("OffsetToExceptionTbl", AuxSym.OffsetToExceptionTbl); + IO.mapOptional("SizeOfFunction", AuxSym.SizeOfFunction); + IO.mapOptional("SymIdxOfNextBeyond", AuxSym.SymIdxOfNextBeyond); + IO.mapOptional("PtrToLineNum", AuxSym.PtrToLineNum); +} + +static void auxSymMapping(IO &IO, XCOFFYAML::ExcpetionAuxEnt &AuxSym) { + IO.mapOptional("OffsetToExceptionTbl", AuxSym.OffsetToExceptionTbl); + IO.mapOptional("SizeOfFunction", AuxSym.SizeOfFunction); + IO.mapOptional("SymIdxOfNextBeyond", AuxSym.SymIdxOfNextBeyond); +} + +static void auxSymMapping(IO &IO, XCOFFYAML::SectAuxEntForDWARF &AuxSym) { + IO.mapOptional("LengthOfSectionPortion", AuxSym.LengthOfSectionPortion); + IO.mapOptional("NumberOfRelocEnt", AuxSym.NumberOfRelocEnt); +} + +static void auxSymMapping(IO &IO, XCOFFYAML::SectAuxEntForStat &AuxSym) { + IO.mapOptional("SectionLength", AuxSym.SectionLength); + IO.mapOptional("NumberOfRelocEnt", AuxSym.NumberOfRelocEnt); + IO.mapOptional("NumberOfLineNum", AuxSym.NumberOfLineNum); +} + +void MappingTraits>::mapping( + IO &IO, std::unique_ptr &AuxSym) { + assert(!IO.outputting() && "We don't dump aux symbols currently."); + const bool Is64 = + static_cast(IO.getContext())->Header.Magic == + (llvm::yaml::Hex16)XCOFF::XCOFF64; + XCOFFYAML::AuxSymbolType AuxType; + IO.mapRequired("Type", AuxType); + switch (AuxType) { + case XCOFFYAML::AUX_EXCEPT: + if (!Is64) + IO.setError("an auxiliary symbol of type AUX_EXCEPT cannot be defined in " + "XCOFF32"); + AuxSym.reset(new XCOFFYAML::ExcpetionAuxEnt()); + auxSymMapping(IO, *cast(AuxSym.get())); + break; + case XCOFFYAML::AUX_FCN: + AuxSym.reset(new XCOFFYAML::FunctionAuxEnt()); + auxSymMapping(IO, *cast(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_SYM: + AuxSym.reset(new XCOFFYAML::BlockAuxEnt()); + auxSymMapping(IO, *cast(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_FILE: + AuxSym.reset(new XCOFFYAML::FileAuxEnt()); + auxSymMapping(IO, *cast(AuxSym.get())); + break; + case XCOFFYAML::AUX_CSECT: + AuxSym.reset(new XCOFFYAML::CsectAuxEnt()); + auxSymMapping(IO, *cast(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_SECT: + AuxSym.reset(new XCOFFYAML::SectAuxEntForDWARF()); + auxSymMapping(IO, *cast(AuxSym.get())); + break; + case XCOFFYAML::AUX_STAT: + if (Is64) + IO.setError( + "an auxiliary symbol of type AUX_STAT cannot be defined in XCOFF64"); + AuxSym.reset(new XCOFFYAML::SectAuxEntForStat()); + auxSymMapping(IO, *cast(AuxSym.get())); + break; + } +} + void MappingTraits::mapping(IO &IO, XCOFFYAML::Symbol &S) { IO.mapOptional("Name", S.SymbolName); IO.mapOptional("Value", S.Value); @@ -181,6 +334,8 @@ IO.mapOptional("Type", S.Type); IO.mapOptional("StorageClass", S.StorageClass); IO.mapOptional("NumberOfAuxEntries", S.NumberOfAuxEntries); + if (!IO.outputting()) + IO.mapOptional("AuxEntries", S.AuxEntries); } void MappingTraits::mapping(IO &IO, XCOFFYAML::StringTable &Str) { @@ -191,12 +346,14 @@ } void MappingTraits::mapping(IO &IO, XCOFFYAML::Object &Obj) { + IO.setContext(&Obj); IO.mapTag("!XCOFF", true); IO.mapRequired("FileHeader", Obj.Header); IO.mapOptional("AuxiliaryHeader", Obj.AuxHeader); IO.mapOptional("Sections", Obj.Sections); IO.mapOptional("Symbols", Obj.Symbols); IO.mapOptional("StringTable", Obj.StrTbl); + IO.setContext(nullptr); } } // namespace yaml diff --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp --- a/llvm/tools/obj2yaml/xcoff2yaml.cpp +++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp @@ -132,7 +132,8 @@ Sym.Type = SymbolEntRef.getSymbolType(); Sym.StorageClass = SymbolEntRef.getStorageClass(); Sym.NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries(); - Symbols.push_back(Sym); + + Symbols.push_back(std::move(Sym)); } return Error::success();