diff options
author | Esme-Yi <esme.yi@ibm.com> | 2022-01-10 02:38:49 +0000 |
---|---|---|
committer | Esme-Yi <esme.yi@ibm.com> | 2022-01-10 02:38:49 +0000 |
commit | 817936408badc5d29cbd99cda90ac7896c4bdc00 (patch) | |
tree | 8f0658484f205d31a339ef518a8d83a1dd23014b | |
parent | 2c46ca96e2421ad460de23476f92061e76ca296b (diff) | |
download | llvm-817936408badc5d29cbd99cda90ac7896c4bdc00.tar.gz |
[yaml2obj][XCOFF] parsing auxiliary symbols.
Summary: The patch adds support for yaml2obj parsing auxiliary
symbols for XCOFF. Since the test cases of this patch are
interdependent with D113825 ([llvm-readobj][XCOFF] dump
auxiliary symbols), test cases of this patch will be committed
after D113825 is committed.
Reviewed By: jhenderson, DiggerLin
Differential Revision: https://reviews.llvm.org/D113552
-rw-r--r-- | llvm/include/llvm/ObjectYAML/XCOFFYAML.h | 124 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/XCOFFEmitter.cpp | 187 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/XCOFFYAML.cpp | 157 | ||||
-rw-r--r-- | llvm/tools/obj2yaml/xcoff2yaml.cpp | 3 |
4 files changed, 456 insertions, 15 deletions
diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h index aa1bc396f134..39bc334e1a89 100644 --- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h +++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h @@ -82,6 +82,110 @@ struct Section { std::vector<Relocation> 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<StringRef> FileNameOrString; + Optional<XCOFF::CFileStringType> 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<uint32_t> SectionOrLength; + Optional<uint32_t> StabInfoIndex; + Optional<uint16_t> StabSectNum; + // Only for XCOFF64. + Optional<uint32_t> SectionOrLengthLo; + Optional<uint32_t> SectionOrLengthHi; + // Common fields for both XCOFF32 and XCOFF64. + Optional<uint32_t> ParameterHashIndex; + Optional<uint16_t> TypeChkSectNum; + Optional<uint8_t> SymbolAlignmentAndType; + Optional<XCOFF::StorageMappingClass> StorageMappingClass; + + CsectAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_CSECT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_CSECT; + } +}; + +struct FunctionAuxEnt : AuxSymbolEnt { + Optional<uint32_t> OffsetToExceptionTbl; // Only for XCOFF32. + Optional<uint64_t> PtrToLineNum; + Optional<uint32_t> SizeOfFunction; + Optional<int32_t> SymIdxOfNextBeyond; + + FunctionAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_FCN) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_FCN; + } +}; + +struct ExcpetionAuxEnt : AuxSymbolEnt { + Optional<uint64_t> OffsetToExceptionTbl; + Optional<uint32_t> SizeOfFunction; + Optional<int32_t> 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<uint16_t> LineNumHi; + Optional<uint16_t> LineNumLo; + // Only for XCOFF64. + Optional<uint32_t> LineNum; + + BlockAuxEnt() : AuxSymbolEnt(AuxSymbolType::AUX_SYM) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_SYM; + } +}; + +struct SectAuxEntForDWARF : AuxSymbolEnt { + Optional<uint32_t> LengthOfSectionPortion; + Optional<uint32_t> NumberOfRelocEnt; + + SectAuxEntForDWARF() : AuxSymbolEnt(AuxSymbolType::AUX_SECT) {} + static bool classof(const AuxSymbolEnt *S) { + return S->Type == AuxSymbolType::AUX_SECT; + } +}; + +struct SectAuxEntForStat : AuxSymbolEnt { + Optional<uint32_t> SectionLength; + Optional<uint16_t> NumberOfRelocEnt; + Optional<uint16_t> 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 @@ struct Symbol { Optional<uint16_t> SectionIndex; llvm::yaml::Hex16 Type; XCOFF::StorageClass StorageClass; - uint8_t NumberOfAuxEntries; + Optional<uint8_t> NumberOfAuxEntries; + std::vector<std::unique_ptr<AuxSymbolEnt>> AuxEntries; }; struct StringTable { @@ -114,6 +219,7 @@ struct Object { 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<llvm::XCOFFYAML::AuxSymbolEnt>) namespace llvm { namespace yaml { @@ -126,6 +232,18 @@ template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> { static void enumeration(IO &IO, XCOFF::StorageClass &Value); }; +template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> { + static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value); +}; + +template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> { + static void enumeration(IO &IO, XCOFF::CFileStringType &Type); +}; + +template <> struct ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType> { + static void enumeration(IO &IO, XCOFFYAML::AuxSymbolType &Type); +}; + template <> struct MappingTraits<XCOFFYAML::FileHeader> { static void mapping(IO &IO, XCOFFYAML::FileHeader &H); }; @@ -134,6 +252,10 @@ template <> struct MappingTraits<XCOFFYAML::AuxiliaryHeader> { static void mapping(IO &IO, XCOFFYAML::AuxiliaryHeader &AuxHdr); }; +template <> struct MappingTraits<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>> { + static void mapping(IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym); +}; + template <> struct MappingTraits<XCOFFYAML::Symbol> { static void mapping(IO &IO, XCOFFYAML::Symbol &S); }; diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp index cf0d058c518c..2a7204d3f773 100644 --- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp +++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp @@ -47,6 +47,7 @@ private: bool initRelocations(uint64_t &CurrentOffset); bool initStringTable(); bool assignAddressesAndIndices(); + void writeFileHeader(); void writeAuxFileHeader(); void writeSectionHeader(); @@ -55,6 +56,15 @@ private: 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<XCOFFYAML::AuxSymbolEnt> &AuxSym); + XCOFFYAML::Object &Obj; bool Is64Bit = false; support::endian::Writer W; @@ -190,12 +200,23 @@ bool XCOFFWriter::initStringTable() { } } } 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<XCOFFYAML::AuxSymbolEnt> &AuxSym : + YamlSym.AuxEntries) { + if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get())) + if (nameShouldBeInStringTable(AS->FileNameOrString.getValueOr(""))) + StrTblBuilder.add(AS->FileNameOrString.getValueOr("")); + } + } + StrTblBuilder.finalize(); size_t StrTblSize = StrTblBuilder.getSize(); @@ -216,9 +237,21 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) { 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<uint32_t>(*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 @@ bool XCOFFWriter::writeRelocations() { return true; } +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) { + if (Is64Bit) { + W.write<uint32_t>(AuxSym.SectionOrLengthLo.getValueOr(0)); + W.write<uint32_t>(AuxSym.ParameterHashIndex.getValueOr(0)); + W.write<uint16_t>(AuxSym.TypeChkSectNum.getValueOr(0)); + W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.getValueOr(0)); + W.write<uint8_t>(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR)); + W.write<uint32_t>(AuxSym.SectionOrLengthHi.getValueOr(0)); + W.write<uint8_t>(0); + W.write<uint8_t>(XCOFF::AUX_CSECT); + } else { + W.write<uint32_t>(AuxSym.SectionOrLength.getValueOr(0)); + W.write<uint32_t>(AuxSym.ParameterHashIndex.getValueOr(0)); + W.write<uint16_t>(AuxSym.TypeChkSectNum.getValueOr(0)); + W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.getValueOr(0)); + W.write<uint8_t>(AuxSym.StorageMappingClass.getValueOr(XCOFF::XMC_PR)); + W.write<uint32_t>(AuxSym.StabInfoIndex.getValueOr(0)); + W.write<uint16_t>(AuxSym.StabSectNum.getValueOr(0)); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) { + assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32"); + W.write<uint64_t>(AuxSym.OffsetToExceptionTbl.getValueOr(0)); + W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0)); + W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.getValueOr(0)); + W.write<uint8_t>(0); + W.write<uint8_t>(XCOFF::AUX_EXCEPT); +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) { + if (Is64Bit) { + W.write<uint64_t>(AuxSym.PtrToLineNum.getValueOr(0)); + W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0)); + W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.getValueOr(0)); + W.write<uint8_t>(0); + W.write<uint8_t>(XCOFF::AUX_FCN); + } else { + W.write<uint32_t>(AuxSym.OffsetToExceptionTbl.getValueOr(0)); + W.write<uint32_t>(AuxSym.SizeOfFunction.getValueOr(0)); + W.write<uint32_t>(AuxSym.PtrToLineNum.getValueOr(0)); + W.write<uint32_t>(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<int32_t>(0); + W.write<uint32_t>(StrTblBuilder.getOffset(FileName)); + } else { + writeName(FileName, W); + } + W.OS.write_zeros(XCOFF::FileNamePadSize); + W.write<uint8_t>(AuxSym.FileStringType.getValueOr(XCOFF::XFT_FN)); + if (Is64Bit) { + W.OS.write_zeros(2); + W.write<uint8_t>(XCOFF::AUX_FILE); + } else { + W.OS.write_zeros(3); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) { + if (Is64Bit) { + W.write<uint32_t>(AuxSym.LineNum.getValueOr(0)); + W.OS.write_zeros(13); + W.write<uint8_t>(XCOFF::AUX_SYM); + } else { + W.OS.write_zeros(2); + W.write<uint16_t>(AuxSym.LineNumHi.getValueOr(0)); + W.write<uint16_t>(AuxSym.LineNumLo.getValueOr(0)); + W.OS.write_zeros(12); + } +} + +void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) { + if (Is64Bit) { + W.write<uint64_t>(AuxSym.LengthOfSectionPortion.getValueOr(0)); + W.write<uint64_t>(AuxSym.NumberOfRelocEnt.getValueOr(0)); + W.write<uint8_t>(0); + W.write<uint8_t>(XCOFF::AUX_SECT); + } else { + W.write<uint32_t>(AuxSym.LengthOfSectionPortion.getValueOr(0)); + W.OS.write_zeros(4); + W.write<uint32_t>(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<uint32_t>(AuxSym.SectionLength.getValueOr(0)); + W.write<uint16_t>(AuxSym.NumberOfRelocEnt.getValueOr(0)); + W.write<uint16_t>(AuxSym.NumberOfLineNum.getValueOr(0)); + W.OS.write_zeros(10); +} + +void XCOFFWriter::writeAuxSymbol( + const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) { + if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get())) + writeAuxSymbol(*AS); + else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(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 @@ bool XCOFFWriter::writeSymbols() { } W.write<uint16_t>(YamlSym.Type); W.write<uint8_t>(YamlSym.StorageClass); - W.write<uint8_t>(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<uint8_t>(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<XCOFFYAML::AuxSymbolEnt> &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 index 221cf3b064c0..44ef33501b65 100644 --- a/llvm/lib/ObjectYAML/XCOFFYAML.cpp +++ b/llvm/lib/ObjectYAML/XCOFFYAML.cpp @@ -19,6 +19,8 @@ namespace XCOFFYAML { Object::Object() { memset(&Header, 0, sizeof(Header)); } +AuxSymbolEnt::~AuxSymbolEnt() = default; + } // namespace XCOFFYAML namespace yaml { @@ -98,6 +100,56 @@ void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration( #undef ECase } +void ScalarEnumerationTraits<XCOFF::StorageMappingClass>::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<XCOFFYAML::AuxSymbolType>::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<XCOFF::CFileStringType>::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 @@ void MappingTraits<XCOFFYAML::Section>::mapping(IO &IO, 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<std::unique_ptr<XCOFFYAML::AuxSymbolEnt>>::mapping( + IO &IO, std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) { + assert(!IO.outputting() && "We don't dump aux symbols currently."); + const bool Is64 = + static_cast<XCOFFYAML::Object *>(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<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get())); + break; + case XCOFFYAML::AUX_FCN: + AuxSym.reset(new XCOFFYAML::FunctionAuxEnt()); + auxSymMapping(IO, *cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_SYM: + AuxSym.reset(new XCOFFYAML::BlockAuxEnt()); + auxSymMapping(IO, *cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_FILE: + AuxSym.reset(new XCOFFYAML::FileAuxEnt()); + auxSymMapping(IO, *cast<XCOFFYAML::FileAuxEnt>(AuxSym.get())); + break; + case XCOFFYAML::AUX_CSECT: + AuxSym.reset(new XCOFFYAML::CsectAuxEnt()); + auxSymMapping(IO, *cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get()), Is64); + break; + case XCOFFYAML::AUX_SECT: + AuxSym.reset(new XCOFFYAML::SectAuxEntForDWARF()); + auxSymMapping(IO, *cast<XCOFFYAML::SectAuxEntForDWARF>(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<XCOFFYAML::SectAuxEntForStat>(AuxSym.get())); + break; + } +} + void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) { IO.mapOptional("Name", S.SymbolName); IO.mapOptional("Value", S.Value); @@ -181,6 +334,8 @@ void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) { 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<XCOFFYAML::StringTable>::mapping(IO &IO, XCOFFYAML::StringTable &Str) { @@ -191,12 +346,14 @@ void MappingTraits<XCOFFYAML::StringTable>::mapping(IO &IO, XCOFFYAML::StringTab } void MappingTraits<XCOFFYAML::Object>::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 index 86bef80d3773..882c41049601 100644 --- a/llvm/tools/obj2yaml/xcoff2yaml.cpp +++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp @@ -132,7 +132,8 @@ Error XCOFFDumper::dumpSymbols() { 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(); |