[llvm] r264693 - [llvm-readobj] Support GNU style dyn-relocations

Hemant Kulkarni via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 28 19:41:49 PDT 2016


Author: khemant
Date: Mon Mar 28 21:41:49 2016
New Revision: 264693

URL: http://llvm.org/viewvc/llvm-project?rev=264693&view=rev
Log:
[llvm-readobj] Support GNU style dyn-relocations

http://reviews.llvm.org/D18534

Modified:
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=264693&r1=264692&r2=264693&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Mon Mar 28 21:41:49 2016
@@ -335,6 +335,7 @@ private:
                    StringRef StrTable, bool IsDynamic) override;
   std::string getSymbolSectionNdx(const ELFO *Obj, const Elf_Sym *Symbol,
                                   const Elf_Sym *FirstSym);
+  void printDynamicRelocation(const ELFO *Obj, Elf_Rela R, bool IsRela);
   bool checkTLSSections(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
   bool checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
   bool checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
@@ -2323,16 +2324,8 @@ void GNUStyle<ELFT>::printRelocation(con
   StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
   StringRef TargetName;
   const Elf_Sym *Sym = nullptr;
-  unsigned Bias;
-  unsigned Width;
-
-  if (ELFT::Is64Bits) {
-    Bias = 8;
-    Width = 16;
-  } else {
-    Bias = 0;
-    Width = 8;
-  }
+  unsigned Width = (ELFT::Is64Bits) ? 16 : 8;
+  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
 
   // First two fields are bit width dependent. The rest of them are after are
   // fixed width.
@@ -2371,8 +2364,19 @@ void GNUStyle<ELFT>::printRelocation(con
   Fields[4].Str = TargetName;
   for (auto &field : Fields)
     printField(field);
+  OS << Addend;
+  OS << "\n";
+}
+
+static inline void printRelocHeader(raw_ostream &OS, bool Is64, bool IsRela) {
+  if (Is64)
+    OS << "    Offset             Info             Type"
+       << "               Symbol's Value  Symbol's Name";
+  else
+    OS << " Offset     Info    Type                Sym. Value  "
+       << "Symbol's Name";
   if (IsRela)
-    OS << Addend;
+    OS << ((IsRela) ? " + Addend" : "");
   OS << "\n";
 }
 
@@ -2388,14 +2392,7 @@ template <class ELFT> void GNUStyle<ELFT
     OS << "\nRelocation section '" << Name << "' at offset 0x"
        << to_hexString(Offset, false) << " contains " << Entries
        << " entries:\n";
-    if (ELFT::Is64Bits)
-      OS << "    Offset             Info             Type"
-         << "               Symbol's Value  Symbol's Name";
-    else
-      OS << " Offset     Info    Type                Sym. Value  "
-         << "Symbol's Name";
-    OS << ((Sec.sh_type == ELF::SHT_RELA) ? " + Addend" : "") << "\n";
-
+    printRelocHeader(OS,  ELFT::Is64Bits, (Sec.sh_type == ELF::SHT_RELA));
     const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
     if (Sec.sh_type == ELF::SHT_REL) {
       for (const auto &R : Obj->rels(&Sec)) {
@@ -2828,8 +2825,99 @@ void GNUStyle<ELFT>::printProgramHeaders
 }
 
 template <class ELFT>
+void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
+                                            bool IsRela) {
+  SmallString<32> RelocName;
+  StringRef SymbolName;
+  unsigned Width = (ELFT::Is64Bits) ? 16 : 8;
+  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
+  // First two fields are bit width dependent. The rest of them are after are
+  // fixed width.
+  Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
+
+  uint32_t SymIndex = R.getSymbol(Obj->isMips64EL());
+  const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
+  Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
+  SymbolName =
+      unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable()));
+  std::string Addend = "", Info, Offset, Value;
+  Offset = to_string(format_hex_no_prefix(R.r_offset, Width));
+  Info = to_string(format_hex_no_prefix(R.r_info, Width));
+  Value = to_string(format_hex_no_prefix(Sym->getValue(), Width));
+  int64_t RelAddend = R.r_addend;
+  if (SymbolName.size() && IsRela) {
+    if (R.r_addend < 0)
+      Addend = " - ";
+    else
+      Addend = " + ";
+  }
+
+  if (!SymbolName.size() && Sym->getValue() == 0)
+    Value = "";
+
+  if (IsRela)
+    Addend += to_string(format_hex_no_prefix(std::abs(RelAddend), 1));
+
+
+  Fields[0].Str = Offset;
+  Fields[1].Str = Info;
+  Fields[2].Str = RelocName.c_str();
+  Fields[3].Str = Value;
+  Fields[4].Str = SymbolName;
+  for (auto &Field : Fields)
+    printField(Field);
+  OS << Addend;
+  OS << "\n";
+}
+
+template <class ELFT>
 void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
-  OS << "GNU style dynamic relocations not implemented!\n";
+  const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
+  const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
+  const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
+  if (DynRelaRegion.Size > 0) {
+    OS << "\n'RELA' relocation section at offset "
+       << format_hex(reinterpret_cast<const uint8_t *>(DynRelaRegion.Addr) -
+                         Obj->base(),
+                     1) << " contains " << DynRelaRegion.Size << " bytes:\n";
+    printRelocHeader(OS, ELFT::Is64Bits, true);
+    for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
+      printDynamicRelocation(Obj, Rela, true);
+  }
+  if (DynRelRegion.Size > 0) {
+    OS << "\n'REL' relocation section at offset "
+       << format_hex(reinterpret_cast<const uint8_t *>(DynRelRegion.Addr) -
+                         Obj->base(),
+                     1) << " contains " << DynRelRegion.Size << " bytes:\n";
+    printRelocHeader(OS, ELFT::Is64Bits, false);
+    for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
+      Elf_Rela Rela;
+      Rela.r_offset = Rel.r_offset;
+      Rela.r_info = Rel.r_info;
+      Rela.r_addend = 0;
+      printDynamicRelocation(Obj, Rela, false);
+    }
+  }
+  if (DynPLTRelRegion.Size) {
+    OS << "\n'PLT' relocation section at offset "
+       << format_hex(reinterpret_cast<const uint8_t *>(DynPLTRelRegion.Addr) -
+                         Obj->base(),
+                     1) << " contains " << DynPLTRelRegion.Size << " bytes:\n";
+  }
+  if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
+    printRelocHeader(OS, ELFT::Is64Bits, true);
+    for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange<Elf_Rela>())
+      printDynamicRelocation(Obj, Rela, true);
+  } else {
+    printRelocHeader(OS, ELFT::Is64Bits, false);
+    for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange<Elf_Rel>()) {
+      Elf_Rela Rela;
+      Rela.r_offset = Rel.r_offset;
+      Rela.r_info = Rel.r_info;
+      Rela.r_addend = 0;
+      printDynamicRelocation(Obj, Rela, false);
+    }
+  }
 }
 
 template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders(const ELFO *Obj) {




More information about the llvm-commits mailing list