/* Handle JIT code generation in the inferior for GDB, the GNU Debugger.

   Copyright (C) 2009, 2010 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 "defs.h"

#include "jit.h"
#include "breakpoint.h"
#include "gdbcore.h"
#include "observer.h"
#include "objfiles.h"
#include "symfile.h"
#include "symtab.h"
#include "target.h"
#include "gdb_stat.h"

static const struct objfile_data *jit_objfile_data;

static const char *const jit_break_name = "__jit_debug_register_code";

static const char *const jit_descriptor_name = "__jit_debug_descriptor";

/* This is the address of the JIT descriptor in the inferior.  */

static CORE_ADDR jit_descriptor_addr = 0;

/* This is a boolean indicating whether we're currently registering code.  This
   is used to avoid re-entering the registration code.  We want to check for
   new JITed every time a new object file is loaded, but we want to avoid
   checking for new code while we're registering object files for JITed code.
   Therefore, we flip this variable to 1 before registering new object files,
   and set it to 0 before returning.  */

static int registering_code = 0;

/* Helper cleanup function to clear an integer flag like the one above.  */

static void
clear_int (void *int_addr)
{
  *((int *) int_addr) = 0;
}

struct target_buffer
{
  CORE_ADDR base;
  size_t size;
};

/* Openning the file is a no-op.  */

static void *
mem_bfd_iovec_open (struct bfd *abfd, void *open_closure)
{
  return open_closure;
}

/* Closing the file is just freeing the base/size pair on our side.  */

static int
mem_bfd_iovec_close (struct bfd *abfd, void *stream)
{
  xfree (stream);
  return 1;
}

/* For reading the file, we just need to pass through to target_read_memory and
   fix up the arguments and return values.  */

static file_ptr
mem_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
                     file_ptr nbytes, file_ptr offset)
{
  int err;
  struct target_buffer *buffer = (struct target_buffer *) stream;

  /* If this read will read all of the file, limit it to just the rest.  */
  if (offset + nbytes > buffer->size)
    nbytes = buffer->size - offset;

  /* If there are no more bytes left, we've reached EOF.  */
  if (nbytes == 0)
    return 0;

  err = target_read_memory (buffer->base + offset, (gdb_byte *) buf, nbytes);
  if (err)
    return -1;

  return nbytes;
}

/* For statting the file, we only support the st_size attribute.  */

static int
mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
{
  struct target_buffer *buffer = (struct target_buffer*) stream;

  sb->st_size = buffer->size;
  return 0;
}

/* Open a BFD from the target's memory.  */

static struct bfd *
bfd_open_from_target_memory (CORE_ADDR addr, size_t size, char *target)
{
  const char *filename = xstrdup ("<in-memory>");
  struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));

  buffer->base = addr;
  buffer->size = size;
  return bfd_openr_iovec (filename, target,
                          mem_bfd_iovec_open,
                          buffer,
                          mem_bfd_iovec_pread,
                          mem_bfd_iovec_close,
                          mem_bfd_iovec_stat);
}

/* Helper function for reading the global JIT descriptor from remote memory.  */

static void
jit_read_descriptor (struct gdbarch *gdbarch,
		     struct jit_descriptor *descriptor)
{
  int err;
  struct type *ptr_type;
  int ptr_size;
  int desc_size;
  gdb_byte *desc_buf;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Figure out how big the descriptor is on the remote and how to read it.  */
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  ptr_size = TYPE_LENGTH (ptr_type);
  desc_size = 8 + 2 * ptr_size;  /* Two 32-bit ints and two pointers.  */
  desc_buf = alloca (desc_size);

  /* Read the descriptor.  */
  err = target_read_memory (jit_descriptor_addr, desc_buf, desc_size);
  if (err)
    error (_("Unable to read JIT descriptor from remote memory!"));

  /* Fix the endianness to match the host.  */
  descriptor->version = extract_unsigned_integer (&desc_buf[0], 4, byte_order);
  descriptor->action_flag =
      extract_unsigned_integer (&desc_buf[4], 4, byte_order);
  descriptor->relevant_entry = extract_typed_address (&desc_buf[8], ptr_type);
  descriptor->first_entry =
      extract_typed_address (&desc_buf[8 + ptr_size], ptr_type);
}

/* Helper function for reading a JITed code entry from remote memory.  */

