/*
 * File cpu_arm.c
 *
 * Copyright (C) 2009 Eric Pouech
 * Copyright (C) 2010, 2011 André Hentschel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "dbghelp_private.h"
#include "winternl.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);

static BOOL arm_get_addr(HANDLE hThread, const CONTEXT* ctx,
                         enum cpu_addr ca, ADDRESS64* addr)
{
    addr->Mode    = AddrModeFlat;
    addr->Segment = 0; /* don't need segment */
    switch (ca)
    {
#ifdef __arm__
    case cpu_addr_pc:    addr->Offset = ctx->Pc; return TRUE;
    case cpu_addr_stack: addr->Offset = ctx->Sp; return TRUE;
    case cpu_addr_frame: addr->Offset = ctx->Fp; return TRUE;
#endif
    default: addr->Mode = -1;
        return FALSE;
    }
}

#ifdef __arm__
enum st_mode {stm_start, stm_arm, stm_done};

/* indexes in Reserved array */
#define __CurrentModeCount      0

#define curr_mode   (frame->Reserved[__CurrentModeCount] & 0x0F)
#define curr_count  (frame->Reserved[__CurrentModeCount] >> 4)

#define set_curr_mode(m) {frame->Reserved[__CurrentModeCount] &= ~0x0F; frame->Reserved[__CurrentModeCount] |= (m & 0x0F);}
#define inc_curr_count() (frame->Reserved[__CurrentModeCount] += 0x10)

/* fetch_next_frame()
 *
 * modify (at least) context.Pc using unwind information
 * either out of debug info (dwarf), or simple Lr trace
 */
static BOOL fetch_next_frame(struct cpu_stack_walk* csw,
                               CONTEXT* context, DWORD_PTR curr_pc)
{
    DWORD_PTR               xframe;
    DWORD                   oldReturn = context->Lr;

    if (dwarf2_virtual_unwind(csw, curr_pc, context, &xframe))
    {
        context->Sp = xframe;
        context->Pc = oldReturn;
        return TRUE;
    }

    if (context->Pc == context->Lr) return FALSE;
    context->Pc = oldReturn;

    return TRUE;
}

static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
{
    unsigned    deltapc = curr_count <= 1 ? 0 : 4;

    /* sanity check */
    if (curr_mode >= stm_done) return FALSE;

    TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s Count=%s\n",
          wine_dbgstr_addr(&frame->AddrPC),
          wine_dbgstr_addr(&frame->AddrFrame),
          wine_dbgstr_addr(&frame->AddrReturn),
          wine_dbgstr_addr(&frame->AddrStack),
          curr_mode == stm_start ? "start" : "ARM",
          wine_dbgstr_longlong(curr_count));

    if (curr_mode == stm_start)
    {
        /* Init done */
        set_curr_mode(stm_arm);
        frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrModeFlat;
        /* don't set up AddrStack on first call. Either the caller has set it up, or
         * we will get it in the next frame
         */
        memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
    }
    else
    {
        if (context->Sp != frame->AddrStack.Offset) FIXME("inconsistent Stack Pointer\n");
        if (context->Pc != frame->AddrPC.Offset) FIXME("inconsistent Program Counter\n");

        if (frame->AddrReturn.Offset == 0) goto done_err;
        if (!fetch_next_frame(csw, context, frame->AddrPC.Offset - deltapc))
            goto done_err;
    }

    memset(&frame->Params, 0, sizeof(frame->Params));

    /* set frame information */
    frame->AddrStack.Offset = context->Sp;
    frame->AddrReturn.Offset = context->Lr;
    frame->AddrFrame.Offset = context->Fp;
    frame->AddrPC.Offset = context->Pc;

    frame->Far = TRUE;
    frame->Virtual = TRUE;
    inc_curr_count();

    TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s Count=%s FuncTable=%p\n",
          wine_dbgstr_addr(&frame->AddrPC),
          wine_dbgstr_addr(&frame->AddrFrame),
          wine_dbgstr_addr(&frame->AddrReturn),
          wine_dbgstr_addr(&frame->AddrStack),
          curr_mode == stm_start ? "start" : "ARM",
          wine_dbgstr_longlong(curr_count),
          frame->FuncTableEntry);

    return TRUE;
done_err:
    set_curr_mode(stm_done);
    return FALSE;
}
#else
static BOOL arm_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame, CONTEXT* context)
{
    return FALSE;
}
#endif

