Don't iterate over all sections in the ELFFile constructor.
[oota-llvm.git] / tools / llvm-readobj / ARMEHABIPrinter.h
index b223770e1f7077d15e776b9e8b1bbe0daeddc2f2..39bcdaae6512cff11d0f7121f0397549acc9918f 100644 (file)
@@ -305,12 +305,15 @@ void OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset, size_t Length)
 
 template <typename ET>
 class PrinterContext {
-  StreamWriter &SW;
-  const object::ELFFile<ET> *ELF;
-
   typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym;
   typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
   typedef typename object::ELFFile<ET>::Elf_Rel Elf_Rel;
+  typedef typename object::ELFFile<ET>::Elf_Word Elf_Word;
+
+  StreamWriter &SW;
+  const object::ELFFile<ET> *ELF;
+  const Elf_Shdr *Symtab;
+  ArrayRef<Elf_Word> ShndxTable;
 
   static const size_t IndexTableEntrySize;
 
@@ -331,8 +334,9 @@ class PrinterContext {
   void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
 
 public:
-  PrinterContext(StreamWriter &Writer, const object::ELFFile<ET> *File)
-    : SW(Writer), ELF(File) {}
+  PrinterContext(StreamWriter &SW, const object::ELFFile<ET> *ELF,
+                 const Elf_Shdr *Symtab)
+      : SW(SW), ELF(ELF), Symtab(Symtab) {}
 
   void PrintUnwindInformation() const;
 };
@@ -344,10 +348,14 @@ template <typename ET>
 ErrorOr<StringRef>
 PrinterContext<ET>::FunctionAtAddress(unsigned Section,
                                       uint64_t Address) const {
-  for (const Elf_Sym &Sym : ELF->symbols())
+  ErrorOr<StringRef> StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
+  error(StrTableOrErr.getError());
+  StringRef StrTable = *StrTableOrErr;
+
+  for (const Elf_Sym &Sym : ELF->symbols(Symtab))
     if (Sym.st_shndx == Section && Sym.st_value == Address &&
         Sym.getType() == ELF::STT_FUNC)
-      return ELF->getSymbolName(&Sym, false);
+      return Sym.getName(StrTable);
   return readobj_error::unknown_symbol;
 }
 
@@ -364,23 +372,26 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
   /// table.
 
   for (const Elf_Shdr &Sec : ELF->sections()) {
-    if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) {
-      for (const Elf_Rel &R : ELF->rels(&Sec)) {
-        if (R.r_offset == static_cast<unsigned>(IndexTableOffset)) {
-          typename object::ELFFile<ET>::Elf_Rela RelA;
-          RelA.r_offset = R.r_offset;
-          RelA.r_info = R.r_info;
-          RelA.r_addend = 0;
-
-          std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
-              ELF->getRelocationSymbol(&Sec, &RelA);
-
-          ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second);
-          if (std::error_code EC = Ret.getError())
-            report_fatal_error(EC.message());
-          return *Ret;
-        }
-      }
+    if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex)
+      continue;
+
+    for (const Elf_Rel &R : ELF->rels(&Sec)) {
+      if (R.r_offset != static_cast<unsigned>(IndexTableOffset))
+        continue;
+
+      typename object::ELFFile<ET>::Elf_Rela RelA;
+      RelA.r_offset = R.r_offset;
+      RelA.r_info = R.r_info;
+      RelA.r_addend = 0;
+
+      std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
+        ELF->getRelocationSymbol(&Sec, &RelA);
+
+      ErrorOr<const Elf_Shdr *> Ret =
+          ELF->getSection(Symbol.second, Symbol.first, ShndxTable);
+      if (std::error_code EC = Ret.getError())
+        report_fatal_error(EC.message());
+      return *Ret;
     }
   }
   return nullptr;