static void
jit_read_code_entry (struct gdbarch *gdbarch,
		     CORE_ADDR code_addr, struct jit_code_entry *code_entry)
{
  int err;
  struct type *ptr_type;
  int ptr_size;
  int entry_size;
  gdb_byte *entry_buf;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Figure out how big the entry is on the remote and how to read it.  */
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  ptr_size = TYPE_LENGTH (ptr_type);
  entry_size = 3 * ptr_size + 8;  /* Three pointers and one 64-bit int.  */
  entry_buf = alloca (entry_size);

  /* Read the entry.  */
  err = target_read_memory (code_addr, entry_buf, entry_size);
  if (err)
    error (_("Unable to read JIT code entry from remote memory!"));

  /* Fix the endianness to match the host.  */
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
  code_entry->next_entry = extract_typed_address (&entry_buf[0], ptr_type);
  code_entry->prev_entry =
      extract_typed_address (&entry_buf[ptr_size], ptr_type);
  code_entry->symfile_addr =
      extract_typed_address (&entry_buf[2 * ptr_size], ptr_type);
  code_entry->symfile_size =
      extract_unsigned_integer (&entry_buf[3 * ptr_size], 8, byte_order);
}

/* This function registers code associated with a JIT code entry.  It uses the
   pointer and size pair in the entry to read the symbol file from the remote
   and then calls symbol_file_add_from_local_memory to add it as though it were
   a symbol file added by the user.  */

static void
jit_register_code (struct gdbarch *gdbarch,
		   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
{
  bfd *nbfd;
  struct section_addr_info *sai;
  struct bfd_section *sec;
  struct objfile *objfile;
  struct cleanup *old_cleanups, *my_cleanups;
  int i;
  const struct bfd_arch_info *b;
  CORE_ADDR *entry_addr_ptr;

  nbfd = bfd_open_from_target_memory (code_entry->symfile_addr,
                                      code_entry->symfile_size, gnutarget);
  old_cleanups = make_cleanup_bfd_close (nbfd);

  /* Check the format.  NOTE: This initializes important data that GDB uses!
     We would segfault later without this line.  */
  if (!bfd_check_format (nbfd, bfd_object))
    {
      printf_unfiltered (_("\
JITed symbol file is not an object file, ignoring it.\n"));
      do_cleanups (old_cleanups);
      return;
    }

  /* Check bfd arch.  */
  b = gdbarch_bfd_arch_info (gdbarch);
  if (b->compatible (b, bfd_get_arch_info (nbfd)) != b)
    warning (_("JITed object file architecture %s is not compatible "
               "with target architecture %s."), bfd_get_arch_info
             (nbfd)->printable_name, b->printable_name);

  /* Read the section address information out of the symbol file.  Since the
     file is generated by the JIT at runtime, it should all of the absolute
     addresses that we care about.  */
  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup_free_section_addr_info (sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
        /* We assume that these virtual addresses are absolute, and do not
           treat them as offsets.  */
        sai->other[i].addr = bfd_get_section_vma (nbfd, sec);
        sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec));
        sai->other[i].sectindex = sec->index;
        ++i;
      }

  /* Raise this flag while we register code so we won't trigger any
     re-registration.  */
  registering_code = 1;
  my_cleanups = make_cleanup (clear_int, &registering_code);

  /* This call takes ownership of sai.  */
  objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED);

  /* Clear the registering_code flag.  */
  do_cleanups (my_cleanups);

  /* Remember a mapping from entry_addr to objfile.  */
  entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
  *entry_addr_ptr = entry_addr;
  set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);

  discard_cleanups (old_cleanups);
}

/* This function unregisters JITed code and frees the corresponding objfile.  */

static void
jit_unregister_code (struct objfile *objfile)
{
  free_objfile (objfile);
}

/* Look up the objfile with this code entry address.  */

static struct objfile *
jit_find_objf_with_entry_addr (CORE_ADDR entry_addr)
{
  struct objfile *objf;
  CORE_ADDR *objf_entry_addr;

  ALL_OBJFILES (objf)
    {
      objf_entry_addr = (CORE_ADDR *) objfile_data (objf, jit_objfile_data);
      if (objf_entry_addr != NULL && *objf_entry_addr == entry_addr)
        return objf;
    }
  return NULL;
}

/* (Re-)Initialize the jit breakpoint handler, and register any already
   created translations.  */

