Add support for the notion of "hidden" relocations. On MachO, these are relocation...
authorOwen Anderson <resistor@mac.com>
Tue, 25 Oct 2011 20:35:53 +0000 (20:35 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 25 Oct 2011 20:35:53 +0000 (20:35 +0000)
I'm not familiar enough with ELF or COFF to know if they should have any relocations marked hidden.

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

include/llvm/Object/MachO.h
include/llvm/Object/ObjectFile.h
lib/Object/MachOObjectFile.cpp
tools/llvm-objdump/llvm-objdump.cpp

index 1ae9372bbdab8e6410257c3f695a6c63e887ad18..dcf116e6c211b629b2a86c48d2c8c77e98f22eb4 100644 (file)
@@ -88,6 +88,7 @@ protected:
                                                  int64_t &Res) const;
   virtual error_code getRelocationValueString(DataRefImpl Rel,
                                            SmallVectorImpl<char> &Result) const;
+  virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
 
 private:
   MachOObject *MachOObj;
index 331ed7caa063596d4ce1babdf7c18e76affff99b..0c7a518305f4633f0112718afdfce8cf3be5a9bd 100644 (file)
@@ -101,6 +101,11 @@ public:
   error_code getSymbol(SymbolRef &Result) const;
   error_code getType(uint32_t &Result) const;
 
+  /// @brief Indicates whether this relocation should hidden when listing
+  /// relocations, usually because it is the trailing part of a multipart
+  /// relocation that will be printed as part of the leading relocation.
+  error_code getHidden(bool &Result) const;
+
   /// @brief Get a string that represents the type of this relocation.
   ///
   /// This is for display purposes only.
@@ -286,6 +291,10 @@ protected:
                                                  int64_t &Res) const = 0;
   virtual error_code getRelocationValueString(DataRefImpl Rel,
                                        SmallVectorImpl<char> &Result) const = 0;
+  virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
+    Result = false;
+    return object_error::success;
+  }
 
 public:
 
@@ -483,6 +492,10 @@ inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
   return OwningObject->getRelocationValueString(RelocationPimpl, Result);
 }
 
+inline error_code RelocationRef::getHidden(bool &Result) const {
+  return OwningObject->getRelocationHidden(RelocationPimpl, Result);
+}
+
 } // end namespace object
 } // end namespace llvm
 
index 96db34f4114892b0d667d4f197fa680ecd97fa4a..a4d7cb542fb764542543fbbd0e245322acaead31 100644 (file)
@@ -952,6 +952,38 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
   return object_error::success;
 }
 
+error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
+                                                bool &Result) const {
+  InMemoryStruct<macho::RelocationEntry> RE;
+  getRelocation(Rel, RE);
+
+  unsigned Type = (RE->Word1 >> 28) & 0xF;
+  unsigned Arch = getArch();
+
+  Result = false;
+
+  // On arches that use the generic relocations, GENERIC_RELOC_PAIR
+  // is always hidden.
+  if (Arch == Triple::x86 || Arch == Triple::arm) {
+    if (Type == 1) Result = true;
+  } else if (Arch == Triple::x86_64) {
+    // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
+    // an X864_64_RELOC_SUBTRACTOR.
+    if (Type == 0 && Rel.d.a > 0) {
+      DataRefImpl RelPrev = Rel;
+      RelPrev.d.a--;
+      InMemoryStruct<macho::RelocationEntry> REPrev;
+      getRelocation(RelPrev, REPrev);
+
+      unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
+
+      if (PrevType == 5) Result = true;
+    }
+  }
+
+  return object_error::success;
+}
+
 /*===-- Miscellaneous -----------------------------------------------------===*/
 
 uint8_t MachOObjectFile::getBytesInAddress() const {
index c2480df14157354ae32ffc01f853aab9fa225849..c0486defa5e759b3d8de6376a612e6c4cb16d1e9 100644 (file)
@@ -301,9 +301,15 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
 
         // Print relocation for instruction.
         while (rel_cur != rel_end) {
+          bool hidden = false;
           uint64_t addr;
           SmallString<16> name;
           SmallString<32> val;
+
+          // If this relocation is hidden, skip it.
+          if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
+          if (hidden) goto skip_print_rel;
+
           if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
           // Stop when rel_cur's address is past the current instruction.
           if (addr >= Index + Size) break;
@@ -336,9 +342,12 @@ static void PrintRelocations(const ObjectFile *o) {
                              ri != re; ri.increment(ec)) {
       if (error(ec)) return;
 
+      bool hidden;
       uint64_t address;
       SmallString<32> relocname;
       SmallString<32> valuestr;
+      if (error(ri->getHidden(hidden))) continue;
+      if (hidden) continue;
       if (error(ri->getTypeName(relocname))) continue;
       if (error(ri->getAddress(address))) continue;
       if (error(ri->getValueString(valuestr))) continue;