summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-10-25 20:35:53 +0000
committerOwen Anderson <resistor@mac.com>2011-10-25 20:35:53 +0000
commit0685e94895f26f96aa1032696e3150dd00aad1f3 (patch)
treef6d9ff1ff353c7f88f0b43b0461338e50d19fcc6
parentf62333df5e31843178678a6aad6e0d9bbe16c283 (diff)
downloadllvm-0685e94895f26f96aa1032696e3150dd00aad1f3.tar.gz
llvm-0685e94895f26f96aa1032696e3150dd00aad1f3.tar.bz2
llvm-0685e94895f26f96aa1032696e3150dd00aad1f3.tar.xz
Add support for the notion of "hidden" relocations. On MachO, these are relocation entries that are used as additional information for other, real relocations, rather than being relocations themselves.
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
-rw-r--r--include/llvm/Object/MachO.h1
-rw-r--r--include/llvm/Object/ObjectFile.h13
-rw-r--r--lib/Object/MachOObjectFile.cpp32
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp9
4 files changed, 55 insertions, 0 deletions
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 1ae9372bbd..dcf116e6c2 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<char> &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 331ed7caa0..0c7a518305 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<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
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index 96db34f411..a4d7cb542f 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<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 {
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index c2480df141..c0486defa5 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;