// 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.

// Author: Alfred Peng

#include <dirent.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/frame.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <functional>

#include "client/solaris/handler/solaris_lwp.h"
#include "common/solaris/message_output.h"

using namespace google_breakpad;

// This unamed namespace contains helper function.
namespace {

uintptr_t stack_base_address = 0;
static const int HEADER_MAX = 2000;
static const int MAP_MAX = 1000;

// Context information for the callbacks when validating address by listing
// modules.
struct AddressValidatingContext {
  uintptr_t address;
  bool is_mapped;

  AddressValidatingContext() : address(0UL), is_mapped(false) {
  }
};

// Convert from string to int.
static bool LocalAtoi(char *s, int *r) {
  assert(s != NULL);
  assert(r != NULL);
  char *endptr = NULL;
  int ret = strtol(s, &endptr, 10);
  if (endptr == s)
    return false;
  *r = ret;
  return true;
}

// Callback invoked for each mapped module.
// It uses the module's adderss range to validate the address.
static bool AddressNotInModuleCallback(const ModuleInfo &module_info,
                                       void *context) {
  AddressValidatingContext *addr =
    reinterpret_cast<AddressValidatingContext *>(context);
  if (addr->is_mapped = ((module_info.start_addr > 0) &&
                         (addr->address >= module_info.start_addr) &&
                         (addr->address <= module_info.start_addr +
                          module_info.size))) {
    stack_base_address = module_info.start_addr + module_info.size;
  }

  return !addr->is_mapped;
}

static int IterateLwpAll(int pid,
                         CallbackParam<LwpidCallback> *callback_param) {
  char lwp_path[40];
  DIR *dir;
  int count = 0;

  snprintf(lwp_path, sizeof (lwp_path), "/proc/%d/lwp", (int)pid);
  if ((dir = opendir(lwp_path)) == NULL)
    return -1;

  struct dirent *entry = NULL;
  while ((entry = readdir(dir)) != NULL) {
    if ((strcmp(entry->d_name, ".") != 0) &&
        (strcmp(entry->d_name, "..") != 0)) {
      int lwpid = 0;
      int last_pid = 0;
      if (LocalAtoi(entry->d_name, &lwpid) && last_pid != lwpid) {
        last_pid = lwpid;
        ++count;
        if (callback_param &&
            !(callback_param->call_back)(lwpid, callback_param->context)) {
          break;
        }
      }
    }
  }

  closedir(dir);
  return count;
}

#if defined(__i386) && !defined(NO_FRAME_POINTER)
void *GetNextFrame(void **last_ebp) {
  void *sp = *last_ebp;
  if ((unsigned long)sp == (unsigned long)last_ebp)
    return NULL;
  if ((unsigned long)sp & (sizeof(void *) - 1))
    return NULL;
  if ((unsigned long)sp - (unsigned long)last_ebp > 100000)
    return NULL;
  return sp;
}
#elif defined(__sparc)
void *GetNextFrame(void *last_ebp) {
  return reinterpret_cast<struct frame *>(last_ebp)->fr_savfp;
}
#else
void *GetNextFrame(void **last_ebp) {
  return reinterpret_cast<void*>(last_ebp);
}
#endif


class AutoCloser {
 public:
  AutoCloser(int fd) : fd_(fd) {}
  ~AutoCloser() { if (fd_) close(fd_); }
 private:
  int fd_;
};

// Control the execution of the lwp.
// Suspend/Resume lwp based on the value of context.
static bool ControlLwp(int lwpid, void *context) {
  // The current thread is the one to handle the crash. Ignore it.
  if (lwpid != pthread_self()) {
    int ctlfd;
    char procname[PATH_MAX];
    bool suspend = *(bool *)context;

    // Open the /proc/$pid/lwp/$lwpid/lwpctl files
    snprintf(procname, sizeof (procname), "/proc/self/lwp/%d/lwpctl", lwpid);

    if ((ctlfd = open(procname, O_WRONLY|O_EXCL)) < 0) {
      print_message2(2, "failed to open %s in ControlLwp\n", procname);
      return false;
    }

    AutoCloser autocloser(ctlfd);

    long ctl[2];
    ctl[0] = suspend ? PCSTOP : PCRUN;
    ctl[1] = 0;
    if (write(ctlfd, ctl, sizeof (ctl)) != sizeof (ctl)) {
      print_message2(2, "failed in lwp %d\n", lwpid);
      return false;
    }
  }

  return true;
}

/*
 * Utility function to read the contents of a file that contains a
 * prheader_t at the start (/proc/$pid/lstatus or /proc/$pid/lpsinfo).
 * Return true on success.
 */
static bool read_lfile(int pid, const char *lname, prheader_t *lhp) {
  char lpath[PATH_MAX];
  struct stat statb;
  int fd;
  size_t size;

  snprintf(lpath, sizeof (lpath), "/proc/%d/%s", pid, lname);
  if ((fd = open(lpath, O_RDONLY)) < 0) {
    print_message2(2, "failed to open %s in read_lfile\n", lpath);
    return false;
  }

  AutoCloser autocloser(fd);

  if (fstat(fd, &statb) != 0)
    return false;

  size = statb.st_size;
  if ((size / sizeof (prheader_t)) + 32 > HEADER_MAX) {
    print_message1(2, "map size overflow\n");
    return false;
  }

  if (pread(fd, lhp, size, 0) <= sizeof (prheader_t))
    return false;

  return true;
}

}  // namespace

