diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1ae9372bbda..dcf116e6c21 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -88,6 +88,7 @@ protected: int64_t &Res) const; virtual error_code getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const; + virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const; private: MachOObject *MachOObj; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 331ed7caa06..0c7a518305f 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -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 &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 &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 diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 96db34f4114..a4d7cb542fb 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -952,6 +952,38 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, return object_error::success; } +error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, + bool &Result) const { + InMemoryStruct 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 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 { diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index c2480df1415..c0486defa5e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -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;