diff options
| author | George Rimar <grimar@accesssoftek.com> | 2019-09-24 14:22:37 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2019-09-24 14:22:37 +0000 |
| commit | 1a219aa8df9b4f58e6dbf7beadf1316eb3c5b2f8 (patch) | |
| tree | 91a55dd9444d77754241952a37ae9ca66d2576f3 /llvm/lib/ObjectYAML | |
| parent | c526fcaed193b72be76fb49a7e81be2271cda050 (diff) | |
| download | bcm5719-llvm-1a219aa8df9b4f58e6dbf7beadf1316eb3c5b2f8.tar.gz bcm5719-llvm-1a219aa8df9b4f58e6dbf7beadf1316eb3c5b2f8.zip | |
[yaml2obj/obj2yaml] - Add support for .stack_sizes sections.
.stack_sizes is a SHT_PROGBITS section that contains pairs of
<address (4/8 bytes), stack size (uleb128)>.
This patch teach tools to parse and dump it.
Differential revision: https://reviews.llvm.org/D67757
llvm-svn: 372762
Diffstat (limited to 'llvm/lib/ObjectYAML')
| -rw-r--r-- | llvm/lib/ObjectYAML/ELFEmitter.cpp | 26 | ||||
| -rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 49 |
2 files changed, 67 insertions, 8 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 4584e3d73bd..c394763459d 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -19,6 +19,7 @@ #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/EndianStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/YAMLTraits.h" @@ -167,6 +168,9 @@ template <class ELFT> class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::DynamicSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::StackSizesSection &Section, + ContiguousBlobAccumulator &CBA); ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); public: @@ -411,6 +415,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else { llvm_unreachable("Unknown section type"); } @@ -782,6 +788,26 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, } template <class ELFT> +void ELFState<ELFT>::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, + ContiguousBlobAccumulator &CBA) { + using uintX_t = typename ELFT::uint; + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + + if (Section.Content) { + Section.Content->writeAsBinary(OS); + SHeader.sh_size = Section.Content->binary_size(); + return; + } + + for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { + support::endian::write<uintX_t>(OS, E.Address, ELFT::TargetEndianness); + SHeader.sh_size += sizeof(uintX_t) + encodeULEB128(E.Size, OS); + } +} + +template <class ELFT> void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::VerdefSection &Section, ContiguousBlobAccumulator &CBA) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 161224b0bb7..af795f9732c 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1017,6 +1017,12 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { IO.mapOptional("Info", Section.Info); } +static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Content", Section.Content); + IO.mapOptional("Entries", Section.Entries); +} + static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Size", Section.Size, Hex64(0)); @@ -1142,20 +1148,40 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping( sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get())); break; default: - if (!IO.outputting()) - Section.reset(new ELFYAML::RawContentSection()); - sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get())); + if (!IO.outputting()) { + StringRef Name; + IO.mapOptional("Name", Name, StringRef()); + + if (ELFYAML::StackSizesSection::nameMatches(Name)) + Section = std::make_unique<ELFYAML::StackSizesSection>(); + else + Section = std::make_unique<ELFYAML::RawContentSection>(); + } + + if (auto S = dyn_cast<ELFYAML::RawContentSection>(Section.get())) + sectionMapping(IO, *S); + else + sectionMapping(IO, *cast<ELFYAML::StackSizesSection>(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) + if (const auto *RawSection = + dyn_cast<ELFYAML::RawContentSection>(Section.get())) { + if (RawSection->Size && RawSection->Content && + (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size()) + return "Section size must be greater than or equal to the content size"; return {}; - if (RawSection->Size && RawSection->Content && - (uint64_t)(*RawSection->Size) < RawSection->Content->binary_size()) - return "Section size must be greater than or equal to the content size"; + } + + if (const auto *SS = dyn_cast<ELFYAML::StackSizesSection>(Section.get())) { + if (SS->Content && SS->Entries) + return ".stack_sizes: Content and Entries cannot be used together"; + if (!SS->Content && !SS->Entries) + return ".stack_sizes: either Content or Entries tag must be specified"; + return {}; + } return {}; } @@ -1184,6 +1210,13 @@ struct NormalizedMips64RelType { } // end anonymous namespace +void MappingTraits<ELFYAML::StackSizeEntry>::mapping( + IO &IO, ELFYAML::StackSizeEntry &E) { + assert(IO.getContext() && "The IO context is not initialized"); + IO.mapOptional("Address", E.Address, Hex64(0)); + IO.mapRequired("Size", E.Size); +} + void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO, ELFYAML::DynamicEntry &Rel) { assert(IO.getContext() && "The IO context is not initialized"); |