namespace google_breakpad {

SolarisLwp::SolarisLwp(int pid) : pid_(pid) {
}

SolarisLwp::~SolarisLwp() {
}

int SolarisLwp::ControlAllLwps(bool suspend) {
  CallbackParam<LwpidCallback> callback_param(ControlLwp, &suspend);
  return IterateLwpAll(pid_, &callback_param);
}

int SolarisLwp::GetLwpCount() const {
  return IterateLwpAll(pid_, NULL);
}

int SolarisLwp::Lwp_iter_all(int pid,
                             CallbackParam<LwpCallback> *callback_param) const {
  lwpstatus_t *Lsp;
  lwpstatus_t *sp;
  prheader_t lphp[HEADER_MAX];
  prheader_t lhp[HEADER_MAX];
  prheader_t *Lphp = lphp;
  prheader_t *Lhp = lhp;
  lwpsinfo_t *Lpsp;
  long nstat;
  long ninfo;
  int rv = 0;

  /*
   * The /proc/pid/lstatus file has the array of lwpstatus_t's and the
   * /proc/pid/lpsinfo file has the array of lwpsinfo_t's.
   */
  if (read_lfile(pid, "lstatus", Lhp) == NULL)
    return -1;
  if (read_lfile(pid, "lpsinfo", Lphp) == NULL) {
    return -1;
  }

  Lsp = (lwpstatus_t *)(uintptr_t)(Lhp + 1);
  Lpsp = (lwpsinfo_t *)(uintptr_t)(Lphp + 1);

  for (ninfo = Lphp->pr_nent; ninfo != 0; --ninfo) {
    if (Lpsp->pr_sname != 'Z') {
      sp = Lsp;
      Lsp = (lwpstatus_t *)((uintptr_t)Lsp + Lhp->pr_entsize);
    } else {
      sp = NULL;
    }
    if (callback_param &&
        !(callback_param->call_back)(sp, callback_param->context))
      break;
    ++rv;
    Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize);
  }

  return rv;
}

uintptr_t SolarisLwp::GetLwpStackBottom(uintptr_t current_esp) const {
  AddressValidatingContext addr;
  addr.address = current_esp;
  CallbackParam<ModuleCallback> callback_param(AddressNotInModuleCallback,
                                               &addr);
  ListModules(&callback_param);
  return stack_base_address;
}

int SolarisLwp::GetModuleCount() const {
  return ListModules(NULL);
}

