Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -276,7 +276,8 @@ bool isBerkeleyData(DataRefImpl Sec) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; - std::vector dynamic_relocation_sections() const override; + Expected> + dynamic_relocation_sections() const override; section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; @@ -749,29 +750,38 @@ } template -std::vector +Expected> ELFObjectFile::dynamic_relocation_sections() const { + if (getEType() != ELF::ET_DYN && getEType() != ELF::ET_EXEC) + return createError("EType is not ET_DYN or ET_EXEC"); + std::vector Res; std::vector Offsets; auto SectionsOrErr = EF.sections(); - if (!SectionsOrErr) - return Res; - - for (const Elf_Shdr &Sec : *SectionsOrErr) { - if (Sec.sh_type != ELF::SHT_DYNAMIC) - continue; - Elf_Dyn *Dynamic = - reinterpret_cast((uintptr_t)base() + Sec.sh_offset); - for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) { - if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA || - Dynamic->d_tag == ELF::DT_JMPREL) { - Offsets.push_back(Dynamic->d_un.d_val); - } + if (auto Err = SectionsOrErr.takeError()) + return Err; + auto &Sections = *SectionsOrErr; + + auto Sec = + std::find_if(Sections.begin(), Sections.end(), [](const Elf_Shdr &Sec) { + return Sec.sh_type == ELF::SHT_DYNAMIC; + }); + + if (Sec == Sections.end()) + return createError("No DYNAMIC section found"); + + Elf_Dyn *Dynamic = + reinterpret_cast((uintptr_t)base() + Sec->sh_offset); + for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) { + if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA || + Dynamic->d_tag == ELF::DT_JMPREL) { + Offsets.push_back(Dynamic->d_un.d_val); } } + for (const Elf_Shdr &Sec : *SectionsOrErr) { - if (is_contained(Offsets, Sec.sh_offset)) + if (is_contained(Offsets, Sec.sh_addr)) Res.emplace_back(toDRI(&Sec), this); } return Res; Index: include/llvm/Object/ObjectFile.h =================================================================== --- include/llvm/Object/ObjectFile.h +++ include/llvm/Object/ObjectFile.h @@ -299,7 +299,8 @@ return getCommonSymbolSizeImpl(Symb); } - virtual std::vector dynamic_relocation_sections() const { + virtual Expected> + dynamic_relocation_sections() const { return std::vector(); } Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -1526,22 +1526,22 @@ void llvm::printDynamicRelocations(const ObjectFile *Obj) { // For the moment, this option is for ELF only - if (!Obj->isELF()) + const auto *Elf = dyn_cast(Obj); + if (!Elf) return; - const auto *Elf = dyn_cast(Obj); - if (!Elf || Elf->getEType() != ELF::ET_DYN) { + auto DynRelSecs = Elf->dynamic_relocation_sections(); + if (auto Err = DynRelSecs.takeError()) { error("not a dynamic object"); return; } - std::vector DynRelSec = Obj->dynamic_relocation_sections(); - if (DynRelSec.empty()) + if (DynRelSecs->empty()) return; outs() << "DYNAMIC RELOCATION RECORDS\n"; StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64; - for (const SectionRef &Section : DynRelSec) { + for (const SectionRef &Section : *DynRelSecs) { if (Section.relocation_begin() == Section.relocation_end()) continue; for (const RelocationRef &Reloc : Section.relocations()) {