/*
 * Copyright (C) 2017 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 <stdint.h>

#include <functional>

#include <unwindstack/Elf.h>
#include <unwindstack/MapInfo.h>
#include <unwindstack/Memory.h>
#include <unwindstack/RegsMips64.h>

#include "MachineMips64.h"
#include "UcontextMips64.h"
#include "UserMips64.h"

namespace unwindstack {

RegsMips64::RegsMips64()
    : RegsImpl<uint64_t>(MIPS64_REG_LAST, MIPS64_REG_SP,
                         Location(LOCATION_REGISTER, MIPS64_REG_RA)) {}

ArchEnum RegsMips64::Arch() {
  return ARCH_MIPS64;
}

uint64_t RegsMips64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
  if (!elf->valid()) {
    return rel_pc;
  }

  // For now, just assuming no compact branches
  if (rel_pc < 8) {
    return rel_pc;
  }
  return rel_pc - 8;
}

void RegsMips64::SetFromRaw() {
  set_pc(regs_[MIPS64_REG_PC]);
  set_sp(regs_[MIPS64_REG_SP]);
}

bool RegsMips64::SetPcFromReturnAddress(Memory*) {
  if (pc() == regs_[MIPS64_REG_RA]) {
    return false;
  }

  set_pc(regs_[MIPS64_REG_RA]);
  return true;
}

void RegsMips64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
  fn("r0", regs_[MIPS64_REG_R0]);
  fn("r1", regs_[MIPS64_REG_R1]);
  fn("r2", regs_[MIPS64_REG_R2]);
  fn("r3", regs_[MIPS64_REG_R3]);
  fn("r4", regs_[MIPS64_REG_R4]);
  fn("r5", regs_[MIPS64_REG_R5]);
  fn("r6", regs_[MIPS64_REG_R6]);
  fn("r7", regs_[MIPS64_REG_R7]);
  fn("r8", regs_[MIPS64_REG_R8]);
  fn("r9", regs_[MIPS64_REG_R9]);
  fn("r10", regs_[MIPS64_REG_R10]);
  fn("r11", regs_[MIPS64_REG_R11]);
  fn("r12", regs_[MIPS64_REG_R12]);
  fn("r13", regs_[MIPS64_REG_R13]);
  fn("r14", regs_[MIPS64_REG_R14]);
  fn("r15", regs_[MIPS64_REG_R15]);
  fn("r16", regs_[MIPS64_REG_R16]);
  fn("r17", regs_[MIPS64_REG_R17]);
  fn("r18", regs_[MIPS64_REG_R18]);
  fn("r19", regs_[MIPS64_REG_R19]);
  fn("r20", regs_[MIPS64_REG_R20]);
  fn("r21", regs_[MIPS64_REG_R21]);
  fn("r22", regs_[MIPS64_REG_R22]);
  fn("r23", regs_[MIPS64_REG_R23]);
  fn("r24", regs_[MIPS64_REG_R24]);
  fn("r25", regs_[MIPS64_REG_R25]);
  fn("r26", regs_[MIPS64_REG_R26]);
  fn("r27", regs_[MIPS64_REG_R27]);
  fn("r28", regs_[MIPS64_REG_R28]);
  fn("sp", regs_[MIPS64_REG_SP]);
  fn("r30", regs_[MIPS64_REG_R30]);
  fn("ra", regs_[MIPS64_REG_RA]);
  fn("pc", regs_[MIPS64_REG_PC]);
}

Regs* RegsMips64::Read(void* remote_data) {
  mips64_user_regs* user = reinterpret_cast<mips64_user_regs*>(remote_data);
  RegsMips64* regs = new RegsMips64();
  uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());

  memcpy(regs->RawData(), &user->regs[MIPS64_EF_R0], (MIPS64_REG_R31 + 1) * sizeof(uint64_t));

  reg_data[MIPS64_REG_PC] = user->regs[MIPS64_EF_CP0_EPC];
  regs->SetFromRaw();
  return regs;
}

Regs* RegsMips64::CreateFromUcontext(void* ucontext) {
  mips64_ucontext_t* mips64_ucontext = reinterpret_cast<mips64_ucontext_t*>(ucontext);

  RegsMips64* regs = new RegsMips64();
  // Copy 64 bit sc_regs over to 64 bit regs
  memcpy(regs->RawData(), &mips64_ucontext->uc_mcontext.sc_regs[0], 32 * sizeof(uint64_t));
  (*regs)[MIPS64_REG_PC] = mips64_ucontext->uc_mcontext.sc_pc;
  regs->SetFromRaw();
  return regs;
}

bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
  uint64_t data;
  Memory* elf_memory = elf->memory();
  // Read from elf memory since it is usually more expensive to read from
  // process memory.
  if (!elf_memory->Read(rel_pc, &data, sizeof(data))) {
    return false;
  }

  // Look for the kernel sigreturn function.
  // __vdso_rt_sigreturn:
  // 0x2402145b     li  v0, 0x145b
  // 0x0000000c     syscall
  if (data != 0x0000000c2402145bULL) {
    return false;
  }

  // vdso_rt_sigreturn => read rt_sigframe
  // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset
  // read 64 bit sc_regs[32] from stack into 64 bit regs_
  if (!process_memory->Read(sp() + 24 + 128 + 40, regs_.data(),
                            sizeof(uint64_t) * (MIPS64_REG_LAST - 1))) {
    return false;
  }

  // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset + sc_pc offset
  // read 64 bit sc_pc from stack into 64 bit regs_[MIPS64_REG_PC]
  if (!process_memory->Read(sp() + 24 + 128 + 40 + 576, &regs_[MIPS64_REG_PC],
                            sizeof(uint64_t))) {
    return false;
  }

  SetFromRaw();
  return true;
}

}  // namespace unwindstack
