summaryrefslogtreecommitdiff
path: root/lib/ObjectYAML
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ObjectYAML')
-rw-r--r--lib/ObjectYAML/COFFYAML.cpp16
-rw-r--r--lib/ObjectYAML/CodeViewYAMLDebugSections.cpp7
-rw-r--r--lib/ObjectYAML/CodeViewYAMLSymbols.cpp17
-rw-r--r--lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp7
-rw-r--r--lib/ObjectYAML/CodeViewYAMLTypes.cpp11
-rw-r--r--lib/ObjectYAML/DWARFEmitter.cpp7
-rw-r--r--lib/ObjectYAML/DWARFVisitor.cpp7
-rw-r--r--lib/ObjectYAML/DWARFVisitor.h7
-rw-r--r--lib/ObjectYAML/DWARFYAML.cpp7
-rw-r--r--lib/ObjectYAML/ELFYAML.cpp244
-rw-r--r--lib/ObjectYAML/MachOYAML.cpp7
-rw-r--r--lib/ObjectYAML/MinidumpYAML.cpp673
-rw-r--r--lib/ObjectYAML/ObjectYAML.cpp22
-rw-r--r--lib/ObjectYAML/WasmYAML.cpp80
-rw-r--r--lib/ObjectYAML/XCOFFYAML.cpp109
-rw-r--r--lib/ObjectYAML/YAML.cpp14
16 files changed, 1133 insertions, 102 deletions
diff --git a/lib/ObjectYAML/COFFYAML.cpp b/lib/ObjectYAML/COFFYAML.cpp
index fdd94f4054e15..b5154467f11ac 100644
--- a/lib/ObjectYAML/COFFYAML.cpp
+++ b/lib/ObjectYAML/COFFYAML.cpp
@@ -1,9 +1,8 @@
//===- COFFYAML.cpp - COFF YAMLIO implementation --------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -188,6 +187,7 @@ void ScalarEnumerationTraits<COFF::RelocationTypesARM>::enumeration(
ECase(IMAGE_REL_ARM_TOKEN);
ECase(IMAGE_REL_ARM_BLX24);
ECase(IMAGE_REL_ARM_BLX11);
+ ECase(IMAGE_REL_ARM_REL32);
ECase(IMAGE_REL_ARM_SECTION);
ECase(IMAGE_REL_ARM_SECREL);
ECase(IMAGE_REL_ARM_MOV32A);
@@ -195,6 +195,7 @@ void ScalarEnumerationTraits<COFF::RelocationTypesARM>::enumeration(
ECase(IMAGE_REL_ARM_BRANCH20T);
ECase(IMAGE_REL_ARM_BRANCH24T);
ECase(IMAGE_REL_ARM_BLX23T);
+ ECase(IMAGE_REL_ARM_PAIR);
}
void ScalarEnumerationTraits<COFF::RelocationTypesARM64>::enumeration(
@@ -216,6 +217,7 @@ void ScalarEnumerationTraits<COFF::RelocationTypesARM64>::enumeration(
ECase(IMAGE_REL_ARM64_ADDR64);
ECase(IMAGE_REL_ARM64_BRANCH19);
ECase(IMAGE_REL_ARM64_BRANCH14);
+ ECase(IMAGE_REL_ARM64_REL32);
}
void ScalarEnumerationTraits<COFF::WindowsSubsystem>::enumeration(
@@ -576,6 +578,12 @@ void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
else if (Sec.Name == ".debug$H")
IO.mapOptional("GlobalHashes", Sec.DebugH);
+ // Uninitialized sections, such as .bss, typically have no data, but the size
+ // is carried in SizeOfRawData, even though PointerToRawData is zero.
+ if (Sec.SectionData.binary_size() == 0 &&
+ NC->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ IO.mapOptional("SizeOfRawData", Sec.Header.SizeOfRawData);
+
IO.mapOptional("Relocations", Sec.Relocations);
}
diff --git a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
index 4deeae878013a..eeebb694589b2 100644
--- a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
+++ b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
@@ -1,9 +1,8 @@
//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index 713e9a710e945..227107c051ddc 100644
--- a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -1,9 +1,8 @@
//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -148,7 +147,7 @@ void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
}
void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
- auto RegNames = getRegisterNames();
+ auto RegNames = getRegisterNames(CPUType::X64);
for (const auto &E : RegNames) {
io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
}
@@ -249,7 +248,7 @@ struct UnknownSymbolRecord : public SymbolRecordBase {
uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
- return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
+ return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
}
Error fromCodeViewSymbol(CVSymbol CVS) override {
@@ -554,6 +553,12 @@ template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
IO.mapRequired("Namespace", Symbol.Name);
}
+template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
+ IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
+ IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
+ IO.mapRequired("Strings", Symbol.Strings);
+}
+
} // end namespace detail
} // end namespace CodeViewYAML
} // end namespace llvm
diff --git a/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp b/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
index ed117059560fd..e921ae1e7d8d3 100644
--- a/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
+++ b/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
@@ -1,9 +1,8 @@
//===- CodeViewYAMLTypeHashing.cpp - CodeView YAMLIO type hashing ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/lib/ObjectYAML/CodeViewYAMLTypes.cpp
index 791b115dc4929..a5e3ce1e71e88 100644
--- a/lib/ObjectYAML/CodeViewYAMLTypes.cpp
+++ b/lib/ObjectYAML/CodeViewYAMLTypes.cpp
@@ -1,9 +1,8 @@
//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types implementation -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -99,7 +98,7 @@ template <typename T> struct LeafRecordImpl : public LeafRecordBase {
CVType toCodeViewRecord(AppendingTypeTableBuilder &TS) const override {
TS.writeLeafType(Record);
- return CVType(Kind, TS.records().back());
+ return CVType(TS.records().back());
}
mutable T Record;
@@ -497,7 +496,7 @@ CVType LeafRecordImpl<FieldListRecord>::toCodeViewRecord(
Member.Member->writeTo(CRB);
}
TS.insertRecord(CRB);
- return CVType(Kind, TS.records().back());
+ return CVType(TS.records().back());
}
void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) {
diff --git a/lib/ObjectYAML/DWARFEmitter.cpp b/lib/ObjectYAML/DWARFEmitter.cpp
index f23fa12376004..2ae66997cf597 100644
--- a/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/lib/ObjectYAML/DWARFEmitter.cpp
@@ -1,9 +1,8 @@
//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ObjectYAML/DWARFVisitor.cpp b/lib/ObjectYAML/DWARFVisitor.cpp
index e6114c85ac0b9..ecb5967ac532d 100644
--- a/lib/ObjectYAML/DWARFVisitor.cpp
+++ b/lib/ObjectYAML/DWARFVisitor.cpp
@@ -1,9 +1,8 @@
//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/DWARFVisitor.h b/lib/ObjectYAML/DWARFVisitor.h
index 5489031dc3319..50e88aa7a26bf 100644
--- a/lib/ObjectYAML/DWARFVisitor.h
+++ b/lib/ObjectYAML/DWARFVisitor.h
@@ -1,9 +1,8 @@
//===--- DWARFVisitor.h -----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/DWARFYAML.cpp b/lib/ObjectYAML/DWARFYAML.cpp
index d6c09e1a35d73..bb3b1422eb62d 100644
--- a/lib/ObjectYAML/DWARFYAML.cpp
+++ b/lib/ObjectYAML/DWARFYAML.cpp
@@ -1,9 +1,8 @@
//===- DWARFYAML.cpp - DWARF YAMLIO implementation ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp
index 215d6bdd091eb..7497154c757d3 100644
--- a/lib/ObjectYAML/ELFYAML.cpp
+++ b/lib/ObjectYAML/ELFYAML.cpp
@@ -1,9 +1,8 @@
//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -233,8 +232,9 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
IO &IO, ELFYAML::ELF_ELFDATA &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X)
- // Since the semantics of ELFDATANONE is "invalid", just don't accept it
- // here.
+ // ELFDATANONE is an invalid data encoding, but we accept it because
+ // we want to be able to produce invalid binaries for the tests.
+ ECase(ELFDATANONE);
ECase(ELFDATA2LSB);
ECase(ELFDATA2MSB);
#undef ECase
@@ -410,7 +410,11 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
BCase(EF_AMDGPU_XNACK);
BCase(EF_AMDGPU_SRAM_ECC);
break;
@@ -447,7 +451,6 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_GROUP);
ECase(SHT_SYMTAB_SHNDX);
ECase(SHT_RELR);
- ECase(SHT_LOOS);
ECase(SHT_ANDROID_REL);
ECase(SHT_ANDROID_RELA);
ECase(SHT_ANDROID_RELR);
@@ -455,13 +458,12 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_LLVM_LINKER_OPTIONS);
ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
ECase(SHT_LLVM_ADDRSIG);
+ ECase(SHT_LLVM_DEPENDENT_LIBRARIES);
ECase(SHT_GNU_ATTRIBUTES);
ECase(SHT_GNU_HASH);
ECase(SHT_GNU_verdef);
ECase(SHT_GNU_verneed);
ECase(SHT_GNU_versym);
- ECase(SHT_HIOS);
- ECase(SHT_LOPROC);
switch (Object->Header.Machine) {
case ELF::EM_ARM:
ECase(SHT_ARM_EXIDX);
@@ -479,6 +481,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
case ELF::EM_MIPS:
ECase(SHT_MIPS_REGINFO);
ECase(SHT_MIPS_OPTIONS);
+ ECase(SHT_MIPS_DWARF);
ECase(SHT_MIPS_ABIFLAGS);
break;
default:
@@ -486,6 +489,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
break;
}
#undef ECase
+ IO.enumFallback<Hex32>(Value);
}
void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO,
@@ -552,6 +556,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
ECase(SHN_COMMON);
ECase(SHN_XINDEX);
ECase(SHN_HIRESERVE);
+ ECase(SHN_AMDGPU_LDS);
ECase(SHN_HEXAGON_SCOMMON);
ECase(SHN_HEXAGON_SCOMMON_1);
ECase(SHN_HEXAGON_SCOMMON_2);
@@ -561,6 +566,17 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
IO.enumFallback<Hex32>(Value);
}
+void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
+ IO &IO, ELFYAML::ELF_STB &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X)
+ ECase(STB_LOCAL);
+ ECase(STB_GLOBAL);
+ ECase(STB_WEAK);
+ ECase(STB_GNU_UNIQUE);
+#undef ECase
+ IO.enumFallback<Hex8>(Value);
+}
+
void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
IO &IO, ELFYAML::ELF_STT &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X)
@@ -573,6 +589,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
ECase(STT_TLS);
ECase(STT_GNU_IFUNC);
#undef ECase
+ IO.enumFallback<Hex8>(Value);
}
void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
@@ -661,6 +678,74 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
IO.enumFallback<Hex32>(Value);
}
+void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
+ IO &IO, ELFYAML::ELF_DYNTAG &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+
+// Disable architecture specific tags by default. We might enable them below.
+#define AARCH64_DYNAMIC_TAG(name, value)
+#define MIPS_DYNAMIC_TAG(name, value)
+#define HEXAGON_DYNAMIC_TAG(name, value)
+#define PPC_DYNAMIC_TAG(name, value)
+#define PPC64_DYNAMIC_TAG(name, value)
+// Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
+#define DYNAMIC_TAG_MARKER(name, value)
+
+#define STRINGIFY(X) (#X)
+#define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_AARCH64:
+#undef AARCH64_DYNAMIC_TAG
+#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef AARCH64_DYNAMIC_TAG
+#define AARCH64_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_MIPS:
+#undef MIPS_DYNAMIC_TAG
+#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef MIPS_DYNAMIC_TAG
+#define MIPS_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_HEXAGON:
+#undef HEXAGON_DYNAMIC_TAG
+#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef HEXAGON_DYNAMIC_TAG
+#define HEXAGON_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_PPC:
+#undef PPC_DYNAMIC_TAG
+#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef PPC_DYNAMIC_TAG
+#define PPC_DYNAMIC_TAG(name, value)
+ break;
+ case ELF::EM_PPC64:
+#undef PPC64_DYNAMIC_TAG
+#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef PPC64_DYNAMIC_TAG
+#define PPC64_DYNAMIC_TAG(name, value)
+ break;
+ default:
+#include "llvm/BinaryFormat/DynamicTags.def"
+ break;
+ }
+#undef AARCH64_DYNAMIC_TAG
+#undef MIPS_DYNAMIC_TAG
+#undef HEXAGON_DYNAMIC_TAG
+#undef PPC_DYNAMIC_TAG
+#undef PPC64_DYNAMIC_TAG
+#undef DYNAMIC_TAG_MARKER
+#undef STRINGIFY
+#undef DYNAMIC_TAG
+
+ IO.enumFallback<Hex64>(Value);
+}
+
void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X)
@@ -758,6 +843,11 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
IO.mapRequired("Machine", FileHdr.Machine);
IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
+
+ IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
+ IO.mapOptional("SHOffset", FileHdr.SHOffset);
+ IO.mapOptional("SHNum", FileHdr.SHNum);
+ IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
}
void MappingTraits<ELFYAML::ProgramHeader>::mapping(
@@ -768,6 +858,9 @@ void MappingTraits<ELFYAML::ProgramHeader>::mapping(
IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
IO.mapOptional("Align", Phdr.Align);
+ IO.mapOptional("FileSize", Phdr.FileSize);
+ IO.mapOptional("MemSize", Phdr.MemSize);
+ IO.mapOptional("Offset", Phdr.Offset);
}
namespace {
@@ -788,12 +881,13 @@ struct NormalizedOther {
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Name", Symbol.Name, StringRef());
+ IO.mapOptional("NameIndex", Symbol.NameIndex);
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Index", Symbol.Index);
+ IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
IO.mapOptional("Value", Symbol.Value, Hex64(0));
IO.mapOptional("Size", Symbol.Size, Hex64(0));
-
MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
@@ -801,40 +895,44 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
ELFYAML::Symbol &Symbol) {
- if (Symbol.Index && Symbol.Section.data()) {
+ if (Symbol.Index && Symbol.Section.data())
return "Index and Section cannot both be specified for Symbol";
- }
- if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX)) {
+ if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX))
return "Large indexes are not supported";
- }
- if (Symbol.Index && *Symbol.Index < ELFYAML::ELF_SHN(ELF::SHN_LORESERVE)) {
- return "Use a section name to define which section a symbol is defined in";
- }
+ if (Symbol.NameIndex && !Symbol.Name.empty())
+ return "Name and NameIndex cannot both be specified for Symbol";
return StringRef();
}
-void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
- IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
- IO.mapOptional("Local", Symbols.Local);
- IO.mapOptional("Global", Symbols.Global);
- IO.mapOptional("Weak", Symbols.Weak);
-}
-
static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Name", Section.Name, StringRef());
IO.mapRequired("Type", Section.Type);
- IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
+ IO.mapOptional("Flags", Section.Flags);
IO.mapOptional("Address", Section.Address, Hex64(0));
IO.mapOptional("Link", Section.Link, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
IO.mapOptional("EntSize", Section.EntSize);
- IO.mapOptional("Info", Section.Info, StringRef());
+
+ // obj2yaml does not dump these fields. They are expected to be empty when we
+ // are producing YAML, because yaml2obj sets appropriate values for sh_offset
+ // and sh_size automatically when they are not explicitly defined.
+ assert(!IO.outputting() ||
+ (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue()));
+ IO.mapOptional("ShOffset", Section.ShOffset);
+ IO.mapOptional("ShSize", Section.ShSize);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Entries", Section.Entries);
+ IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size()));
+ IO.mapOptional("Size", Section.Size);
+ IO.mapOptional("Info", Section.Info);
}
static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
@@ -842,14 +940,33 @@ static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
IO.mapOptional("Size", Section.Size, Hex64(0));
}
+static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Info", Section.Info);
+ IO.mapRequired("Entries", Section.Entries);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Entries", Section.Entries);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Info", Section.Info);
+ IO.mapRequired("Dependencies", Section.VerneedV);
+}
+
static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
commonSectionMapping(IO, Section);
+ IO.mapOptional("Info", Section.RelocatableSec, StringRef());
IO.mapOptional("Relocations", Section.Relocations);
}
-static void groupSectionMapping(IO &IO, ELFYAML::Group &group) {
- commonSectionMapping(IO, group);
- IO.mapRequired("Members", group.Members);
+static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
+ commonSectionMapping(IO, Group);
+ IO.mapOptional("Info", Group.Signature, StringRef());
+ IO.mapRequired("Members", Group.Members);
}
void MappingTraits<ELFYAML::SectionOrType>::mapping(
@@ -891,6 +1008,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
IO.mapRequired("Type", sectionType);
switch (sectionType) {
+ case ELF::SHT_DYNAMIC:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::DynamicSection());
+ sectionMapping(IO, *cast<ELFYAML::DynamicSection>(Section.get()));
+ break;
case ELF::SHT_REL:
case ELF::SHT_RELA:
if (!IO.outputting())
@@ -912,6 +1034,21 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
Section.reset(new ELFYAML::MipsABIFlags());
sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
break;
+ case ELF::SHT_GNU_verdef:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::VerdefSection());
+ sectionMapping(IO, *cast<ELFYAML::VerdefSection>(Section.get()));
+ break;
+ case ELF::SHT_GNU_versym:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::SymverSection());
+ sectionMapping(IO, *cast<ELFYAML::SymverSection>(Section.get()));
+ break;
+ case ELF::SHT_GNU_verneed:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::VerneedSection());
+ sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
+ break;
default:
if (!IO.outputting())
Section.reset(new ELFYAML::RawContentSection());
@@ -922,9 +1059,12 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Section.get());
- if (!RawSection || RawSection->Size >= RawSection->Content.binary_size())
- return StringRef();
- return "Section size must be greater or equal to the content size";
+ if (!RawSection)
+ return {};
+ if (RawSection->Size && RawSection->Content &&
+ (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size())
+ return "Section size must be greater than or equal to the content size";
+ return {};
}
namespace {
@@ -952,6 +1092,44 @@ struct NormalizedMips64RelType {
} // end anonymous namespace
+void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO,
+ ELFYAML::DynamicEntry &Rel) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Tag", Rel.Tag);
+ IO.mapRequired("Value", Rel.Val);
+}
+
+void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
+ ELFYAML::VerdefEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Version", E.Version);
+ IO.mapRequired("Flags", E.Flags);
+ IO.mapRequired("VersionNdx", E.VersionNdx);
+ IO.mapRequired("Hash", E.Hash);
+ IO.mapRequired("Names", E.VerNames);
+}
+
+void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO,
+ ELFYAML::VerneedEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Version", E.Version);
+ IO.mapRequired("File", E.File);
+ IO.mapRequired("Entries", E.AuxV);
+}
+
+void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO,
+ ELFYAML::VernauxEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+
+ IO.mapRequired("Name", E.Name);
+ IO.mapRequired("Hash", E.Hash);
+ IO.mapRequired("Flags", E.Flags);
+ IO.mapRequired("Other", E.Other);
+}
+
void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
ELFYAML::Relocation &Rel) {
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
diff --git a/lib/ObjectYAML/MachOYAML.cpp b/lib/ObjectYAML/MachOYAML.cpp
index e00a4ea93074a..d12f12cf44350 100644
--- a/lib/ObjectYAML/MachOYAML.cpp
+++ b/lib/ObjectYAML/MachOYAML.cpp
@@ -1,9 +1,8 @@
//===- MachOYAML.cpp - MachO YAMLIO implementation ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ObjectYAML/MinidumpYAML.cpp b/lib/ObjectYAML/MinidumpYAML.cpp
new file mode 100644
index 0000000000000..f5f2acd0cc4bd
--- /dev/null
+++ b/lib/ObjectYAML/MinidumpYAML.cpp
@@ -0,0 +1,673 @@
+//===- MinidumpYAML.cpp - Minidump YAMLIO implementation ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/MinidumpYAML.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ConvertUTF.h"
+
+using namespace llvm;
+using namespace llvm::MinidumpYAML;
+using namespace llvm::minidump;
+
+namespace {
+/// A helper class to manage the placement of various structures into the final
+/// minidump binary. Space for objects can be allocated via various allocate***
+/// methods, while the final minidump file is written by calling the writeTo
+/// method. The plain versions of allocation functions take a reference to the
+/// data which is to be written (and hence the data must be available until
+/// writeTo is called), while the "New" versions allocate the data in an
+/// allocator-managed buffer, which is available until the allocator object is
+/// destroyed. For both kinds of functions, it is possible to modify the
+/// data for which the space has been "allocated" until the final writeTo call.
+/// This is useful for "linking" the allocated structures via their offsets.
+class BlobAllocator {
+public:
+ size_t tell() const { return NextOffset; }
+
+ size_t allocateCallback(size_t Size,
+ std::function<void(raw_ostream &)> Callback) {
+ size_t Offset = NextOffset;
+ NextOffset += Size;
+ Callbacks.push_back(std::move(Callback));
+ return Offset;
+ }
+
+ size_t allocateBytes(ArrayRef<uint8_t> Data) {
+ return allocateCallback(
+ Data.size(), [Data](raw_ostream &OS) { OS << toStringRef(Data); });
+ }
+
+ size_t allocateBytes(yaml::BinaryRef Data) {
+ return allocateCallback(Data.binary_size(), [Data](raw_ostream &OS) {
+ Data.writeAsBinary(OS);
+ });
+ }
+
+ template <typename T> size_t allocateArray(ArrayRef<T> Data) {
+ return allocateBytes({reinterpret_cast<const uint8_t *>(Data.data()),
+ sizeof(T) * Data.size()});
+ }
+
+ template <typename T, typename RangeType>
+ std::pair<size_t, MutableArrayRef<T>>
+ allocateNewArray(const iterator_range<RangeType> &Range);
+
+ template <typename T> size_t allocateObject(const T &Data) {
+ return allocateArray(makeArrayRef(Data));
+ }
+
+ template <typename T, typename... Types>
+ std::pair<size_t, T *> allocateNewObject(Types &&... Args) {
+ T *Object = new (Temporaries.Allocate<T>()) T(std::forward<Types>(Args)...);
+ return {allocateObject(*Object), Object};
+ }
+
+ size_t allocateString(StringRef Str);
+
+ void writeTo(raw_ostream &OS) const;
+
+private:
+ size_t NextOffset = 0;
+
+ BumpPtrAllocator Temporaries;
+ std::vector<std::function<void(raw_ostream &)>> Callbacks;
+};
+} // namespace
+
+template <typename T, typename RangeType>
+std::pair<size_t, MutableArrayRef<T>>
+BlobAllocator::allocateNewArray(const iterator_range<RangeType> &Range) {
+ size_t Num = std::distance(Range.begin(), Range.end());
+ MutableArrayRef<T> Array(Temporaries.Allocate<T>(Num), Num);
+ std::uninitialized_copy(Range.begin(), Range.end(), Array.begin());
+ return {allocateArray(Array), Array};
+}
+
+size_t BlobAllocator::allocateString(StringRef Str) {
+ SmallVector<UTF16, 32> WStr;
+ bool OK = convertUTF8ToUTF16String(Str, WStr);
+ assert(OK && "Invalid UTF8 in Str?");
+ (void)OK;
+
+ // The utf16 string is null-terminated, but the terminator is not counted in
+ // the string size.
+ WStr.push_back(0);
+ size_t Result =
+ allocateNewObject<support::ulittle32_t>(2 * (WStr.size() - 1)).first;
+ allocateNewArray<support::ulittle16_t>(make_range(WStr.begin(), WStr.end()));
+ return Result;
+}
+
+void BlobAllocator::writeTo(raw_ostream &OS) const {
+ size_t BeginOffset = OS.tell();
+ for (const auto &Callback : Callbacks)
+ Callback(OS);
+ assert(OS.tell() == BeginOffset + NextOffset &&
+ "Callbacks wrote an unexpected number of bytes.");
+ (void)BeginOffset;
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type EndianType. The
+/// only purpose of this function is to avoid casting the Default value to the
+/// endian type;
+template <typename EndianType>
+static inline void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val,
+ typename EndianType::value_type Default) {
+ IO.mapOptional(Key, Val, EndianType(Default));
+}
+
+/// Yaml-map an endian-aware type EndianType as some other type MapType.
+template <typename MapType, typename EndianType>
+static inline void mapRequiredAs(yaml::IO &IO, const char *Key,
+ EndianType &Val) {
+ MapType Mapped = static_cast<typename EndianType::value_type>(Val);
+ IO.mapRequired(Key, Mapped);
+ Val = static_cast<typename EndianType::value_type>(Mapped);
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type EndianType as some
+/// other type MapType.
+template <typename MapType, typename EndianType>
+static inline void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val,
+ MapType Default) {
+ MapType Mapped = static_cast<typename EndianType::value_type>(Val);
+ IO.mapOptional(Key, Mapped, Default);
+ Val = static_cast<typename EndianType::value_type>(Mapped);
+}
+
+namespace {
+/// Return the appropriate yaml Hex type for a given endian-aware type.
+template <typename EndianType> struct HexType;
+template <> struct HexType<support::ulittle16_t> { using type = yaml::Hex16; };
+template <> struct HexType<support::ulittle32_t> { using type = yaml::Hex32; };
+template <> struct HexType<support::ulittle64_t> { using type = yaml::Hex64; };
+} // namespace
+
+/// Yaml-map an endian-aware type as an appropriately-sized hex value.
+template <typename EndianType>
+static inline void mapRequiredHex(yaml::IO &IO, const char *Key,
+ EndianType &Val) {
+ mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
+}
+
+/// Perform an optional yaml-mapping of an endian-aware type as an
+/// appropriately-sized hex value.
+template <typename EndianType>
+static inline void mapOptionalHex(yaml::IO &IO, const char *Key,
+ EndianType &Val,
+ typename EndianType::value_type Default) {
+ mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val, Default);
+}
+
+Stream::~Stream() = default;
+
+Stream::StreamKind Stream::getKind(StreamType Type) {
+ switch (Type) {
+ case StreamType::MemoryList:
+ return StreamKind::MemoryList;
+ case StreamType::ModuleList:
+ return StreamKind::ModuleList;
+ case StreamType::SystemInfo:
+ return StreamKind::SystemInfo;
+ case StreamType::LinuxCPUInfo:
+ case StreamType::LinuxProcStatus:
+ case StreamType::LinuxLSBRelease:
+ case StreamType::LinuxCMDLine:
+ case StreamType::LinuxMaps:
+ case StreamType::LinuxProcStat:
+ case StreamType::LinuxProcUptime:
+ return StreamKind::TextContent;
+ case StreamType::ThreadList:
+ return StreamKind::ThreadList;
+ default:
+ return StreamKind::RawContent;
+ }
+}
+
+std::unique_ptr<Stream> Stream::create(StreamType Type) {
+ StreamKind Kind = getKind(Type);
+ switch (Kind) {
+ case StreamKind::MemoryList:
+ return llvm::make_unique<MemoryListStream>();
+ case StreamKind::ModuleList:
+ return llvm::make_unique<ModuleListStream>();
+ case StreamKind::RawContent:
+ return llvm::make_unique<RawContentStream>(Type);
+ case StreamKind::SystemInfo:
+ return llvm::make_unique<SystemInfoStream>();
+ case StreamKind::TextContent:
+ return llvm::make_unique<TextContentStream>(Type);
+ case StreamKind::ThreadList:
+ return llvm::make_unique<ThreadListStream>();
+ }
+ llvm_unreachable("Unhandled stream kind!");
+}
+
+void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
+ IO &IO, ProcessorArchitecture &Arch) {
+#define HANDLE_MDMP_ARCH(CODE, NAME) \
+ IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex16>(Arch);
+}
+
+void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
+ OSPlatform &Plat) {
+#define HANDLE_MDMP_PLATFORM(CODE, NAME) \
+ IO.enumCase(Plat, #NAME, OSPlatform::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex32>(Plat);
+}
+
+void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
+ StreamType &Type) {
+#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \
+ IO.enumCase(Type, #NAME, StreamType::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+ IO.enumFallback<Hex32>(Type);
+}
+
+void yaml::MappingTraits<CPUInfo::ArmInfo>::mapping(IO &IO,
+ CPUInfo::ArmInfo &Info) {
+ mapRequiredHex(IO, "CPUID", Info.CPUID);
+ mapOptionalHex(IO, "ELF hwcaps", Info.ElfHWCaps, 0);
+}
+
+namespace {
+template <std::size_t N> struct FixedSizeHex {
+ FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}
+
+ uint8_t (&Storage)[N];
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {
+ static void output(const FixedSizeHex<N> &Fixed, void *, raw_ostream &OS) {
+ OS << toHex(makeArrayRef(Fixed.Storage));
+ }
+
+ static StringRef input(StringRef Scalar, void *, FixedSizeHex<N> &Fixed) {
+ if (!all_of(Scalar, isHexDigit))
+ return "Invalid hex digit in input";
+ if (Scalar.size() < 2 * N)
+ return "String too short";
+ if (Scalar.size() > 2 * N)
+ return "String too long";
+ copy(fromHex(Scalar), Fixed.Storage);
+ return "";
+ }
+
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+} // namespace yaml
+} // namespace llvm
+void yaml::MappingTraits<CPUInfo::OtherInfo>::mapping(
+ IO &IO, CPUInfo::OtherInfo &Info) {
+ FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);
+ IO.mapRequired("Features", Features);
+}
+
+namespace {
+/// A type which only accepts strings of a fixed size for yaml conversion.
+template <std::size_t N> struct FixedSizeString {
+ FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}
+
+ char (&Storage)[N];
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {
+ static void output(const FixedSizeString<N> &Fixed, void *, raw_ostream &OS) {
+ OS << StringRef(Fixed.Storage, N);
+ }
+
+ static StringRef input(StringRef Scalar, void *, FixedSizeString<N> &Fixed) {
+ if (Scalar.size() < N)
+ return "String too short";
+ if (Scalar.size() > N)
+ return "String too long";
+ copy(Scalar, Fixed.Storage);
+ return "";
+ }
+
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
+};
+} // namespace yaml
+} // namespace llvm
+
+void yaml::MappingTraits<CPUInfo::X86Info>::mapping(IO &IO,
+ CPUInfo::X86Info &Info) {
+ FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);
+ IO.mapRequired("Vendor ID", VendorID);
+
+ mapRequiredHex(IO, "Version Info", Info.VersionInfo);
+ mapRequiredHex(IO, "Feature Info", Info.FeatureInfo);
+ mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
+}
+
+void yaml::MappingTraits<VSFixedFileInfo>::mapping(IO &IO,
+ VSFixedFileInfo &Info) {
+ mapOptionalHex(IO, "Signature", Info.Signature, 0);
+ mapOptionalHex(IO, "Struct Version", Info.StructVersion, 0);
+ mapOptionalHex(IO, "File Version High", Info.FileVersionHigh, 0);
+ mapOptionalHex(IO, "File Version Low", Info.FileVersionLow, 0);
+ mapOptionalHex(IO, "Product Version High", Info.ProductVersionHigh, 0);
+ mapOptionalHex(IO, "Product Version Low", Info.ProductVersionLow, 0);
+ mapOptionalHex(IO, "File Flags Mask", Info.FileFlagsMask, 0);
+ mapOptionalHex(IO, "File Flags", Info.FileFlags, 0);
+ mapOptionalHex(IO, "File OS", Info.FileOS, 0);
+ mapOptionalHex(IO, "File Type", Info.FileType, 0);
+ mapOptionalHex(IO, "File Subtype", Info.FileSubtype, 0);
+ mapOptionalHex(IO, "File Date High", Info.FileDateHigh, 0);
+ mapOptionalHex(IO, "File Date Low", Info.FileDateLow, 0);
+}
+
+void yaml::MappingTraits<ModuleListStream::entry_type>::mapping(
+ IO &IO, ModuleListStream::entry_type &M) {
+ mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);
+ mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);
+ mapOptionalHex(IO, "Checksum", M.Entry.Checksum, 0);
+ IO.mapOptional("Time Date Stamp", M.Entry.TimeDateStamp,
+ support::ulittle32_t(0));
+ IO.mapRequired("Module Name", M.Name);
+ IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());
+ IO.mapRequired("CodeView Record", M.CvRecord);
+ IO.mapOptional("Misc Record", M.MiscRecord, yaml::BinaryRef());
+ mapOptionalHex(IO, "Reserved0", M.Entry.Reserved0, 0);
+ mapOptionalHex(IO, "Reserved1", M.Entry.Reserved1, 0);
+}
+
+static void streamMapping(yaml::IO &IO, RawContentStream &Stream) {
+ IO.mapOptional("Content", Stream.Content);
+ IO.mapOptional("Size", Stream.Size, Stream.Content.binary_size());
+}
+
+static StringRef streamValidate(RawContentStream &Stream) {
+ if (Stream.Size.value < Stream.Content.binary_size())
+ return "Stream size must be greater or equal to the content size";
+ return "";
+}
+
+void yaml::MappingTraits<MemoryListStream::entry_type>::mapping(
+ IO &IO, MemoryListStream::entry_type &Range) {
+ MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
+ IO, Range.Entry, Range.Content);
+}
+
+static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
+ IO.mapRequired("Memory Ranges", Stream.Entries);
+}
+
+static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
+ IO.mapRequired("Modules", Stream.Entries);
+}
+
+static void streamMapping(yaml::IO &IO, SystemInfoStream &Stream) {
+ SystemInfo &Info = Stream.Info;
+ IO.mapRequired("Processor Arch", Info.ProcessorArch);
+ mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);
+ mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);
+ IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);
+ IO.mapOptional("Product type", Info.ProductType, 0);
+ mapOptional(IO, "Major Version", Info.MajorVersion, 0);
+ mapOptional(IO, "Minor Version", Info.MinorVersion, 0);
+ mapOptional(IO, "Build Number", Info.BuildNumber, 0);
+ IO.mapRequired("Platform ID", Info.PlatformId);
+ IO.mapOptional("CSD Version", Stream.CSDVersion, "");
+ mapOptionalHex(IO, "Suite Mask", Info.SuiteMask, 0);
+ mapOptionalHex(IO, "Reserved", Info.Reserved, 0);
+ switch (static_cast<ProcessorArchitecture>(Info.ProcessorArch)) {
+ case ProcessorArchitecture::X86:
+ case ProcessorArchitecture::AMD64:
+ IO.mapOptional("CPU", Info.CPU.X86);
+ break;
+ case ProcessorArchitecture::ARM:
+ case ProcessorArchitecture::ARM64:
+ IO.mapOptional("CPU", Info.CPU.Arm);
+ break;
+ default:
+ IO.mapOptional("CPU", Info.CPU.Other);
+ break;
+ }
+}
+
+static void streamMapping(yaml::IO &IO, TextContentStream &Stream) {
+ IO.mapOptional("Text", Stream.Text);
+}
+
+void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
+ IO &IO, MemoryDescriptor &Memory, BinaryRef &Content) {
+ mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
+ IO.mapRequired("Content", Content);
+}
+
+void yaml::MappingTraits<ThreadListStream::entry_type>::mapping(
+ IO &IO, ThreadListStream::entry_type &T) {
+ mapRequiredHex(IO, "Thread Id", T.Entry.ThreadId);
+ mapOptionalHex(IO, "Suspend Count", T.Entry.SuspendCount, 0);
+ mapOptionalHex(IO, "Priority Class", T.Entry.PriorityClass, 0);
+ mapOptionalHex(IO, "Priority", T.Entry.Priority, 0);
+ mapOptionalHex(IO, "Environment Block", T.Entry.EnvironmentBlock, 0);
+ IO.mapRequired("Context", T.Context);
+ IO.mapRequired("Stack", T.Entry.Stack, T.Stack);
+}
+
+static void streamMapping(yaml::IO &IO, ThreadListStream &Stream) {
+ IO.mapRequired("Threads", Stream.Entries);
+}
+
+void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
+ yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
+ StreamType Type;
+ if (IO.outputting())
+ Type = S->Type;
+ IO.mapRequired("Type", Type);
+
+ if (!IO.outputting())
+ S = MinidumpYAML::Stream::create(Type);
+ switch (S->Kind) {
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
+ streamMapping(IO, llvm::cast<MemoryListStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::ModuleList:
+ streamMapping(IO, llvm::cast<ModuleListStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::RawContent:
+ streamMapping(IO, llvm::cast<RawContentStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::SystemInfo:
+ streamMapping(IO, llvm::cast<SystemInfoStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::TextContent:
+ streamMapping(IO, llvm::cast<TextContentStream>(*S));
+ break;
+ case MinidumpYAML::Stream::StreamKind::ThreadList:
+ streamMapping(IO, llvm::cast<ThreadListStream>(*S));
+ break;
+ }
+}
+
+StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
+ yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
+ switch (S->Kind) {
+ case MinidumpYAML::Stream::StreamKind::RawContent:
+ return streamValidate(cast<RawContentStream>(*S));
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
+ case MinidumpYAML::Stream::StreamKind::ModuleList:
+ case MinidumpYAML::Stream::StreamKind::SystemInfo:
+ case MinidumpYAML::Stream::StreamKind::TextContent:
+ case MinidumpYAML::Stream::StreamKind::ThreadList:
+ return "";
+ }
+ llvm_unreachable("Fully covered switch above!");
+}
+
+void yaml::MappingTraits<Object>::mapping(IO &IO, Object &O) {
+ IO.mapTag("!minidump", true);
+ mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);
+ mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);
+ mapOptionalHex(IO, "Flags", O.Header.Flags, 0);
+ IO.mapRequired("Streams", O.Streams);
+}
+
+static LocationDescriptor layout(BlobAllocator &File, yaml::BinaryRef Data) {
+ return {support::ulittle32_t(Data.binary_size()),
+ support::ulittle32_t(File.allocateBytes(Data))};
+}
+
+static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
+ Range.Entry.Memory = layout(File, Range.Content);
+}
+
+static void layout(BlobAllocator &File, ModuleListStream::entry_type &M) {
+ M.Entry.ModuleNameRVA = File.allocateString(M.Name);
+
+ M.Entry.CvRecord = layout(File, M.CvRecord);
+ M.Entry.MiscRecord = layout(File, M.MiscRecord);
+}
+
+static void layout(BlobAllocator &File, ThreadListStream::entry_type &T) {
+ T.Entry.Stack.Memory = layout(File, T.Stack);
+ T.Entry.Context = layout(File, T.Context);
+}
+
+template <typename EntryT>
+static size_t layout(BlobAllocator &File,
+ MinidumpYAML::detail::ListStream<EntryT> &S) {
+
+ File.allocateNewObject<support::ulittle32_t>(S.Entries.size());
+ for (auto &E : S.Entries)
+ File.allocateObject(E.Entry);
+
+ size_t DataEnd = File.tell();
+
+ // Lay out the auxiliary data, (which is not a part of the stream).
+ DataEnd = File.tell();
+ for (auto &E : S.Entries)
+ layout(File, E);
+
+ return DataEnd;
+}
+
+static Directory layout(BlobAllocator &File, Stream &S) {
+ Directory Result;
+ Result.Type = S.Type;
+ Result.Location.RVA = File.tell();
+ Optional<size_t> DataEnd;
+ switch (S.Kind) {
+ case Stream::StreamKind::MemoryList:
+ DataEnd = layout(File, cast<MemoryListStream>(S));
+ break;
+ case Stream::StreamKind::ModuleList:
+ DataEnd = layout(File, cast<ModuleListStream>(S));
+ break;
+ case Stream::StreamKind::RawContent: {
+ RawContentStream &Raw = cast<RawContentStream>(S);
+ File.allocateCallback(Raw.Size, [&Raw](raw_ostream &OS) {
+ Raw.Content.writeAsBinary(OS);
+ assert(Raw.Content.binary_size() <= Raw.Size);
+ OS << std::string(Raw.Size - Raw.Content.binary_size(), '\0');
+ });
+ break;
+ }
+ case Stream::StreamKind::SystemInfo: {
+ SystemInfoStream &SystemInfo = cast<SystemInfoStream>(S);
+ File.allocateObject(SystemInfo.Info);
+ // The CSD string is not a part of the stream.
+ DataEnd = File.tell();
+ SystemInfo.Info.CSDVersionRVA = File.allocateString(SystemInfo.CSDVersion);
+ break;
+ }
+ case Stream::StreamKind::TextContent:
+ File.allocateArray(arrayRefFromStringRef(cast<TextContentStream>(S).Text));
+ break;
+ case Stream::StreamKind::ThreadList:
+ DataEnd = layout(File, cast<ThreadListStream>(S));
+ break;
+ }
+ // If DataEnd is not set, we assume everything we generated is a part of the
+ // stream.
+ Result.Location.DataSize =
+ DataEnd.getValueOr(File.tell()) - Result.Location.RVA;
+ return Result;
+}
+
+void MinidumpYAML::writeAsBinary(Object &Obj, raw_ostream &OS) {
+ BlobAllocator File;
+ File.allocateObject(Obj.Header);
+
+ std::vector<Directory> StreamDirectory(Obj.Streams.size());
+ Obj.Header.StreamDirectoryRVA =
+ File.allocateArray(makeArrayRef(StreamDirectory));
+ Obj.Header.NumberOfStreams = StreamDirectory.size();
+
+ for (auto &Stream : enumerate(Obj.Streams))
+ StreamDirectory[Stream.index()] = layout(File, *Stream.value());
+
+ File.writeTo(OS);
+}
+
+Error MinidumpYAML::writeAsBinary(StringRef Yaml, raw_ostream &OS) {
+ yaml::Input Input(Yaml);
+ Object Obj;
+ Input >> Obj;
+ if (std::error_code EC = Input.error())
+ return errorCodeToError(EC);
+
+ writeAsBinary(Obj, OS);
+ return Error::success();
+}
+
+Expected<std::unique_ptr<Stream>>
+Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
+ StreamKind Kind = getKind(StreamDesc.Type);
+ switch (Kind) {
+ case StreamKind::MemoryList: {
+ auto ExpectedList = File.getMemoryList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<MemoryListStream::entry_type> Ranges;
+ for (const MemoryDescriptor &MD : *ExpectedList) {
+ auto ExpectedContent = File.getRawData(MD.Memory);
+ if (!ExpectedContent)
+ return ExpectedContent.takeError();
+ Ranges.push_back({MD, *ExpectedContent});
+ }
+ return llvm::make_unique<MemoryListStream>(std::move(Ranges));
+ }
+ case StreamKind::ModuleList: {
+ auto ExpectedList = File.getModuleList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<ModuleListStream::entry_type> Modules;
+ for (const Module &M : *ExpectedList) {
+ auto ExpectedName = File.getString(M.ModuleNameRVA);
+ if (!ExpectedName)
+ return ExpectedName.takeError();
+ auto ExpectedCv = File.getRawData(M.CvRecord);
+ if (!ExpectedCv)
+ return ExpectedCv.takeError();
+ auto ExpectedMisc = File.getRawData(M.MiscRecord);
+ if (!ExpectedMisc)
+ return ExpectedMisc.takeError();
+ Modules.push_back(
+ {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
+ }
+ return llvm::make_unique<ModuleListStream>(std::move(Modules));
+ }
+ case StreamKind::RawContent:
+ return llvm::make_unique<RawContentStream>(StreamDesc.Type,
+ File.getRawStream(StreamDesc));
+ case StreamKind::SystemInfo: {
+ auto ExpectedInfo = File.getSystemInfo();
+ if (!ExpectedInfo)
+ return ExpectedInfo.takeError();
+ auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
+ if (!ExpectedCSDVersion)
+ return ExpectedInfo.takeError();
+ return llvm::make_unique<SystemInfoStream>(*ExpectedInfo,
+ std::move(*ExpectedCSDVersion));
+ }
+ case StreamKind::TextContent:
+ return llvm::make_unique<TextContentStream>(
+ StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));
+ case StreamKind::ThreadList: {
+ auto ExpectedList = File.getThreadList();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<ThreadListStream::entry_type> Threads;
+ for (const Thread &T : *ExpectedList) {
+ auto ExpectedStack = File.getRawData(T.Stack.Memory);
+ if (!ExpectedStack)
+ return ExpectedStack.takeError();
+ auto ExpectedContext = File.getRawData(T.Context);
+ if (!ExpectedContext)
+ return ExpectedContext.takeError();
+ Threads.push_back({T, *ExpectedStack, *ExpectedContext});
+ }
+ return llvm::make_unique<ThreadListStream>(std::move(Threads));
+ }
+ }
+ llvm_unreachable("Unhandled stream kind!");
+}
+
+Expected<Object> Object::create(const object::MinidumpFile &File) {
+ std::vector<std::unique_ptr<Stream>> Streams;
+ Streams.reserve(File.streams().size());
+ for (const Directory &StreamDesc : File.streams()) {
+ auto ExpectedStream = Stream::create(StreamDesc, File);
+ if (!ExpectedStream)
+ return ExpectedStream.takeError();
+ Streams.push_back(std::move(*ExpectedStream));
+ }
+ return Object(File.header(), std::move(Streams));
+}
diff --git a/lib/ObjectYAML/ObjectYAML.cpp b/lib/ObjectYAML/ObjectYAML.cpp
index 850c1a5a06c02..7f636f4eabac4 100644
--- a/lib/ObjectYAML/ObjectYAML.cpp
+++ b/lib/ObjectYAML/ObjectYAML.cpp
@@ -1,9 +1,8 @@
//===- ObjectYAML.cpp - YAML utilities for object files -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -33,6 +32,7 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO,
MappingTraits<MachOYAML::UniversalBinary>::mapping(IO,
*ObjectFile.FatMachO);
} else {
+ Input &In = (Input &)IO;
if (IO.mapTag("!ELF")) {
ObjectFile.Elf.reset(new ELFYAML::Object());
MappingTraits<ELFYAML::Object>::mapping(IO, *ObjectFile.Elf);
@@ -46,18 +46,18 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO,
ObjectFile.FatMachO.reset(new MachOYAML::UniversalBinary());
MappingTraits<MachOYAML::UniversalBinary>::mapping(IO,
*ObjectFile.FatMachO);
+ } else if (IO.mapTag("!minidump")) {
+ ObjectFile.Minidump.reset(new MinidumpYAML::Object());
+ MappingTraits<MinidumpYAML::Object>::mapping(IO, *ObjectFile.Minidump);
} else if (IO.mapTag("!WASM")) {
ObjectFile.Wasm.reset(new WasmYAML::Object());
MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm);
- } else {
- Input &In = (Input &)IO;
- std::string Tag = In.getCurrentNode()->getRawTag();
- if (Tag.empty())
+ } else if (const Node *N = In.getCurrentNode()) {
+ if (N->getRawTag().empty())
IO.setError("YAML Object File missing document type tag!");
else
- IO.setError(
- Twine("YAML Object File unsupported document type tag '") +
- Twine(Tag) + Twine("'!"));
+ IO.setError("YAML Object File unsupported document type tag '" +
+ N->getRawTag() + "'!");
}
}
}
diff --git a/lib/ObjectYAML/WasmYAML.cpp b/lib/ObjectYAML/WasmYAML.cpp
index 47bf853e0d3e2..88491d955c497 100644
--- a/lib/ObjectYAML/WasmYAML.cpp
+++ b/lib/ObjectYAML/WasmYAML.cpp
@@ -1,9 +1,8 @@
//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -74,6 +73,20 @@ static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
IO.mapOptional("Comdats", Section.Comdats);
}
+static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapOptional("Languages", Section.Languages);
+ IO.mapOptional("Tools", Section.Tools);
+ IO.mapOptional("SDKs", Section.SDKs);
+}
+
+static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Name", Section.Name);
+ IO.mapRequired("Features", Section.Features);
+}
+
static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
@@ -140,6 +153,11 @@ static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
IO.mapRequired("Segments", Section.Segments);
}
+static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Count", Section.Count);
+}
+
void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
WasmYAML::SectionType SectionType;
@@ -169,6 +187,14 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
if (!IO.outputting())
Section.reset(new WasmYAML::NameSection());
sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
+ } else if (SectionName == "producers") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::ProducersSection());
+ sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
+ } else if (SectionName == "target_features") {
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::TargetFeaturesSection());
+ sectionMapping(IO, *cast<WasmYAML::TargetFeaturesSection>(Section.get()));
} else {
if (!IO.outputting())
Section.reset(new WasmYAML::CustomSection(SectionName));
@@ -236,6 +262,11 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
Section.reset(new WasmYAML::DataSection());
sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get()));
break;
+ case wasm::WASM_SEC_DATACOUNT:
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::DataCountSection());
+ sectionMapping(IO, *cast<WasmYAML::DataCountSection>(Section.get()));
+ break;
default:
llvm_unreachable("Unknown section type");
}
@@ -257,6 +288,7 @@ void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
ECase(ELEM);
ECase(CODE);
ECase(DATA);
+ ECase(DATACOUNT);
#undef ECase
}
@@ -293,6 +325,27 @@ void MappingTraits<WasmYAML::NameEntry>::mapping(
IO.mapRequired("Name", NameEntry.Name);
}
+void MappingTraits<WasmYAML::ProducerEntry>::mapping(
+ IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
+ IO.mapRequired("Name", ProducerEntry.Name);
+ IO.mapRequired("Version", ProducerEntry.Version);
+}
+
+void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration(
+ IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
+ ECase(USED);
+ ECase(REQUIRED);
+ ECase(DISALLOWED);
+#undef ECase
+}
+
+void MappingTraits<WasmYAML::FeatureEntry>::mapping(
+ IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
+ IO.mapRequired("Prefix", FeatureEntry.Prefix);
+ IO.mapRequired("Name", FeatureEntry.Name);
+}
+
void MappingTraits<WasmYAML::SegmentInfo>::mapping(
IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
IO.mapRequired("Index", SegmentInfo.Index);
@@ -386,8 +439,18 @@ void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
void MappingTraits<WasmYAML::DataSegment>::mapping(
IO &IO, WasmYAML::DataSegment &Segment) {
IO.mapOptional("SectionOffset", Segment.SectionOffset);
- IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
- IO.mapRequired("Offset", Segment.Offset);
+ IO.mapRequired("InitFlags", Segment.InitFlags);
+ if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) {
+ IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
+ } else {
+ Segment.MemoryIndex = 0;
+ }
+ if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) {
+ IO.mapRequired("Offset", Segment.Offset);
+ } else {
+ Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
+ Segment.Offset.Value.Int32 = 0;
+ }
IO.mapRequired("Content", Segment.Content);
}
@@ -421,7 +484,8 @@ void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
WasmYAML::SymbolInfo &Info) {
IO.mapRequired("Index", Info.Index);
IO.mapRequired("Kind", Info.Kind);
- IO.mapRequired("Name", Info.Name);
+ if (Info.Kind != wasm::WASM_SYMBOL_TYPE_SECTION)
+ IO.mapRequired("Name", Info.Name);
IO.mapRequired("Flags", Info.Flags);
if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
IO.mapRequired("Function", Info.ElementIndex);
@@ -469,6 +533,8 @@ void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
// BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
BCaseMask(UNDEFINED, UNDEFINED);
+ BCaseMask(EXPORTED, EXPORTED);
+ BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME);
#undef BCaseMask
}
diff --git a/lib/ObjectYAML/XCOFFYAML.cpp b/lib/ObjectYAML/XCOFFYAML.cpp
new file mode 100644
index 0000000000000..982e6aecbb987
--- /dev/null
+++ b/lib/ObjectYAML/XCOFFYAML.cpp
@@ -0,0 +1,109 @@
+//===-- XCOFFYAML.cpp - XCOFF YAMLIO implementation -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes for handling the YAML representation of XCOFF.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/XCOFFYAML.h"
+#include "llvm/BinaryFormat/XCOFF.h"
+#include <string.h>
+
+namespace llvm {
+namespace XCOFFYAML {
+
+Object::Object() { memset(&Header, 0, sizeof(Header)); }
+
+} // namespace XCOFFYAML
+
+namespace yaml {
+
+void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
+ IO &IO, XCOFF::StorageClass &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+ ECase(C_NULL);
+ ECase(C_AUTO);
+ ECase(C_EXT);
+ ECase(C_STAT);
+ ECase(C_REG);
+ ECase(C_EXTDEF);
+ ECase(C_LABEL);
+ ECase(C_ULABEL);
+ ECase(C_MOS);
+ ECase(C_ARG);
+ ECase(C_STRTAG);
+ ECase(C_MOU);
+ ECase(C_UNTAG);
+ ECase(C_TPDEF);
+ ECase(C_USTATIC);
+ ECase(C_ENTAG);
+ ECase(C_MOE);
+ ECase(C_REGPARM);
+ ECase(C_FIELD);
+ ECase(C_BLOCK);
+ ECase(C_FCN);
+ ECase(C_EOS);
+ ECase(C_FILE);
+ ECase(C_LINE);
+ ECase(C_ALIAS);
+ ECase(C_HIDDEN);
+ ECase(C_HIDEXT);
+ ECase(C_BINCL);
+ ECase(C_EINCL);
+ ECase(C_INFO);
+ ECase(C_WEAKEXT);
+ ECase(C_DWARF);
+ ECase(C_GSYM);
+ ECase(C_LSYM);
+ ECase(C_PSYM);
+ ECase(C_RSYM);
+ ECase(C_RPSYM);
+ ECase(C_STSYM);
+ ECase(C_TCSYM);
+ ECase(C_BCOMM);
+ ECase(C_ECOML);
+ ECase(C_ECOMM);
+ ECase(C_DECL);
+ ECase(C_ENTRY);
+ ECase(C_FUN);
+ ECase(C_BSTAT);
+ ECase(C_ESTAT);
+ ECase(C_GTLS);
+ ECase(C_STTLS);
+ ECase(C_EFCN);
+#undef ECase
+}
+
+void MappingTraits<XCOFFYAML::FileHeader>::mapping(
+ IO &IO, XCOFFYAML::FileHeader &FileHdr) {
+ IO.mapRequired("MagicNumber", FileHdr.Magic);
+ IO.mapRequired("NumberOfSections", FileHdr.NumberOfSections);
+ IO.mapRequired("CreationTime", FileHdr.TimeStamp);
+ IO.mapRequired("OffsetToSymbolTable", FileHdr.SymbolTableOffset);
+ IO.mapRequired("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries);
+ IO.mapRequired("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize);
+ IO.mapRequired("Flags", FileHdr.Flags);
+}
+
+void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
+ IO.mapRequired("Name", S.SymbolName);
+ IO.mapRequired("Value", S.Value);
+ IO.mapRequired("Section", S.SectionName);
+ IO.mapRequired("Type", S.Type);
+ IO.mapRequired("StorageClass", S.StorageClass);
+ IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
+}
+
+void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
+ IO.mapTag("!XCOFF", true);
+ IO.mapRequired("FileHeader", Obj.Header);
+ IO.mapRequired("Symbols", Obj.Symbols);
+}
+
+} // namespace yaml
+} // namespace llvm
diff --git a/lib/ObjectYAML/YAML.cpp b/lib/ObjectYAML/YAML.cpp
index 67b5764eadaa4..6eba16e36c2a2 100644
--- a/lib/ObjectYAML/YAML.cpp
+++ b/lib/ObjectYAML/YAML.cpp
@@ -1,9 +1,8 @@
//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -32,7 +31,7 @@ StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
// TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
// (e.g. a caret pointing to the offending character).
for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
- if (!isxdigit(Scalar[I]))
+ if (!llvm::isHexDigit(Scalar[I]))
return "BinaryRef hex string must contain only hex digits.";
Val = yaml::BinaryRef(Scalar);
return {};
@@ -44,8 +43,9 @@ void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const {
return;
}
for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
- uint8_t Byte;
- StringRef((const char *)&Data[I], 2).getAsInteger(16, Byte);
+ uint8_t Byte = llvm::hexDigitValue(Data[I]);
+ Byte <<= 4;
+ Byte |= llvm::hexDigitValue(Data[I + 1]);
OS.write(Byte);
}
}