[lld] [llvm] [llvm-readelf] Print more information for RELR (PR #89162)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 18 01:45:32 PDT 2024


================
@@ -3926,13 +3930,85 @@ template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
     OS << "\nRelocation section '" << Name << "' at offset 0x"
        << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum
        << " entries:\n";
-    printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
-    this->printRelocationsHelper(Sec);
+
+    if (PrintAsRelr(Sec)) {
+      printRelr(Sec);
+    } else {
+      printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
+      this->printRelocationsHelper(Sec);
+    }
   }
   if (!HasRelocSections)
     OS << "\nThere are no relocations in this file.\n";
 }
 
+template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) {
+  Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec);
+  if (!RangeOrErr) {
+    this->reportUniqueWarning("unable to read relocations from " +
+                              this->describe(Sec) + ": " +
+                              toString(RangeOrErr.takeError()));
+    return;
+  }
+  if (ELFT::Is64Bits)
+    OS << "Index: Entry            Address           Symbolic Address\n";
+  else
+    OS << "Index: Entry    Address   Symbolic Address\n";
+
+  SmallVector<std::pair<uint64_t, std::string>, 0> Syms;
+  if (this->DotSymtabSec) {
+    if (auto SymsOrErr = this->Obj.symbols(this->DotSymtabSec)) {
+      StringRef Strtab =
+          unwrapOrError(this->FileName,
+                        this->Obj.getStringTableForSymtab(*this->DotSymtabSec));
+      for (auto [I, Sym] : enumerate(*SymsOrErr)) {
+        Syms.emplace_back(Sym.st_value,
+                          this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(),
+                                                  Strtab, false));
+      }
+    } else {
+      this->reportUniqueWarning(SymsOrErr.takeError());
+    }
+  }
+  llvm::stable_sort(Syms);
+
+  typename ELFT::uint Base = 0;
+  size_t I = 0;
+  auto Print = [&](uint64_t Where) {
+    OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8);
+    for (; I < Syms.size() && Syms[I].first <= Where; ++I)
+      ;
+    if (I) {
+      OS << "  " << Syms[I - 1].second;
+      if (Syms[I - 1].first < Where)
+        OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first);
+    }
+    OS << '\n';
+  };
+  for (auto [I, R] : enumerate(*RangeOrErr)) {
----------------
jh7370 wrote:

It's a bit weird using `I` again here, given that it's declared further up. I'm slightly surprised that's even legal, but regardless, it doesn't help readability of this code, so should probably be renamed. Personally, I'd consider changing `R` too, since it's not necessarily clear whether this is a "relocation" or something else.

https://github.com/llvm/llvm-project/pull/89162


More information about the llvm-commits mailing list