diff options
author | Owen Anderson <resistor@mac.com> | 2011-10-24 21:44:00 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-10-24 21:44:00 +0000 |
commit | 0135fe1854bef035efea1e3113dc6a127ef6e51e (patch) | |
tree | d087e40da5b0bd42499819e781b9fb833428887d /lib | |
parent | 3846163aee1b14545057c8664f80a18c55309462 (diff) | |
download | external_llvm-0135fe1854bef035efea1e3113dc6a127ef6e51e.zip external_llvm-0135fe1854bef035efea1e3113dc6a127ef6e51e.tar.gz external_llvm-0135fe1854bef035efea1e3113dc6a127ef6e51e.tar.bz2 |
Get relocation parsing/dumping to a mostly-working state for MachO files.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142852 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 133 |
1 files changed, 127 insertions, 6 deletions
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 19396be..5bf03ff 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -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::getRelocationNext(DataRefImpl Rel, } 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::getRelocationType(DataRefImpl Rel, } 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::getRelocationAdditionalInfo(DataRefImpl Rel, } 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; } |