+void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
+ IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(ELFOSABI_NONE)
+ ECase(ELFOSABI_HPUX)
+ ECase(ELFOSABI_NETBSD)
+ ECase(ELFOSABI_GNU)
+ ECase(ELFOSABI_GNU)
+ ECase(ELFOSABI_HURD)
+ ECase(ELFOSABI_SOLARIS)
+ ECase(ELFOSABI_AIX)
+ ECase(ELFOSABI_IRIX)
+ ECase(ELFOSABI_FREEBSD)
+ ECase(ELFOSABI_TRU64)
+ ECase(ELFOSABI_MODESTO)
+ ECase(ELFOSABI_OPENBSD)
+ ECase(ELFOSABI_OPENVMS)
+ ECase(ELFOSABI_NSK)
+ ECase(ELFOSABI_AROS)
+ ECase(ELFOSABI_FENIXOS)
+ ECase(ELFOSABI_C6000_ELFABI)
+ ECase(ELFOSABI_C6000_LINUX)
+ ECase(ELFOSABI_ARM)
+ ECase(ELFOSABI_STANDALONE)
+#undef ECase
+}
+
+void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
+ ELFYAML::ELF_EF &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
+#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M);
+ switch (Object->Header.Machine) {
+ case ELF::EM_ARM:
+ BCase(EF_ARM_SOFT_FLOAT)
+ BCase(EF_ARM_VFP_FLOAT)
+ BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK)
+ break;
+ case ELF::EM_MIPS:
+ BCase(EF_MIPS_NOREORDER)
+ BCase(EF_MIPS_PIC)
+ BCase(EF_MIPS_CPIC)
+ BCase(EF_MIPS_ABI2)
+ BCase(EF_MIPS_32BITMODE)
+ BCase(EF_MIPS_NAN2008)
+ BCase(EF_MIPS_ABI_O32)
+ BCase(EF_MIPS_MICROMIPS)
+ BCase(EF_MIPS_ARCH_ASE_M16)
+ BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH)
+ break;
+ case ELF::EM_HEXAGON:
+ BCase(EF_HEXAGON_MACH_V2)
+ BCase(EF_HEXAGON_MACH_V3)
+ BCase(EF_HEXAGON_MACH_V4)
+ BCase(EF_HEXAGON_MACH_V5)
+ BCase(EF_HEXAGON_ISA_V2)
+ BCase(EF_HEXAGON_ISA_V3)
+ BCase(EF_HEXAGON_ISA_V4)
+ BCase(EF_HEXAGON_ISA_V5)
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
+#undef BCase
+#undef BCaseMask
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
+ IO &IO, ELFYAML::ELF_SHT &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(SHT_NULL)
+ ECase(SHT_PROGBITS)
+ // No SHT_SYMTAB. Use the top-level `Symbols` key instead.
+ // FIXME: Issue a diagnostic with this information.
+ ECase(SHT_STRTAB)
+ ECase(SHT_RELA)
+ ECase(SHT_HASH)
+ ECase(SHT_DYNAMIC)
+ ECase(SHT_NOTE)
+ ECase(SHT_NOBITS)
+ ECase(SHT_REL)
+ ECase(SHT_SHLIB)
+ ECase(SHT_DYNSYM)
+ ECase(SHT_INIT_ARRAY)
+ ECase(SHT_FINI_ARRAY)
+ ECase(SHT_PREINIT_ARRAY)
+ ECase(SHT_GROUP)
+ ECase(SHT_SYMTAB_SHNDX)
+ ECase(SHT_LOOS)
+ 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)
+ ECase(SHT_ARM_PREEMPTMAP)
+ ECase(SHT_ARM_ATTRIBUTES)
+ ECase(SHT_ARM_DEBUGOVERLAY)
+ ECase(SHT_ARM_OVERLAYSECTION)
+ break;
+ case ELF::EM_HEXAGON:
+ ECase(SHT_HEX_ORDERED)
+ break;
+ case ELF::EM_X86_64:
+ ECase(SHT_X86_64_UNWIND)
+ break;
+ case ELF::EM_MIPS:
+ ECase(SHT_MIPS_REGINFO)
+ ECase(SHT_MIPS_OPTIONS)
+ ECase(SHT_MIPS_ABIFLAGS)
+ break;
+ default:
+ // Nothing to do.
+ break;
+ }
+#undef ECase
+}
+
+void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
+ ELFYAML::ELF_SHF &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
+ BCase(SHF_WRITE)
+ BCase(SHF_ALLOC)
+ BCase(SHF_EXCLUDE)
+ BCase(SHF_EXECINSTR)
+ BCase(SHF_MERGE)
+ BCase(SHF_STRINGS)
+ BCase(SHF_INFO_LINK)
+ BCase(SHF_LINK_ORDER)
+ BCase(SHF_OS_NONCONFORMING)
+ BCase(SHF_GROUP)
+ BCase(SHF_TLS)
+#undef BCase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
+ IO &IO, ELFYAML::ELF_STT &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(STT_NOTYPE)
+ ECase(STT_OBJECT)
+ ECase(STT_FUNC)
+ ECase(STT_SECTION)
+ ECase(STT_FILE)
+ ECase(STT_COMMON)
+ ECase(STT_TLS)
+ ECase(STT_GNU_IFUNC)
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
+ IO &IO, ELFYAML::ELF_STV &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(STV_DEFAULT)
+ ECase(STV_INTERNAL)
+ ECase(STV_HIDDEN)
+ ECase(STV_PROTECTED)
+#undef ECase
+}
+
+void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
+ ELFYAML::ELF_STO &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_MIPS:
+ BCase(STO_MIPS_OPTIONAL)
+ BCase(STO_MIPS_PLT)
+ BCase(STO_MIPS_PIC)
+ BCase(STO_MIPS_MICROMIPS)
+ break;
+ default:
+ break; // Nothing to do
+ }
+#undef BCase
+#undef BCaseMask
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
+ IO &IO, ELFYAML::ELF_RSS &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(RSS_UNDEF)
+ ECase(RSS_GP)
+ ECase(RSS_GP0)
+ ECase(RSS_LOC)
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
+ IO &IO, ELFYAML::ELF_REL &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_X86_64:
+#include "llvm/Support/ELFRelocs/x86_64.def"
+ break;
+ case ELF::EM_MIPS:
+#include "llvm/Support/ELFRelocs/Mips.def"
+ break;
+ case ELF::EM_HEXAGON:
+#include "llvm/Support/ELFRelocs/Hexagon.def"
+ break;
+ case ELF::EM_386:
+#include "llvm/Support/ELFRelocs/i386.def"
+ break;
+ case ELF::EM_AARCH64:
+#include "llvm/Support/ELFRelocs/AArch64.def"
+ break;
+ case ELF::EM_ARM:
+#include "llvm/Support/ELFRelocs/ARM.def"
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
+#undef ELF_RELOC
+}
+
+void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
+ ELFYAML::FileHeader &FileHdr) {
+ IO.mapRequired("Class", FileHdr.Class);
+ IO.mapRequired("Data", FileHdr.Data);
+ IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
+ IO.mapRequired("Type", FileHdr.Type);
+ IO.mapRequired("Machine", FileHdr.Machine);
+ IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
+ IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
+}
+
+namespace {
+struct NormalizedOther {
+ NormalizedOther(IO &)
+ : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {}
+ NormalizedOther(IO &, uint8_t Original)
+ : Visibility(Original & 0x3), Other(Original & ~0x3) {}
+
+ uint8_t denormalize(IO &) { return Visibility | Other; }
+
+ ELFYAML::ELF_STV Visibility;
+ ELFYAML::ELF_STO Other;
+};
+}
+
+void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
+ IO.mapOptional("Name", Symbol.Name, StringRef());
+ IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
+ IO.mapOptional("Section", Symbol.Section, StringRef());
+ 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));
+}
+
+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("Address", Section.Address, Hex64(0));
+ IO.mapOptional("Link", Section.Link, StringRef());
+ IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
+ IO.mapOptional("Info", Section.Info, StringRef());
+}
+
+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()));
+}
+
+static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Relocations", Section.Relocations);
+}
+
+static void groupSectionMapping(IO &IO, ELFYAML::Group &group) {
+ commonSectionMapping(IO, group);
+ IO.mapRequired("Members", group.Members);
+}
+
+void MappingTraits<ELFYAML::SectionOrType>::mapping(
+ IO &IO, ELFYAML::SectionOrType §ionOrType) {
+ IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
+}
+
+void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
+ IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
+ ELFYAML::ELF_SHT sectionType;
+ if (IO.outputting())
+ sectionType = Section->Type;
+ else
+ IO.mapRequired("Type", sectionType);
+
+ switch (sectionType) {
+ case ELF::SHT_REL:
+ case ELF::SHT_RELA:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RelocationSection());
+ sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
+ break;
+ case ELF::SHT_GROUP:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::Group());
+ groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
+ break;
+ default:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RawContentSection());
+ sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get()));
+ }
+}
+
+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";
+}
+
+namespace {
+struct NormalizedMips64RelType {
+ NormalizedMips64RelType(IO &)
+ : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
+ NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
+ : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
+ Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
+
+ ELFYAML::ELF_REL denormalize(IO &) {
+ ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
+ return Res;
+ }
+
+ ELFYAML::ELF_REL Type;
+ ELFYAML::ELF_REL Type2;
+ ELFYAML::ELF_REL Type3;
+ ELFYAML::ELF_RSS SpecSym;
+};
+}
+
+void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
+ ELFYAML::Relocation &Rel) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+
+ IO.mapRequired("Offset", Rel.Offset);
+ IO.mapRequired("Symbol", Rel.Symbol);
+
+ if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
+ Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
+ MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
+ IO, Rel.Type);
+ IO.mapRequired("Type", Key->Type);
+ IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
+ } else
+ IO.mapRequired("Type", Rel.Type);
+
+ IO.mapOptional("Addend", Rel.Addend, (int64_t)0);