[llvm-objdump] - Move getRelocationValueString and dependenices out of the llvm-objdump.cpp

getRelocationValueString is a dispatcher function that calls the
corresponding ELF/COFF/Wasm/MachO implementations
that currently live in the llvm-objdump.cpp file.

These implementations better be moved to ELFDump.cpp,
COFFDump.cpp and other corresponding files, to move platform specific
implementation out from the common logic.

The patch does that. Also, I had to move ToolSectionFilter helper
and SectionFilterIterator, SectionFilter to a header to make them
available across the objdump code.

Differential revision: https://reviews.llvm.org/D56842

llvm-svn: 351545
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index b17a15a..3cece39 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm-objdump.h"
+#include "llvm/Demangle/Demangle.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MathExtras.h"
@@ -52,6 +53,87 @@
 }
 
 template <class ELFT>
+static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
+                                                const RelocationRef &RelRef,
+                                                SmallVectorImpl<char> &Result) {
+  typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
+  typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
+  typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
+
+  const ELFFile<ELFT> &EF = *Obj->getELFFile();
+  DataRefImpl Rel = RelRef.getRawDataRefImpl();
+  auto SecOrErr = EF.getSection(Rel.d.a);
+  if (!SecOrErr)
+    return errorToErrorCode(SecOrErr.takeError());
+
+  int64_t Addend = 0;
+  // If there is no Symbol associated with the relocation, we set the undef
+  // boolean value to 'true'. This will prevent us from calling functions that
+  // requires the relocation to be associated with a symbol.
+  //
+  // In SHT_REL case we would need to read the addend from section data.
+  // GNU objdump does not do that and we just follow for simplicity atm.
+  bool Undef = false;
+  if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
+    const Elf_Rela *ERela = Obj->getRela(Rel);
+    Addend = ERela->r_addend;
+    Undef = ERela->getSymbol(false) == 0;
+  } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
+    return object_error::parse_failed;
+  }
+
+  // Default scheme is to print Target, as well as "+ <addend>" for nonzero
+  // addend. Should be acceptable for all normal purposes.
+  std::string FmtBuf;
+  raw_string_ostream Fmt(FmtBuf);
+
+  if (!Undef) {
+    symbol_iterator SI = RelRef.getSymbol();
+    const Elf_Sym *Sym = Obj->getSymbol(SI->getRawDataRefImpl());
+    if (Sym->getType() == ELF::STT_SECTION) {
+      Expected<section_iterator> SymSI = SI->getSection();
+      if (!SymSI)
+        return errorToErrorCode(SymSI.takeError());
+      const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
+      auto SecName = EF.getSectionName(SymSec);
+      if (!SecName)
+        return errorToErrorCode(SecName.takeError());
+      Fmt << *SecName;
+    } else {
+      Expected<StringRef> SymName = SI->getName();
+      if (!SymName)
+        return errorToErrorCode(SymName.takeError());
+      if (Demangle)
+        Fmt << demangle(*SymName);
+      else
+        Fmt << *SymName;
+    }
+  } else {
+    Fmt << "*ABS*";
+  }
+
+  if (Addend != 0)
+    Fmt << (Addend < 0 ? "" : "+") << Addend;
+  Fmt.flush();
+  Result.append(FmtBuf.begin(), FmtBuf.end());
+  return std::error_code();
+}
+
+std::error_code
+llvm::getELFRelocationValueString(const ELFObjectFileBase *Obj,
+                                  const RelocationRef &Rel,
+                                  SmallVectorImpl<char> &Result) {
+  if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
+    return getRelocationValueString(ELF32LE, Rel, Result);
+  if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
+    return getRelocationValueString(ELF64LE, Rel, Result);
+  if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
+    return getRelocationValueString(ELF32BE, Rel, Result);
+  auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
+  return getRelocationValueString(ELF64BE, Rel, Result);
+}
+
+template <class ELFT>
 void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
   auto ProgramHeaderOrError = Elf->program_headers();
   if (!ProgramHeaderOrError)