// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//  dynamic_images.h
//
//    Implements most of the function of the dyld API, but allowing an
//    arbitrary task to be introspected, unlike the dyld API which
//    only allows operation on the current task.  The current implementation
//    is limited to use by 32-bit tasks.

#ifndef CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
#define CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__

#include <mach/mach.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include "mach_vm_compat.h"

namespace google_breakpad {

using std::string;
using std::vector;

//==============================================================================
// The memory layout of this struct matches the dyld_image_info struct
// defined in "dyld_gdb.h" in the darwin source.
typedef struct dyld_image_info32 {
  uint32_t                   load_address_;  // struct mach_header*
  uint32_t                   file_path_;     // char*
  uint32_t                   file_mod_date_;
} dyld_image_info32;

typedef struct dyld_image_info64 {
  uint64_t                   load_address_;  // struct mach_header*
  uint64_t                   file_path_;     // char*
  uint64_t                   file_mod_date_;
} dyld_image_info64;

//==============================================================================
// This is as defined in "dyld_gdb.h" in the darwin source.
// _dyld_all_image_infos (in dyld) is a structure of this type
// which will be used to determine which dynamic code has been loaded.
typedef struct dyld_all_image_infos32 {
  uint32_t                      version;  // == 1 in Mac OS X 10.4
  uint32_t                      infoArrayCount;
  uint32_t                      infoArray;  // const struct dyld_image_info*
  uint32_t                      notification;
  bool                          processDetachedFromSharedRegion;
} dyld_all_image_infos32;

typedef struct dyld_all_image_infos64 {
  uint32_t                      version;  // == 1 in Mac OS X 10.4
  uint32_t                      infoArrayCount;
  uint64_t                      infoArray;  // const struct dyld_image_info*
  uint64_t                      notification;
  bool                          processDetachedFromSharedRegion;
} dyld_all_image_infos64;

// some typedefs to isolate 64/32 bit differences
#ifdef __LP64__
typedef mach_header_64 breakpad_mach_header;
typedef segment_command_64 breakpad_mach_segment_command;
#else
typedef mach_header breakpad_mach_header;
typedef segment_command breakpad_mach_segment_command;
#endif

// Helper functions to deal with 32-bit/64-bit Mach-O differences.
class DynamicImage;
template<typename MachBits>
bool FindTextSection(DynamicImage& image);

template<typename MachBits>
uint32_t GetFileTypeFromHeader(DynamicImage& image);

//==============================================================================
// Represents a single dynamically loaded mach-o image
class DynamicImage {
 public:
  DynamicImage(uint8_t *header,     // data is copied
               size_t header_size,  // includes load commands
               uint64_t load_address,
               string file_path,
               uintptr_t image_mod_date,
               mach_port_t task,
               cpu_type_t cpu_type)
    : header_(header, header + header_size),
      header_size_(header_size),
      load_address_(load_address),
      vmaddr_(0),
      vmsize_(0),
      slide_(0),
      version_(0),
      file_path_(file_path),
      file_mod_date_(image_mod_date),
      task_(task),
      cpu_type_(cpu_type) {
    CalculateMemoryAndVersionInfo();
  }

  // Size of mach_header plus load commands
  size_t GetHeaderSize() const {return header_.size();}

  // Full path to mach-o binary
  string GetFilePath() {return file_path_;}

  uint64_t GetModDate() const {return file_mod_date_;}

  // Actual address where the image was loaded
  uint64_t GetLoadAddress() const {return load_address_;}

  // Address where the image should be loaded
  mach_vm_address_t GetVMAddr() const {return vmaddr_;}

  // Difference between GetLoadAddress() and GetVMAddr()
  ptrdiff_t GetVMAddrSlide() const {return slide_;}

  // Size of the image
  mach_vm_size_t GetVMSize() const {return vmsize_;}

  // Task owning this loaded image
  mach_port_t GetTask() {return task_;}

  // CPU type of the task
  cpu_type_t GetCPUType() {return cpu_type_;}

  // filetype from the Mach-O header.
  uint32_t GetFileType();

  // Return true if the task is a 64-bit architecture.
  bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }

  uint32_t GetVersion() {return version_;}
  // For sorting
  bool operator<(const DynamicImage &inInfo) {
    return GetLoadAddress() < inInfo.GetLoadAddress();
  }

  // Sanity checking
  bool IsValid() {return GetVMSize() != 0;}

 private:
  DynamicImage(const DynamicImage &);
  DynamicImage &operator=(const DynamicImage &);

