/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmStandardIncludes.h" // to get CMAKE_USE_MACH_PARSER first
#include "cmMachO.h"

#include <cmsys/FStream.hxx>

// Include the Mach-O format information system header.
#include <mach-o/loader.h>
#include <mach-o/fat.h>

/**

  https://developer.apple.com/library/mac/documentation/
          DeveloperTools/Conceptual/MachORuntime/index.html

  A Mach-O file has 3 major regions: header, load commands and segments.
  Data Structures are provided from <mach-o/loader.h> which
  correspond to the file structure.

  The header can be either a struct mach_header or struct mach_header_64.
  One can peek at the first 4 bytes to identify the type of header.

  Following is the load command region which starts with
  struct load_command, and is followed by n number of load commands.

  In the case of a universal binary (an archive of multiple Mach-O files),
  the file begins with a struct fat_header and is followed by multiple
  struct fat_arch instances.  The struct fat_arch indicates the offset
  for each Mach-O file.

  */

namespace {

  // peek in the file
  template <typename T>
  bool peek(cmsys::ifstream& fin, T &v)
    {
    std::streampos p = fin.tellg();
    if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T)))
      {
      return false;
      }
    fin.seekg(p);
    return fin.good();
    }

  // read from the file and fill a data structure
  template <typename T>
  bool read(cmsys::ifstream& fin, T& v)
    {
    if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T)))
      {
      return false;
      }
    return true;
    }

  // read from the file and fill multiple data structures where
  // the vector has been resized
  template <typename T>
  bool read(cmsys::ifstream& fin, std::vector<T>& v)
    {
    // nothing to read
    if(v.empty())
      {
      return true;
      }
    if(!fin.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size()))
      {
      return false;
      }
    return true;
    }
}


// Contains header and load commands for a single Mach-O file
class cmMachOHeaderAndLoadCommands
{
public:
  // A load_command and its associated data
  struct RawLoadCommand
    {
    uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
      {
      if(this->LoadCommand.size() < sizeof(load_command))
        {
        return 0;
        }
      const load_command* cmd =
        reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
      return m->swap(cmd->cmd);
      }
    std::vector<char> LoadCommand;
    };

  cmMachOHeaderAndLoadCommands(bool _swap)
    : Swap(_swap)
    {
    }
  virtual ~cmMachOHeaderAndLoadCommands()
    {
    }

  virtual bool read_mach_o(cmsys::ifstream& fin) = 0;

  const std::vector<RawLoadCommand>& load_commands() const
    {
    return this->LoadCommands;
    }

  uint32_t swap(uint32_t v) const
    {
    if(this->Swap)
      {
      char* c = reinterpret_cast<char*>(&v);
      std::swap(c[0], c[3]);
      std::swap(c[1], c[2]);
      }
    return v;
    }

protected:
  bool read_load_commands(uint32_t ncmds, uint32_t sizeofcmds,
                          cmsys::ifstream& fin);

  bool Swap;
  std::vector<RawLoadCommand> LoadCommands;
};

// Implementation for reading Mach-O header and load commands.
// This is 32 or 64 bit arch specific.
template <class T>
class cmMachOHeaderAndLoadCommandsImpl : public cmMachOHeaderAndLoadCommands
{
public:
  cmMachOHeaderAndLoadCommandsImpl(bool _swap)
    : cmMachOHeaderAndLoadCommands(_swap)
    {
    }
  bool read_mach_o(cmsys::ifstream& fin)
    {
    if(!read(fin, this->Header))
      {
      return false;
      }
    this->Header.cputype = swap(this->Header.cputype);
    this->Header.cpusubtype = swap(this->Header.cpusubtype);
    this->Header.filetype = swap(this->Header.filetype);
    this->Header.ncmds = swap(this->Header.ncmds);
    this->Header.sizeofcmds = swap(this->Header.sizeofcmds);
    this->Header.flags = swap(this->Header.flags);

    return read_load_commands(this->Header.ncmds,
                              this->Header.sizeofcmds,
                              fin);
    }
protected:
  T Header;
};


bool cmMachOHeaderAndLoadCommands::read_load_commands(uint32_t ncmds,
                                                      uint32_t sizeofcmds,
                                                      cmsys::ifstream& fin)
{
  uint32_t size_read = 0;
  this->LoadCommands.resize(ncmds);
  for(uint32_t i = 0; i<ncmds; i++)
    {
    load_command lc;
    if(!peek(fin, lc))
      {
      return false;
      }
    lc.cmd = swap(lc.cmd);
    lc.cmdsize = swap(lc.cmdsize);
    size_read += lc.cmdsize;

    RawLoadCommand& c = this->LoadCommands[i];
    c.LoadCommand.resize(lc.cmdsize);
    if(!read(fin, c.LoadCommand))
      {
      return false;
      }
    }

  if(size_read != sizeofcmds)
    {
    this->LoadCommands.clear();
    return false;
    }

  return true;
}

//----------------------------------------------------------------------------
class cmMachOInternal
{
public:
  cmMachOInternal(const char* fname);
  ~cmMachOInternal();

