119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- MachOObjectFile.cpp - Mach-O object file binding ---------*- C++ -*-===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file defines the MachOObjectFile class, which binds the MachOObject
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// class to the generic ObjectFile wrapper.
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Triple.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Object/MachO.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Object/MachOFormat.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/MemoryBuffer.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cctype>
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cstring>
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <limits>
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace object;
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace llvm {
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace object {
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO,
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 error_code &ec)
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    : ObjectFile(Binary::isMachO, Object, ec),
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachOObj(MOO),
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      RegisteredStringTable(std::numeric_limits<uint32_t>::max()) {
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl DRI;
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.a = DRI.d.b = 0;
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSection(DRI);
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (DRI.d.a < LoadCommandCount) {
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sections.push_back(DRI);
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DRI.d.b++;
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    moveToNextSection(DRI);
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  error_code ec;
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::string Err;
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err);
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MachOObj)
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return NULL;
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new MachOObjectFile(Buffer, MachOObj, ec);
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*===-- Symbols -----------------------------------------------------------===*/
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const {
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (DRI.d.a < LoadCommandCount) {
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (LCI.Command.Type == macho::LCT_Symtab) {
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DRI.d.a++;
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DRI.d.b = 0;
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI,
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> &Res) const {
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RegisteredStringTable != DRI.d.a) {
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->RegisterStringTable(*SymtabLoadCmd);
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RegisteredStringTable = DRI.d.a;
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b,
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 Res);
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI,
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RegisteredStringTable != DRI.d.a) {
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->RegisterStringTable(*SymtabLoadCmd);
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RegisteredStringTable = DRI.d.a;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b,
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   Res);
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolNext(DataRefImpl DRI,
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          SymbolRef &Result) const {
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.b++;
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSymbol(DRI);
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = SymbolRef(DRI, this);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolName(DataRefImpl DRI,
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          StringRef &Result) const {
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(DRI, Entry);
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = MachOObj->getStringAtIndex(Entry->StringIndex);
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(DRI, Entry);
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = MachOObj->getStringAtIndex(Entry->StringIndex);
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolOffset(DataRefImpl DRI,
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             uint64_t &Result) const {
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t SectionOffset;
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t SectionIndex;
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(DRI, Entry);
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Value;
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionIndex = Entry->SectionIndex;
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(DRI, Entry);
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Value;
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SectionIndex = Entry->SectionIndex;
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getSectionAddress(Sections[SectionIndex-1], SectionOffset);
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result -= SectionOffset;
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI,
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             uint64_t &Result) const {
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(DRI, Entry);
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Value;
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(DRI, Entry);
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Value;
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          uint64_t &Result) const {
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = UnknownAddressOrSize;
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI,
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                char &Result) const {
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t Type, Flags;
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(DRI, Entry);
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type = Entry->Type;
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Flags = Entry->Flags;
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(DRI, Entry);
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type = Entry->Type;
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Flags = Entry->Flags;
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  char Char;
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Type & macho::STF_TypeMask) {
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case macho::STT_Undefined:
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Char = 'u';
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case macho::STT_Absolute:
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case macho::STT_Section:
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Char = 's';
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Char = '?';
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Char = toupper(Char);
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = Char;
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::isSymbolInternal(DataRefImpl DRI,
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool &Result) const {
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(DRI, Entry);
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Flags & macho::STF_StabsEntryMask;
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(DRI, Entry);
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Entry->Flags & macho::STF_StabsEntryMask;
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::isSymbolGlobal(DataRefImpl Symb, bool &Res) const {
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(Symb, Entry);
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = Entry->Type & MachO::NlistMaskExternal;
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(Symb, Entry);
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = Entry->Type & MachO::NlistMaskExternal;
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          SymbolRef::SymbolType &Res) const {
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint8_t n_type;
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(Symb, Entry);
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    n_type = Entry->Type;
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(Symb, Entry);
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    n_type = Entry->Type;
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = SymbolRef::ST_Other;
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If this is a STAB debugging symbol, we can do nothing more.
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (n_type & MachO::NlistMaskStab)
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return object_error::success;
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (n_type & MachO::NlistMaskType) {
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MachO::NListTypeUndefined :
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Res = SymbolRef::ST_External;
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MachO::NListTypeSection :
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Res = SymbolRef::ST_Function;
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumansymbol_iterator MachOObjectFile::begin_symbols() const {
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // DRI.d.a = segment number; DRI.d.b = symbol index.
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl DRI;
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.a = DRI.d.b = 0;
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSymbol(DRI);
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return symbol_iterator(SymbolRef(DRI, this));
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumansymbol_iterator MachOObjectFile::end_symbols() const {
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl DRI;
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.a = MachOObj->getHeader().NumLoadCommands;
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.b = 0;
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return symbol_iterator(SymbolRef(DRI, this));
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*===-- Sections ----------------------------------------------------------===*/
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands;
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (DRI.d.a < LoadCommandCount) {
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (LCI.Command.Type == macho::LCT_Segment) {
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InMemoryStruct<macho::SegmentLoadCommand> SegmentLoadCmd;
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd);
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (DRI.d.b < SegmentLoadCmd->NumSections)
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else if (LCI.Command.Type == macho::LCT_Segment64) {
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InMemoryStruct<macho::Segment64LoadCommand> Segment64LoadCmd;
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd);
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (DRI.d.b < Segment64LoadCmd->NumSections)
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DRI.d.a++;
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DRI.d.b = 0;
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionNext(DataRefImpl DRI,
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           SectionRef &Result) const {
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.b++;
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSection(DRI);
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = SectionRef(DRI, this);
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMachOObjectFile::getSection(DataRefImpl DRI,
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            InMemoryStruct<macho::Section> &Res) const {
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::SegmentLoadCommand> SLC;
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSegmentLoadCommand(LCI, SLC);
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSection(LCI, DRI.d.b, Res);
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstd::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SectionList::const_iterator loc =
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::find(Sections.begin(), Sections.end(), Sec);
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(loc != Sections.end() && "Sec is not a valid section!");
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return std::distance(Sections.begin(), loc);
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMachOObjectFile::getSection64(DataRefImpl DRI,
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            InMemoryStruct<macho::Section64> &Res) const {
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::Segment64LoadCommand> SLC;
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSegment64LoadCommand(LCI, SLC);
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadSection64(LCI, DRI.d.b, Res);
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (LCI.Command.Type == macho::LCT_Segment64)
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type.");
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionName(DataRefImpl DRI,
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           StringRef &Result) const {
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: thread safety.
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static char result[34];
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Segment64LoadCommand> SLC;
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->ReadSegment64LoadCommand(LCI, SLC);
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->ReadSection64(LCI, DRI.d.b, Sect);
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcpy(result, Sect->SegmentName);
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcat(result, ",");
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcat(result, Sect->Name);
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SegmentLoadCommand> SLC;
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->ReadSegmentLoadCommand(LCI, SLC);
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachOObj->ReadSection(LCI, DRI.d.b, Sect);
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcpy(result, Sect->SegmentName);
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcat(result, ",");
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    strcat(result, Sect->Name);
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = StringRef(result);
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              uint64_t &Result) const {
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(DRI, Sect);
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Sect->Address;
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(DRI, Sect);
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Sect->Address;
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           uint64_t &Result) const {
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(DRI, Sect);
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Sect->Size;
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(DRI, Sect);
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = Sect->Size;
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               StringRef &Result) const {
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(DRI, Sect);
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = MachOObj->getData(Sect->Offset, Sect->Size);
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(DRI, Sect);
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = MachOObj->getData(Sect->Offset, Sect->Size);
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                uint64_t &Result) const {
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(DRI, Sect);
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = uint64_t(1) << Sect->Align;
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(DRI, Sect);
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = uint64_t(1) << Sect->Align;
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::isSectionText(DataRefImpl DRI,
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool &Result) const {
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, DRI)) {
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(DRI, Sect);
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = !strcmp(Sect->Name, "__text");
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(DRI, Sect);
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = !strcmp(Sect->Name, "__text");
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::isSectionData(DataRefImpl DRI,
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          bool &Result) const {
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Unimplemented.
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = false;
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         bool &Result) const {
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // FIXME: Unimplemented.
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Result = false;
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  DataRefImpl Symb,
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  bool &Result) const {
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SymbolRef::SymbolType ST;
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getSymbolType(Symb, ST);
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (ST == SymbolRef::ST_External) {
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = false;
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return object_error::success;
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t SectBegin, SectEnd;
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getSectionAddress(Sec, SectBegin);
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getSectionSize(Sec, SectEnd);
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SectEnd += SectBegin;
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Symbol64TableEntry> Entry;
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbol64TableEntry(Symb, Entry);
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t SymAddr= Entry->Value;
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::SymbolTableEntry> Entry;
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSymbolTableEntry(Symb, Entry);
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint64_t SymAddr= Entry->Value;
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanrelocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl ret;
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ret.d.a = 0;
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ret.d.b = getSectionIndex(Sec);
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return relocation_iterator(RelocationRef(ret, this));
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanrelocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t last_reloc;
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (is64BitLoadCommand(MachOObj, Sec)) {
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(Sec, Sect);
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    last_reloc = Sect->NumRelocationTableEntries;
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(Sec, Sect);
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    last_reloc = Sect->NumRelocationTableEntries;
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl ret;
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ret.d.a = last_reloc;
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ret.d.b = getSectionIndex(Sec);
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return relocation_iterator(RelocationRef(ret, this));
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumansection_iterator MachOObjectFile::begin_sections() const {
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl DRI;
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.a = DRI.d.b = 0;
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSection(DRI);
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return section_iterator(SectionRef(DRI, this));
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumansection_iterator MachOObjectFile::end_sections() const {
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl DRI;
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.a = MachOObj->getHeader().NumLoadCommands;
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DRI.d.b = 0;
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return section_iterator(SectionRef(DRI, this));
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*===-- Relocations -------------------------------------------------------===*/
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MachOObjectFile::
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumangetRelocation(DataRefImpl Rel,
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              InMemoryStruct<macho::RelocationEntry> &Res) const {
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t relOffset;
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(Sections[Rel.d.b], Sect);
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    relOffset = Sect->RelocationTableOffset;
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(Sections[Rel.d.b], Sect);
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    relOffset = Sect->RelocationTableOffset;
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res);
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              RelocationRef &Res) const {
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++Rel.d.a;
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = RelocationRef(Rel, this);
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 uint64_t &Res) const {
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const uint8_t* sectAddress = base();
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MachOObj->is64Bit()) {
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section64> Sect;
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection64(Sections[Rel.d.b], Sect);
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sectAddress += Sect->Offset;
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InMemoryStruct<macho::Section> Sect;
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getSection(Sections[Rel.d.b], Sect);
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sectAddress += Sect->Offset;
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::RelocationEntry> RE;
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getRelocation(Rel, RE);
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = reinterpret_cast<uintptr_t>(sectAddress + RE->Word0);
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                SymbolRef &Res) const {
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::RelocationEntry> RE;
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getRelocation(Rel, RE);
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint32_t SymbolIdx = RE->Word1 & 0xffffff;
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool isExtern = (RE->Word1 >> 27) & 1;
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DataRefImpl Sym;
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Sym.d.a = Sym.d.b = 0;
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  moveToNextSymbol(Sym);
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (isExtern) {
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0; i < SymbolIdx; i++) {
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sym.d.b++;
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      moveToNextSymbol(Sym);
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands &&
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             "Relocation symbol index out of range!");
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = SymbolRef(Sym, this);
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              uint32_t &Res) const {
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::RelocationEntry> RE;
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getRelocation(Rel, RE);
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = RE->Word1;
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          SmallVectorImpl<char> &Result) const {
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                        int64_t &Res) const {
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InMemoryStruct<macho::RelocationEntry> RE;
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getRelocation(Rel, RE);
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool isExtern = (RE->Word1 >> 27) & 1;
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Res = 0;
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!isExtern) {
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const uint8_t* sectAddress = base();
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (MachOObj->is64Bit()) {
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InMemoryStruct<macho::Section64> Sect;
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      getSection64(Sections[Rel.d.b], Sect);
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      sectAddress += Sect->Offset;
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InMemoryStruct<macho::Section> Sect;
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      getSection(Sections[Rel.d.b], Sect);
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      sectAddress += Sect->Offset;
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Res = reinterpret_cast<uintptr_t>(sectAddress);
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          SmallVectorImpl<char> &Result) const {
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return object_error::success;
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*===-- Miscellaneous -----------------------------------------------------===*/
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanuint8_t MachOObjectFile::getBytesInAddress() const {
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return MachOObj->is64Bit() ? 8 : 4;
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanStringRef MachOObjectFile::getFileFormatName() const {
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MachOObj->is64Bit()) {
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (MachOObj->getHeader().CPUType) {
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case llvm::MachO::CPUTypeI386:
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "Mach-O 32-bit i386";
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case llvm::MachO::CPUTypeARM:
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "Mach-O arm";
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case llvm::MachO::CPUTypePowerPC:
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "Mach-O 32-bit ppc";
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 &&
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             "64-bit object file when we're not 64-bit?");
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "Mach-O 32-bit unknown";
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (MachOObj->getHeader().CPUType) {
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypeX86_64:
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return "Mach-O 64-bit x86-64";
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypePowerPC64:
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return "Mach-O 64-bit ppc64";
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 &&
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           "32-bit object file when we're 64-bit?");
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return "Mach-O 64-bit unknown";
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MachOObjectFile::getArch() const {
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (MachOObj->getHeader().CPUType) {
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypeI386:
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::x86;
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypeX86_64:
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::x86_64;
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypeARM:
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::arm;
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypePowerPC:
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::ppc;
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case llvm::MachO::CPUTypePowerPC64:
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::ppc64;
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Triple::UnknownArch;
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace object
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace llvm
672