/*
 * Copyright (C) 2012 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.
 */

/*
 * Backtracing functions for mips
 */

#define LOG_TAG "Corkscrew"
//#define LOG_NDEBUG 0

#include "../backtrace-arch.h"
#include "../backtrace-helper.h"
#include <corkscrew/ptrace.h>

#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <limits.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/exec_elf.h>
#include <cutils/log.h>

/* For PTRACE_GETREGS */
typedef struct {
    /* FIXME: check this definition */
    uint64_t regs[32];
    uint64_t lo;
    uint64_t hi;
    uint64_t epc;
    uint64_t badvaddr;
    uint64_t status;
    uint64_t cause;
} user_regs_struct;

/* Machine context at the time a signal was raised. */
typedef struct ucontext {
    /* FIXME: use correct definition */
    uint32_t sp;
    uint32_t ra;
    uint32_t pc;
} ucontext_t;

/* Unwind state. */
typedef struct {
    uint32_t sp;
    uint32_t ra;
    uint32_t pc;
} unwind_state_t;

uintptr_t rewind_pc_arch(const memory_t* memory, uintptr_t pc) {
    if (pc == 0)
        return pc;
    if ((pc & 1) == 0)
        return pc-8;            /* jal/bal/jalr + branch delay slot */
    return pc;
}

static ssize_t unwind_backtrace_common(const memory_t* memory,
        const map_info_t* map_info_list,
        unwind_state_t* state, backtrace_frame_t* backtrace,
        size_t ignore_depth, size_t max_depth) {
    size_t ignored_frames = 0;
    size_t returned_frames = 0;

    for (size_t index = 0; returned_frames < max_depth; index++) {
        uintptr_t pc = index ? rewind_pc_arch(memory, state->pc) : state->pc;
        backtrace_frame_t* frame;
        uintptr_t addr;
        int maxcheck = 1024;
        int stack_size = 0, ra_offset = 0;
        bool found_start = false;

        frame = add_backtrace_entry(pc, backtrace, ignore_depth,
                                    max_depth, &ignored_frames, &returned_frames);

        if (frame)
            frame->stack_top = state->sp;

        ALOGV("#%d: frame=%p pc=%08x sp=%08x\n", index, frame, frame->absolute_pc, frame->stack_top);

        for (addr = state->pc; maxcheck-- > 0 && !found_start; addr -= 4) {
            uint32_t op;
            if (!try_get_word(memory, addr, &op))
                break;

            // ALOGV("@0x%08x: 0x%08x\n", addr, op);
            switch (op & 0xffff0000) {
            case 0x27bd0000: // addiu sp, imm
                {
                    // looking for stack being decremented
                    int32_t immediate = ((((int)op) << 16) >> 16);
                    if (immediate < 0) {
                        stack_size = -immediate;
                        found_start = true;
                        ALOGV("@0x%08x: found stack adjustment=%d\n", addr, stack_size);
                    }
                }
                break;
            case 0xafbf0000: // sw ra, imm(sp)
                ra_offset = ((((int)op) << 16) >> 16);
                ALOGV("@0x%08x: found ra offset=%d\n", addr, ra_offset);
                break;
            case 0x3c1c0000: // lui gp
                    ALOGV("@0x%08x: found function boundary\n", addr);
                found_start = true;
                break;
            default:
                break;
            }
        }

        if (ra_offset) {
            uint32_t next_ra;
            if (!try_get_word(memory, state->sp + ra_offset, &next_ra))
                break;
            state->ra = next_ra;
            ALOGV("New ra: 0x%08x\n", state->ra);
        }

        if (stack_size) {
            if (frame)
                frame->stack_size = stack_size;
            state->sp += stack_size;
            ALOGV("New sp: 0x%08x\n", state->sp);
        }

        if (state->pc == state->ra && stack_size == 0)
            break;

        if (state->ra == 0)
            break;

        state->pc = state->ra;
    }

    ALOGV("returning %d frames\n", returned_frames);

    return returned_frames;
}

ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo, void* sigcontext,
        const map_info_t* map_info_list,
        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
    const ucontext_t* uc = (const ucontext_t*)sigcontext;

    unwind_state_t state;
    state.sp = uc->sp;
    state.pc = uc->pc;
    state.ra = uc->ra;

    ALOGV("unwind_backtrace_signal_arch: ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
          ignore_depth, max_depth, state.pc, state.sp, state.ra);

    memory_t memory;
    init_memory(&memory, map_info_list);
    return unwind_backtrace_common(&memory, map_info_list,
            &state, backtrace, ignore_depth, max_depth);
}

ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {

    user_regs_struct regs;
    if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
        return -1;
    }

    unwind_state_t state;
    state.sp = regs.regs[29];
    state.ra = regs.regs[31];
    state.pc = regs.epc;

    ALOGV("unwind_backtrace_ptrace_arch: ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
          ignore_depth, max_depth, state.pc, state.sp, state.ra);

    memory_t memory;
    init_memory_ptrace(&memory, tid);
    return unwind_backtrace_common(&memory, context->map_info_list,
            &state, backtrace, ignore_depth, max_depth);
}
