20void MachOReader::readHeader(
Object &O)
 const {
 
   21  O.Header.Magic = MachOObj.getHeader().magic;
 
   22  O.Header.CPUType = MachOObj.getHeader().cputype;
 
   23  O.Header.CPUSubType = MachOObj.getHeader().cpusubtype;
 
   24  O.Header.FileType = MachOObj.getHeader().filetype;
 
   25  O.Header.NCmds = MachOObj.getHeader().ncmds;
 
   26  O.Header.SizeOfCmds = MachOObj.getHeader().sizeofcmds;
 
   27  O.Header.Flags = MachOObj.getHeader().flags;
 
   30template <
typename SectionType>
 
   32  StringRef SegName(Sec.segname, strnlen(Sec.segname, 
sizeof(Sec.segname)));
 
   33  StringRef SectName(Sec.sectname, strnlen(Sec.sectname, 
sizeof(Sec.sectname)));
 
 
   59template <
typename SectionType, 
typename SegmentType>
 
   63  std::vector<std::unique_ptr<Section>> Sections;
 
   64  for (
auto Curr = 
reinterpret_cast<const SectionType *
>(LoadCmd.
Ptr +
 
   66            End = 
reinterpret_cast<const SectionType *
>(LoadCmd.
Ptr +
 
   70    memcpy((
void *)&Sec, 
reinterpret_cast<const char *
>(Curr),
 
   89      return Data.takeError();
 
  112           "Incorrect number of relocations");
 
  114  return std::move(Sections);
 
 
  117Error MachOReader::readLoadCommands(
Object &O)
 const {
 
  119  uint32_t NextSectionIndex = 1;
 
  120  static constexpr char TextSegmentName[] = 
"__TEXT";
 
  121  for (
auto LoadCmd : MachOObj.load_commands()) {
 
  123    switch (LoadCmd.C.cmd) {
 
  124    case MachO::LC_CODE_SIGNATURE:
 
  125      O.CodeSignatureCommandIndex = 
O.LoadCommands.size();
 
  127    case MachO::LC_SEGMENT:
 
  131      if (StringRef(
reinterpret_cast<const char *
>(
 
  132              LoadCmd.Ptr + 
offsetof(MachO::segment_command, segname))) ==
 
  134        O.TextSegmentCommandIndex = 
O.LoadCommands.size();
 
  136      if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
 
  138                  LoadCmd, MachOObj, NextSectionIndex))
 
  141        return Sections.takeError();
 
  143    case MachO::LC_SEGMENT_64:
 
  147      if (StringRef(
reinterpret_cast<const char *
>(
 
  148              LoadCmd.Ptr + 
offsetof(MachO::segment_command_64, segname))) ==
 
  150        O.TextSegmentCommandIndex = 
O.LoadCommands.size();
 
  152      if (Expected<std::vector<std::unique_ptr<Section>>> Sections =
 
  154                  LoadCmd, MachOObj, NextSectionIndex))
 
  157        return Sections.takeError();
 
  159    case MachO::LC_SYMTAB:
 
  160      O.SymTabCommandIndex = 
O.LoadCommands.size();
 
  162    case MachO::LC_DYSYMTAB:
 
  163      O.DySymTabCommandIndex = 
O.LoadCommands.size();
 
  165    case MachO::LC_DYLD_INFO:
 
  166    case MachO::LC_DYLD_INFO_ONLY:
 
  167      O.DyLdInfoCommandIndex = 
O.LoadCommands.size();
 
  169    case MachO::LC_DATA_IN_CODE:
 
  170      O.DataInCodeCommandIndex = 
O.LoadCommands.size();
 
  172    case MachO::LC_LINKER_OPTIMIZATION_HINT:
 
  173      O.LinkerOptimizationHintCommandIndex = 
O.LoadCommands.size();
 
  175    case MachO::LC_FUNCTION_STARTS:
 
  176      O.FunctionStartsCommandIndex = 
O.LoadCommands.size();
 
  178    case MachO::LC_DYLIB_CODE_SIGN_DRS:
 
  179      O.DylibCodeSignDRsIndex = 
O.LoadCommands.size();
 
  181    case MachO::LC_DYLD_EXPORTS_TRIE:
 
  182      O.ExportsTrieCommandIndex = 
O.LoadCommands.size();
 
  184    case MachO::LC_DYLD_CHAINED_FIXUPS:
 
  185      O.ChainedFixupsCommandIndex = 
O.LoadCommands.size();
 
  188#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct)                         \ 
  189  case MachO::LCName:                                                          \ 
  190    memcpy((void *)&(LC.MachOLoadCommand.LCStruct##_data), LoadCmd.Ptr,        \ 
  191           sizeof(MachO::LCStruct));                                           \ 
  192    if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost)                  \ 
  193      MachO::swapStruct(LC.MachOLoadCommand.LCStruct##_data);                  \ 
  194    if (LoadCmd.C.cmdsize > sizeof(MachO::LCStruct))                           \ 
  195      LC.Payload = ArrayRef<uint8_t>(                                          \ 
  196          reinterpret_cast<uint8_t *>(const_cast<char *>(LoadCmd.Ptr)) +       \ 
  197              sizeof(MachO::LCStruct),                                         \ 
  198          LoadCmd.C.cmdsize - sizeof(MachO::LCStruct));                        \ 
  201    switch (LoadCmd.C.cmd) {
 
  204             sizeof(MachO::load_command));
 
  207      if (LoadCmd.C.cmdsize > 
sizeof(MachO::load_command))
 
  208        LC.
Payload = ArrayRef<uint8_t>(
 
  209            reinterpret_cast<uint8_t *
>(
const_cast<char *
>(LoadCmd.Ptr)) +
 
  210                sizeof(MachO::load_command),
 
  211            LoadCmd.C.cmdsize - 
sizeof(MachO::load_command));
 
  213#include "llvm/BinaryFormat/MachO.def" 
  215    O.LoadCommands.push_back(std::move(LC));
 
  220template <
typename nlist_t>
 
  223         "n_strx exceeds the size of the string table");
 
 
  233void MachOReader::readSymbolTable(
Object &O)
 const {
 
  234  StringRef StrTable = MachOObj.getStringTableData();
 
  235  for (
auto Symbol : MachOObj.symbols()) {
 
  239                                                  Symbol.getRawDataRefImpl()))
 
  241                                                  Symbol.getRawDataRefImpl())));
 
  243    O.SymTable.Symbols.push_back(std::make_unique<SymbolEntry>(SE));
 
  247void MachOReader::setSymbolInRelocationInfo(
Object &O)
 const {
 
  248  std::vector<const Section *> Sections;
 
  249  for (
auto &LC : 
O.LoadCommands)
 
  250    for (std::unique_ptr<Section> &Sec : LC.
Sections)
 
  251      Sections.push_back(Sec.get());
 
  253  for (LoadCommand &LC : 
O.LoadCommands)
 
  254    for (std::unique_ptr<Section> &Sec : LC.
Sections)
 
  255      for (
auto &Reloc : Sec->Relocations)
 
  256        if (!Reloc.Scattered && !Reloc.IsAddend) {
 
  257          const uint32_t SymbolNum =
 
  258              Reloc.getPlainRelocationSymbolNum(MachOObj.isLittleEndian());
 
  260            Reloc.Symbol = 
O.SymTable.getSymbolByIndex(SymbolNum);
 
  264            assert(SymbolNum >= 1 && SymbolNum <= Sections.size() &&
 
  265                   "Invalid section index.");
 
  266            Reloc.Sec = Sections[SymbolNum - 1];
 
  271void MachOReader::readRebaseInfo(
Object &O)
 const {
 
  272  O.Rebases.Opcodes = MachOObj.getDyldInfoRebaseOpcodes();
 
  275void MachOReader::readBindInfo(
Object &O)
 const {
 
  276  O.Binds.Opcodes = MachOObj.getDyldInfoBindOpcodes();
 
  279void MachOReader::readWeakBindInfo(
Object &O)
 const {
 
  280  O.WeakBinds.Opcodes = MachOObj.getDyldInfoWeakBindOpcodes();
 
  283void MachOReader::readLazyBindInfo(
Object &O)
 const {
 
  284  O.LazyBinds.Opcodes = MachOObj.getDyldInfoLazyBindOpcodes();
 
  287void MachOReader::readExportInfo(
Object &O)
 const {
 
  289  ArrayRef<uint8_t> Trie = MachOObj.getDyldInfoExportsTrie();
 
  291    Trie = MachOObj.getDyldExportsTrie();
 
  292  O.Exports.Trie = Trie;
 
  295void MachOReader::readLinkData(
Object &O, std::optional<size_t> LCIndex,
 
  299  const MachO::linkedit_data_command &LC =
 
  300      O.LoadCommands[*LCIndex].MachOLoadCommand.linkedit_data_command_data;
 
  305void MachOReader::readDataInCodeData(
Object &O)
 const {
 
  306  return readLinkData(O, 
O.DataInCodeCommandIndex, 
O.DataInCode);
 
  309void MachOReader::readLinkerOptimizationHint(
Object &O)
 const {
 
  310  return readLinkData(O, 
O.LinkerOptimizationHintCommandIndex,
 
  311                      O.LinkerOptimizationHint);
 
  314void MachOReader::readFunctionStartsData(
Object &O)
 const {
 
  315  return readLinkData(O, 
O.FunctionStartsCommandIndex, 
O.FunctionStarts);
 
  318void MachOReader::readDylibCodeSignDRs(
Object &O)
 const {
 
  319  return readLinkData(O, 
O.DylibCodeSignDRsIndex, 
O.DylibCodeSignDRs);
 
  322void MachOReader::readExportsTrie(
Object &O)
 const {
 
  323  return readLinkData(O, 
O.ExportsTrieCommandIndex, 
O.ExportsTrie);
 
  326void MachOReader::readChainedFixups(
Object &O)
 const {
 
  327  return readLinkData(O, 
O.ChainedFixupsCommandIndex, 
O.ChainedFixups);
 
  330void MachOReader::readIndirectSymbolTable(
Object &O)
 const {
 
  331  MachO::dysymtab_command DySymTab = MachOObj.getDysymtabLoadCommand();
 
  332  constexpr uint32_t AbsOrLocalMask =
 
  335    uint32_t 
Index = MachOObj.getIndirectSymbolTableEntry(DySymTab, i);
 
  336    if ((Index & AbsOrLocalMask) != 0)
 
  337      O.IndirectSymTable.Symbols.emplace_back(Index, std::nullopt);
 
  339      O.IndirectSymTable.Symbols.emplace_back(
 
  340          Index, 
O.SymTable.getSymbolByIndex(Index));
 
  344void MachOReader::readSwiftVersion(
Object &O)
 const {
 
  345  struct ObjCImageInfo {
 
  350  for (
const LoadCommand &LC : 
O.LoadCommands)
 
  351    for (
const std::unique_ptr<Section> &Sec : LC.
Sections)
 
  352      if (Sec->Sectname == 
"__objc_imageinfo" &&
 
  353          (Sec->Segname == 
"__DATA" || Sec->Segname == 
"__DATA_CONST" ||
 
  354           Sec->Segname == 
"__DATA_DIRTY") &&
 
  355          Sec->Content.size() >= 
sizeof(ObjCImageInfo)) {
 
  356        memcpy(&ImageInfo, Sec->Content.data(), 
sizeof(ObjCImageInfo));
 
  361        O.SwiftVersion = (ImageInfo.Flags >> 8) & 0xff;
 
  367  auto Obj = std::make_unique<Object>();
 
  369  if (
Error E = readLoadCommands(*Obj))
 
  371  readSymbolTable(*Obj);
 
  372  setSymbolInRelocationInfo(*Obj);
 
  373  readRebaseInfo(*Obj);
 
  375  readWeakBindInfo(*Obj);
 
  376  readLazyBindInfo(*Obj);
 
  377  readExportInfo(*Obj);
 
  378  readDataInCodeData(*Obj);
 
  379  readLinkerOptimizationHint(*Obj);
 
  380  readFunctionStartsData(*Obj);
 
  381  readDylibCodeSignDRs(*Obj);
 
  382  readExportsTrie(*Obj);
 
  383  readChainedFixups(*Obj);
 
  384  readIndirectSymbolTable(*Obj);
 
  385  readSwiftVersion(*Obj);
 
  386  return std::move(Obj);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define offsetof(TYPE, MEMBER)
static Section constructSectionCommon(const SectionType &Sec, uint32_t Index)
static Expected< std::vector< std::unique_ptr< Section > > > extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd, const object::MachOObjectFile &MachOObj, uint32_t &NextSectionIndex)
Section constructSection(const MachO::section &Sec, uint32_t Index)
SymbolEntry constructSymbolEntry(StringRef StrTable, const nlist_t &nlist)
bool empty() const
empty - Check if the array is empty.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
The instances of the Type class are immutable: once they are created, they are never changed.
Expected< std::unique_ptr< Object > > create() const override
bool isLittleEndian() const
Expected< SectionRef > getSection(unsigned SectionIndex) const
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
ArrayRef< uint8_t > getSectionContents(uint32_t Offset, uint64_t Size) const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
const MachO::mach_header & getHeader() const
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
void swapStruct(fat_header &mh)
constexpr bool IsLittleEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
FunctionAddr VTableAddr uintptr_t uintptr_t Data
MachO::macho_load_command MachOLoadCommand
std::vector< std::unique_ptr< Section > > Sections
std::vector< uint8_t > Payload
std::optional< uint32_t > OriginalOffset
std::vector< RelocationInfo > Relocations