summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEsme-Yi <esme.yi@ibm.com>2022-01-10 02:38:49 +0000
committerEsme-Yi <esme.yi@ibm.com>2022-01-10 02:38:49 +0000
commit817936408badc5d29cbd99cda90ac7896c4bdc00 (patch)
tree8f0658484f205d31a339ef518a8d83a1dd23014b
parent2c46ca96e2421ad460de23476f92061e76ca296b (diff)
downloadllvm-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.h124
-rw-r--r--llvm/lib/ObjectYAML/XCOFFEmitter.cpp187
-rw-r--r--llvm/lib/ObjectYAML/XCOFFYAML.cpp157
-rw-r--r--llvm/tools/obj2yaml/xcoff2yaml.cpp3
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();