From b8eb9d3761e4c9dccdd3a990d7f81ca5e3fb0bfd Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 11 Nov 2024 19:04:40 +0900 Subject: [PATCH 1/7] [ELFYAML] Introduce `CustomRawContent` --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 70 +++++++++++++++++++++++++- llvm/include/llvm/Support/YAMLTraits.h | 17 +++++++ llvm/lib/ObjectYAML/ELFEmitter.cpp | 16 +++++- llvm/lib/ObjectYAML/ELFYAML.cpp | 24 ++++++++- llvm/lib/Support/YAMLTraits.cpp | 8 +++ llvm/tools/obj2yaml/elf2yaml.cpp | 63 +++++++++++++++++++++++ llvm/tools/yaml2obj/yaml2obj.cpp | 16 ++++++ 7 files changed, 211 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 8f045d6383623..ee8ca11aa2ee6 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -211,6 +211,7 @@ struct Chunk { Dynamic, Group, RawContent, + CustomRawContent, Relocation, Relr, NoBits, @@ -388,7 +389,7 @@ struct DynamicSection : Section { struct RawContentSection : Section { std::optional Info; - RawContentSection() : Section(ChunkKind::RawContent) {} + RawContentSection(ChunkKind Kind = ChunkKind::RawContent) : Section(Kind) {} static bool classof(const Chunk *S) { return S->Kind == ChunkKind::RawContent; @@ -398,6 +399,29 @@ struct RawContentSection : Section { std::optional> ContentBuf; }; +/// Abstract base class for non-blob contents. +struct CustomRawContentSection : RawContentSection { + CustomRawContentSection() : RawContentSection(ChunkKind::CustomRawContent) { + // Type assumes PROGBITS. + Type = ELF::SHT_PROGBITS; + Flags = ELF::SHF_GNU_RETAIN; + AddressAlign = 1; + } + + /// Apply mappings. + virtual void sectionMapping(yaml::IO &IO) = 0; + + /// Decode Content and store to members. + virtual Error decode(const ArrayRef Content, bool isLE) = 0; + + /// Encode members and returns Content. + virtual std::string encode() const = 0; + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::CustomRawContent; + } +}; + struct NoBitsSection : Section { NoBitsSection() : Section(ChunkKind::NoBits) {} @@ -757,6 +781,50 @@ struct Object { bool shouldAllocateFileSpace(ArrayRef Phdrs, const NoBitsSection &S); +/// ELFYAML::Opt -- Abstract base class for ELFYAML to provide +/// the interface for handling CustomRawConetentSection. +/// +/// Users in ELFYAML should obtain the pointer with +/// dyn_cast if IO::Opt is the instance from yaml::Opt. +/// +/// if (auto *Opt = dyn_cast(IO.Opt)) +/// +/// Derivered classes should not modify OptClassID to ensue that +/// dyn_cast can find this interface. +class Opt : public yaml::Opt { +public: + Opt() { + OptClassID = &ID; + ELFOptClassID = &ID; + } + ~Opt(); + + /// Create an empty new object of CustomRawContentSection. + /// Its contents will be filled later. + /// This is called: + /// - Before preMapping for elf2yaml. + /// - After preMapping for yaml2elf. + virtual std::unique_ptr + makeCustomRawContentSection(StringRef Name) const = 0; + + /// Called before mapping sections for prettyprinting yaml. + virtual void preMapping(const ELFYAML::Object &Object, bool IsOutputting) = 0; + + /// Called after mapping sections to gather members for the file format. + virtual void postMapping(const ELFYAML::Object &Object, + bool IsOutputting) = 0; + + /// Tell IO::Opt to be this and derivered classes. + static bool classof(const yaml::Opt *Obj) { return (Obj->OptClassID == &ID); } + + /// This will be not needed unless the pointer to ELFYAML::Opt would + /// be cast further. + static bool classof(const Opt *Obj) { return (Obj->ELFOptClassID == &ID); } + const char *ELFOptClassID; + +private: + static const char ID; +}; } // end namespace ELFYAML } // end namespace llvm diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h index 1d04783753d5c..1f1e06a9e3773 100644 --- a/llvm/include/llvm/Support/YAMLTraits.h +++ b/llvm/include/llvm/Support/YAMLTraits.h @@ -39,6 +39,18 @@ class VersionTuple; namespace yaml { +/// The base class of options. +class Opt { +public: + virtual ~Opt(); + + static bool classof(const Opt *Obj) { return (Obj->OptClassID == &ID); } + const char *OptClassID = &ID; + +private: + static const char ID; +}; + enum class NodeKind : uint8_t { Scalar, Map, @@ -964,6 +976,11 @@ class IO { private: void *Ctxt; + Opt DefaultOpt; + +public: + /// This may be overwritten in derivered classes. + Opt *Opt = &DefaultOpt; }; namespace detail { diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index fc234581a45a7..09a540b048517 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -251,6 +251,9 @@ template class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::NoBitsSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::CustomRawContentSection &Section, + ContiguousBlobAccumulator &CBA); void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, ContiguousBlobAccumulator &CBA); @@ -859,7 +862,9 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, if (!isa(Sec) && (Sec->Content || Sec->Size)) SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size); - if (auto S = dyn_cast(Sec)) { + if (auto S = dyn_cast(Sec)) { + writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); @@ -1264,6 +1269,15 @@ void ELFState::writeSectionContent( SHeader.sh_info = *Section.Info; } +template +void ELFState::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::CustomRawContentSection &Section, + ContiguousBlobAccumulator &CBA) { + std::string Storage = Section.encode(); + SHeader.sh_size = Storage.size(); + CBA.write(Storage.data(), Storage.size()); +} + static bool isMips64EL(const ELFYAML::Object &Obj) { return Obj.getMachine() == llvm::ELF::EM_MIPS && Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 89ffc383a4a6e..7d06c2c32e23b 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -29,6 +29,9 @@ namespace llvm { ELFYAML::Chunk::~Chunk() = default; +ELFYAML::Opt::~Opt() = default; +const char ELFYAML::Opt::ID = 'E'; + namespace ELFYAML { ELF_ELFOSABI Object::getOSAbi() const { return Header.OSABI; } @@ -1582,6 +1585,19 @@ static bool isInteger(StringRef Val) { void MappingTraits>::mapping( IO &IO, std::unique_ptr &Section) { + if (!IO.outputting()) { + /// Prepare CustomRawContentSection by Name for ELFEmitter. + if (auto *Opt = dyn_cast(IO.Opt)) { + StringRef Name; + IO.mapOptional("Name", Name); + if (auto S = Opt->makeCustomRawContentSection(Name)) { + S->sectionMapping(IO); + Section = std::move(S); + return; + } + } + } + ELFYAML::ELF_SHT Type; StringRef TypeStr; if (IO.outputting()) { @@ -1731,7 +1747,9 @@ void MappingTraits>::mapping( Section = std::make_unique(); } - if (auto S = dyn_cast(Section.get())) + if (auto S = dyn_cast(Section.get())) + S->sectionMapping(IO); + else if (auto S = dyn_cast(Section.get())) sectionMapping(IO, *S); else sectionMapping(IO, *cast(Section.get())); @@ -1981,6 +1999,8 @@ void MappingTraits::mapping( void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) { assert(!IO.getContext() && "The IO context is initialized already"); IO.setContext(&Object); + if (auto *Opt = dyn_cast(IO.Opt)) + Opt->preMapping(Object, IO.outputting()); IO.mapTag("!ELF", true); IO.mapRequired("FileHeader", Object.Header); IO.mapOptional("ProgramHeaders", Object.ProgramHeaders); @@ -1994,6 +2014,8 @@ void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) { Object.DWARF->Is64BitAddrSize = Object.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); } + if (auto *Opt = dyn_cast(IO.Opt)) + Opt->postMapping(Object, IO.outputting()); IO.setContext(nullptr); } diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index 56b557646100b..4c5d8d5a138aa 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -31,6 +31,14 @@ using namespace llvm; using namespace yaml; +//===----------------------------------------------------------------------===// +// Opt +//===----------------------------------------------------------------------===// + +Opt::~Opt() = default; + +const char Opt::ID = '@'; + //===----------------------------------------------------------------------===// // IO //===----------------------------------------------------------------------===// diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 9b4644bde36c0..3b3fc0f9e8b3c 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -22,6 +22,19 @@ using namespace llvm; namespace { +class DumperOpt : public ELFYAML::Opt { +public: + std::unique_ptr + makeCustomRawContentSection(StringRef Name) const override { + return nullptr; + } + void preMapping(const ELFYAML::Object &Object, bool IsOutputting) override { + // Do nothing. + } + void postMapping(const ELFYAML::Object &Object, bool IsOutputting) override { + // Do nothing. + } +}; template class ELFDumper { @@ -80,6 +93,8 @@ class ELFDumper { Expected dumpRelrSection(const Elf_Shdr *Shdr); Expected dumpContentSection(const Elf_Shdr *Shdr); + Expected + dumpCustomRawContentSection(const Elf_Shdr *Shdr); Expected dumpSymtabShndxSection(const Elf_Shdr *Shdr); Expected dumpNoBitsSection(const Elf_Shdr *Shdr); @@ -104,6 +119,8 @@ class ELFDumper { std::optional DWARF); public: + DumperOpt Opt; + ELFDumper(const object::ELFFile &O, std::unique_ptr DCtx); Expected dump(); }; @@ -657,6 +674,18 @@ ELFDumper::dumpSections() { if (!NameOrErr) return NameOrErr.takeError(); + if (auto ResultOrErr = dumpCustomRawContentSection(&Sec)) { + auto *Ptr = *ResultOrErr; + if (Ptr) { + if (Error E = Add(Ptr)) + return E; + continue; + } else { + // Do nothing -- nullptr + } + } else + return ResultOrErr.takeError(); + if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr)) { if (Error E = Add(dumpStackSizesSection(&Sec))) return std::move(E); @@ -1654,6 +1683,39 @@ ELFDumper::dumpMipsABIFlags(const Elf_Shdr *Shdr) { return S.release(); } +template +Expected +ELFDumper::dumpCustomRawContentSection(const Elf_Shdr *Shdr) { + Expected NameOrErr = getUniquedSectionName(*Shdr); + if (Error E = NameOrErr.takeError()) + return nullptr; + auto Name = std::move(*NameOrErr); + + auto S = Opt.makeCustomRawContentSection(Name); + if (!S) + return nullptr; + + if (Error E = dumpCommonSection(Shdr, *S)) + return std::move(E); + + unsigned SecIndex = Shdr - &Sections[0]; + if (SecIndex == 0 && Shdr->sh_type == ELF::SHT_NULL) + return nullptr; + + auto ContentOrErr = Obj.getSectionContents(*Shdr); + if (!ContentOrErr) + return ContentOrErr.takeError(); + + ArrayRef Content = *ContentOrErr; + if (Content.empty()) + return nullptr; + + S->Content = yaml::BinaryRef(Content); + if (Error E = S->decode(Content, Obj.isLE())) + return E; + return S.release(); +} + template static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, std::unique_ptr DWARFCtx) { @@ -1664,6 +1726,7 @@ static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, std::unique_ptr YAML(YAMLOrErr.get()); yaml::Output Yout(Out); + Yout.Opt = &Dumper.Opt; Yout << *YAML; return Error::success(); diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index 4a060e1aad427..3d356dc7a006f 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -58,6 +58,20 @@ static cl::opt MaxSize( cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"), cl::Prefix, cl::cat(Cat)); + +class EmitterOpt : public ELFYAML::Opt { +public: + std::unique_ptr + makeCustomRawContentSection(StringRef Name) const override { + return nullptr; + } + void preMapping(const ELFYAML::Object &Object, bool IsOutputting) override { + // Do nothing. + } + void postMapping(const ELFYAML::Object &Object, bool IsOutputting) override { + // Do nothing. + } +}; } // namespace static std::optional preprocess(StringRef Buf, @@ -142,7 +156,9 @@ int main(int argc, char **argv) { if (PreprocessOnly) { Out->os() << Buffer; } else { + EmitterOpt Opt; yaml::Input YIn(*Buffer); + YIn.Opt = &Opt; if (!convertYAML(YIn, Out->os(), ErrHandler, DocNum, MaxSize == 0 ? UINT64_MAX : MaxSize)) From 94b13aa2e89ed269e6b996cf906d199d011863be Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 12 Nov 2024 23:48:52 +0900 Subject: [PATCH 2/7] Make CustomRaw more generic --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 7 +------ llvm/lib/ObjectYAML/ELFYAML.cpp | 6 ++++-- llvm/tools/obj2yaml/elf2yaml.cpp | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index ee8ca11aa2ee6..0723c23a9beff 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -401,12 +401,7 @@ struct RawContentSection : Section { /// Abstract base class for non-blob contents. struct CustomRawContentSection : RawContentSection { - CustomRawContentSection() : RawContentSection(ChunkKind::CustomRawContent) { - // Type assumes PROGBITS. - Type = ELF::SHT_PROGBITS; - Flags = ELF::SHF_GNU_RETAIN; - AddressAlign = 1; - } + CustomRawContentSection() : RawContentSection(ChunkKind::CustomRawContent) {} /// Apply mappings. virtual void sectionMapping(yaml::IO &IO) = 0; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 7d06c2c32e23b..aff2d5e18ce89 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1591,6 +1591,7 @@ void MappingTraits>::mapping( StringRef Name; IO.mapOptional("Name", Name); if (auto S = Opt->makeCustomRawContentSection(Name)) { + commonSectionMapping(IO, *S); S->sectionMapping(IO); Section = std::move(S); return; @@ -1747,9 +1748,10 @@ void MappingTraits>::mapping( Section = std::make_unique(); } - if (auto S = dyn_cast(Section.get())) + if (auto S = dyn_cast(Section.get())) { + commonSectionMapping(IO, *S); S->sectionMapping(IO); - else if (auto S = dyn_cast(Section.get())) + } else if (auto S = dyn_cast(Section.get())) sectionMapping(IO, *S); else sectionMapping(IO, *cast(Section.get())); diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 3b3fc0f9e8b3c..7ef5db512b6bc 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -1710,7 +1710,6 @@ ELFDumper::dumpCustomRawContentSection(const Elf_Shdr *Shdr) { if (Content.empty()) return nullptr; - S->Content = yaml::BinaryRef(Content); if (Error E = S->decode(Content, Obj.isLE())) return E; return S.release(); From eedb1bfb63d077a9c1dc333fe3bda32d6ff7359a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 12 Nov 2024 23:49:34 +0900 Subject: [PATCH 3/7] Emit Content as the fallback --- llvm/lib/ObjectYAML/ELFEmitter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 09a540b048517..1c7297bf5f09f 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -1273,6 +1273,13 @@ template void ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::CustomRawContentSection &Section, ContiguousBlobAccumulator &CBA) { + if (Section.Info) + SHeader.sh_info = *Section.Info; + + // If Section has Content, emit it w/o encoding other fields. + if (Section.Content) + return; + std::string Storage = Section.encode(); SHeader.sh_size = Storage.size(); CBA.write(Storage.data(), Storage.size()); From 4b47bb25feb84116315173293beecd8086220911 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 12 Nov 2024 23:50:38 +0900 Subject: [PATCH 4/7] Make CustomRawContentSection sibling and independet from RawContentSection --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 0723c23a9beff..30d83fcf1a158 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -389,7 +389,7 @@ struct DynamicSection : Section { struct RawContentSection : Section { std::optional Info; - RawContentSection(ChunkKind Kind = ChunkKind::RawContent) : Section(Kind) {} + RawContentSection() : Section(ChunkKind::RawContent) {} static bool classof(const Chunk *S) { return S->Kind == ChunkKind::RawContent; @@ -400,8 +400,10 @@ struct RawContentSection : Section { }; /// Abstract base class for non-blob contents. -struct CustomRawContentSection : RawContentSection { - CustomRawContentSection() : RawContentSection(ChunkKind::CustomRawContent) {} +struct CustomRawContentSection : Section { + std::optional Info; + + CustomRawContentSection() : Section(ChunkKind::CustomRawContent) {} /// Apply mappings. virtual void sectionMapping(yaml::IO &IO) = 0; From 6f449538308c796295e78931bc0e27cd6b979122 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 14 Nov 2024 21:50:01 +0900 Subject: [PATCH 5/7] Move yaml::Opt to yaml::IO::OptBase [-fpermissive] --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 14 +++++++----- llvm/include/llvm/Support/YAMLTraits.h | 31 ++++++++++++++------------ llvm/lib/Support/YAMLTraits.cpp | 6 ++--- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 30d83fcf1a158..983d9fe9c3320 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -788,11 +788,11 @@ bool shouldAllocateFileSpace(ArrayRef Phdrs, /// /// Derivered classes should not modify OptClassID to ensue that /// dyn_cast can find this interface. -class Opt : public yaml::Opt { +class Opt : public yaml::IO::OptBase { public: Opt() { + OptBaseClassID = &ID; OptClassID = &ID; - ELFOptClassID = &ID; } ~Opt(); @@ -811,13 +811,15 @@ class Opt : public yaml::Opt { virtual void postMapping(const ELFYAML::Object &Object, bool IsOutputting) = 0; - /// Tell IO::Opt to be this and derivered classes. - static bool classof(const yaml::Opt *Obj) { return (Obj->OptClassID == &ID); } + /// Tell IO::OptBase to be this and derivered classes. + static bool classof(const yaml::IO::OptBase *Obj) { + return (Obj->OptBaseClassID == &ID); + } /// This will be not needed unless the pointer to ELFYAML::Opt would /// be cast further. - static bool classof(const Opt *Obj) { return (Obj->ELFOptClassID == &ID); } - const char *ELFOptClassID; + static bool classof(const Opt *Obj) { return (Obj->OptClassID == &ID); } + const char *OptClassID; private: static const char ID; diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h index 1f1e06a9e3773..2b16dd21c56b6 100644 --- a/llvm/include/llvm/Support/YAMLTraits.h +++ b/llvm/include/llvm/Support/YAMLTraits.h @@ -39,18 +39,6 @@ class VersionTuple; namespace yaml { -/// The base class of options. -class Opt { -public: - virtual ~Opt(); - - static bool classof(const Opt *Obj) { return (Obj->OptClassID == &ID); } - const char *OptClassID = &ID; - -private: - static const char ID; -}; - enum class NodeKind : uint8_t { Scalar, Map, @@ -974,13 +962,28 @@ class IO { } } +public: + /// The base class of options. + class OptBase { + public: + virtual ~OptBase(); + + static bool classof(const OptBase *Obj) { + return (Obj->OptBaseClassID == &ID); + } + const char *OptBaseClassID = &ID; + + private: + static const char ID; + }; + private: void *Ctxt; - Opt DefaultOpt; + OptBase DefaultOpt; public: /// This may be overwritten in derivered classes. - Opt *Opt = &DefaultOpt; + OptBase *Opt = &DefaultOpt; }; namespace detail { diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index 4c5d8d5a138aa..4b1c4b368d239 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -32,12 +32,12 @@ using namespace llvm; using namespace yaml; //===----------------------------------------------------------------------===// -// Opt +// IO::OptBase //===----------------------------------------------------------------------===// -Opt::~Opt() = default; +IO::OptBase::~OptBase() = default; -const char Opt::ID = '@'; +const char IO::OptBase::ID = '@'; //===----------------------------------------------------------------------===// // IO From 9f7a0c4524bd95f39ddde9c254920ba7dd13510a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 14 Nov 2024 22:10:06 +0900 Subject: [PATCH 6/7] Make ELFYAML::Opt non-abstract --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 12 ++++++------ llvm/lib/ObjectYAML/ELFYAML.cpp | 13 +++++++++++++ llvm/tools/obj2yaml/elf2yaml.cpp | 14 +------------- llvm/tools/yaml2obj/yaml2obj.cpp | 14 +------------- 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 983d9fe9c3320..59af9ac8851c0 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -778,8 +778,8 @@ struct Object { bool shouldAllocateFileSpace(ArrayRef Phdrs, const NoBitsSection &S); -/// ELFYAML::Opt -- Abstract base class for ELFYAML to provide -/// the interface for handling CustomRawConetentSection. +/// ELFYAML::Opt -- Null base class for ELFYAML to provide the +/// interface for handling CustomRawConetentSection. /// /// Users in ELFYAML should obtain the pointer with /// dyn_cast if IO::Opt is the instance from yaml::Opt. @@ -801,15 +801,15 @@ class Opt : public yaml::IO::OptBase { /// This is called: /// - Before preMapping for elf2yaml. /// - After preMapping for yaml2elf. + /// Returns nullptr to delegate default actions. virtual std::unique_ptr - makeCustomRawContentSection(StringRef Name) const = 0; + makeCustomRawContentSection(StringRef Name) const; /// Called before mapping sections for prettyprinting yaml. - virtual void preMapping(const ELFYAML::Object &Object, bool IsOutputting) = 0; + virtual void preMapping(const ELFYAML::Object &Object, bool IsOutputting); /// Called after mapping sections to gather members for the file format. - virtual void postMapping(const ELFYAML::Object &Object, - bool IsOutputting) = 0; + virtual void postMapping(const ELFYAML::Object &Object, bool IsOutputting); /// Tell IO::OptBase to be this and derivered classes. static bool classof(const yaml::IO::OptBase *Obj) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index aff2d5e18ce89..83ee88e57d66b 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -32,6 +32,19 @@ ELFYAML::Chunk::~Chunk() = default; ELFYAML::Opt::~Opt() = default; const char ELFYAML::Opt::ID = 'E'; +std::unique_ptr +ELFYAML::Opt::makeCustomRawContentSection(StringRef Name) const { + return nullptr; +} + +/// Called before mapping sections for prettyprinting yaml. +void ELFYAML::Opt::preMapping(const ELFYAML::Object &Object, + bool IsOutputting) {} + +/// Called after mapping sections to gather members for the file format. +void ELFYAML::Opt::postMapping(const ELFYAML::Object &Object, + bool IsOutputting) {} + namespace ELFYAML { ELF_ELFOSABI Object::getOSAbi() const { return Header.OSABI; } diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 7ef5db512b6bc..d3fbe9c2d17c1 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -22,19 +22,7 @@ using namespace llvm; namespace { -class DumperOpt : public ELFYAML::Opt { -public: - std::unique_ptr - makeCustomRawContentSection(StringRef Name) const override { - return nullptr; - } - void preMapping(const ELFYAML::Object &Object, bool IsOutputting) override { - // Do nothing. - } - void postMapping(const ELFYAML::Object &Object, bool IsOutputting) override { - // Do nothing. - } -}; +struct DumperOpt : public ELFYAML::Opt {}; template class ELFDumper { diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index 3d356dc7a006f..b899b8d7cdf2c 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -59,19 +59,7 @@ cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"), cl::Prefix, cl::cat(Cat)); -class EmitterOpt : public ELFYAML::Opt { -public: - std::unique_ptr - makeCustomRawContentSection(StringRef Name) const override { - return nullptr; - } - void preMapping(const ELFYAML::Object &Object, bool IsOutputting) override { - // Do nothing. - } - void postMapping(const ELFYAML::Object &Object, bool IsOutputting) override { - // Do nothing. - } -}; +struct EmitterOpt : public ELFYAML::Opt {}; } // namespace static std::optional preprocess(StringRef Buf, From 67df0dc3bac0462137d34bc2cdb315634a2dae97 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 14 Nov 2024 22:11:07 +0900 Subject: [PATCH 7/7] s/CustomRawContentSection/CustomSection/ --- llvm/include/llvm/ObjectYAML/ELFYAML.h | 14 +++++++------- llvm/lib/ObjectYAML/ELFEmitter.cpp | 10 +++++----- llvm/lib/ObjectYAML/ELFYAML.cpp | 10 +++++----- llvm/tools/obj2yaml/elf2yaml.cpp | 11 +++++------ 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 59af9ac8851c0..38497c813c0fa 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -211,7 +211,7 @@ struct Chunk { Dynamic, Group, RawContent, - CustomRawContent, + CustomContent, Relocation, Relr, NoBits, @@ -400,10 +400,10 @@ struct RawContentSection : Section { }; /// Abstract base class for non-blob contents. -struct CustomRawContentSection : Section { +struct CustomSection : Section { std::optional Info; - CustomRawContentSection() : Section(ChunkKind::CustomRawContent) {} + CustomSection() : Section(ChunkKind::CustomContent) {} /// Apply mappings. virtual void sectionMapping(yaml::IO &IO) = 0; @@ -415,7 +415,7 @@ struct CustomRawContentSection : Section { virtual std::string encode() const = 0; static bool classof(const Chunk *S) { - return S->Kind == ChunkKind::CustomRawContent; + return S->Kind == ChunkKind::CustomContent; } }; @@ -796,14 +796,14 @@ class Opt : public yaml::IO::OptBase { } ~Opt(); - /// Create an empty new object of CustomRawContentSection. + /// Create an empty new object of CustomSection. /// Its contents will be filled later. /// This is called: /// - Before preMapping for elf2yaml. /// - After preMapping for yaml2elf. /// Returns nullptr to delegate default actions. - virtual std::unique_ptr - makeCustomRawContentSection(StringRef Name) const; + virtual std::unique_ptr + makeCustomSection(StringRef Name) const; /// Called before mapping sections for prettyprinting yaml. virtual void preMapping(const ELFYAML::Object &Object, bool IsOutputting); diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 1c7297bf5f09f..f70f9e5601403 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -252,7 +252,7 @@ template class ELFState { const ELFYAML::NoBitsSection &Section, ContiguousBlobAccumulator &CBA); void writeSectionContent(Elf_Shdr &SHeader, - const ELFYAML::CustomRawContentSection &Section, + const ELFYAML::CustomSection &Section, ContiguousBlobAccumulator &CBA); void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, @@ -862,7 +862,7 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, if (!isa(Sec) && (Sec->Content || Sec->Size)) SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size); - if (auto S = dyn_cast(Sec)) { + if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); @@ -1270,9 +1270,9 @@ void ELFState::writeSectionContent( } template -void ELFState::writeSectionContent( - Elf_Shdr &SHeader, const ELFYAML::CustomRawContentSection &Section, - ContiguousBlobAccumulator &CBA) { +void ELFState::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::CustomSection &Section, + ContiguousBlobAccumulator &CBA) { if (Section.Info) SHeader.sh_info = *Section.Info; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 83ee88e57d66b..3f73637929cad 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -32,8 +32,8 @@ ELFYAML::Chunk::~Chunk() = default; ELFYAML::Opt::~Opt() = default; const char ELFYAML::Opt::ID = 'E'; -std::unique_ptr -ELFYAML::Opt::makeCustomRawContentSection(StringRef Name) const { +std::unique_ptr +ELFYAML::Opt::makeCustomSection(StringRef Name) const { return nullptr; } @@ -1599,11 +1599,11 @@ static bool isInteger(StringRef Val) { void MappingTraits>::mapping( IO &IO, std::unique_ptr &Section) { if (!IO.outputting()) { - /// Prepare CustomRawContentSection by Name for ELFEmitter. + /// Prepare CustomSection by Name for ELFEmitter. if (auto *Opt = dyn_cast(IO.Opt)) { StringRef Name; IO.mapOptional("Name", Name); - if (auto S = Opt->makeCustomRawContentSection(Name)) { + if (auto S = Opt->makeCustomSection(Name)) { commonSectionMapping(IO, *S); S->sectionMapping(IO); Section = std::move(S); @@ -1761,7 +1761,7 @@ void MappingTraits>::mapping( Section = std::make_unique(); } - if (auto S = dyn_cast(Section.get())) { + if (auto S = dyn_cast(Section.get())) { commonSectionMapping(IO, *S); S->sectionMapping(IO); } else if (auto S = dyn_cast(Section.get())) diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index d3fbe9c2d17c1..8567de489a0bf 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -81,8 +81,7 @@ class ELFDumper { Expected dumpRelrSection(const Elf_Shdr *Shdr); Expected dumpContentSection(const Elf_Shdr *Shdr); - Expected - dumpCustomRawContentSection(const Elf_Shdr *Shdr); + Expected dumpCustomSection(const Elf_Shdr *Shdr); Expected dumpSymtabShndxSection(const Elf_Shdr *Shdr); Expected dumpNoBitsSection(const Elf_Shdr *Shdr); @@ -662,7 +661,7 @@ ELFDumper::dumpSections() { if (!NameOrErr) return NameOrErr.takeError(); - if (auto ResultOrErr = dumpCustomRawContentSection(&Sec)) { + if (auto ResultOrErr = dumpCustomSection(&Sec)) { auto *Ptr = *ResultOrErr; if (Ptr) { if (Error E = Add(Ptr)) @@ -1672,14 +1671,14 @@ ELFDumper::dumpMipsABIFlags(const Elf_Shdr *Shdr) { } template -Expected -ELFDumper::dumpCustomRawContentSection(const Elf_Shdr *Shdr) { +Expected +ELFDumper::dumpCustomSection(const Elf_Shdr *Shdr) { Expected NameOrErr = getUniquedSectionName(*Shdr); if (Error E = NameOrErr.takeError()) return nullptr; auto Name = std::move(*NameOrErr); - auto S = Opt.makeCustomRawContentSection(Name); + auto S = Opt.makeCustomSection(Name); if (!S) return nullptr;