/* Copyright (C) 2009-2021 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 "jit-reader-host.h"

GDB_DECLARE_GPL_COMPATIBLE_READER;

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

struct reader_state
{
  struct {
    uintptr_t begin;
    uintptr_t end;
  } func_stack_mangle;
};

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, "");

  struct reader_state *state = (struct reader_state *) self->priv_data;

  /* Record the stack mangle function's range, for the unwinder.  */
  state->func_stack_mangle.begin
    = (uintptr_t) symfile->function_stack_mangle.begin;
  state->func_stack_mangle.end
    = (uintptr_t) symfile->function_stack_mangle.end;

  cbs->block_open (cbs, symtab, NULL,
		   (GDB_CORE_ADDR) symfile->function_stack_mangle.begin,
		   (GDB_CORE_ADDR) symfile->function_stack_mangle.end,
		   "jit_function_stack_mangle");

  cbs->block_open (cbs, symtab, NULL,
		   (GDB_CORE_ADDR) symfile->function_add.begin,
		   (GDB_CORE_ADDR) symfile->function_add.end,
		   "jit_function_add");

  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->func_stack_mangle.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->func_stack_mangle.end
      || this_ip < state->func_stack_mangle.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->func_stack_mangle.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;
}
