diff options
author | Owen Anderson <resistor@mac.com> | 2011-10-27 20:46:09 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-10-27 20:46:09 +0000 |
commit | eb6bd339954376e4ab1fda52133ef3f94c3029b7 (patch) | |
tree | eed52e4c493c9c002303a509eec7ca99350ea6fd /lib/Object | |
parent | 999f90bedf94e7d55508f0797802b75064f1de09 (diff) |
Fix pretty printing of i386 local sect diff relocations, TLV relocations, and x86_64 TLV relocations in MachO.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143140 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Object')
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 06d62fa1aa..099ac2c37f 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -675,10 +675,11 @@ error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, "GENERIC_RELOC_VANILLA", "GENERIC_RELOC_PAIR", "GENERIC_RELOC_SECTDIFF", + "GENERIC_RELOC_PB_LA_PTR", "GENERIC_RELOC_LOCAL_SECTDIFF", - "GENERIC_RELOC_PB_LA_PTR" }; + "GENERIC_RELOC_TLV" }; - if (r_type > 4) + if (r_type > 6) res = "Unknown"; else res = Table[r_type]; @@ -859,6 +860,12 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, else Type = (RE->Word1 >> 28) & 0xF; + bool isPCRel; + if (isScattered) + isPCRel = ((RE->Word0 >> 30) & 1); + else + isPCRel = ((RE->Word1 >> 24) & 1); + // Determine any addends that should be displayed with the relocation. // These require decoding the relocation type, which is triple-specific. @@ -894,6 +901,11 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, fmt << "-"; printRelocationTargetName(RE, fmt); } + case macho::RIT_X86_64_TLV: + printRelocationTargetName(RE, fmt); + fmt << "@TLV"; + if (isPCRel) fmt << "P"; + break; case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1 printRelocationTargetName(RE, fmt); fmt << "-1"; @@ -916,8 +928,7 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, switch (Type) { case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info return object_error::success; - case macho::RIT_Difference: // GENERIC_RELOC_SECTDIFF - case macho::RIT_Generic_LocalDifference: { // GENERIC_RELOC_LOCAL_SECTDIFF + case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF InMemoryStruct<macho::RelocationEntry> RENext; DataRefImpl RelNext = Rel; RelNext.d.a++; @@ -934,8 +945,7 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, RType = (RENext->Word1 >> 28) & 0xF; if (RType != 1) report_fatal_error("Expected GENERIC_RELOC_PAIR after " - "GENERIC_RELOC_SECTDIFF or " - "GENERIC_RELOC_LOCAL_SECTDIFF."); + "GENERIC_RELOC_SECTDIFF."); printRelocationTargetName(RE, fmt); fmt << "-"; @@ -947,7 +957,40 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, if (Arch == Triple::x86) { // All X86 relocations that need special printing were already // handled in the generic code. - printRelocationTargetName(RE, fmt); + switch (Type) { + case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF + InMemoryStruct<macho::RelocationEntry> RENext; + DataRefImpl RelNext = Rel; + RelNext.d.a++; + getRelocation(RelNext, RENext); + + // X86 sect diff's must be followed by a relocation of type + // GENERIC_RELOC_PAIR. + bool isNextScattered = (Arch != Triple::x86_64) && + (RENext->Word0 & macho::RF_Scattered); + unsigned RType; + if (isNextScattered) + RType = (RENext->Word0 >> 24) & 0xF; + else + RType = (RENext->Word1 >> 28) & 0xF; + if (RType != 1) + report_fatal_error("Expected GENERIC_RELOC_PAIR after " + "GENERIC_RELOC_LOCAL_SECTDIFF."); + + printRelocationTargetName(RE, fmt); + fmt << "-"; + printRelocationTargetName(RENext, fmt); + break; + } + case macho::RIT_Generic_TLV: { + printRelocationTargetName(RE, fmt); + fmt << "@TLV"; + if (isPCRel) fmt << "P"; + break; + } + default: + printRelocationTargetName(RE, fmt); + } } else { // ARM-specific relocations switch (Type) { case macho::RIT_ARM_Half: // ARM_RELOC_HALF |