Refactor the RelocVisitor::visit method
authorRenato Golin <renato.golin@linaro.org>
Wed, 24 Sep 2014 20:07:22 +0000 (20:07 +0000)
committerRenato Golin <renato.golin@linaro.org>
Wed, 24 Sep 2014 20:07:22 +0000 (20:07 +0000)
This change replaces the brittle if/else chain of string comparisons
with a switch statement on the detected target triple, removing the
need for testing arbitrary architecture names returned from
getFileFormatName, whose primary purpose seems to be for display
(user-interface) purposes. The visitor now takes a reference to the
object file, rather than its arbitrary file format name to figure out
whether the file is a 32 or 64-bit object file and what the detected
target triple is.

A set of tests have been added to help show that the refactoring processes
relocations for the same targets as the original code.

Patch by Charlie Turner.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218406 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELFObjectFile.h
include/llvm/Object/RelocVisitor.h
lib/DebugInfo/DWARFContext.cpp
test/DebugInfo/processes-relocations.ll [new file with mode: 0644]

index b2c22336b7ba03d406c23bda163566e4cfdc98e3..ed3c08f6f3276e934ff82ba789a12ede45680f34 100644 (file)
@@ -924,6 +924,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
     default:
       report_fatal_error("Invalid ELFCLASS!");
     }
+  case ELF::EM_PPC:
+    return Triple::ppc;
   case ELF::EM_PPC64:
     return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
   case ELF::EM_S390:
