[llvm] 22ebf08 - [llvm-readobj] - Refactor the code that dumps relocations.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 16 04:05:52 PST 2020


Author: Georgii Rymar
Date: 2020-02-16T14:39:24+03:00
New Revision: 22ebf08006a5b17a4ff6aed09ec5b72867338458

URL: https://github.com/llvm/llvm-project/commit/22ebf08006a5b17a4ff6aed09ec5b72867338458
DIFF: https://github.com/llvm/llvm-project/commit/22ebf08006a5b17a4ff6aed09ec5b72867338458.diff

LOG: [llvm-readobj] - Refactor the code that dumps relocations.

The current code has following issues:
1) It has a duplicated logic part.
2) This logic relies on unwrapOrError calls, but if we want to convert
   them to warnings, we will need to change all of them what is hard to do
   because of the duplication.

In this patch I've created a new method that returns Expected<> what allows
now to catch all errors in a single place and remove the code duplication.

Note: this change is itself a refactor NFC. It does not change the current logic
anyhow. It prepares the code for the follow-up(s).

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 4dd4e4129c24..ec24c3ef706b 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -362,6 +362,9 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   getVersionDefinitions(const Elf_Shdr *Sec) const;
   Expected<std::vector<VerNeed>>
   getVersionDependencies(const Elf_Shdr *Sec) const;
+
+  Expected<std::pair<const Elf_Sym *, std::string>>
+  getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const;
 };
 
 template <class ELFT>
@@ -1050,6 +1053,41 @@ Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym *Sym,
   return this->getSymbolVersionByIndex(Versym->vs_index, IsDefault);
 }
 
+template <typename ELFT>
+Expected<std::pair<const typename ELFT::Sym *, std::string>>
+ELFDumper<ELFT>::getRelocationTarget(const Elf_Shdr *SymTab,
+                                     const Elf_Rela &R) const {
+  const ELFFile<ELFT> *Obj = ObjF->getELFFile();
+  Expected<const Elf_Sym *> SymOrErr = Obj->getRelocationSymbol(&R, SymTab);
+  if (!SymOrErr)
+    return SymOrErr.takeError();
+  const Elf_Sym *Sym = *SymOrErr;
+  if (!Sym)
+    return std::make_pair(nullptr, "");
+
+  // The st_name field of a STT_SECTION is usually 0 (empty string).
+  // This code block returns the section name.
+  if (Sym->getType() == ELF::STT_SECTION) {
+    Expected<const Elf_Shdr *> SecOrErr =
+        Obj->getSection(Sym, SymTab, ShndxTable);
+    if (!SecOrErr)
+      return SecOrErr.takeError();
+
+    Expected<StringRef> NameOrErr = Obj->getSectionName(*SecOrErr);
+    if (!NameOrErr)
+      return NameOrErr.takeError();
+    return std::make_pair(Sym, NameOrErr->str());
+  }
+
+  Expected<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*SymTab);
+  if (!StrTableOrErr)
+    return StrTableOrErr.takeError();
+
+  std::string SymbolName =
+      getFullSymbolName(Sym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM);
+  return std::make_pair(Sym, SymbolName);
+}
+
 static std::string maybeDemangle(StringRef Name) {
   return opts::Demangle ? demangle(std::string(Name)) : Name.str();
 }
@@ -3281,22 +3319,11 @@ template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
 template <class ELFT>
 void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
                                      const Elf_Rela &R, bool IsRela) {
-  const Elf_Sym *Sym =
-      unwrapOrError(this->FileName, Obj->getRelocationSymbol(&R, SymTab));
-  std::string TargetName;
-  if (Sym && Sym->getType() == ELF::STT_SECTION) {
-    const Elf_Shdr *Sec = unwrapOrError(
-        this->FileName,
-        Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
-    TargetName =
-        std::string(unwrapOrError(this->FileName, Obj->getSectionName(Sec)));
-  } else if (Sym) {
-    StringRef StrTable =
-        unwrapOrError(this->FileName, Obj->getStringTableForSymtab(*SymTab));
-    TargetName = this->dumper()->getFullSymbolName(
-        Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */);
-  }
-  printRelocation(Obj, Sym, TargetName, R, IsRela);
+  const typename ELFT::Sym *Sym;
+  std::string Name;
+  std::tie(Sym, Name) = unwrapOrError(
+      this->FileName, this->dumper()->getRelocationTarget(SymTab, R));
+  printRelocation(Obj, Sym, Name, R, IsRela);
 }
 
 template <class ELFT>
@@ -5709,23 +5736,13 @@ void LLVMStyle<ELFT>::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) {
 template <class ELFT>
 void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
                                       const Elf_Shdr *SymTab) {
+  std::string TargetName =
+      unwrapOrError(this->FileName,
+                    this->dumper()->getRelocationTarget(SymTab, Rel))
+          .second;
+
   SmallString<32> RelocName;
   Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
-  std::string TargetName;
-  const Elf_Sym *Sym =
-      unwrapOrError(this->FileName, Obj->getRelocationSymbol(&Rel, SymTab));
-  if (Sym && Sym->getType() == ELF::STT_SECTION) {
-    const Elf_Shdr *Sec = unwrapOrError(
-        this->FileName,
-        Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
-    TargetName =
-        std::string(unwrapOrError(this->FileName, Obj->getSectionName(Sec)));
-  } else if (Sym) {
-    StringRef StrTable =
-        unwrapOrError(this->FileName, Obj->getStringTableForSymtab(*SymTab));
-    TargetName = this->dumper()->getFullSymbolName(
-        Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */);
-  }
 
   if (opts::ExpandRelocs) {
     DictScope Group(W, "Relocation");


        


More information about the llvm-commits mailing list