  // read a Mach-O file
  bool read_mach_o(uint32_t file_offset);

  // the file we are reading
  cmsys::ifstream Fin;

  // The archs in the universal binary
  // If the binary is not a universal binary, this will be empty.
  std::vector<fat_arch> FatArchs;

  // the error message while parsing
  std::string ErrorMessage;

  // the list of Mach-O's
  std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
};

cmMachOInternal::cmMachOInternal(const char* fname)
  : Fin(fname)
{
  // Quit now if the file could not be opened.
  if(!this->Fin || !this->Fin.get() )
    {
    this->ErrorMessage = "Error opening input file.";
    return;
    }

  if(!this->Fin.seekg(0))
    {
    this->ErrorMessage = "Error seeking to beginning of file.";
    return;
    }

  // Read the binary identification block.
  uint32_t magic = 0;
  if(!peek(this->Fin, magic))
    {
    this->ErrorMessage = "Error reading Mach-O identification.";
    return;
    }

  // Verify the binary identification.
  if(!(magic == MH_CIGAM ||
       magic == MH_MAGIC ||
       magic == MH_CIGAM_64 ||
       magic == MH_MAGIC_64 ||
       magic == FAT_CIGAM ||
       magic == FAT_MAGIC))
    {
    this->ErrorMessage = "File does not have a valid Mach-O identification.";
    return;
    }

  if(magic == FAT_MAGIC || magic == FAT_CIGAM)
    {
    // this is a universal binary
    fat_header header;
    if(!read(this->Fin, header))
      {
      this->ErrorMessage = "Error reading fat header.";
      return;
      }

    // read fat_archs
    this->FatArchs.resize(OSSwapBigToHostInt32(header.nfat_arch));
    if(!read(this->Fin, this->FatArchs))
      {
      this->ErrorMessage = "Error reading fat header archs.";
      return;
      }

    // parse each Mach-O file
    for(size_t i=0; i<this->FatArchs.size(); i++)
      {
      const fat_arch& arch = this->FatArchs[i];
      if(!this->read_mach_o(OSSwapBigToHostInt32(arch.offset)))
        {
        return;
        }
      }
    }
  else
    {
    // parse Mach-O file at the beginning of the file
    this->read_mach_o(0);
    }
}

cmMachOInternal::~cmMachOInternal()
{
  for(size_t i=0; i<this->MachOList.size(); i++)
    {
    delete this->MachOList[i];
    }
}

bool cmMachOInternal::read_mach_o(uint32_t file_offset)
{
  if(!this->Fin.seekg(file_offset))
    {
    this->ErrorMessage = "Failed to locate Mach-O content.";
    return false;
    }

  uint32_t magic;
  if(!peek(this->Fin, magic))
    {
    this->ErrorMessage = "Error reading Mach-O identification.";
    return false;
    }

  cmMachOHeaderAndLoadCommands* f = NULL;
  if(magic == MH_CIGAM || magic == MH_MAGIC)
    {
    bool swap = false;
    if(magic == MH_CIGAM)
      {
      swap = true;
      }
    f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
    }
  else if(magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
    {
    bool swap = false;
    if(magic == MH_CIGAM_64)
      {
      swap = true;
      }
    f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
    }

  if(f && f->read_mach_o(this->Fin))
    {
    this->MachOList.push_back(f);
    }
  else
    {
    delete f;
    this->ErrorMessage = "Failed to read Mach-O header.";
    return false;
    }

  return true;
}

//============================================================================
// External class implementation.

//----------------------------------------------------------------------------
cmMachO::cmMachO(const char* fname): Internal(0)
{
  this->Internal = new cmMachOInternal(fname);

}

//----------------------------------------------------------------------------
cmMachO::~cmMachO()
{
  delete this->Internal;
}

std::string const& cmMachO::GetErrorMessage() const
{
  return this->Internal->ErrorMessage;
}

//----------------------------------------------------------------------------
bool cmMachO::Valid() const
{
  return !this->Internal->MachOList.empty();
}

bool cmMachO::GetInstallName(std::string& install_name)
{
  if(this->Internal->MachOList.empty())
    {
    return false;
    }

  // grab the first Mach-O and get the install name from that one
  cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
  for(size_t i=0; i<macho->load_commands().size(); i++)
    {
    const cmMachOHeaderAndLoadCommands::RawLoadCommand &cmd =
      macho->load_commands()[i];
    uint32_t lc_cmd = cmd.type(macho);
    if(lc_cmd == LC_ID_DYLIB ||
       lc_cmd == LC_LOAD_WEAK_DYLIB ||
       lc_cmd == LC_LOAD_DYLIB)
      {
      if(sizeof(dylib_command) < cmd.LoadCommand.size())
        {
        uint32_t namelen = cmd.LoadCommand.size() - sizeof(dylib_command);
        install_name.assign(&cmd.LoadCommand[sizeof(dylib_command)], namelen);
        return true;
        }
      }
    }

  return false;
}

void cmMachO::PrintInfo(std::ostream& /*os*/) const
{
}
