[llvm-commits] [llvm] r142852 - /llvm/trunk/lib/Object/MachOObjectFile.cpp

Owen Anderson resistor at mac.com
Mon Oct 24 14:44:00 PDT 2011


Author: resistor
Date: Mon Oct 24 16:44:00 2011
New Revision: 142852

URL: http://llvm.org/viewvc/llvm-project?rev=142852&view=rev
Log:
Get relocation parsing/dumping to a mostly-working state for MachO files.

Modified:
    llvm/trunk/lib/Object/MachOObjectFile.cpp

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=142852&r1=142851&r2=142852&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Mon Oct 24 16:44:00 2011
@@ -16,6 +16,7 @@
 #include "llvm/Object/MachO.h"
 #include "llvm/Object/MachOFormat.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
 
 #include <cctype>
 #include <cstring>
@@ -596,15 +597,15 @@
 }
 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
                                                  uint64_t &Res) const {
-  const uint8_t* sectAddress = base();
+  const uint8_t* sectAddress = 0;
   if (MachOObj->is64Bit()) {
     InMemoryStruct<macho::Section64> Sect;
     getSection64(Sections[Rel.d.b], Sect);
-    sectAddress += Sect->Offset;
+    sectAddress += Sect->Address;
   } else {
     InMemoryStruct<macho::Section> Sect;
     getSection(Sections[Rel.d.b], Sect);
-    sectAddress += Sect->Offset;
+    sectAddress += Sect->Address;
   }
   InMemoryStruct<macho::RelocationEntry> RE;
   getRelocation(Rel, RE);
@@ -641,7 +642,88 @@
 }
 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
                                           SmallVectorImpl<char> &Result) const {
-  StringRef res = "Unknown";
+  // TODO: Support scattered relocations.
+  StringRef res;
+  InMemoryStruct<macho::RelocationEntry> RE;
+  getRelocation(Rel, RE);
+  unsigned r_type = (RE->Word1 >> 28) & 0xF;
+
+  unsigned Arch = getArch();
+  switch (Arch) {
+    case Triple::x86: {
+      const char* Table[] =  {
+        "GENERIC_RELOC_VANILLA",
+        "GENERIC_RELOC_PAIR",
+        "GENERIC_RELOC_SECTDIFF",
+        "GENERIC_RELOC_LOCAL_SECTDIFF",
+        "GENERIC_RELOC_PB_LA_PTR" };
+
+      if (r_type > 4)
+        res = "Unknown";
+      else
+        res = Table[r_type];
+      break;
+    }
+    case Triple::x86_64: {
+      const char* Table[] =  {
+        "X86_64_RELOC_BRANCH",
+        "X86_64_RELOC_GOT_LOAD",
+        "X86_64_RELOC_GOT",
+        "X86_64_RELOC_SIGNED",
+        "X86_64_RELOC_UNSIGNED",
+        "X86_64_RELOC_SUBTRACTOR" };
+
+      if (r_type > 5)
+        res = "Unknown";
+      else
+        res = Table[r_type];
+      break;
+    }
+    case Triple::arm: {
+      const char* Table[] =  {
+        "ARM_RELOC_VANILLA",
+        "ARM_RELOC_PAIR",
+        "ARM_RELOC_SECTDIFF",
+        "ARM_RELOC_LOCAL_SECTDIFF",
+        "ARM_RELOC_PB_LA_PTR",
+        "ARM_RELOC_BR24",
+        "ARM_THUMB_RELOC_BR22",
+        "ARM_THUMB_32BIT_BRANCH",
+        "ARM_RELOC_HALF",
+        "ARM_RELOC_HALF_SECTDIFF" };
+
+      if (r_type > 9)
+        res = "Unknown";
+      else
+        res = Table[r_type];
+      break;
+    }
+    case Triple::ppc: {
+      const char* Table[] =  {
+        "PPC_RELOC_VANILLA",
+        "PPC_RELOC_PAIR",
+        "PPC_RELOC_BR14",
+        "PPC_RELOC_BR24",
+        "PPC_RELOC_HI16",
+        "PPC_RELOC_LO16",
+        "PPC_RELOC_HA16",
+        "PPC_RELOC_LO14",
+        "PPC_RELOC_SECTDIFF",
+        "PPC_RELOC_PB_LA_PTR",
+        "PPC_RELOC_HI16_SECTDIFF",
+        "PPC_RELOC_LO16_SECTDIFF",
+        "PPC_RELOC_HA16_SECTDIFF",
+        "PPC_RELOC_JBSR",
+        "PPC_RELOC_LO14_SECTDIFF",
+        "PPC_RELOC_LOCAL_SECTDIFF" };
+
+      res = Table[r_type];
+      break;
+    }
+    case Triple::UnknownArch:
+      res = "Unknown";
+      break;
+  }
   Result.append(res.begin(), res.end());
   return object_error::success;
 }
@@ -668,8 +750,47 @@
 }
 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
                                           SmallVectorImpl<char> &Result) const {
-  StringRef res = "Unknown";
-  Result.append(res.begin(), res.end());
+  InMemoryStruct<macho::RelocationEntry> RE;
+  getRelocation(Rel, RE);
+
+  std::string fmtbuf;
+  raw_string_ostream fmt(fmtbuf);
+
+  bool isExtern = (RE->Word1 >> 27) & 1;
+  if (isExtern) {
+    uint32_t Val = (RE->Word1 & 0xFFFFFF);
+    symbol_iterator SI = begin_symbols();
+
+    error_code ec;
+    while (Val--) {
+      SI.increment(ec);
+      if (ec) report_fatal_error(ec.message());
+    }
+
+    StringRef SymName;
+    if ((ec = SI->getName(SymName)))
+      report_fatal_error(ec.message());
+
+    fmt << SymName;
+  } else {
+    uint32_t Val = (RE->Word1 & 0xFFFFFF);
+    section_iterator SI = begin_sections();
+
+    error_code ec;
+    while (Val--) {
+      SI.increment(ec);
+      if (ec) report_fatal_error(ec.message());
+    }
+
+    StringRef SectName;
+    if ((ec = SI->getName(SectName)))
+      report_fatal_error(ec.message());
+
+    fmt << SectName;
+  }
+
+  fmt.flush();
+  Result.append(fmtbuf.begin(), fmtbuf.end());
   return object_error::success;
 }
 





More information about the llvm-commits mailing list