static unsigned arm_map_dwarf_register(unsigned regno, BOOL eh_frame)
{
    if (regno <= 15) return CV_ARM_R0 + regno;
    if (regno == 128) return CV_ARM_CPSR;

    FIXME("Don't know how to map register %d\n", regno);
    return CV_ARM_NOREG;
}

static void* arm_fetch_context_reg(CONTEXT* ctx, unsigned regno, unsigned* size)
{
#ifdef __arm__
    switch (regno)
    {
    case CV_ARM_R0 +  0: *size = sizeof(ctx->R0); return &ctx->R0;
    case CV_ARM_R0 +  1: *size = sizeof(ctx->R1); return &ctx->R1;
    case CV_ARM_R0 +  2: *size = sizeof(ctx->R2); return &ctx->R2;
    case CV_ARM_R0 +  3: *size = sizeof(ctx->R3); return &ctx->R3;
    case CV_ARM_R0 +  4: *size = sizeof(ctx->R4); return &ctx->R4;
    case CV_ARM_R0 +  5: *size = sizeof(ctx->R5); return &ctx->R5;
    case CV_ARM_R0 +  6: *size = sizeof(ctx->R6); return &ctx->R6;
    case CV_ARM_R0 +  7: *size = sizeof(ctx->R7); return &ctx->R7;
    case CV_ARM_R0 +  8: *size = sizeof(ctx->R8); return &ctx->R8;
    case CV_ARM_R0 +  9: *size = sizeof(ctx->R9); return &ctx->R9;
    case CV_ARM_R0 + 10: *size = sizeof(ctx->R10); return &ctx->R10;
    case CV_ARM_R0 + 11: *size = sizeof(ctx->Fp); return &ctx->Fp;
    case CV_ARM_R0 + 12: *size = sizeof(ctx->Ip); return &ctx->Ip;

    case CV_ARM_SP: *size = sizeof(ctx->Sp); return &ctx->Sp;
    case CV_ARM_LR: *size = sizeof(ctx->Lr); return &ctx->Lr;
    case CV_ARM_PC: *size = sizeof(ctx->Pc); return &ctx->Pc;
    case CV_ARM_CPSR: *size = sizeof(ctx->Cpsr); return &ctx->Cpsr;
    }
#endif
    FIXME("Unknown register %x\n", regno);
    return NULL;
}

static const char* arm_fetch_regname(unsigned regno)
{
    switch (regno)
    {
    case CV_ARM_R0 +  0: return "r0";
    case CV_ARM_R0 +  1: return "r1";
    case CV_ARM_R0 +  2: return "r2";
    case CV_ARM_R0 +  3: return "r3";
    case CV_ARM_R0 +  4: return "r4";
    case CV_ARM_R0 +  5: return "r5";
    case CV_ARM_R0 +  6: return "r6";
    case CV_ARM_R0 +  7: return "r7";
    case CV_ARM_R0 +  8: return "r8";
    case CV_ARM_R0 +  9: return "r9";
    case CV_ARM_R0 + 10: return "r10";
    case CV_ARM_R0 + 11: return "r11";
    case CV_ARM_R0 + 12: return "r12";

    case CV_ARM_SP: return "sp";
    case CV_ARM_LR: return "lr";
    case CV_ARM_PC: return "pc";
    case CV_ARM_CPSR: return "cpsr";
    }
    FIXME("Unknown register %x\n", regno);
    return NULL;
}

static BOOL arm_fetch_minidump_thread(struct dump_context* dc, unsigned index, unsigned flags, const CONTEXT* ctx)
{
    if (ctx->ContextFlags && (flags & ThreadWriteInstructionWindow))
    {
        /* FIXME: crop values across module boundaries, */
#ifdef __arm__
        ULONG base = ctx->Pc <= 0x80 ? 0 : ctx->Pc - 0x80;
        minidump_add_memory_block(dc, base, ctx->Pc + 0x80 - base, 0);
#endif
    }

    return TRUE;
}

static BOOL arm_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
    /* FIXME: actually, we should probably take care of FPO data, unless it's stored in
     * function table minidump stream
     */
    return FALSE;
}

DECLSPEC_HIDDEN struct cpu cpu_arm = {
    IMAGE_FILE_MACHINE_ARMNT,
    4,
    CV_ARM_R0 + 11,
    arm_get_addr,
    arm_stack_walk,
    NULL,
    arm_map_dwarf_register,
    arm_fetch_context_reg,
    arm_fetch_regname,
    arm_fetch_minidump_thread,
    arm_fetch_minidump_module,
};
