diff options
| author | George Rimar <grimar@accesssoftek.com> | 2019-02-19 14:53:48 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2019-02-19 14:53:48 +0000 |
| commit | 0621b795878c1105f2aff097e6a217c700676540 (patch) | |
| tree | 8bfac8ca07fbfea1ec471c897fc3aa72a7f1384a /llvm/tools/obj2yaml | |
| parent | 6aae216109544a9d87b1332642632292595ca7a6 (diff) | |
| download | bcm5719-llvm-0621b795878c1105f2aff097e6a217c700676540.tar.gz bcm5719-llvm-0621b795878c1105f2aff097e6a217c700676540.zip | |
Recommit r354328, r354329 "[obj2yaml][yaml2obj] - Add support of parsing/dumping of the .gnu.version_r section."
Fix:
Replace
assert(!IO.getContext() && "The IO context is initialized already");
with
assert(IO.getContext() && "The IO context is not initialized");
(this was introduced in r354329, where I tried to quickfix the darwin BB
and seems copypasted the assert from the wrong place).
Original commit message:
The section is described here:
https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/symverrqmts.html
Patch just teaches obj2yaml/yaml2obj to dump and parse such sections.
We did the finalization of string tables very late,
and I had to move the logic to make it a bit earlier.
That was needed in this patch since .gnu.version_r adds strings to .dynstr.
This might also be useful for implementing other special sections.
Everything else changed in this patch seems to be straightforward.
Differential revision: https://reviews.llvm.org/D58119
llvm-svn: 354335
Diffstat (limited to 'llvm/tools/obj2yaml')
| -rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index a3fe811b9d5..cb18e1820df 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -57,6 +57,7 @@ class ELFDumper { ErrorOr<ELFYAML::RawContentSection *> dumpContentSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); + ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); @@ -184,6 +185,13 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); break; } + case ELF::SHT_GNU_verneed: { + ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec); + if (std::error_code EC = S.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); + break; + } default: { ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); if (std::error_code EC = S.getError()) @@ -444,6 +452,63 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { } template <class ELFT> +ErrorOr<ELFYAML::VerneedSection *> +ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) { + typedef typename ELFT::Verneed Elf_Verneed; + typedef typename ELFT::Vernaux Elf_Vernaux; + + auto S = make_unique<ELFYAML::VerneedSection>(); + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + + S->Info = Shdr->sh_info; + + auto Contents = Obj.getSectionContents(Shdr); + if (!Contents) + return errorToErrorCode(Contents.takeError()); + + auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); + if (!StringTableShdrOrErr) + return errorToErrorCode(StringTableShdrOrErr.takeError()); + + auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); + if (!StringTableOrErr) + return errorToErrorCode(StringTableOrErr.takeError()); + + llvm::ArrayRef<uint8_t> Data = *Contents; + const uint8_t *Buf = Data.data(); + while (Buf) { + const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf); + + ELFYAML::VerneedEntry Entry; + Entry.Version = Verneed->vn_version; + Entry.File = + StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data()); + + const uint8_t *BufAux = Buf + Verneed->vn_aux; + while (BufAux) { + const Elf_Vernaux *Vernaux = + reinterpret_cast<const Elf_Vernaux *>(BufAux); + + ELFYAML::VernauxEntry Aux; + Aux.Hash = Vernaux->vna_hash; + Aux.Flags = Vernaux->vna_flags; + Aux.Other = Vernaux->vna_other; + Aux.Name = + StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data()); + + Entry.AuxV.push_back(Aux); + BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; + } + + S->VerneedV.push_back(Entry); + Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; + } + + return S.release(); +} + +template <class ELFT> ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { auto S = make_unique<ELFYAML::Group>(); |

