[yaml2obj][obj2yaml] - Add support for dumping/parsing .dynamic sections.
This teaches the tools to parse and dump
the .dynamic section and its dynamic tags.
Differential revision: https://reviews.llvm.org/D57691
llvm-svn: 353606
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index e2fb463..a089890 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -21,6 +21,7 @@
template <class ELFT>
class ELFDumper {
typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef typename ELFT::Dyn Elf_Dyn;
typedef typename ELFT::Shdr Elf_Shdr;
typedef typename ELFT::Word Elf_Word;
typedef typename ELFT::Rel Elf_Rel;
@@ -50,7 +51,8 @@
template <class RelT>
std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
ELFYAML::Relocation &R);
-
+
+ ErrorOr<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
ErrorOr<ELFYAML::RawContentSection *>
dumpContentSection(const Elf_Shdr *Shdr);
@@ -129,6 +131,13 @@
SectionNames.resize(Sections.size());
for (const Elf_Shdr &Sec : Sections) {
switch (Sec.sh_type) {
+ case ELF::SHT_DYNAMIC: {
+ ErrorOr<ELFYAML::DynamicSection *> S = dumpDynamicSection(&Sec);
+ if (std::error_code EC = S.getError())
+ return EC;
+ Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+ break;
+ }
case ELF::SHT_NULL:
case ELF::SHT_STRTAB:
// Do not dump these sections.
@@ -351,6 +360,23 @@
}
template <class ELFT>
+ErrorOr<ELFYAML::DynamicSection *>
+ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
+ auto S = make_unique<ELFYAML::DynamicSection>();
+ if (std::error_code EC = dumpCommonSection(Shdr, *S))
+ return EC;
+
+ auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
+ if (!DynTagsOrErr)
+ return errorToErrorCode(DynTagsOrErr.takeError());
+
+ for (const Elf_Dyn &Dyn : *DynTagsOrErr)
+ S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
+
+ return S.release();
+}
+
+template <class ELFT>
ErrorOr<ELFYAML::RelocationSection *>
ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
auto S = make_unique<ELFYAML::RelocationSection>();
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index 0b2c99cc..4e3a1d7 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -159,6 +159,9 @@
bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::MipsABIFlags &Section,
ContiguousBlobAccumulator &CBA);
+ void writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::DynamicSection &Section,
+ ContiguousBlobAccumulator &CBA);
bool hasDynamicSymbols() const;
SmallVector<const char *, 5> implicitSectionNames() const;
@@ -291,6 +294,8 @@
// SHT_NOBITS section does not have content
// so just to setup the section offset.
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
+ writeSectionContent(SHeader, *S, CBA);
} else
llvm_unreachable("Unknown section type");
@@ -465,8 +470,6 @@
SHeader.sh_entsize = *Section.EntSize;
else if (Section.Type == llvm::ELF::SHT_RELR)
SHeader.sh_entsize = sizeof(Elf_Relr);
- else if (Section.Type == llvm::ELF::SHT_DYNAMIC)
- SHeader.sh_entsize = sizeof(Elf_Dyn);
else
SHeader.sh_entsize = 0;
SHeader.sh_size = Section.Size;
@@ -575,6 +578,29 @@
return true;
}
+template <class ELFT>
+void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::DynamicSection &Section,
+ ContiguousBlobAccumulator &CBA) {
+ typedef typename ELFT::uint uintX_t;
+ assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
+ "Section type is not SHT_DYNAMIC");
+
+ SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
+ if (Section.EntSize)
+ SHeader.sh_entsize = *Section.EntSize;
+ else
+ SHeader.sh_entsize = sizeof(Elf_Dyn);
+
+ auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ for (const ELFYAML::DynamicEntry &DE : Section.Entries) {
+ uintX_t Tag = DE.Tag;
+ OS.write((const char *)&Tag, sizeof(uintX_t));
+ uintX_t Val = DE.Val;
+ OS.write((const char *)&Val, sizeof(uintX_t));
+ }
+}
+
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
StringRef Name = Doc.Sections[i]->Name;