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
58a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael EspindolaStringRef RuntimeDyldMachO::getEHFrameSection() {
59a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  SectionEntry *Text = NULL;
60a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  SectionEntry *EHFrame = NULL;
61a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  SectionEntry *ExceptTab = NULL;
62a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  for (int i = 0, e = Sections.size(); i != e; ++i) {
63a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    if (Sections[i].Name == "__eh_frame")
64a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      EHFrame = &Sections[i];
65a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    else if (Sections[i].Name == "__text")
66a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Text = &Sections[i];
67a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    else if (Sections[i].Name == "__gcc_except_tab")
68a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      ExceptTab = &Sections[i];
69a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  }
70a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Text == NULL || EHFrame == NULL)
71a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    return StringRef();
72a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
73a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t DeltaForText = computeDelta(Text, EHFrame);
74a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  intptr_t DeltaForEH = 0;
75a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (ExceptTab)
76a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    DeltaForEH = computeDelta(ExceptTab, EHFrame);
77a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
78a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  unsigned char *P = EHFrame->Address;
79a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  unsigned char *End = P + EHFrame->Size;
80a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  do  {
81a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    P = processFDE(P, DeltaForText, DeltaForEH);
82a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  } while(P != End);
83a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
84a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  return StringRef((char*)EHFrame->Address, EHFrame->Size);
85a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola}
86a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola
8787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
8887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         uint64_t Value) {
8987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  const SectionEntry &Section = Sections[RE.SectionID];
9087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
9187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                           RE.IsPCRel, RE.Size);
9287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola}
9387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola
94a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
95a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor                                         uint64_t Offset,
960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                         uint64_t Value,
970e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                         uint32_t Type,
9887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         int64_t Addend,
9987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         bool isPCRel,
10087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                                         unsigned LogSize) {
101a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor  uint8_t *LocalAddress = Section.Address + Offset;
102a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor  uint64_t FinalAddress = Section.LoadAddress + Offset;
10387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned MachoType = Type;
10487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned Size = 1 << LogSize;
1050e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
1066d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky  DEBUG(dbgs() << "resolveRelocation LocalAddress: "
1076d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky        << format("%p", LocalAddress)
1080e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " FinalAddress: " << format("%p", FinalAddress)
1090e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Value: " << format("%p", Value)
1100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Addend: " << Addend
1110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " isPCRel: " << isPCRel
1120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " MachoType: " << MachoType
1130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << " Size: " << Size
1140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        << "\n");
1150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // This just dispatches to the proper target specific routine.
1170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  switch (Arch) {
118858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper  default: llvm_unreachable("Unsupported CPU type!");
1190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86_64:
1200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveX86_64Relocation(LocalAddress,
1210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            FinalAddress,
1220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            (uintptr_t)Value,
1230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            isPCRel,
1240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            MachoType,
1250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            Size,
1260e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                            Addend);
1270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
1280e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::x86:
1290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveI386Relocation(LocalAddress,
1306d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          FinalAddress,
1316d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          (uintptr_t)Value,
1326d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          isPCRel,
133ba9ba9f9bcb8e627ff9cc4bd11904db21762e5a2Jim Grosbach                          MachoType,
1346d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          Size,
1356d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                          Addend);
1360e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
1370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::arm:    // Fall through.
1380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  case Triple::thumb:
1390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    resolveARMRelocation(LocalAddress,
1400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         FinalAddress,
1410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         (uintptr_t)Value,
1420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         isPCRel,
1430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         MachoType,
1440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         Size,
1450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                         Addend);
1460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    break;
147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
1506d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
1516d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             uint64_t FinalAddress,
1526d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             uint64_t Value,
1536d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             bool isPCRel,
1546d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             unsigned Type,
1556d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             unsigned Size,
1566d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                             int64_t Addend) {
157b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  if (isPCRel)
158b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    Value -= FinalAddress + 4; // see resolveX86_64Relocation
159b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
160b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  switch (Type) {
161b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  default:
162b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    llvm_unreachable("Invalid relocation type!");
163b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  case macho::RIT_Vanilla: {
164b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    uint8_t *p = LocalAddress;
165b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    uint64_t ValueToWrite = Value + Addend;
166b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    for (unsigned i = 0; i < Size; ++i) {
167b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan      *p++ = (uint8_t)(ValueToWrite & 0xff);
168b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan      ValueToWrite >>= 8;
169b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    }
1706f6f17197259edbb82cc9b0d800fe0e3cb8e201cJim Grosbach    return false;
171b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
172b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  case macho::RIT_Difference:
173b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  case macho::RIT_Generic_LocalDifference:
174b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  case macho::RIT_Generic_PreboundLazyPointer:
175b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan    return Error("Relocation type not implemented yet!");
176b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan  }
177b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan}
178b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan
1796d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
1806d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               uint64_t FinalAddress,
1816d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               uint64_t Value,
1826d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               bool isPCRel,
1836d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               unsigned Type,
1846d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               unsigned Size,
1856d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                               int64_t Addend) {
186cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
187cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
188cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (isPCRel)
189cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
190cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // address. Is that expected? Only for branches, perhaps?
19161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    Value -= FinalAddress + 4;
192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  switch(Type) {
194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
196652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach  case macho::RIT_X86_64_Signed1:
197652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach  case macho::RIT_X86_64_Signed2:
198652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach  case macho::RIT_X86_64_Signed4:
199652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach  case macho::RIT_X86_64_Signed:
200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_Unsigned:
201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_Branch: {
202652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach    Value += Addend;
203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask in the target value a byte at a time (we don't have an alignment
204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // guarantee for the target address, so this is safest).
20561dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint8_t *p = (uint8_t*)LocalAddress;
206cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    for (unsigned i = 0; i < Size; ++i) {
207cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      *p++ = (uint8_t)Value;
208cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      Value >>= 8;
209cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
210cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return false;
211cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
212cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_GOTLoad:
213cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_GOT:
214cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_Subtractor:
215cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_X86_64_TLV:
216cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
217cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
218cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
219cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
2206d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
2216d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            uint64_t FinalAddress,
2226d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            uint64_t Value,
2236d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            bool isPCRel,
2246d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            unsigned Type,
2256d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            unsigned Size,
2266d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky                                            int64_t Addend) {
227cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // If the relocation is PC-relative, the value to be encoded is the
228cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  // pointer difference.
229cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (isPCRel) {
23061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    Value -= FinalAddress;
231cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // ARM PCRel relocations have an effective-PC offset of two instructions
232cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // (four bytes in Thumb mode, 8 bytes in ARM mode).
233cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: For now, assume ARM mode.
234cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value -= 8;
235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
236cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
237cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  switch(Type) {
238cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  default:
239cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    llvm_unreachable("Invalid relocation type!");
240cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_Vanilla: {
241cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask in the target value a byte at a time (we don't have an alignment
242cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // guarantee for the target address, so this is safest).
24361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint8_t *p = (uint8_t*)LocalAddress;
244cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    for (unsigned i = 0; i < Size; ++i) {
245cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      *p++ = (uint8_t)Value;
246cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev      Value >>= 8;
247cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
248cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    break;
249cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
250cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_Branch24Bit: {
251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value into the target address. We know instructions are
252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // 32-bit aligned, so we can do it all at once.
25361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan    uint32_t *p = (uint32_t*)LocalAddress;
254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // The low two bits of the value are not encoded.
255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value >>= 2;
256cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Mask the value to 24 bits.
257cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    Value &= 0xffffff;
258cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // FIXME: If the destination is a Thumb function (and the instruction
259cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // is a non-predicated BL instruction), we need to change it to a BLX
260cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // instruction instead.
261cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    // Insert the value into the instruction.
263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    *p = (*p & ~0xffffff) | Value;
264cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    break;
265cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
266cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_ThumbBranch22Bit:
267cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_ThumbBranch32Bit:
268cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_Half:
269cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_HalfDifference:
270cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_Pair:
271cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_Difference:
272cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_LocalDifference:
273cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  case macho::RIT_ARM_PreboundLazyPointer:
274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    return Error("Relocation type not implemented yet!");
275cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  }
276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
277cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
279efa91f6475f6e96552986104ab4857db46185a2aRafael Espindolavoid RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
280ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola                                            RelocationRef RelI,
281689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd                                            ObjectImage &Obj,
2820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                            ObjSectionToIDMap &ObjSectionToID,
283d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky                                            const SymbolTableMap &Symbols,
2840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                            StubMap &Stubs) {
285efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  const ObjectFile *OF = Obj.getObjectFile();
286efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF);
287ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola  macho::RelocationEntry RE = MachO->getRelocation(RelI.getRawDataRefImpl());
2880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
289efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  uint32_t RelType = MachO->getAnyRelocationType(RE);
2900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  RelocationValueRef Value;
291efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  SectionEntry &Section = Sections[SectionID];
2920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
293efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola  bool isExtern = MachO->getPlainRelocationExternal(RE);
29487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
29587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola  unsigned Size = MachO->getAnyRelocationLength(RE);
2968e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola  uint64_t Offset;
2978e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola  RelI.getOffset(Offset);
298e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint8_t *LocalAddress = Section.Address + Offset;
299e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  unsigned NumBytes = 1 << Size;
300e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  uint64_t Addend = 0;
301e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  memcpy(&Addend, LocalAddress, NumBytes);
3028e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola
303e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola  if (isExtern) {
304c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // Obtain the symbol name which is referenced in the relocation
3056c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola    symbol_iterator Symbol = RelI.getSymbol();
3060e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StringRef TargetName;
3076c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola    Symbol->getName(TargetName);
308c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    // First search for the symbol in the local symbol table
309d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky    SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
3100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    if (lsi != Symbols.end()) {
3110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Value.SectionID = lsi->second.first;
3128e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      Value.Addend = lsi->second.second + Addend;
3130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    } else {
314c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      // Search for the symbol in the global symbol table
315d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky      SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data());
316d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky      if (gsi != GlobalSymbolTable.end()) {
3170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SectionID = gsi->second.first;
3188e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = gsi->second.second + Addend;
3198e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      } else {
3200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev        Value.SymbolName = TargetName.data();
3218e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola        Value.Addend = Addend;
3228e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola      }
323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev    }
3240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev  } else {
325e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    SectionRef Sec = MachO->getRelocationSection(RE);
326e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
327e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    uint64_t Addr;
328e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Sec.getAddress(Addr);
329e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola    Value.Addend = Addend - Addr;
330288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling  }
331288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling
332a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  if (Arch == Triple::x86_64 && RelType == macho::RIT_X86_64_GOT) {
333a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(IsPCRel);
334a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    assert(Size == 2);
335a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    StubMap::const_iterator i = Stubs.find(Value);
336a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    uint8_t *Addr;
337a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    if (i != Stubs.end()) {
338a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = Section.Address + i->second;
339a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    } else {
340a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Stubs[Value] = Section.StubOffset;
341a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      uint8_t *GOTEntry = Section.Address + Section.StubOffset;
342a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      RelocationEntry RE(SectionID, Section.StubOffset,
343a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola                         macho::RIT_X86_64_Unsigned, Value.Addend - 4, false,
344a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola                         3);
345a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      if (Value.SymbolName)
346a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola        addRelocationForSymbol(RE, Value.SymbolName);
347a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      else
348a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola        addRelocationForSection(RE, Value.SectionID);
349a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Section.StubOffset += 8;
350a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola      Addr = GOTEntry;
351a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    }
352a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola    resolveRelocation(Section, Offset, (uint64_t)Addr,
353a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola                      macho::RIT_X86_64_Unsigned, 4, true, 2);
354a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola  } else if (Arch == Triple::arm &&
355a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola             (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) {
3560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    // This is an ARM branch relocation, need to use a stub function.
3570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev
3580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    //  Look up for existing stub.
3590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    StubMap::const_iterator i = Stubs.find(Value);
3600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    if (i != Stubs.end())
361efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      resolveRelocation(Section, Offset,
3620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                        (uint64_t)Section.Address + i->second,
36387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                        RelType, 0, IsPCRel, Size);
3640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    else {
3650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      // Create a new stub function.
3660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Stubs[Value] = Section.StubOffset;
3670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      uint8_t *StubTargetAddr = createStubFunction(Section.Address +
3680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                                                   Section.StubOffset);
369efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
370c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky                         macho::RIT_Vanilla, Value.Addend);
371c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      if (Value.SymbolName)
372c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky        addRelocationForSymbol(RE, Value.SymbolName);
373c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      else
374c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky        addRelocationForSection(RE, Value.SectionID);
375efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola      resolveRelocation(Section, Offset,
3760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev                        (uint64_t)Section.Address + Section.StubOffset,
37787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                        RelType, 0, IsPCRel, Size);
3780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev      Section.StubOffset += getMaxStubSize();
3790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev    }
380c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  } else {
38187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
38287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola                       IsPCRel, Size);
383c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    if (Value.SymbolName)
384c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSymbol(RE, Value.SymbolName);
385c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky    else
386c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky      addRelocationForSection(RE, Value.SectionID);
387c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky  }
388cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
389cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
390cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
3916d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat(
3923f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor        const ObjectBuffer *InputBuffer) const {
3933f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  if (InputBuffer->getBufferSize() < 4)
3943f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor    return false;
3953f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  StringRef Magic(InputBuffer->getBufferStart(), 4);
396cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xFE\xED\xFA\xCE") return true;
397cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xCE\xFA\xED\xFE") return true;
398cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xFE\xED\xFA\xCF") return true;
399cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  if (Magic == "\xCF\xFA\xED\xFE") return true;
400cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev  return false;
401cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev}
402cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev
403cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm
404