/* Copyright (C) 2009-2019 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include JIT_READER_H  /* Please see jit-reader.exp for an explanation.  */
#include "jithost.h"

GDB_DECLARE_GPL_COMPATIBLE_READER;

enum register_mapping
{
  AMD64_RA = 16,
  AMD64_RBP = 6,
  AMD64_RSP = 7,
};

struct reader_state
{
  uintptr_t code_begin;
  uintptr_t code_end;
};

static enum gdb_status
read_debug_info (struct gdb_reader_funcs *self,
		 struct gdb_symbol_callbacks *cbs,
                 void *memory, long memory_sz)
{
  struct jithost_abi *symfile = memory;
  struct gdb_object *object = cbs->object_open (cbs);
  struct gdb_symtab *symtab = cbs->symtab_open (cbs, object, "");
  GDB_CORE_ADDR begin = (GDB_CORE_ADDR) symfile->begin;
  GDB_CORE_ADDR end = (GDB_CORE_ADDR) symfile->end;
  struct reader_state *state = (struct reader_state *) self->priv_data;

  /* Record the function's range, for the unwinder.  */
  state->code_begin = begin;
  state->code_end = end;

  cbs->block_open (cbs, symtab, NULL, begin, end, "jit_function_00");

  cbs->symtab_close (cbs, symtab);
  cbs->object_close (cbs, object);
  return GDB_SUCCESS;
}

static void
free_reg_value (struct gdb_reg_value *value)
{
  free (value);
}

static void
write_register (struct gdb_unwind_callbacks *callbacks, int dw_reg,
                uintptr_t value)
{
  const int size = sizeof (uintptr_t);
  struct gdb_reg_value *reg_val =
    malloc (sizeof (struct gdb_reg_value) + size - 1);
  reg_val->defined = 1;
  reg_val->free = free_reg_value;

  memcpy (reg_val->value, &value, size);
  callbacks->reg_set (callbacks, dw_reg, reg_val);
}

static int
read_register (struct gdb_unwind_callbacks *callbacks, int dw_reg,
	       uintptr_t *value)
{
  const int size = sizeof (uintptr_t);
  struct gdb_reg_value *reg_val = callbacks->reg_get (callbacks, dw_reg);
  if (reg_val->size != size || !reg_val->defined)
    {
      reg_val->free (reg_val);
      return 0;
    }
  memcpy (value, reg_val->value, size);
  reg_val->free (reg_val);
  return 1;
}

/* Read the stack pointer into *VALUE.  IP is the address the inferior
   is currently stopped at.  Takes care of demangling the stack
   pointer if necessary.  */

static int
read_sp (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs,
	 uintptr_t ip, uintptr_t *value)
{
  struct reader_state *state = (struct reader_state *) self->priv_data;
  uintptr_t sp;

  if (!read_register (cbs, AMD64_RSP, &sp))
    return GDB_FAIL;

  /* If stopped at the instruction after the "xor $-1, %rsp", demangle
     the stack pointer back.  */
  if (ip == state->code_begin + 5)
    sp ^= (uintptr_t) -1;

  *value = sp;
  return GDB_SUCCESS;
}

static enum gdb_status
unwind_frame (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
{
  const int word_size = sizeof (uintptr_t);
  uintptr_t prev_sp, this_sp;
  uintptr_t prev_ip, this_ip;
  uintptr_t prev_bp, this_bp;
  struct reader_state *state = (struct reader_state *) self->priv_data;

  if (!read_register (cbs, AMD64_RA, &this_ip))
    return GDB_FAIL;

  if (this_ip >= state->code_end || this_ip < state->code_begin)
    return GDB_FAIL;

  /* Unwind RBP in order to make the unwinder that tries to unwind
     from the just-unwound frame happy.  */
  if (!read_register (cbs, AMD64_RBP, &this_bp))
    return GDB_FAIL;
  /* RBP is unmodified.  */
  prev_bp = this_bp;

  /* Fetch the demangled stack pointer.  */
  if (!read_sp (self, cbs, this_ip, &this_sp))
    return GDB_FAIL;

  /* The return address is saved on the stack.  */
  if (cbs->target_read (this_sp, &prev_ip, word_size) == GDB_FAIL)
    return GDB_FAIL;
  prev_sp = this_sp + word_size;

  write_register (cbs, AMD64_RA, prev_ip);
  write_register (cbs, AMD64_RSP, prev_sp);
  write_register (cbs, AMD64_RBP, prev_bp);
  return GDB_SUCCESS;
}

static struct gdb_frame_id
get_frame_id (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
{
  struct reader_state *state = (struct reader_state *) self->priv_data;
  struct gdb_frame_id frame_id;
  uintptr_t ip;
  uintptr_t sp;

  read_register (cbs, AMD64_RA, &ip);
  read_sp (self, cbs, ip, &sp);

  frame_id.code_address = (GDB_CORE_ADDR) state->code_begin;
  frame_id.stack_address = (GDB_CORE_ADDR) sp;

  return frame_id;
}

static void
destroy_reader (struct gdb_reader_funcs *self)
{
  free (self->priv_data);
  free (self);
}

struct gdb_reader_funcs *
gdb_init_reader (void)
{
  struct reader_state *state = calloc (1, sizeof (struct reader_state));
  struct gdb_reader_funcs *reader_funcs =
    malloc (sizeof (struct gdb_reader_funcs));

  reader_funcs->reader_version = GDB_READER_INTERFACE_VERSION;
  reader_funcs->priv_data = state;
  reader_funcs->read = read_debug_info;
  reader_funcs->unwind = unwind_frame;
  reader_funcs->get_frame_id = get_frame_id;
  reader_funcs->destroy = destroy_reader;

  return reader_funcs;
}
