diff options
Diffstat (limited to 'llvm/lib/ObjectYAML')
-rw-r--r-- | llvm/lib/ObjectYAML/ELFEmitter.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 24 |
2 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index b9c22e7d99c..1a6f0a8337a 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -200,6 +200,9 @@ template <class ELFT> class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::GnuHashSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::LinkerOptionsSection &Section, + ContiguousBlobAccumulator &CBA); void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); @@ -466,6 +469,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) { writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) { @@ -893,6 +898,30 @@ void ELFState<ELFT>::writeSectionContent( } template <class ELFT> +void ELFState<ELFT>::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &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.Options) + return; + + for (const ELFYAML::LinkerOption &LO : *Section.Options) { + OS.write(LO.Key.data(), LO.Key.size()); + OS.write('\0'); + OS.write(LO.Value.data(), LO.Value.size()); + OS.write('\0'); + SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2); + } +} + +template <class ELFT> void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::HashSection &Section, ContiguousBlobAccumulator &CBA) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index b50f842bba5..bc546b19ff3 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1100,6 +1100,12 @@ static void fillMapping(IO &IO, ELFYAML::Fill &Fill) { IO.mapRequired("Size", Fill.Size); } +static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Options", Section.Options); + IO.mapOptional("Content", Section.Content); +} + void MappingTraits<ELFYAML::SectionOrType>::mapping( IO &IO, ELFYAML::SectionOrType §ionOrType) { IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType); @@ -1217,6 +1223,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping( Section.reset(new ELFYAML::AddrsigSection()); sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get())); break; + case ELF::SHT_LLVM_LINKER_OPTIONS: + if (!IO.outputting()) + Section.reset(new ELFYAML::LinkerOptionsSection()); + sectionMapping(IO, *cast<ELFYAML::LinkerOptionsSection>(Section.get())); + break; default: if (!IO.outputting()) { StringRef Name; @@ -1355,6 +1366,12 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate( return {}; } + if (const auto *Sec = dyn_cast<ELFYAML::LinkerOptionsSection>(C.get())) { + if (Sec->Options && Sec->Content) + return "\"Options\" and \"Content\" can't be used together"; + return {}; + } + if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) { if (!F->Pattern) return {}; @@ -1493,6 +1510,13 @@ void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymb IO.mapOptional("Index", Sym.Index); } +void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO, + ELFYAML::LinkerOption &Opt) { + assert(IO.getContext() && "The IO context is not initialized"); + IO.mapRequired("Name", Opt.Key); + IO.mapRequired("Value", Opt.Value); +} + LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) |