diff options
Diffstat (limited to 'tools/obj2yaml/elf2yaml.cpp')
-rw-r--r-- | tools/obj2yaml/elf2yaml.cpp | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index d770ce1..e606df2 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -21,8 +21,10 @@ namespace { template <class ELFT> class ELFDumper { + typedef object::Elf_Sym_Impl<ELFT> Elf_Sym; typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; + typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; const object::ELFFile<ELFT> &Obj; @@ -38,6 +40,7 @@ class ELFDumper { ErrorOr<ELFYAML::RelocationSection *> dumpRelaSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::RawContentSection *> dumpContentSection(const Elf_Shdr *Shdr); + ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); public: ELFDumper(const object::ELFFile<ELFT> &O); @@ -86,7 +89,13 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); break; } - // FIXME: Support SHT_GROUP section format. + case ELF::SHT_GROUP: { + ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec); + if (std::error_code EC = G.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); + break; + } default: { ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); if (std::error_code EC = S.getError()) @@ -275,6 +284,41 @@ ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) { } template <class ELFT> +ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { + auto S = make_unique<ELFYAML::Group>(); + + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + // Get sh_info which is the signature. + const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info); + const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link); + auto sectionContents = Obj.getSectionContents(Shdr); + if (std::error_code ec = sectionContents.getError()) + return ec; + ErrorOr<StringRef> symbolName = Obj.getSymbolName(symtab, symbol); + if (std::error_code EC = symbolName.getError()) + return EC; + S->Info = *symbolName; + const Elf_Word *groupMembers = + reinterpret_cast<const Elf_Word *>(sectionContents->data()); + const long count = (Shdr->sh_size) / sizeof(Elf_Word); + ELFYAML::SectionOrType s; + for (int i = 0; i < count; i++) { + if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { + s.sectionNameOrType = "GRP_COMDAT"; + } else { + const Elf_Shdr *sHdr = Obj.getSection(groupMembers[i]); + ErrorOr<StringRef> sectionName = Obj.getSectionName(sHdr); + if (std::error_code ec = sectionName.getError()) + return ec; + s.sectionNameOrType = *sectionName; + } + S->Members.push_back(s); + } + return S.release(); +} + +template <class ELFT> static std::error_code elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) { ELFDumper<ELFT> Dumper(Obj); |