LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MachOUniversal.cpp
Go to the documentation of this file.
1 //===- MachOUniversal.cpp - Mach-O universal binary -------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the MachOUniversalBinary class.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
16 #include "llvm/Object/MachO.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/Host.h"
21 
22 using namespace llvm;
23 using namespace object;
24 
25 template<typename T>
26 static void SwapValue(T &Value) {
27  Value = sys::SwapByteOrder(Value);
28 }
29 
30 template<typename T>
31 static void SwapStruct(T &Value);
32 
33 template<>
35  SwapValue(H.magic);
37 }
38 
39 template<>
41  SwapValue(H.cputype);
43  SwapValue(H.offset);
44  SwapValue(H.size);
45  SwapValue(H.align);
46 }
47 
48 template<typename T>
49 static T getUniversalBinaryStruct(const char *Ptr) {
50  T Res;
51  memcpy(&Res, Ptr, sizeof(T));
52  // Universal binary headers have big-endian byte order.
54  SwapStruct(Res);
55  return Res;
56 }
57 
59  const MachOUniversalBinary *Parent, uint32_t Index)
60  : Parent(Parent), Index(Index) {
61  if (Parent == 0 || Index > Parent->getNumberOfObjects()) {
62  clear();
63  } else {
64  // Parse object header.
65  StringRef ParentData = Parent->getData();
66  const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
67  Index * sizeof(MachO::fat_arch);
68  Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
69  if (ParentData.size() < Header.offset + Header.size) {
70  clear();
71  }
72  }
73 }
74 
76  OwningPtr<ObjectFile> &Result) const {
77  if (Parent) {
78  StringRef ParentData = Parent->getData();
79  StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
80  std::string ObjectName =
81  Parent->getFileName().str() + ":" +
84  ObjectData, ObjectName, false);
85  if (ObjectFile *Obj = ObjectFile::createMachOObjectFile(ObjBuffer)) {
86  Result.reset(Obj);
87  return object_error::success;
88  }
89  }
91 }
92 
93 void MachOUniversalBinary::anchor() { }
94 
96  error_code &ec)
98  NumberOfObjects(0) {
99  if (Source->getBufferSize() < sizeof(MachO::fat_header)) {
101  return;
102  }
103  // Check for magic value and sufficient header size.
104  StringRef Buf = getData();
105  MachO::fat_header H= getUniversalBinaryStruct<MachO::fat_header>(Buf.begin());
106  NumberOfObjects = H.nfat_arch;
107  uint32_t MinSize = sizeof(MachO::fat_header) +
108  sizeof(MachO::fat_arch) * NumberOfObjects;
109  if (H.magic != MachO::FAT_MAGIC || Buf.size() < MinSize) {
111  return;
112  }
114 }
115 
117  switch (Arch) {
118  case Triple::x86: CTM = MachO::CPU_TYPE_I386; return true;
119  case Triple::x86_64: CTM = MachO::CPU_TYPE_X86_64; return true;
120  case Triple::arm: CTM = MachO::CPU_TYPE_ARM; return true;
121  case Triple::sparc: CTM = MachO::CPU_TYPE_SPARC; return true;
122  case Triple::ppc: CTM = MachO::CPU_TYPE_POWERPC; return true;
123  case Triple::ppc64: CTM = MachO::CPU_TYPE_POWERPC64; return true;
124  default: return false;
125  }
126 }
127 
130  OwningPtr<ObjectFile> &Result) const {
131  MachO::CPUType CTM;
132  if (!getCTMForArch(Arch, CTM))
134  for (object_iterator I = begin_objects(), E = end_objects(); I != E; ++I) {
135  if (I->getCPUType() == static_cast<uint32_t>(CTM))
136  return I->getAsObjectFile(Result);
137  }
139 }
static MemoryBuffer * getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
static T getUniversalBinaryStruct(const char *Ptr)
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
StringRef substr(size_t Start, size_t N=npos) const
Definition: StringRef.h:392
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:181
ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index)
static void SwapValue(T &Value)
error_code getAsObjectFile(OwningPtr< ObjectFile > &Result) const
StringRef getData() const
Definition: Binary.cpp:37
static bool getCTMForArch(Triple::ArchType Arch, MachO::CPUType &CTM)
static const bool IsLittleEndianHost
Definition: Host.h:38
error_code getObjectForArch(Triple::ArchType Arch, OwningPtr< ObjectFile > &Result) const
iterator begin() const
Definition: StringRef.h:97
void reset(T *P=0)
Definition: OwningPtr.h:51
#define H(x, y, z)
Definition: MD5.cpp:53
object_iterator end_objects() const
virtual unsigned getArch() const
static const char * getArchTypeName(ArchType Kind)
getArchTypeName - Get the canonical name for the Kind architecture.
Definition: Triple.cpp:18
MachOUniversalBinary(MemoryBuffer *Source, error_code &ec)
unsigned char SwapByteOrder(unsigned char C)
Definition: SwapByteOrder.h:71
size_t getBufferSize() const
Definition: MemoryBuffer.h:53
#define I(x, y, z)
Definition: MD5.cpp:54
object_iterator begin_objects() const
LLVM Value Representation.
Definition: Value.h:66
static void SwapStruct(T &Value)
static ObjectFile * createMachOObjectFile(MemoryBuffer *Object)