int SolarisLwp::ListModules(
    CallbackParam<ModuleCallback> *callback_param) const {
  const char *maps_path = "/proc/self/map";
  struct stat status;
  int fd = 0, num;
  prmap_t map_array[MAP_MAX];
  prmap_t *maps = map_array;
  size_t size;

  if ((fd = open(maps_path, O_RDONLY)) == -1) {
    print_message2(2, "failed to open %s in ListModules\n", maps_path);
    return -1;
  }

  AutoCloser autocloser(fd);

  if (fstat(fd, &status))
    return -1;

  /*
   * Determine number of mappings, this value must be 
   * larger than the actual module count
   */
  size = status.st_size;
  if ((num = (int)(size / sizeof (prmap_t))) > MAP_MAX) {
    print_message1(2, "map size overflow\n");
    return -1;
  }

  if (read(fd, (void *)maps, size) < 0) {
    print_message2(2, "failed to read %d\n", fd);
    return -1;
  }

  prmap_t *_maps;
  int _num;
  int module_count = 0;
  
  /*
   * Scan each mapping - note it is assummed that the mappings are
   * presented in order.  We fill holes between mappings.  On intel
   * the last mapping is usually the data segment of ld.so.1, after
   * this comes a red zone into which non-fixed mapping won't get
   * place.  Thus we can simply bail from the loop after seeing the
   * last mapping.
   */
  for (_num = 0, _maps = maps; _num < num; ++_num, ++_maps) {
    ModuleInfo module;
    char *name = _maps->pr_mapname;

    memset(&module, 0, sizeof (module));
    module.start_addr = _maps->pr_vaddr;
    module.size = _maps->pr_size;
    if (strlen(name) > 0) {
      int objectfd = 0;
      char path[PATH_MAX];
      char buf[SELFMAG];

      snprintf(path, sizeof (path), "/proc/self/object/%s", name);
      if ((objectfd = open(path, O_RDONLY)) < 0) {
        print_message1(2, "can't open module file\n");
        continue;
      }

      AutoCloser autocloser(objectfd);

      if (read(objectfd, buf, SELFMAG) != SELFMAG) {
        print_message1(2, "can't read module file\n");
        continue;
      }
      if (buf[0] != ELFMAG0 || buf[1] != ELFMAG1 ||
          buf[2] != ELFMAG2 || buf[3] != ELFMAG3) {
        continue;
      }

      strncpy(module.name, name, sizeof (module.name) - 1);
      ++module_count;
    }
    if (callback_param &&
        (!callback_param->call_back(module, callback_param->context))) {
      break;
    }
  }

  return module_count;
}

// Check if the address is a valid virtual address.
// If the address is in any of the mapped modules, we take it as valid.
// Otherwise it is invalid.
bool SolarisLwp::IsAddressMapped(uintptr_t address) const {
  AddressValidatingContext addr;
  addr.address = address;
  CallbackParam<ModuleCallback> callback_param(AddressNotInModuleCallback,
                                               &addr);
  ListModules(&callback_param);
  return addr.is_mapped;
}

// We're looking for a ucontext_t as the second parameter
// to a signal handler function call.  Luckily, the ucontext_t
// has an ebp(fp on SPARC) member which should match the ebp(fp)
// pointed to by the ebp(fp) of the signal handler frame.
// The Solaris stack looks like this:
// http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libproc/common/Pstack.c#81
bool SolarisLwp::FindSigContext(uintptr_t sighandler_ebp,
                                ucontext_t **sig_ctx) {
  uintptr_t previous_ebp;
  uintptr_t sig_ebp;
  const int MAX_STACK_DEPTH = 50;
  int depth_counter = 0;

  do {
#if TARGET_CPU_SPARC
    previous_ebp = reinterpret_cast<uintptr_t>(GetNextFrame(
                                  reinterpret_cast<void*>(sighandler_ebp)));
    *sig_ctx = reinterpret_cast<ucontext_t*>(sighandler_ebp + sizeof (struct frame));
    uintptr_t sig_esp = (*sig_ctx)->uc_mcontext.gregs[REG_O6];
    if (sig_esp < previous_ebp && sig_esp > sighandler_ebp)
      sig_ebp = (uintptr_t)(((struct frame *)sig_esp)->fr_savfp);

#elif TARGET_CPU_X86
    previous_ebp = reinterpret_cast<uintptr_t>(GetNextFrame(
                                  reinterpret_cast<void**>(sighandler_ebp)));
    *sig_ctx = reinterpret_cast<ucontext_t*>(sighandler_ebp + sizeof (struct frame) +
                                             3 * sizeof(uintptr_t));
    sig_ebp = (*sig_ctx)->uc_mcontext.gregs[EBP];
#endif
    sighandler_ebp = previous_ebp;
    depth_counter++;
  } while(previous_ebp != sig_ebp && sighandler_ebp != 0 &&
          IsAddressMapped(sighandler_ebp) && depth_counter < MAX_STACK_DEPTH);

  return previous_ebp == sig_ebp && previous_ebp != 0;
}

}  // namespace google_breakpad
