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
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldMachO.h"
15cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h"
17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "ObjectImageCommon.h"
18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "JITRegistrar.h"
19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm;
20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object;
21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld"
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
24cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm {
25cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass MachOObjectImage : public ObjectImageCommon {
27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate:
28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef SmallVector<uint64_t, 1> SectionAddrList;
29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SectionAddrList OldSectionAddrList;
30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprotected:
32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool is64;
33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool Registered;
34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate:
36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void initOldAddress() {
37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get());
38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Unfortunately we need to do this, since there's information encoded
39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // in the original addr of the section that we could not otherwise
40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // recover. The reason for this is that symbols do not actually store
41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // their file offset, but only their vmaddr. This means that in order
42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // to locate the symbol correctly in the object file, we need to know
43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // where the original start of the section was (including any padding,
44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // etc).
45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (section_iterator i = objf->section_begin(), e = objf->section_end();
46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines         i != e; ++i) {
47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      uint64_t Addr;
48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      i->getAddress(Addr);
49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      OldSectionAddrList[i->getRawDataRefImpl().d.a] = Addr;
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic:
54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MachOObjectImage(ObjectBuffer *Input, bool is64)
55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      : ObjectImageCommon(Input),
56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0),
57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        is64(is64), Registered(false) {
58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    initOldAddress();
59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MachOObjectImage(std::unique_ptr<object::ObjectFile> Input, bool is64)
62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      : ObjectImageCommon(std::move(Input)),
63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0),
64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        is64(is64), Registered(false) {
65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    initOldAddress();
66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
67cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual ~MachOObjectImage() {
69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Registered)
70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      deregisterWithDebugger();
71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
72cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Subclasses can override these methods to update the image with loaded
74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // addresses for sections and common symbols
75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) {
76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get());
77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    char *data =
78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        const_cast<char *>(objf->getSectionPointer(Sec.getRawDataRefImpl()));
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t oldAddr = OldSectionAddrList[Sec.getRawDataRefImpl().d.a];
81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (is64) {
83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ((MachO::section_64 *)data)->addr = Addr;
84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else {
85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ((MachO::section *)data)->addr = Addr;
86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (symbol_iterator i = objf->symbol_begin(), e = objf->symbol_end();
89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines         i != e; ++i) {
90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      section_iterator symSec(objf->section_end());
91cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      (*i).getSection(symSec);
92cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (*symSec == Sec) {
93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        uint64_t symAddr;
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        (*i).getAddress(symAddr);
95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        updateSymbolAddress(*i, symAddr + Addr - oldAddr);
96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint64_t getOldSectionAddr(const SectionRef &Sec) const {
101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return OldSectionAddrList[Sec.getRawDataRefImpl().d.a];
102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) {
105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    char *data = const_cast<char *>(
106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        reinterpret_cast<const char *>(Sym.getRawDataRefImpl().p));
107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (is64)
108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ((MachO::nlist_64 *)data)->n_value = Addr;
109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    else
110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ((MachO::nlist *)data)->n_value = Addr;
111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual void registerWithDebugger() {
114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    JITRegistrar::getGDBRegistrar().registerObject(*Buffer);
115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Registered = true;
116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual void deregisterWithDebugger() {
119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer);
120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines};
122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesObjectImage *RuntimeDyldMachO::createObjectImage(ObjectBuffer *Buffer) {
124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint32_t magic = *((const uint32_t *)Buffer->getBufferStart());
125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool is64 = (magic == MachO::MH_MAGIC_64);
126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) &&
127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines         "Unrecognized Macho Magic");
128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return new MachOObjectImage(Buffer, is64);
129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesObjectImage *RuntimeDyldMachO::createObjectImageFromFile(
132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    std::unique_ptr<object::ObjectFile> ObjFile) {
133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!ObjFile)
134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return nullptr;
135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MemoryBuffer *Buffer =
137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false);
138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint32_t magic = *((const uint32_t *)Buffer->getBufferStart());
140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool is64 = (magic == MachO::MH_MAGIC_64);
141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) &&
142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines         "Unrecognized Macho Magic");
143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return new MachOObjectImage(std::move(ObjFile), is64);
144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 intptr_t DeltaForEH) {
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << ", Delta for EH: " << DeltaForEH << "\n");
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Length = *((uint32_t *)P);
151a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 4;
152a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  unsigned char *Ret = P + Length;
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Offset = *((uint32_t *)P);
154a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Offset == 0) // is a CIE
155a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    return Ret;
156a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
157a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 4;
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  intptr_t FDELocation = *((intptr_t *)P);
159a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t NewLocation = FDELocation - DeltaForText;
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  *((intptr_t *)P) = NewLocation;
161a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += sizeof(intptr_t);
162a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
163a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  // Skip the FDE address range
164a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += sizeof(intptr_t);
165a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
166a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  uint8_t Augmentationsize = *P;
167a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  P += 1;
168a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Augmentationsize != 0) {
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    intptr_t LSDA = *((intptr_t *)P);
170a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    intptr_t NewLSDA = LSDA - DeltaForEH;
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    *((intptr_t *)P) = NewLSDA;
172a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  }
173a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
174a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  return Ret;
175a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
176a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
177a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  intptr_t ObjDistance = A->ObjAddress - B->ObjAddress;
179a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t MemDistance = A->LoadAddress - B->LoadAddress;
180a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  return ObjDistance - MemDistance;
181a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
182a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
183528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::registerEHFrames() {
184528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
185528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  if (!MemMgr)
186528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    return;
187528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
188528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
189528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
190528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor        SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
191528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      continue;
192528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SectionEntry *Text = &Sections[SectionInfo.TextSID];
193528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SectionEntry *ExceptTab = nullptr;
195528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
196528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      ExceptTab = &Sections[SectionInfo.ExceptTabSID];
197528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
198528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    intptr_t DeltaForText = computeDelta(Text, EHFrame);
199528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    intptr_t DeltaForEH = 0;
200528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (ExceptTab)
201528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      DeltaForEH = computeDelta(ExceptTab, EHFrame);
202a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
203528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    unsigned char *P = EHFrame->Address;
204528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    unsigned char *End = P + EHFrame->Size;
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    do {
206528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      P = processFDE(P, DeltaForText, DeltaForEH);
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } while (P != End);
208a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
210528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor                             EHFrame->Size);
211528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  }
212528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  UnregisteredEHFrameSections.clear();
213528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor}
214a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg,
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    ObjSectionToIDMap &SectionMap) {
217528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
218528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
219528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
220528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  ObjSectionToIDMap::iterator i, e;
221528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
222528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    const SectionRef &Section = i->first;
223528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    StringRef Name;
224528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    Section.getName(Name);
225528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    if (Name == "__eh_frame")
226528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      EHFrameSID = i->second;
227528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    else if (Name == "__text")
228528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      TextSID = i->second;
229528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor    else if (Name == "__gcc_except_tab")
230528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor      ExceptTabSID = i->second;
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (Name == "__jump_table")
232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        Section, i->second);
234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (Name == "__pointers")
235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              Section, i->second);
237528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  }
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UnregisteredEHFrameSections.push_back(
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
240a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
241a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
24232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and
24332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset.  RE.SectionID can be used to find the SectionEntry.  Each
24432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location.
24532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded
24632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process.  SectionEntry::LoadAddress is the
24732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process.
24832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the
24932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space).
25032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
25132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at
25232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based
25332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address.  SectionEntry::ObjAddress will be used to refer to
25432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations.
25532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor//
25632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the
25732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied.  For relocations which refer to symbols in the
25832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which
25932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the
26032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location).  For external symbols, Value will be the address of the
26132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space.
26287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
26387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         uint64_t Value) {
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DEBUG (
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const SectionEntry &Section = Sections[RE.SectionID];
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint8_t* LocalAddress = Section.Address + RE.Offset;
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    dbgs() << "resolveRelocation Section: " << RE.SectionID
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " LocalAddress: " << format("%p", LocalAddress)
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " FinalAddress: " << format("%p", FinalAddress)
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " Value: " << format("%p", Value)
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " Addend: " << RE.Addend
274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " isPCRel: " << RE.IsPCRel
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " MachoType: " << RE.RelType
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << " Size: " << (1 << RE.Size) << "\n";
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  );
2780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // This just dispatches to the proper target specific routine.
2800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  switch (Arch) {
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Unsupported CPU type!");
2830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86_64:
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveX86_64Relocation(RE, Value);
2850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
2860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86:
287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveI386Relocation(RE, Value);
2880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::arm: // Fall through.
2900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::thumb:
291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveARMRelocation(RE, Value);
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Triple::aarch64:
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Triple::arm64:
295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveAArch64Relocation(RE, Value);
2960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
298cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE,
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             uint64_t Value) {
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const SectionEntry &Section = Sections[RE.SectionID];
303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t* LocalAddress = Section.Address + RE.Offset;
304b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RE.IsPCRel) {
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
308b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RE.RelType) {
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    default:
312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      llvm_unreachable("Invalid relocation type!");
313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MachO::GENERIC_RELOC_VANILLA:
314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return applyRelocationValue(LocalAddress, Value + RE.Addend,
315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  1 << RE.Size);
316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MachO::GENERIC_RELOC_SECTDIFF:
317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress;
319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress;
320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert((Value == SectionABase || Value == SectionBBase) &&
321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines             "Unexpected SECTDIFF relocation value.");
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value = SectionABase - SectionBBase + RE.Addend;
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case MachO::GENERIC_RELOC_PB_LA_PTR:
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error("Relocation type not implemented yet!");
327b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
328b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan}
329b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveX86_64Relocation(const RelocationEntry &RE,
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               uint64_t Value) {
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const SectionEntry &Section = Sections[RE.SectionID];
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t* LocalAddress = Section.Address + RE.Offset;
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
335cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
336cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RE.IsPCRel) {
338cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
339cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // address. Is that expected? Only for branches, perhaps?
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
343cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RE.RelType) {
345cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
346cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
3475510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_1:
3485510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_2:
3495510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED_4:
3505510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SIGNED:
3515510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_UNSIGNED:
352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MachO::X86_64_RELOC_BRANCH:
353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return applyRelocationValue(LocalAddress, Value + RE.Addend, 1 << RE.Size);
3545510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_GOT_LOAD:
3555510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_GOT:
3565510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_SUBTRACTOR:
3575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::X86_64_RELOC_TLV:
358cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
359cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
360cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
361cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveARMRelocation(const RelocationEntry &RE,
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            uint64_t Value) {
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const SectionEntry &Section = Sections[RE.SectionID];
365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t* LocalAddress = Section.Address + RE.Offset;
366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
367cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
368cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RE.IsPCRel) {
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
37161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    Value -= FinalAddress;
372cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // ARM PCRel relocations have an effective-PC offset of two instructions
373cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // (four bytes in Thumb mode, 8 bytes in ARM mode).
374cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: For now, assume ARM mode.
375cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value -= 8;
376cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
377cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RE.RelType) {
379cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
380cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MachO::ARM_RELOC_VANILLA:
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
3835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_BR24: {
384cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value into the target address. We know instructions are
385cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // 32-bit aligned, so we can do it all at once.
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t *p = (uint32_t *)LocalAddress;
387cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // The low two bits of the value are not encoded.
388cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value >>= 2;
389cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value to 24 bits.
390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalValue = Value & 0xffffff;
391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check for overflow.
392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value != FinalValue)
393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error("ARM BR24 relocation out of range.");
394cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: If the destination is a Thumb function (and the instruction
395cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // is a non-predicated BL instruction), we need to change it to a BLX
396cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // instruction instead.
397cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
398cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Insert the value into the instruction.
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *p = (*p & ~0xffffff) | FinalValue;
400cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    break;
401cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
4025510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_THUMB_RELOC_BR22:
4035510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_THUMB_32BIT_BRANCH:
4045510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_HALF:
4055510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_HALF_SECTDIFF:
4065510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_PAIR:
4075510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_SECTDIFF:
4085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_LOCAL_SECTDIFF:
4095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::ARM_RELOC_PB_LA_PTR:
410cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
411cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
412cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
413cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
414cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveAArch64Relocation(const RelocationEntry &RE,
416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                uint64_t Value) {
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const SectionEntry &Section = Sections[RE.SectionID];
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t* LocalAddress = Section.Address + RE.Offset;
419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If the relocation is PC-relative, the value to be encoded is the
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // pointer difference.
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (RE.IsPCRel) {
423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value -= FinalAddress;
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (RE.RelType) {
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Invalid relocation type!");
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case MachO::ARM64_RELOC_UNSIGNED:
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_BRANCH26: {
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Mask the value into the target address. We know instructions are
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // 32-bit aligned, so we can do it all at once.
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t *p = (uint32_t *)LocalAddress;
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The low two bits of the value are not encoded.
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value >>= 2;
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Mask the value to 26 bits.
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t FinalValue = Value & 0x3ffffff;
440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Check for overflow.
441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (FinalValue != Value)
442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return Error("ARM64 BRANCH26 relocation out of range.");
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Insert the value into the instruction.
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    *p = (*p & ~0x3ffffff) | FinalValue;
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_SUBTRACTOR:
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_PAGE21:
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_PAGEOFF12:
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_POINTER_TO_GOT:
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachO::ARM64_RELOC_ADDEND:
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error("Relocation type not implemented yet!");
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj,
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         const SectionRef &JTSection,
463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         unsigned JTSectionID) {
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(!Obj.is64Bit() &&
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "__jump_table section not supported in 64-bit MachO.");
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t JTSectionSize = Sec32.size;
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned FirstIndirectSymbol = Sec32.reserved1;
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned JTEntrySize = Sec32.reserved2;
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumJTEntries = JTSectionSize / JTEntrySize;
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t* JTSectionAddr = getSectionAddress(JTSectionID);
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned JTEntryOffset = 0;
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((JTSectionSize % JTEntrySize) == 0 &&
477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Jump-table section does not contain a whole number of stubs?");
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned i = 0; i < NumJTEntries; ++i) {
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SymbolIndex =
481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef IndirectSymbolName;
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SI->getName(IndirectSymbolName);
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset;
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    createStubFunction(JTEntryAddr);
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RelocationEntry RE(JTSectionID, JTEntryOffset + 1,
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       MachO::GENERIC_RELOC_VANILLA, 0, true, 2);
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    addRelocationForSymbol(RE, IndirectSymbolName);
490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    JTEntryOffset += JTEntrySize;
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj,
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               const SectionRef &PTSection,
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               unsigned PTSectionID) {
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(!Obj.is64Bit() &&
498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "__pointers section not supported in 64-bit MachO.");
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl());
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t PTSectionSize = Sec32.size;
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned FirstIndirectSymbol = Sec32.reserved1;
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const unsigned PTEntrySize = 4;
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumPTEntries = PTSectionSize / PTEntrySize;
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned PTEntryOffset = 0;
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((PTSectionSize % PTEntrySize) == 0 &&
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Pointers section does not contain a whole number of stubs?");
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << ", " << NumPTEntries << " entries, "
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << PTEntrySize << " bytes each:\n");
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned i = 0; i < NumPTEntries; ++i) {
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SymbolIndex =
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef IndirectSymbolName;
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SI->getName(IndirectSymbolName);
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DEBUG(dbgs() << "  " << IndirectSymbolName << ": index " << SymbolIndex
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          << ", PT offset: " << PTEntryOffset << "\n");
523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RelocationEntry RE(PTSectionID, PTEntryOffset,
524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    addRelocationForSymbol(RE, IndirectSymbolName);
526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    PTEntryOffset += PTEntrySize;
527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinessection_iterator getSectionByAddress(const MachOObjectFile &Obj,
532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     uint64_t Addr) {
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  section_iterator SI = Obj.section_begin();
534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  section_iterator SE = Obj.section_end();
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (; SI != SE; ++SI) {
537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t SAddr, SSize;
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SI->getAddress(SAddr);
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SI->getSize(SSize);
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((Addr >= SAddr) && (Addr < SAddr + SSize))
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return SI;
542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return SE;
545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned SectionID,
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            relocation_iterator RelI,
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            ObjectImage &Obj,
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            ObjSectionToIDMap &ObjSectionToID) {
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachOObjectFile *MachO =
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static_cast<const MachOObjectFile*>(Obj.getObjectFile());
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::any_relocation_info RE =
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachO->getRelocation(RelI->getRawDataRefImpl());
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionEntry &Section = Sections[SectionID];
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t RelocType = MachO->getAnyRelocationType(RE);
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Size = MachO->getAnyRelocationLength(RE);
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t Offset;
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RelI->getOffset(Offset);
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t *LocalAddress = Section.Address + Offset;
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumBytes = 1 << Size;
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t Addend = 0;
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  memcpy(&Addend, LocalAddress, NumBytes);
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ++RelI;
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::any_relocation_info RE2 =
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachO->getRelocation(RelI->getRawDataRefImpl());
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  section_iterator SAI = getSectionByAddress(*MachO, AddrA);
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(SAI != MachO->section_end() && "Can't find section for address A");
575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t SectionABase;
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SAI->getAddress(SectionABase);
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t SectionAOffset = AddrA - SectionABase;
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionRef SectionA = *SAI;
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsCode;
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionA.isText(IsCode);
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode,
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          ObjSectionToID);
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  section_iterator SBI = getSectionByAddress(*MachO, AddrB);
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(SBI != MachO->section_end() && "Can't find section for address B");
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t SectionBBase;
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SBI->getAddress(SectionBBase);
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t SectionBOffset = AddrB - SectionBBase;
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionRef SectionB = *SBI;
591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode,
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          ObjSectionToID);
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Addend != AddrA - AddrB)
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Error("Unexpected SECTDIFF relocation addend.");
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << ", Addend: " << Addend << ", SectionA ID: "
599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << SectionAID << ", SectionAOffset: " << SectionAOffset
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << ", SectionB ID: " << SectionBID << ", SectionBOffset: "
601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines               << SectionBOffset << "\n");
602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RelocationEntry R(SectionID, Offset, RelocType, 0,
603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    SectionAID, SectionAOffset, SectionBID, SectionBOffset,
604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    IsPCRel, Size);
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  addRelocationForSection(R, SectionAID);
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  addRelocationForSection(R, SectionBID);
608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return ++RelI;
610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA(
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            unsigned SectionID,
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            relocation_iterator RelI,
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            ObjectImage &Obj,
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                            ObjSectionToIDMap &ObjSectionToID) {
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MachOObjectFile *MachO =
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    static_cast<const MachOObjectFile*>(Obj.getObjectFile());
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachO::any_relocation_info RE =
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachO->getRelocation(RelI->getRawDataRefImpl());
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionEntry &Section = Sections[SectionID];
623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t RelocType = MachO->getAnyRelocationType(RE);
624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Size = MachO->getAnyRelocationLength(RE);
626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t Offset;
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RelI->getOffset(Offset);
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint8_t *LocalAddress = Section.Address + Offset;
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned NumBytes = 1 << Size;
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int64_t Addend = 0;
631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  memcpy(&Addend, LocalAddress, NumBytes);
632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE);
634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint64_t SectionBaseAddr;
637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TargetSI->getAddress(SectionBaseAddr);
638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SectionRef TargetSection = *TargetSI;
639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsCode;
640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TargetSection.isText(IsCode);
641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode,
642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               ObjSectionToID);
643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Addend -= SectionBaseAddr;
645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  RelocationEntry R(SectionID, Offset, RelocType, Addend,
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    IsPCRel, Size);
647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  addRelocationForSection(R, TargetSectionID);
649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return ++RelI;
651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator RuntimeDyldMachO::processRelocationRef(
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StubMap &Stubs) {
657efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  const ObjectFile *OF = Obj.getObjectFile();
658cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MachOObjectImage &MachOObj = *static_cast<MachOObjectImage *>(&Obj);
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MachOObjectFile *MachO = static_cast<const MachOObjectFile *>(OF);
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachO::any_relocation_info RE =
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MachO->getRelocation(RelI->getRawDataRefImpl());
6620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
663efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  uint32_t RelType = MachO->getAnyRelocationType(RE);
664623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames
665623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames  // FIXME: Properly handle scattered relocations.
666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        Special case the couple of scattered relocations that we know how
667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        to handle: SECTDIFF relocations, and scattered VANILLA relocations
668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        on I386.
669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        For all other scattered relocations, just bail out and hope for the
670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        best, since the offsets computed by scattered relocations have often
671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        been optimisticaly filled in by the compiler. This will fail
672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        horribly where the relocations *do* need to be applied, but that was
673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  //        already the case.
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (MachO->isRelocationScattered(RE)) {
675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA)
679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);
680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return ++RelI;
682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
683623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames
6840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  RelocationValueRef Value;
685efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  SectionEntry &Section = Sections[SectionID];
6860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool IsExtern = MachO->getPlainRelocationExternal(RE);
68887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
68987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned Size = MachO->getAnyRelocationLength(RE);
6908e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola  uint64_t Offset;
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RelI->getOffset(Offset);
692e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint8_t *LocalAddress = Section.Address + Offset;
693e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  unsigned NumBytes = 1 << Size;
694e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint64_t Addend = 0;
695e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  memcpy(&Addend, LocalAddress, NumBytes);
6968e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola
697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsExtern) {
698c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // Obtain the symbol name which is referenced in the relocation
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    symbol_iterator Symbol = RelI->getSymbol();
7000e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StringRef TargetName;
7016c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola    Symbol->getName(TargetName);
702c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // First search for the symbol in the local symbol table
703d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky    SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
7040e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    if (lsi != Symbols.end()) {
7050e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Value.SectionID = lsi->second.first;
7068e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      Value.Addend = lsi->second.second + Addend;
7070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    } else {
708c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      // Search for the symbol in the global symbol table
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SymbolTableMap::const_iterator gsi =
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          GlobalSymbolTable.find(TargetName.data());
711d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky      if (gsi != GlobalSymbolTable.end()) {
7120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SectionID = gsi->second.first;
7138e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = gsi->second.second + Addend;
7148e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      } else {
7150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SymbolName = TargetName.data();
7168e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = Addend;
7178e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      }
718cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Addends for external, PC-rel relocations on i386 point back to the zero
721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // offset. Calculate the final offset from the relocation target instead.
722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // This allows us to use the same logic for both external and internal
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // relocations in resolveI386RelocationRef.
724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Arch == Triple::x86 && IsPCRel) {
725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t RelocAddr = 0;
726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RelI->getAddress(RelocAddr);
727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value.Addend += RelocAddr + 4;
728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
7300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  } else {
731e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    SectionRef Sec = MachO->getRelocationSection(RE);
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool IsCode = false;
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sec.isText(IsCode);
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID);
735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t Addr = MachOObj.getOldSectionAddr(Sec);
736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    DEBUG(dbgs() << "\nAddr: " << Addr << "\nAddend: " << Addend);
737e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Value.Addend = Addend - Addr;
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (IsPCRel)
73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Value.Addend += Offset + NumBytes;
740288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling  }
741288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling
7425510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT ||
7435510728d28bb1ee04abc32da3d21b7df12948053Charles Davis                                 RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
744a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(IsPCRel);
745a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(Size == 2);
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FIXME: Teach the generic code above not to prematurely conflate
748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    //        relocation addends and symbol offsets.
749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value.Addend -= Addend;
750a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    StubMap::const_iterator i = Stubs.find(Value);
751a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    uint8_t *Addr;
752a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    if (i != Stubs.end()) {
753a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = Section.Address + i->second;
754a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    } else {
755a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Stubs[Value] = Section.StubOffset;
756a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      uint8_t *GOTEntry = Section.Address + Section.StubOffset;
757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RelocationEntry GOTRE(SectionID, Section.StubOffset,
758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false,
759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            3);
760a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      if (Value.SymbolName)
761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        addRelocationForSymbol(GOTRE, Value.SymbolName);
762a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      else
763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        addRelocationForSection(GOTRE, Value.SectionID);
764a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Section.StubOffset += 8;
765a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = GOTEntry;
766a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    }
767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RelocationEntry TargetRE(SectionID, Offset,
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             MachO::X86_64_RELOC_UNSIGNED, Addend, true,
769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             2);
770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveRelocation(TargetRE, (uint64_t)Addr);
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
7720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    // This is an ARM branch relocation, need to use a stub function.
7730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
7740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    //  Look up for existing stub.
7750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StubMap::const_iterator i = Stubs.find(Value);
776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint8_t *Addr;
777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (i != Stubs.end()) {
778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Addr = Section.Address + i->second;
779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
7800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      // Create a new stub function.
7810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Stubs[Value] = Section.StubOffset;
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint8_t *StubTargetAddr =
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          createStubFunction(Section.Address + Section.StubOffset);
784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      RelocationEntry StubRE(SectionID, StubTargetAddr - Section.Address,
785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             MachO::GENERIC_RELOC_VANILLA, Value.Addend);
786c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      if (Value.SymbolName)
787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        addRelocationForSymbol(StubRE, Value.SymbolName);
788c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      else
789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        addRelocationForSection(StubRE, Value.SectionID);
790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Addr = Section.Address + Section.StubOffset;
7910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Section.StubOffset += getMaxStubSize();
7920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    }
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RelocationEntry TargetRE(Value.SectionID, Offset, RelType, 0, IsPCRel,
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             Size);
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    resolveRelocation(TargetRE, (uint64_t)Addr);
796c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  } else {
79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size);
798c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    if (Value.SymbolName)
799c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSymbol(RE, Value.SymbolName);
800c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    else
801c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSection(RE, Value.SectionID);
802c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  }
80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ++RelI;
804cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
805cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const {
8083f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  if (InputBuffer->getBufferSize() < 4)
8093f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor    return false;
8103f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  StringRef Magic(InputBuffer->getBufferStart(), 4);
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Magic == "\xFE\xED\xFA\xCE")
81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Magic == "\xCE\xFA\xED\xFE")
81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Magic == "\xFE\xED\xFA\xCF")
81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Magic == "\xCF\xFA\xED\xFE")
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
819cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
820cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
821cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const {
82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Obj->isMachO();
82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
826cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm
827