diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-10-01 09:45:59 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-10-01 09:45:59 +0000 |
commit | e5163ebf8d9e4262c8adc1309f70e8cabef10f3a (patch) | |
tree | cceebce3cbe56a07f2869f59db1691c150216ec1 /llvm/lib | |
parent | c2c377ea584d17060fd44151af0c3f2259423d8c (diff) | |
download | bcm5719-llvm-e5163ebf8d9e4262c8adc1309f70e8cabef10f3a.tar.gz bcm5719-llvm-e5163ebf8d9e4262c8adc1309f70e8cabef10f3a.zip |
[yaml2obj/obj2yaml] - Add support for SHT_HASH sections.
SHT_HASH specification is:
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
In short the format is the following: it has 2 uint32 fields
in its header: nbucket and nchain followed by (nbucket + nchain)
uint32 values.
This patch allows dumping and parsing such sections.
Differential revision: https://reviews.llvm.org/D68085
llvm-svn: 373315
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ObjectYAML/ELFEmitter.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 30 |
2 files changed, 64 insertions, 1 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 6edc3c8e763..5acb02a5a57 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -171,6 +171,9 @@ template <class ELFT> class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::HashSection &Section, + ContiguousBlobAccumulator &CBA); ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); public: @@ -417,7 +420,9 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, } 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); + writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else { llvm_unreachable("Unknown section type"); } @@ -810,6 +815,34 @@ void ELFState<ELFT>::writeSectionContent( template <class ELFT> void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::HashSection &Section, + ContiguousBlobAccumulator &CBA) { + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + + unsigned Link = 0; + if (SN2I.lookup(".dynsym", Link)) + SHeader.sh_link = Link; + + if (Section.Content) { + SHeader.sh_size = writeContent(OS, Section.Content, None); + return; + } + + support::endian::write<uint32_t>(OS, Section.Bucket->size(), + ELFT::TargetEndianness); + support::endian::write<uint32_t>(OS, Section.Chain->size(), + ELFT::TargetEndianness); + for (uint32_t Val : *Section.Bucket) + support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); + for (uint32_t Val : *Section.Chain) + support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); + + SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; +} + +template <class ELFT> +void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::VerdefSection &Section, ContiguousBlobAccumulator &CBA) { typedef typename ELFT::Verdef Elf_Verdef; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 94b1df10439..3a09a11ad83 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1024,6 +1024,13 @@ static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) { IO.mapOptional("Entries", Section.Entries); } +static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Content", Section.Content); + IO.mapOptional("Bucket", Section.Bucket); + IO.mapOptional("Chain", Section.Chain); +} + static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Size", Section.Size, Hex64(0)); @@ -1123,6 +1130,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping( Section.reset(new ELFYAML::NoBitsSection()); sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get())); break; + case ELF::SHT_HASH: + if (!IO.outputting()) + Section.reset(new ELFYAML::HashSection()); + sectionMapping(IO, *cast<ELFYAML::HashSection>(Section.get())); + break; case ELF::SHT_MIPS_ABIFLAGS: if (!IO.outputting()) Section.reset(new ELFYAML::MipsABIFlags()); @@ -1196,6 +1208,24 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate( return ".stack_sizes: Content and Entries cannot be used together"; return {}; } + + if (const auto *HS = dyn_cast<ELFYAML::HashSection>(Section.get())) { + if (!HS->Content && !HS->Bucket && !HS->Chain) + return "one of \"Content\", \"Bucket\" or \"Chain\" must be specified"; + + if (HS->Content) { + if (HS->Bucket) + return "\"Content\" and \"Bucket\" cannot be used together"; + if (HS->Chain) + return "\"Content\" and \"Chain\" cannot be used together"; + return {}; + } + + if ((HS->Bucket && !HS->Chain) || (!HS->Bucket && HS->Chain)) + return "\"Bucket\" and \"Chain\" must be used together"; + return {}; + } + return {}; } |