X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FELF.h;h=eed9bdd69e92de63838e10d1403193e7ea7d1db2;hb=0377a22491ed19ba2d9a6fc0ed34c901a3f56faa;hp=509355b105d92ad1e226f7120eeea3d41c195faf;hpb=96d9043a78bebbb18881632cd3bcb2f61a84d17a;p=oota-llvm.git diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 509355b105d..eed9bdd69e9 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -140,10 +140,7 @@ public: typedef Elf_Vernaux_Impl Elf_Vernaux; typedef Elf_Versym_Impl Elf_Versym; typedef Elf_Hash_Impl Elf_Hash; - typedef ELFEntityIterator Elf_Dyn_Iter; - typedef iterator_range Elf_Dyn_Range; - typedef ELFEntityIterator Elf_Rela_Iter; - typedef ELFEntityIterator Elf_Rel_Iter; + typedef iterator_range Elf_Dyn_Range; typedef iterator_range Elf_Shdr_Range; /// \brief Archive files are 2 byte aligned, so we need this for @@ -284,12 +281,10 @@ public: return make_range(symbol_begin(), symbol_end()); } - Elf_Dyn_Iter dynamic_table_begin() const; - /// \param NULLEnd use one past the first DT_NULL entry as the end instead of - /// the section size. - Elf_Dyn_Iter dynamic_table_end(bool NULLEnd = false) const; - Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const { - return make_range(dynamic_table_begin(), dynamic_table_end(NULLEnd)); + const Elf_Dyn *dynamic_table_begin() const; + const Elf_Dyn *dynamic_table_end() const; + Elf_Dyn_Range dynamic_table() const { + return make_range(dynamic_table_begin(), dynamic_table_end()); } const Elf_Sym *dynamic_symbol_begin() const { @@ -311,40 +306,58 @@ public: return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); } - Elf_Rela_Iter dyn_rela_begin() const { - if (DynRelaRegion.Addr) - return Elf_Rela_Iter(DynRelaRegion.EntSize, - (const char *)DynRelaRegion.Addr); - return Elf_Rela_Iter(0, nullptr); + const Elf_Rela *dyn_rela_begin() const { + if (DynRelaRegion.Size && DynRelaRegion.EntSize != sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(DynRelaRegion.Addr); } - Elf_Rela_Iter dyn_rela_end() const { - if (DynRelaRegion.Addr) - return Elf_Rela_Iter( - DynRelaRegion.EntSize, - (const char *)DynRelaRegion.Addr + DynRelaRegion.Size); - return Elf_Rela_Iter(0, nullptr); + const Elf_Rela *dyn_rela_end() const { + uint64_t Size = DynRelaRegion.Size; + if (Size % sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation table size"); + return dyn_rela_begin() + Size / sizeof(Elf_Rela); } - Elf_Rela_Iter rela_begin(const Elf_Shdr *sec) const { - return Elf_Rela_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset)); + typedef iterator_range Elf_Rela_Range; + + Elf_Rela_Range dyn_relas() const { + return make_range(dyn_rela_begin(), dyn_rela_end()); + } + + const Elf_Rela *rela_begin(const Elf_Shdr *sec) const { + if (sec->sh_entsize != sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(base() + sec->sh_offset); + } + + const Elf_Rela *rela_end(const Elf_Shdr *sec) const { + uint64_t Size = sec->sh_size; + if (Size % sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation table size"); + return rela_begin(sec) + Size / sizeof(Elf_Rela); + } + + Elf_Rela_Range relas(const Elf_Shdr *Sec) const { + return make_range(rela_begin(Sec), rela_end(Sec)); } - Elf_Rela_Iter rela_end(const Elf_Shdr *sec) const { - return Elf_Rela_Iter( - sec->sh_entsize, - (const char *)(base() + sec->sh_offset + sec->sh_size)); + const Elf_Rel *rel_begin(const Elf_Shdr *sec) const { + if (sec->sh_entsize != sizeof(Elf_Rel)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(base() + sec->sh_offset); } - Elf_Rel_Iter rel_begin(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset)); + const Elf_Rel *rel_end(const Elf_Shdr *sec) const { + uint64_t Size = sec->sh_size; + if (Size % sizeof(Elf_Rel)) + report_fatal_error("Invalid relocation table size"); + return rel_begin(sec) + Size / sizeof(Elf_Rel); } - Elf_Rel_Iter rel_end(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset + sec->sh_size)); + typedef iterator_range Elf_Rel_Range; + Elf_Rel_Range rels(const Elf_Shdr *Sec) const { + return make_range(rel_begin(Sec), rel_end(Sec)); } /// \brief Iterate over program header table. @@ -652,16 +665,6 @@ ELFFile::ELFFile(StringRef Object, std::error_code &EC) DotDynSymSec = &Sec; break; } - case ELF::SHT_DYNAMIC: - if (DynamicRegion.Addr) { - // More than one .dynamic! - EC = object_error::parse_failed; - return; - } - DynamicRegion.Addr = base() + Sec.sh_offset; - DynamicRegion.Size = Sec.sh_size; - DynamicRegion.EntSize = Sec.sh_entsize; - break; case ELF::SHT_GNU_versym: if (dot_gnu_version_sec != nullptr) { // More than one .gnu.version section! @@ -726,7 +729,6 @@ template void ELFFile::scanDynamicTable() { if (Phdr.p_type == ELF::PT_DYNAMIC) { DynamicRegion.Addr = base() + Phdr.p_offset; DynamicRegion.Size = Phdr.p_filesz; - DynamicRegion.EntSize = sizeof(Elf_Dyn); continue; } if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0) @@ -747,32 +749,31 @@ template void ELFFile::scanDynamicTable() { return this->base() + Phdr.p_offset + Delta; }; - for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end(); - DynI != DynE; ++DynI) { - switch (DynI->d_tag) { + for (const Elf_Dyn &Dyn : dynamic_table()) { + switch (Dyn.d_tag) { case ELF::DT_HASH: if (HashTable) continue; HashTable = - reinterpret_cast(toMappedAddr(DynI->getPtr())); + reinterpret_cast(toMappedAddr(Dyn.getPtr())); break; case ELF::DT_STRTAB: if (!DynStrRegion.Addr) - DynStrRegion.Addr = toMappedAddr(DynI->getPtr()); + DynStrRegion.Addr = toMappedAddr(Dyn.getPtr()); break; case ELF::DT_STRSZ: if (!DynStrRegion.Size) - DynStrRegion.Size = DynI->getVal(); + DynStrRegion.Size = Dyn.getVal(); break; case ELF::DT_RELA: if (!DynRelaRegion.Addr) - DynRelaRegion.Addr = toMappedAddr(DynI->getPtr()); + DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr()); break; case ELF::DT_RELASZ: - DynRelaRegion.Size = DynI->getVal(); + DynRelaRegion.Size = Dyn.getVal(); break; case ELF::DT_RELAENT: - DynRelaRegion.EntSize = DynI->getVal(); + DynRelaRegion.EntSize = Dyn.getVal(); } } } @@ -808,33 +809,19 @@ const typename ELFFile::Elf_Sym *ELFFile::symbol_end() const { } template -typename ELFFile::Elf_Dyn_Iter +const typename ELFFile::Elf_Dyn * ELFFile::dynamic_table_begin() const { - if (DynamicRegion.Addr) - return Elf_Dyn_Iter(DynamicRegion.EntSize, - (const char *)DynamicRegion.Addr); - return Elf_Dyn_Iter(0, nullptr); + return reinterpret_cast(DynamicRegion.Addr); } template -typename ELFFile::Elf_Dyn_Iter -ELFFile::dynamic_table_end(bool NULLEnd) const { - if (!DynamicRegion.Addr) - return Elf_Dyn_Iter(0, nullptr); - Elf_Dyn_Iter Ret(DynamicRegion.EntSize, - (const char *)DynamicRegion.Addr + DynamicRegion.Size); - - if (NULLEnd) { - Elf_Dyn_Iter Start = dynamic_table_begin(); - while (Start != Ret && Start->getTag() != ELF::DT_NULL) - ++Start; - - // Include the DT_NULL. - if (Start != Ret) - ++Start; - Ret = Start; - } - return Ret; +const typename ELFFile::Elf_Dyn * +ELFFile::dynamic_table_end() const { + uint64_t Size = DynamicRegion.Size; + if (Size % sizeof(Elf_Dyn)) + report_fatal_error("Invalid dynamic table size"); + + return dynamic_table_begin() + Size / sizeof(Elf_Dyn); } template