RuntimeDyldMachO.cpp revision 528f6d787b1a847e61eb2f1114559f423fdeb68c
1e0934bee3a4f40731169bc42b15a39ce39978175Jim Grosbach//===-- RuntimeDyldMachO.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-=//
2cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//
3cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//                     The LLVM Compiler Infrastructure
4cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//
5cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// This file is distributed under the University of Illinois Open Source
6cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// License. See LICENSE.TXT for details.
7cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//
8cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===//
9cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//
10cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Implementation of the MC-JIT runtime dynamic linker.
11cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//
12cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===//
13cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
14cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#define DEBUG_TYPE "dyld"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldMachO.h"
16cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/OwningPtr.h"
17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h"
19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm;
20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object;
21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm {
23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
24a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr_t DeltaForEH) {
25a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  uint32_t Length = *((uint32_t*)P);
26a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 4;
27a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  unsigned char *Ret = P + Length;
28a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  uint32_t Offset = *((uint32_t*)P);
29a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Offset == 0) // is a CIE
30a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    return Ret;
31a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
32a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 4;
33a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t FDELocation = *((intptr_t*)P);
34a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t NewLocation = FDELocation - DeltaForText;
35a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  *((intptr_t*)P) = NewLocation;
36a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += sizeof(intptr_t);
37a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
38a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  // Skip the FDE address range
39a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += sizeof(intptr_t);
40a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
41a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  uint8_t Augmentationsize = *P;
42a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 1;
43a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Augmentationsize != 0) {
44a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    intptr_t LSDA = *((intptr_t*)P);
45a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    intptr_t NewLSDA = LSDA - DeltaForEH;
46a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    *((intptr_t*)P) = NewLSDA;
47a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  }
48a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
49a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  return Ret;
50a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
51a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
52a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
53a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t ObjDistance = A->ObjAddress  - B->ObjAddress;
54a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t MemDistance = A->LoadAddress - B->LoadAddress;
55a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  return ObjDistance - MemDistance;
56a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
57a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
58528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::registerEHFrames() {
59528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
60528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  if (!MemMgr)
61528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    return;
62528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
63528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
64528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
65528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor        SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
66528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      continue;
67528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SectionEntry *Text = &Sections[SectionInfo.TextSID];
68528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
69528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SectionEntry *ExceptTab = NULL;
70528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
71528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      ExceptTab = &Sections[SectionInfo.ExceptTabSID];
72528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
73528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    intptr_t DeltaForText = computeDelta(Text, EHFrame);
74528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    intptr_t DeltaForEH = 0;
75528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (ExceptTab)
76528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      DeltaForEH = computeDelta(ExceptTab, EHFrame);
77a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
78528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    unsigned char *P = EHFrame->Address;
79528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    unsigned char *End = P + EHFrame->Size;
80528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    do  {
81528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      P = processFDE(P, DeltaForText, DeltaForEH);
82528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    } while(P != End);
83a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
84528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    MemMgr->registerEHFrames(EHFrame->Address,
85528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor                             EHFrame->LoadAddress,
86528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor                             EHFrame->Size);
87528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  }
88528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  UnregisteredEHFrameSections.clear();
89528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor}
90a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
91528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
92528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
93528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
94528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
95528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  ObjSectionToIDMap::iterator i, e;
96528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
97528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    const SectionRef &Section = i->first;
98528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    StringRef Name;
99528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    Section.getName(Name);
100528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (Name == "__eh_frame")
101528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      EHFrameSID = i->second;
102528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    else if (Name == "__text")
103528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      TextSID = i->second;
104528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    else if (Name == "__gcc_except_tab")
105528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      ExceptTabSID = i->second;
106528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  }
107528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  UnregisteredEHFrameSections.push_back(EHFrameRelatedSections(EHFrameSID,
108528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor                                                               TextSID,
109528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor                                                               ExceptTabSID));
110a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
111a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
11232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and
11332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset.  RE.SectionID can be used to find the SectionEntry.  Each
11432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location.
11532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded
11632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process.  SectionEntry::LoadAddress is the
11732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process.
11832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the
11932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space).
12032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
12132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at
12232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based
12332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address.  SectionEntry::ObjAddress will be used to refer to
12432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations.
12532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
12632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the
12732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied.  For relocations which refer to symbols in the
12832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which
12932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the
13032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location).  For external symbols, Value will be the address of the
13132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space.
13287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
13387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         uint64_t Value) {
13487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  const SectionEntry &Section = Sections[RE.SectionID];
13587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
13687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                           RE.IsPCRel, RE.Size);
13787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola}
13887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola
139a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
140a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor                                         uint64_t Offset,
1410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                         uint64_t Value,
1420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                         uint32_t Type,
14387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         int64_t Addend,
14487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         bool isPCRel,
14587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         unsigned LogSize) {
146a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor  uint8_t *LocalAddress = Section.Address + Offset;
147a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor  uint64_t FinalAddress = Section.LoadAddress + Offset;
14887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned MachoType = Type;
14987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned Size = 1 << LogSize;
1500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
1516d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky  DEBUG(dbgs() << "resolveRelocation LocalAddress: "
1526d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky        << format("%p", LocalAddress)
1530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " FinalAddress: " << format("%p", FinalAddress)
1540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Value: " << format("%p", Value)
1550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Addend: " << Addend
1560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " isPCRel: " << isPCRel
1570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " MachoType: " << MachoType
1580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Size: " << Size
1590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << "\n");
1600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
161cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // This just dispatches to the proper target specific routine.
1620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  switch (Arch) {
163858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper  default: llvm_unreachable("Unsupported CPU type!");
1640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86_64:
1650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveX86_64Relocation(LocalAddress,
1660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            FinalAddress,
1670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            (uintptr_t)Value,
1680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            isPCRel,
1690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            MachoType,
1700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            Size,
1710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            Addend);
1720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
1730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86:
1740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveI386Relocation(LocalAddress,
1756d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          FinalAddress,
1766d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          (uintptr_t)Value,
1776d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          isPCRel,
178ba9ba9f9bcb8e627ff9cc4bd11904db21762e5a2Jim Grosbach                          MachoType,
1796d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          Size,
1806d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          Addend);
1810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
1820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::arm:    // Fall through.
1830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::thumb:
1840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveARMRelocation(LocalAddress,
1850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         FinalAddress,
1860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         (uintptr_t)Value,
1870e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         isPCRel,
1880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         MachoType,
1890e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         Size,
1900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         Addend);
1910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
1956d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
1966d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             uint64_t FinalAddress,
1976d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             uint64_t Value,
1986d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             bool isPCRel,
1996d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             unsigned Type,
2006d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             unsigned Size,
2016d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             int64_t Addend) {
202b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  if (isPCRel)
203b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    Value -= FinalAddress + 4; // see resolveX86_64Relocation
204b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
205b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  switch (Type) {
206b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  default:
207b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    llvm_unreachable("Invalid relocation type!");
2085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::GENERIC_RELOC_VANILLA: {
209b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    uint8_t *p = LocalAddress;
210b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    uint64_t ValueToWrite = Value + Addend;
211b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    for (unsigned i = 0; i < Size; ++i) {
212b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan      *p++ = (uint8_t)(ValueToWrite & 0xff);
213b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan      ValueToWrite >>= 8;
214b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    }
2156f6f17197259edbb82cc9b0d800fe0e3cb8e201cJim Grosbach    return false;
216b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
2175510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::GENERIC_RELOC_SECTDIFF:
2185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::GENERIC_RELOC_LOCAL_SECTDIFF:
2195510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::GENERIC_RELOC_PB_LA_PTR:
220b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    return Error("Relocation type not implemented yet!");
221b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
222b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan}
223b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
2246d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
2256d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               uint64_t FinalAddress,
2266d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               uint64_t Value,
2276d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               bool isPCRel,
2286d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               unsigned Type,
2296d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               unsigned Size,
2306d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               int64_t Addend) {
231cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
232cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
233cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (isPCRel)
234cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // address. Is that expected? Only for branches, perhaps?
23661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    Value -= FinalAddress + 4;
237cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
238cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  switch(Type) {
239cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
240cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
2415510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_1:
2425510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_2:
2435510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_4:
2445510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED:
2455510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_UNSIGNED:
2465510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_BRANCH: {
247652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach    Value += Addend;
248cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask in the target value a byte at a time (we don't have an alignment
249cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // guarantee for the target address, so this is safest).
25061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint8_t *p = (uint8_t*)LocalAddress;
251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    for (unsigned i = 0; i < Size; ++i) {
252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      *p++ = (uint8_t)Value;
253cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      Value >>= 8;
254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return false;
256cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
2575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_GOT_LOAD:
2585510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_GOT:
2595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SUBTRACTOR:
2605510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_TLV:
261cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
264cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
2656d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
2666d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            uint64_t FinalAddress,
2676d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            uint64_t Value,
2686d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            bool isPCRel,
2696d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            unsigned Type,
2706d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            unsigned Size,
2716d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            int64_t Addend) {
272cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
273cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (isPCRel) {
27561dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    Value -= FinalAddress;
276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // ARM PCRel relocations have an effective-PC offset of two instructions
277cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // (four bytes in Thumb mode, 8 bytes in ARM mode).
278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: For now, assume ARM mode.
279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value -= 8;
280cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  switch(Type) {
283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
284cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
2855510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_VANILLA: {
286cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask in the target value a byte at a time (we don't have an alignment
287cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // guarantee for the target address, so this is safest).
28861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint8_t *p = (uint8_t*)LocalAddress;
289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    for (unsigned i = 0; i < Size; ++i) {
290f69a29b23a116a3520f185054290c445abf9aa62Charles Davis      *p++ = (uint8_t)Value;
291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      Value >>= 8;
292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    break;
294cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
2955510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_BR24: {
296cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value into the target address. We know instructions are
297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // 32-bit aligned, so we can do it all at once.
29861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint32_t *p = (uint32_t*)LocalAddress;
299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // The low two bits of the value are not encoded.
300cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value >>= 2;
301cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value to 24 bits.
302cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value &= 0xffffff;
303cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: If the destination is a Thumb function (and the instruction
304cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // is a non-predicated BL instruction), we need to change it to a BLX
305cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // instruction instead.
306cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
307cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Insert the value into the instruction.
308cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    *p = (*p & ~0xffffff) | Value;
309cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    break;
310cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
3115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_THUMB_RELOC_BR22:
3125510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_THUMB_32BIT_BRANCH:
3135510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_HALF:
3145510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_HALF_SECTDIFF:
3155510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_PAIR:
3165510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_SECTDIFF:
3175510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_LOCAL_SECTDIFF:
3185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_PB_LA_PTR:
319cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
320cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
321cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
322cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
324efa91f6475f6e96552986104ab4857db46185a2aRafael Espindolavoid RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
325ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola                                            RelocationRef RelI,
326689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd                                            ObjectImage &Obj,
3270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                            ObjSectionToIDMap &ObjSectionToID,
328d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky                                            const SymbolTableMap &Symbols,
3290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                            StubMap &Stubs) {
330efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  const ObjectFile *OF = Obj.getObjectFile();
331efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF);
3325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl());
3330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
334efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  uint32_t RelType = MachO->getAnyRelocationType(RE);
335623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames
336623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  // FIXME: Properly handle scattered relocations.
337623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  //        For now, optimistically skip these: they can often be ignored, as
338623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  //        the static linker will already have applied the relocation, and it
339623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  //        only needs to be reapplied if symbols move relative to one another.
340623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  //        Note: This will fail horribly where the relocations *do* need to be
341623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  //        applied, but that was already the case.
342623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  if (MachO->isRelocationScattered(RE))
343623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames    return;
344623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames
3450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  RelocationValueRef Value;
346efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  SectionEntry &Section = Sections[SectionID];
3470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
348efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  bool isExtern = MachO->getPlainRelocationExternal(RE);
34987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
35087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned Size = MachO->getAnyRelocationLength(RE);
3518e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola  uint64_t Offset;
3528e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola  RelI.getOffset(Offset);
353e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint8_t *LocalAddress = Section.Address + Offset;
354e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  unsigned NumBytes = 1 << Size;
355e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint64_t Addend = 0;
356e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  memcpy(&Addend, LocalAddress, NumBytes);
3578e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola
358e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  if (isExtern) {
359c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // Obtain the symbol name which is referenced in the relocation
3606c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola    symbol_iterator Symbol = RelI.getSymbol();
3610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StringRef TargetName;
3626c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola    Symbol->getName(TargetName);
363c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // First search for the symbol in the local symbol table
364d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky    SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
3650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    if (lsi != Symbols.end()) {
3660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Value.SectionID = lsi->second.first;
3678e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      Value.Addend = lsi->second.second + Addend;
3680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    } else {
369c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      // Search for the symbol in the global symbol table
370d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data());
371d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky      if (gsi != GlobalSymbolTable.end()) {
3720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SectionID = gsi->second.first;
3738e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = gsi->second.second + Addend;
3748e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      } else {
3750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SymbolName = TargetName.data();
3768e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = Addend;
3778e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      }
378cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
3790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  } else {
380e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    SectionRef Sec = MachO->getRelocationSection(RE);
381e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
382e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    uint64_t Addr;
383e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Sec.getAddress(Addr);
384e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Value.Addend = Addend - Addr;
385288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling  }
386288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling
3875510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT ||
3885510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                                 RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
389a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(IsPCRel);
390a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(Size == 2);
391a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    StubMap::const_iterator i = Stubs.find(Value);
392a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    uint8_t *Addr;
393a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    if (i != Stubs.end()) {
394a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = Section.Address + i->second;
395a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    } else {
396a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Stubs[Value] = Section.StubOffset;
397a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      uint8_t *GOTEntry = Section.Address + Section.StubOffset;
398a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      RelocationEntry RE(SectionID, Section.StubOffset,
3995510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                         MachO::X86_64_RELOC_UNSIGNED, 0, false, 3);
400a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      if (Value.SymbolName)
401a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola        addRelocationForSymbol(RE, Value.SymbolName);
402a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      else
403a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola        addRelocationForSection(RE, Value.SectionID);
404a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Section.StubOffset += 8;
405a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = GOTEntry;
406a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    }
407a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    resolveRelocation(Section, Offset, (uint64_t)Addr,
4085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                      MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2);
409a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  } else if (Arch == Triple::arm &&
4105510728d28bb1ee04abc32da3d21b7df12948053Charles Davis             (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
4110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    // This is an ARM branch relocation, need to use a stub function.
4120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
4130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    //  Look up for existing stub.
4140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StubMap::const_iterator i = Stubs.find(Value);
4150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    if (i != Stubs.end())
416efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      resolveRelocation(Section, Offset,
4170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                        (uint64_t)Section.Address + i->second,
41887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                        RelType, 0, IsPCRel, Size);
4190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    else {
4200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      // Create a new stub function.
4210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Stubs[Value] = Section.StubOffset;
4220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      uint8_t *StubTargetAddr = createStubFunction(Section.Address +
4230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                                   Section.StubOffset);
424efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
4255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                         MachO::GENERIC_RELOC_VANILLA, Value.Addend);
426c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      if (Value.SymbolName)
427c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky        addRelocationForSymbol(RE, Value.SymbolName);
428c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      else
429c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky        addRelocationForSection(RE, Value.SectionID);
430efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      resolveRelocation(Section, Offset,
4310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                        (uint64_t)Section.Address + Section.StubOffset,
43287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                        RelType, 0, IsPCRel, Size);
4330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Section.StubOffset += getMaxStubSize();
4340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    }
435c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  } else {
43687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
43787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                       IsPCRel, Size);
438c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    if (Value.SymbolName)
439c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSymbol(RE, Value.SymbolName);
440c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    else
441c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSection(RE, Value.SectionID);
442c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  }
443cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
444cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
445cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
4466d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat(
4473f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor        const ObjectBuffer *InputBuffer) const {
4483f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  if (InputBuffer->getBufferSize() < 4)
4493f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor    return false;
4503f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  StringRef Magic(InputBuffer->getBufferStart(), 4);
451cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xFE\xED\xFA\xCE") return true;
452cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xCE\xFA\xED\xFE") return true;
453cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xFE\xED\xFA\xCF") return true;
454cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xCF\xFA\xED\xFE") return true;
455cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
456cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
457cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
458cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm
459