/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <unistd.h>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <string>

#include <backtrace/Backtrace.h>
#include <cutils/log.h>

#include "Backtrace.h"
#include "thread_utils.h"

//-------------------------------------------------------------------------
// BacktraceImpl functions.
//-------------------------------------------------------------------------
backtrace_t* BacktraceImpl::GetBacktraceData() {
  return &backtrace_obj_->backtrace_;
}

//-------------------------------------------------------------------------
// Backtrace functions.
//-------------------------------------------------------------------------
Backtrace::Backtrace(BacktraceImpl* impl, pid_t pid, backtrace_map_info_t* map_info)
    : impl_(impl), map_info_(map_info), map_info_requires_delete_(false) {
  impl_->SetParent(this);
  backtrace_.num_frames = 0;
  backtrace_.pid = pid;
  backtrace_.tid = -1;

  if (map_info_ == NULL) {
    // Create the map and manage it internally.
    map_info_ = backtrace_create_map_info_list(pid);
    map_info_requires_delete_ = true;
  }
}

Backtrace::~Backtrace() {
  for (size_t i = 0; i < NumFrames(); i++) {
    if (backtrace_.frames[i].func_name) {
      free(backtrace_.frames[i].func_name);
      backtrace_.frames[i].func_name = NULL;
    }
  }

  if (map_info_ && map_info_requires_delete_) {
    backtrace_destroy_map_info_list(map_info_);
    map_info_ = NULL;
  }

  if (impl_) {
    delete impl_;
    impl_ = NULL;
  }
}

bool Backtrace::Unwind(size_t num_ignore_frames) {
  return impl_->Unwind(num_ignore_frames);
}

extern "C" char* __cxa_demangle(const char* mangled, char* buf, size_t* len,
                                int* status);

std::string Backtrace::GetFunctionName(uintptr_t pc, uintptr_t* offset) {
  std::string func_name = impl_->GetFunctionNameRaw(pc, offset);
  if (!func_name.empty()) {
#if defined(__APPLE__)
    // Mac OS' __cxa_demangle demangles "f" as "float"; last tested on 10.7.
    if (symbol_name[0] != '_') {
      return func_name;
    }
#endif
    char* name = __cxa_demangle(func_name.c_str(), 0, 0, 0);
    if (name) {
      func_name = name;
      free(name);
    }
  }
  return func_name;
}

bool Backtrace::VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value) {
  if (ptr & 3) {
    BACK_LOGW("invalid pointer %p", (void*)ptr);
    *out_value = (uint32_t)-1;
    return false;
  }
  return true;
}

const char* Backtrace::GetMapName(uintptr_t pc, uintptr_t* map_start) {
  const backtrace_map_info_t* map_info = FindMapInfo(pc);
  if (map_info) {
    if (map_start) {
      *map_start = map_info->start;
    }
    return map_info->name;
  }
  return NULL;
}

const backtrace_map_info_t* Backtrace::FindMapInfo(uintptr_t ptr) {
  return backtrace_find_map_info(map_info_, ptr);
}

std::string Backtrace::FormatFrameData(size_t frame_num) {
  backtrace_frame_data_t* frame = &backtrace_.frames[frame_num];
  const char* map_name;
  if (frame->map_name) {
    map_name = frame->map_name;
  } else {
    map_name = "<unknown>";
  }
  uintptr_t relative_pc;
  if (frame->map_offset) {
    relative_pc = frame->map_offset;
  } else {
    relative_pc = frame->pc;
  }

  char buf[512];
  if (frame->func_name && frame->func_offset) {
    snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR "  %s (%s+%" PRIuPTR ")",
             frame_num, (int)sizeof(uintptr_t)*2, relative_pc, map_name,
             frame->func_name, frame->func_offset);
  } else if (frame->func_name) {
    snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR "  %s (%s)", frame_num,
             (int)sizeof(uintptr_t)*2, relative_pc, map_name, frame->func_name);
  } else {
    snprintf(buf, sizeof(buf), "#%02zu pc %0*" PRIxPTR "  %s", frame_num,
             (int)sizeof(uintptr_t)*2, relative_pc, map_name);
  }

  return buf;
}

//-------------------------------------------------------------------------
// BacktraceCurrent functions.
//-------------------------------------------------------------------------
BacktraceCurrent::BacktraceCurrent(
    BacktraceImpl* impl, backtrace_map_info_t *map_info) : Backtrace(impl, getpid(), map_info) {

  backtrace_.pid = getpid();
}

BacktraceCurrent::~BacktraceCurrent() {
}

bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) {
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

  const backtrace_map_info_t* map_info = FindMapInfo(ptr);
  if (map_info && map_info->is_readable) {
    *out_value = *reinterpret_cast<uint32_t*>(ptr);
    return true;
  } else {
    BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
    *out_value = static_cast<uint32_t>(-1);
    return false;
  }
}

//-------------------------------------------------------------------------
// BacktracePtrace functions.
//-------------------------------------------------------------------------
BacktracePtrace::BacktracePtrace(
    BacktraceImpl* impl, pid_t pid, pid_t tid, backtrace_map_info_t* map_info)
    : Backtrace(impl, pid, map_info) {
  backtrace_.tid = tid;
}

BacktracePtrace::~BacktracePtrace() {
}

bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) {
  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }

#if defined(__APPLE__)
  BACK_LOGW("MacOS does not support reading from another pid.");
  return false;
#else
  // ptrace() returns -1 and sets errno when the operation fails.
  // To disambiguate -1 from a valid result, we clear errno beforehand.
  errno = 0;
  *out_value = ptrace(PTRACE_PEEKTEXT, Tid(), reinterpret_cast<void*>(ptr), NULL);
  if (*out_value == static_cast<uint32_t>(-1) && errno) {
    BACK_LOGW("invalid pointer %p reading from tid %d, ptrace() strerror(errno)=%s",
              reinterpret_cast<void*>(ptr), Tid(), strerror(errno));
    return false;
  }
  return true;
#endif
}

Backtrace* Backtrace::Create(pid_t pid, pid_t tid, backtrace_map_info_t* map_info) {
  if (pid == BACKTRACE_CURRENT_PROCESS || pid == getpid()) {
    if (tid == BACKTRACE_CURRENT_THREAD || tid == gettid()) {
      return CreateCurrentObj(map_info);
    } else {
      return CreateThreadObj(tid, map_info);
    }
  } else if (tid == BACKTRACE_CURRENT_THREAD) {
    return CreatePtraceObj(pid, pid, map_info);
  } else {
    return CreatePtraceObj(pid, tid, map_info);
  }
}

//-------------------------------------------------------------------------
// Common interface functions.
//-------------------------------------------------------------------------
bool backtrace_create_context_with_map(
    backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames,
    backtrace_map_info_t* map_info) {
  Backtrace* backtrace = Backtrace::Create(pid, tid, map_info);
  if (!backtrace) {
    return false;
  }
  if (!backtrace->Unwind(num_ignore_frames)) {
    delete backtrace;
    return false;
  }

  context->data = backtrace;
  context->backtrace = backtrace->GetBacktrace();
  return true;
}

bool backtrace_create_context(
    backtrace_context_t* context, pid_t pid, pid_t tid, size_t num_ignore_frames) {
  return backtrace_create_context_with_map(context, pid, tid, num_ignore_frames, NULL);
}


void backtrace_destroy_context(backtrace_context_t* context) {
  if (context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    delete backtrace;
    context->data = NULL;
  }
  context->backtrace = NULL;
}

const backtrace_t* backtrace_get_data(backtrace_context_t* context) {
  if (context && context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    return backtrace->GetBacktrace();
  }
  return NULL;
}

bool backtrace_read_word(const backtrace_context_t* context, uintptr_t ptr, uint32_t* value) {
  if (context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    return backtrace->ReadWord(ptr, value);
  }
  return true;
}

const char* backtrace_get_map_name(const backtrace_context_t* context, uintptr_t pc, uintptr_t* map_start) {
  if (context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    return backtrace->GetMapName(pc, map_start);
  }
  return NULL;
}

char* backtrace_get_func_name(const backtrace_context_t* context, uintptr_t pc, uintptr_t* func_offset) {
  if (context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    std::string func_name = backtrace->GetFunctionName(pc, func_offset);
    if (!func_name.empty()) {
      return strdup(func_name.c_str());
    }
  }
  return NULL;
}

void backtrace_format_frame_data(
    const backtrace_context_t* context, size_t frame_num, char* buf,
    size_t buf_size) {
  if (buf_size == 0 || buf == NULL) {
    BACK_LOGW("bad call buf %p buf_size %zu", buf, buf_size);
  } else if (context->data) {
    Backtrace* backtrace = reinterpret_cast<Backtrace*>(context->data);
    std::string line = backtrace->FormatFrameData(frame_num);
    if (line.size() > buf_size) {
      memcpy(buf, line.c_str(), buf_size-1);
      buf[buf_size] = '\0';
    } else {
      memcpy(buf, line.c_str(), line.size()+1);
    }
  }
}
