From 9659464d7e7f30c6a1cee07c739dfe8f812924fd Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Fri, 22 Nov 2019 17:18:34 +0300 Subject: [yaml2obj/obj2yaml] - Add support for SHT_LLVM_DEPENDENT_LIBRARIES sections. This section contains strings specifying libraries to be added to the link by the linker. The strings are encoded as standard null-terminated UTF-8 strings. This patch adds a way to describe and dump SHT_LLVM_DEPENDENT_LIBRARIES sections. I introduced a new YAMLFlowString type here. That used to teach obj2yaml to dump them like: ``` Libraries: [ foo, bar ] ``` instead of the following (if StringRef would be used): ``` Libraries: - foo - bar ``` Differential revision: https://reviews.llvm.org/D70598 --- llvm/lib/ObjectYAML/ELFEmitter.cpp | 27 ++++++++++++++++++++++++++ llvm/lib/ObjectYAML/ELFYAML.cpp | 39 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'llvm/lib/ObjectYAML') diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 1a6f0a8337a..e8b54a7e602 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -203,6 +203,9 @@ template class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::DependentLibrariesSection &Section, + ContiguousBlobAccumulator &CBA); void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); @@ -475,6 +478,8 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, 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); } else { llvm_unreachable("Unknown section type"); } @@ -921,6 +926,28 @@ void ELFState::writeSectionContent( } } +template +void ELFState::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section, + ContiguousBlobAccumulator &CBA) { + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + + if (Section.Content) { + SHeader.sh_size = writeContent(OS, Section.Content, None); + return; + } + + if (!Section.Libs) + return; + + for (StringRef Lib : *Section.Libs) { + OS.write(Lib.data(), Lib.size()); + OS.write('\0'); + SHeader.sh_size += Lib.size() + 1; + } +} + template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::HashSection &Section, diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index bc546b19ff3..a5e5894af04 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -863,6 +863,24 @@ template <> struct SequenceElementTraits { static const bool flow = true; }; +template <> struct ScalarTraits { + static void output(const ELFYAML::YAMLFlowString &Val, void *, + raw_ostream &Out) { + Out << Val; + } + static StringRef input(StringRef Scalar, void *, + ELFYAML::YAMLFlowString &Val) { + Val = Scalar; + return {}; + } + static QuotingType mustQuote(StringRef S) { + return ScalarTraits::mustQuote(S); + } +}; +template <> struct SequenceElementTraits { + static const bool flow = true; +}; + namespace { struct NormalizedOther { @@ -1106,6 +1124,13 @@ static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) { IO.mapOptional("Content", Section.Content); } +static void sectionMapping(IO &IO, + ELFYAML::DependentLibrariesSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Libraries", Section.Libs); + IO.mapOptional("Content", Section.Content); +} + void MappingTraits::mapping( IO &IO, ELFYAML::SectionOrType §ionOrType) { IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType); @@ -1228,6 +1253,12 @@ void MappingTraits>::mapping( Section.reset(new ELFYAML::LinkerOptionsSection()); sectionMapping(IO, *cast(Section.get())); break; + case ELF::SHT_LLVM_DEPENDENT_LIBRARIES: + if (!IO.outputting()) + Section.reset(new ELFYAML::DependentLibrariesSection()); + sectionMapping(IO, + *cast(Section.get())); + break; default: if (!IO.outputting()) { StringRef Name; @@ -1372,6 +1403,14 @@ StringRef MappingTraits>::validate( return {}; } + if (const auto *Sec = dyn_cast(C.get())) { + if (Sec->Libs && Sec->Content) + return "SHT_LLVM_DEPENDENT_LIBRARIES: \"Libraries\" and \"Content\" " + "can't " + "be used together"; + return {}; + } + if (const auto *F = dyn_cast(C.get())) { if (!F->Pattern) return {}; -- cgit v1.2.3