/*
 * 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 unsigned 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)
    {
        if ((frame->AddrPC.Mode == AddrModeFlat) &&
            (frame->AddrFrame.Mode != AddrModeFlat))
        {
            WARN("Bad AddrPC.Mode / AddrFrame.Mode combination\n");
            goto done_err;
        }

        /* 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)
{
    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)
{
    FIXME("NIY\n");
    return FALSE;
}

static BOOL arm_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
{
    FIXME("NIY\n");
    return FALSE;
}

DECLSPEC_HIDDEN struct cpu cpu_arm = {
    IMAGE_FILE_MACHINE_ARMV7,
    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,
};