static void
jit_inferior_init (struct gdbarch *gdbarch)
{
  struct minimal_symbol *reg_symbol;
  struct minimal_symbol *desc_symbol;
  CORE_ADDR reg_addr;
  struct jit_descriptor descriptor;
  struct jit_code_entry cur_entry;
  CORE_ADDR cur_entry_addr;

  /* When we register code, GDB resets its breakpoints in case symbols have
     changed.  That in turn calls this handler, which makes us look for new
     code again.  To avoid being re-entered, we check this flag.  */
  if (registering_code)
    return;

  /* Lookup the registration symbol.  If it is missing, then we assume we are
     not attached to a JIT.  */
  reg_symbol = lookup_minimal_symbol (jit_break_name, NULL, NULL);
  if (reg_symbol == NULL)
    return;
  reg_addr = SYMBOL_VALUE_ADDRESS (reg_symbol);
  if (reg_addr == 0)
    return;

  /* Lookup the descriptor symbol and cache the addr.  If it is missing, we
     assume we are not attached to a JIT and return early.  */
  desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, NULL);
  if (desc_symbol == NULL)
    return;
  jit_descriptor_addr = SYMBOL_VALUE_ADDRESS (desc_symbol);
  if (jit_descriptor_addr == 0)
    return;

  /* Read the descriptor so we can check the version number and load any already
     JITed functions.  */
  jit_read_descriptor (gdbarch, &descriptor);

  /* Check that the version number agrees with that we support.  */
  if (descriptor.version != 1)
    error (_("Unsupported JIT protocol version in descriptor!"));

  /* Put a breakpoint in the registration symbol.  */
  create_jit_event_breakpoint (gdbarch, reg_addr);

  /* If we've attached to a running program, we need to check the descriptor to
     register any functions that were already generated.  */
  for (cur_entry_addr = descriptor.first_entry;
       cur_entry_addr != 0;
       cur_entry_addr = cur_entry.next_entry)
    {
      jit_read_code_entry (gdbarch, cur_entry_addr, &cur_entry);

      /* This hook may be called many times during setup, so make sure we don't
         add the same symbol file twice.  */
      if (jit_find_objf_with_entry_addr (cur_entry_addr) != NULL)
        continue;

      jit_register_code (gdbarch, cur_entry_addr, &cur_entry);
    }
}

/* Exported routine to call when an inferior has been created.  */

void
jit_inferior_created_hook (void)
{
  jit_inferior_init (target_gdbarch);
}

/* Exported routine to call to re-set the jit breakpoints,
   e.g. when a program is rerun.  */

void
jit_breakpoint_re_set (void)
{
  jit_inferior_init (target_gdbarch);
}

/* Wrapper to match the observer function pointer prototype.  */

static void
jit_inferior_created_observer (struct target_ops *objfile, int from_tty)
{
  jit_inferior_init (target_gdbarch);
}

/* This function cleans up any code entries left over when the inferior exits.
   We get left over code when the inferior exits without unregistering its code,
   for example when it crashes.  */

static void
jit_inferior_exit_hook (struct inferior *inf)
{
  struct objfile *objf;
  struct objfile *temp;

  /* We need to reset the descriptor addr so that next time we load up the
     inferior we look for it again.  */
  jit_descriptor_addr = 0;

  ALL_OBJFILES_SAFE (objf, temp)
    if (objfile_data (objf, jit_objfile_data) != NULL)
      jit_unregister_code (objf);
}

void
jit_event_handler (struct gdbarch *gdbarch)
{
  struct jit_descriptor descriptor;
  struct jit_code_entry code_entry;
  CORE_ADDR entry_addr;
  struct objfile *objf;

  /* Read the descriptor from remote memory.  */
  jit_read_descriptor (gdbarch, &descriptor);
  entry_addr = descriptor.relevant_entry;

  /* Do the corresponding action. */
  switch (descriptor.action_flag)
    {
    case JIT_NOACTION:
      break;
    case JIT_REGISTER:
      jit_read_code_entry (gdbarch, entry_addr, &code_entry);
      jit_register_code (gdbarch, entry_addr, &code_entry);
      break;
    case JIT_UNREGISTER:
      objf = jit_find_objf_with_entry_addr (entry_addr);
      if (objf == NULL)
	printf_unfiltered (_("Unable to find JITed code entry at address: %s\n"),
			   paddress (gdbarch, entry_addr));
      else
        jit_unregister_code (objf);

      break;
    default:
      error (_("Unknown action_flag value in JIT descriptor!"));
      break;
    }
}

/* Provide a prototype to silence -Wmissing-prototypes.  */

extern void _initialize_jit (void);

void
_initialize_jit (void)
{
  observer_attach_inferior_created (jit_inferior_created_observer);
  observer_attach_inferior_exit (jit_inferior_exit_hook);
  jit_objfile_data = register_objfile_data ();
}