index 5ca245057a5512c902d35b60456ef8d989d66ab2..36852f21b513d41109e29736bac4dc3bc194bf06 100644 (file)
@@ -40,16 +40,18 @@ struct RelocToApply {
 /// @brief Base class for object file relocation visitors.
 class RelocVisitor {
 public:
-  explicit RelocVisitor(StringRef FileFormat)
-    : FileFormat(FileFormat), HasError(false) {}
+  explicit RelocVisitor(ObjectFile &Obj)
+    : ObjToVisit(Obj), HasError(false) {}
 
   // TODO: Should handle multiple applied relocations via either passing in the
   // previously computed value or just count paired relocations as a single
   // visit.
   RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
                      uint64_t Value = 0) {
-    if (FileFormat == "ELF64-x86-64") {
-      switch (RelocType) {
+    if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
+      switch (ObjToVisit.getArch()) {
+      case Triple::x86_64:
+        switch (RelocType) {
         case llvm::ELF::R_X86_64_NONE:
           return visitELF_X86_64_NONE(R);
         case llvm::ELF::R_X86_64_64:
@@ -63,113 +65,129 @@ public:
         default:
           HasError = true;
           return RelocToApply();
-      }
-    } else if (FileFormat == "ELF32-i386") {
-      switch (RelocType) {
-      case llvm::ELF::R_386_NONE:
-        return visitELF_386_NONE(R);
-      case llvm::ELF::R_386_32:
-        return visitELF_386_32(R, Value);
-      case llvm::ELF::R_386_PC32:
-        return visitELF_386_PC32(R, Value, SecAddr);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF64-ppc64") {
-      switch (RelocType) {
-      case llvm::ELF::R_PPC64_ADDR32:
-        return visitELF_PPC64_ADDR32(R, Value);
-      case llvm::ELF::R_PPC64_ADDR64:
-        return visitELF_PPC64_ADDR64(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF32-ppc") {
-      switch (RelocType) {
-      case llvm::ELF::R_PPC_ADDR32:
-        return visitELF_PPC_ADDR32(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF32-mips") {
-      switch (RelocType) {
-      case llvm::ELF::R_MIPS_32:
-        return visitELF_MIPS_32(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF64-mips") {
-      switch (RelocType) {
-      case llvm::ELF::R_MIPS_32:
-        return visitELF_MIPS_32(R, Value);
-      case llvm::ELF::R_MIPS_64:
-        return visitELF_MIPS_64(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF64-aarch64") {
-      switch (RelocType) {
-      case llvm::ELF::R_AARCH64_ABS32:
-        return visitELF_AARCH64_ABS32(R, Value);
-      case llvm::ELF::R_AARCH64_ABS64:
-        return visitELF_AARCH64_ABS64(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF64-s390") {
-      switch (RelocType) {
-      case llvm::ELF::R_390_32:
-        return visitELF_390_32(R, Value);
-      case llvm::ELF::R_390_64:
-        return visitELF_390_64(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF32-sparc") {
-      switch (RelocType) {
-      case llvm::ELF::R_SPARC_32:
-      case llvm::ELF::R_SPARC_UA32:
-        return visitELF_SPARC_32(R, Value);
-      default:
-        HasError = true;
-        return RelocToApply();
-      }
-    } else if (FileFormat == "ELF64-sparc") {
-      switch (RelocType) {
-      case llvm::ELF::R_SPARC_32:
-      case llvm::ELF::R_SPARC_UA32:
-        return visitELF_SPARCV9_32(R, Value);
-      case llvm::ELF::R_SPARC_64:
-      case llvm::ELF::R_SPARC_UA64:
-        return visitELF_SPARCV9_64(R, Value);
+        }
+      case Triple::aarch64:
+        switch (RelocType) {
+        case llvm::ELF::R_AARCH64_ABS32:
+          return visitELF_AARCH64_ABS32(R, Value);
+        case llvm::ELF::R_AARCH64_ABS64:
+          return visitELF_AARCH64_ABS64(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::mips64el:
+      case Triple::mips64:
+        switch (RelocType) {
+        case llvm::ELF::R_MIPS_32:
+          return visitELF_MIPS_32(R, Value);
+        case llvm::ELF::R_MIPS_64:
+          return visitELF_MIPS_64(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::ppc64le:
+      case Triple::ppc64:
+        switch (RelocType) {
+        case llvm::ELF::R_PPC64_ADDR32:
+          return visitELF_PPC64_ADDR32(R, Value);
+        case llvm::ELF::R_PPC64_ADDR64:
+          return visitELF_PPC64_ADDR64(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::systemz:
+        switch (RelocType) {
+        case llvm::ELF::R_390_32:
+          return visitELF_390_32(R, Value);
+        case llvm::ELF::R_390_64:
+          return visitELF_390_64(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::sparcv9:
+        switch (RelocType) {
+        case llvm::ELF::R_SPARC_32:
+        case llvm::ELF::R_SPARC_UA32:
+          return visitELF_SPARCV9_32(R, Value);
+        case llvm::ELF::R_SPARC_64:
+        case llvm::ELF::R_SPARC_UA64:
+          return visitELF_SPARCV9_64(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
       default:
         HasError = true;
         return RelocToApply();
       }
-    } else if (FileFormat == "ELF32-arm") {
-      switch (RelocType) {
+    } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file
+      switch (ObjToVisit.getArch()) {
+      case Triple::x86:
+        switch (RelocType) {
+        case llvm::ELF::R_386_NONE:
+          return visitELF_386_NONE(R);
+        case llvm::ELF::R_386_32:
+          return visitELF_386_32(R, Value);
+        case llvm::ELF::R_386_PC32:
+          return visitELF_386_PC32(R, Value, SecAddr);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::ppc:
+        switch (RelocType) {
+        case llvm::ELF::R_PPC_ADDR32:
+          return visitELF_PPC_ADDR32(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::arm:
+      case Triple::armeb:
+        switch (RelocType) {
+        default:
+          HasError = true;
+          return RelocToApply();
+        case llvm::ELF::R_ARM_ABS32:
+          return visitELF_ARM_ABS32(R, Value);
+        }
+      case Triple::hexagon:
+        llvm_unreachable("Unimplemented");
+      case Triple::mipsel:
+      case Triple::mips:
+        switch (RelocType) {
+        case llvm::ELF::R_MIPS_32:
+          return visitELF_MIPS_32(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
+      case Triple::sparc:
+        switch (RelocType) {
+        case llvm::ELF::R_SPARC_32:
+        case llvm::ELF::R_SPARC_UA32:
+          return visitELF_SPARC_32(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+        }
       default:
         HasError = true;
         return RelocToApply();
-      case llvm::ELF::R_ARM_ABS32:
-        return visitELF_ARM_ABS32(R, Value);
       }
+    } else {
+      report_fatal_error("Invalid word size in object file");
     }
-    HasError = true;
-    return RelocToApply();
   }
 
   bool error() { return HasError; }
 
 private:
-  StringRef FileFormat;
+  ObjectFile &ObjToVisit;
   bool HasError;
 
   int64_t getAddend32LE(RelocationRef R) {
index 1be0691a1d974bc9689265b51d78096b3f4e7f50..39e6f4665b296ebc03567e0377836f4619c0fe25 100644 (file)
@@ -667,7 +667,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
           Sym->getAddress(SymAddr);
         }
 
-        object::RelocVisitor V(Obj.getFileFormatName());
+        object::RelocVisitor V(Obj);
         // The section address is always 0 for debug sections.
         object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
         if (V.error()) {
diff --git a/test/DebugInfo/processes-relocations.ll b/test/DebugInfo/processes-relocations.ll
new file mode 100644 (file)
index 0000000..ba7e481
--- /dev/null
@@ -0,0 +1,18 @@
+; Make sure that for each supported architecture in RelocVisitor::visit,
+; the visitor does compute the relocation. This should test all archs that
+; have buildbots. We can't set all archs, since some bots don't build all
+; back-ends.
+; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump - 2>&1 | FileCheck %s
+
+; CHECK-NOT: failed to compute relocation
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!5}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.6.0 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !2, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [/a/empty.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"empty.c", metadata !"/a"}
+!2 = metadata !{}
+!3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
+!5 = metadata !{metadata !"clang version 3.6.0 "}