  friend class DynamicImages;
  template<typename MachBits>
  friend bool FindTextSection(DynamicImage& image);
  template<typename MachBits>
  friend uint32_t GetFileTypeFromHeader(DynamicImage& image);

  // Initializes vmaddr_, vmsize_, and slide_
  void CalculateMemoryAndVersionInfo();

  const vector<uint8_t>   header_;        // our local copy of the header
  size_t                  header_size_;    // mach_header plus load commands
  uint64_t                load_address_;   // base address image is mapped into
  mach_vm_address_t       vmaddr_;
  mach_vm_size_t          vmsize_;
  ptrdiff_t               slide_;
  uint32_t                version_;        // Dylib version
  string                  file_path_;     // path dyld used to load the image
  uintptr_t               file_mod_date_;  // time_t of image file

  mach_port_t             task_;
  cpu_type_t              cpu_type_;        // CPU type of task_
};

//==============================================================================
// DynamicImageRef is just a simple wrapper for a pointer to
// DynamicImage.  The reason we use it instead of a simple typedef is so
// that we can use stl::sort() on a vector of DynamicImageRefs
// and simple class pointers can't implement operator<().
//
class DynamicImageRef {
 public:
  explicit DynamicImageRef(DynamicImage *inP) : p(inP) {}
  // The copy constructor is required by STL
  DynamicImageRef(const DynamicImageRef &inRef) : p(inRef.p) {}

  bool operator<(const DynamicImageRef &inRef) const {
    return (*const_cast<DynamicImageRef*>(this)->p)
      < (*const_cast<DynamicImageRef&>(inRef).p);
  }

  bool operator==(const DynamicImageRef &inInfo) const {
    return (*const_cast<DynamicImageRef*>(this)->p).GetLoadAddress() ==
        (*const_cast<DynamicImageRef&>(inInfo)).GetLoadAddress();
  }

  // Be just like DynamicImage*
  DynamicImage  *operator->() {return p;}
  operator DynamicImage*() {return p;}

 private:
  DynamicImage  *p;
};

// Helper function to deal with 32-bit/64-bit Mach-O differences.
class DynamicImages;
template<typename MachBits>
void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);

//==============================================================================
// An object of type DynamicImages may be created to allow introspection of
// an arbitrary task's dynamically loaded mach-o binaries.  This makes the
// assumption that the current task has send rights to the target task.
class DynamicImages {
 public:
  explicit DynamicImages(mach_port_t task);

  ~DynamicImages() {
    for (int i = 0; i < GetImageCount(); ++i) {
      delete image_list_[i];
    }
  }

  // Returns the number of dynamically loaded mach-o images.
  int GetImageCount() const {return static_cast<int>(image_list_.size());}

  // Returns an individual image.
  DynamicImage *GetImage(int i) {
    if (i < (int)image_list_.size()) {
      return image_list_[i];
    }
    return NULL;
  }

  // Returns the image corresponding to the main executable.
  DynamicImage *GetExecutableImage();
  int GetExecutableImageIndex();

  // Returns the task which we're looking at.
  mach_port_t GetTask() const {return task_;}

  // CPU type of the task
  cpu_type_t GetCPUType() {return cpu_type_;}

  // Return true if the task is a 64-bit architecture.
  bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }

  // Determine the CPU type of the task being dumped.
  static cpu_type_t DetermineTaskCPUType(task_t task);

  // Get the native CPU type of this task.
  static cpu_type_t GetNativeCPUType() {
#if defined(__i386__)
    return CPU_TYPE_I386;
#elif defined(__x86_64__)
    return CPU_TYPE_X86_64;
#elif defined(__ppc__)
    return CPU_TYPE_POWERPC;
#elif defined(__ppc64__)
    return CPU_TYPE_POWERPC64;
#elif defined(__arm__)
    return CPU_TYPE_ARM;
#elif defined(__aarch64__)
    return CPU_TYPE_ARM64;
#else
#error "GetNativeCPUType not implemented for this architecture"
#endif
  }

 private:
  template<typename MachBits>
  friend void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);

  bool IsOurTask() {return task_ == mach_task_self();}

  // Initialization
  void ReadImageInfoForTask();
  uint64_t GetDyldAllImageInfosPointer();

  mach_port_t              task_;
  cpu_type_t               cpu_type_;  // CPU type of task_
  vector<DynamicImageRef>  image_list_;
};

// Fill bytes with the contents of memory at a particular
// location in another task.
kern_return_t ReadTaskMemory(task_port_t target_task,
                             const uint64_t address,
                             size_t length,
                             vector<uint8_t> &bytes);

}   // namespace google_breakpad

#endif // CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
