aboutsummaryrefslogtreecommitdiffstats
path: root/tools/obj2yaml/elf2yaml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/obj2yaml/elf2yaml.cpp')
-rw-r--r--tools/obj2yaml/elf2yaml.cpp46
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);