+ 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);