[llvm] 8179364 - [yaml2obj][XCOFF] parsing auxiliary symbols.

via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 9 18:39:29 PST 2022


Author: Esme-Yi
Date: 2022-01-10T02:38:49Z
New Revision: 817936408badc5d29cbd99cda90ac7896c4bdc00

URL: https://github.com/llvm/llvm-project/commit/817936408badc5d29cbd99cda90ac7896c4bdc00
DIFF: https://github.com/llvm/llvm-project/commit/817936408badc5d29cbd99cda90ac7896c4bdc00.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/ObjectYAML/XCOFFYAML.h
    llvm/lib/ObjectYAML/XCOFFEmitter.cpp
    llvm/lib/ObjectYAML/XCOFFYAML.cpp
    llvm/tools/obj2yaml/xcoff2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
index aa1bc396f1345..39bc334e1a89b 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 cf0d058c518c5..2a7204d3f7731 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -47,6 +47,7 @@ class XCOFFWriter {
   bool initRelocations(uint64_t &CurrentOffset);
   bool initStringTable();
   bool assignAddressesAndIndices();
+
   void writeFileHeader();
   void writeAuxFileHeader();
   void writeSectionHeader();
@@ -55,6 +56,15 @@ class XCOFFWriter {
   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 221cf3b064c05..44ef33501b65e 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 86bef80d3773e..882c410496012 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();


        


More information about the llvm-commits mailing list