summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump/ELFDump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objdump/ELFDump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/ELFDump.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index b17a15a0d8f..3cece3963d2 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 @@ Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> *Elf) {
}
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)
OpenPOWER on IntegriCloud