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

#ifndef _LIBBACKTRACE_BACKTRACE_IMPL_H
#define _LIBBACKTRACE_BACKTRACE_IMPL_H

#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>

#include <sys/types.h>
#include <log/log.h>

// Macro to log the function name along with the warning message.
#define BACK_LOGW(format, ...) \
  ALOGW("%s: " format, __PRETTY_FUNCTION__, ##__VA_ARGS__)

class BacktraceImpl {
public:
  virtual ~BacktraceImpl() { }

  virtual bool Unwind(size_t num_ignore_frames) = 0;

  // The name returned is not demangled, Backtrace::GetFunctionName()
  // takes care of demangling the name.
  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) = 0;

  void SetParent(Backtrace* backtrace) { backtrace_obj_ = backtrace; }

  inline pid_t Pid() { return backtrace_obj_->Pid(); }
  inline pid_t Tid() { return backtrace_obj_->Tid(); }

  inline const backtrace_map_t* FindMap(uintptr_t addr) {
    return backtrace_obj_->FindMap(addr);
  }
  inline std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) {
    return backtrace_obj_->GetFunctionName(pc, offset);
  }
  inline BacktraceMap* GetMap() { return backtrace_obj_->GetMap(); }

protected:
  inline std::vector<backtrace_frame_data_t>* GetFrames() { return &backtrace_obj_->frames_; }

  Backtrace* backtrace_obj_;
};

class BacktraceCurrent : public Backtrace {
public:
  BacktraceCurrent(BacktraceImpl* impl, BacktraceMap* map);
  virtual ~BacktraceCurrent();

  bool ReadWord(uintptr_t ptr, uint32_t* out_value);
};

class BacktracePtrace : public Backtrace {
public:
  BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid, BacktraceMap* map);
  virtual ~BacktracePtrace();

  bool ReadWord(uintptr_t ptr, uint32_t* out_value);
};

Backtrace* CreateCurrentObj(BacktraceMap* map);
Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, BacktraceMap* map);
Backtrace* CreateThreadObj(pid_t tid, BacktraceMap* map);

#endif // _LIBBACKTRACE_BACKTRACE_IMPL_H
