/* Handle JIT code generation in the inferior for GDB, the GNU Debugger.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "target.h"
#include "gdb-dlfcn.h"
-#include "gdb_stat.h"
-#include "exceptions.h"
+#include <sys/stat.h>
#include "gdb_bfd.h"
static const char *jit_reader_dir = NULL;
{
struct target_buffer *buffer = (struct target_buffer*) stream;
+ memset (sb, 0, sizeof (struct stat));
sb->st_size = buffer->size;
return 0;
}
static struct bfd *
bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target)
{
- struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
+ struct target_buffer *buffer = XNEW (struct target_buffer);
buffer->base = addr;
buffer->size = size;
so = gdb_dlopen (file_name);
old_cleanups = make_cleanup_dlclose (so);
- init_fn = gdb_dlsym (so, reader_init_fn_sym);
+ init_fn = (reader_init_fn_type *) gdb_dlsym (so, reader_init_fn_sym);
if (!init_fn)
error (_("Could not locate initialization function: %s."),
reader_init_fn_sym);
if (funcs->reader_version != GDB_READER_INTERFACE_VERSION)
error (_("Reader version does not match GDB version."));
- new_reader = XZALLOC (struct jit_reader);
+ new_reader = XCNEW (struct jit_reader);
new_reader->functions = funcs;
new_reader->handle = so;
if (IS_ABSOLUTE_PATH (args))
so_name = xstrdup (args);
else
- so_name = xstrprintf ("%s%s%s", SLASH_STRING, jit_reader_dir, args);
+ so_name = xstrprintf ("%s%s%s", jit_reader_dir, SLASH_STRING, args);
prev_cleanup = make_cleanup (xfree, so_name);
loaded_jit_reader = jit_reader_load (so_name);
{
struct jit_objfile_data *objf_data;
- objf_data = objfile_data (objf, jit_objfile_data);
+ objf_data = (struct jit_objfile_data *) objfile_data (objf, jit_objfile_data);
if (objf_data == NULL)
{
- objf_data = XZALLOC (struct jit_objfile_data);
+ objf_data = XCNEW (struct jit_objfile_data);
set_objfile_data (objf, jit_objfile_data, objf_data);
}
{
struct jit_program_space_data *ps_data;
- ps_data = program_space_data (current_program_space, jit_program_space_data);
+ ps_data
+ = ((struct jit_program_space_data *)
+ program_space_data (current_program_space, jit_program_space_data));
if (ps_data == NULL)
{
- ps_data = XZALLOC (struct jit_program_space_data);
+ ps_data = XCNEW (struct jit_program_space_data);
set_program_space_data (current_program_space, jit_program_space_data,
ps_data);
}
if (jit_debug)
fprintf_unfiltered (gdb_stdlog,
"jit_read_descriptor, descriptor_addr = %s\n",
- paddress (gdbarch, SYMBOL_VALUE_ADDRESS (objf_data->descriptor)));
+ paddress (gdbarch, MSYMBOL_VALUE_ADDRESS (ps_data->objfile,
+ objf_data->descriptor)));
/* 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);
+ desc_buf = (gdb_byte *) alloca (desc_size);
/* Read the descriptor. */
- err = target_read_memory (SYMBOL_VALUE_ADDRESS (objf_data->descriptor),
+ err = target_read_memory (MSYMBOL_VALUE_ADDRESS (ps_data->objfile,
+ objf_data->descriptor),
desc_buf, desc_size);
if (err)
{
off = (off + (align_bytes - 1)) & ~(align_bytes - 1);
entry_size = off + 8; /* Three pointers and one 64-bit int. */
- entry_buf = alloca (entry_size);
+ entry_buf = (gdb_byte *) alloca (entry_size);
/* Read the entry. */
err = target_read_memory (code_addr, entry_buf, entry_size);
static enum gdb_status
jit_target_read_impl (GDB_CORE_ADDR target_mem, void *gdb_buf, int len)
{
- int result = target_read_memory ((CORE_ADDR) target_mem, gdb_buf, len);
+ int result = target_read_memory ((CORE_ADDR) target_mem,
+ (gdb_byte *) gdb_buf, len);
if (result == 0)
return GDB_SUCCESS;
else
/* CB is not required right now, but sometime in the future we might
need a handle to it, and we'd like to do that without breaking
the ABI. */
- return XZALLOC (struct gdb_object);
+ return XCNEW (struct gdb_object);
}
/* Readers call into this function to open a new gdb_symtab, which,
/* CB stays unused. See comment in jit_object_open_impl. */
- ret = XZALLOC (struct gdb_symtab);
+ ret = XCNEW (struct gdb_symtab);
ret->file_name = file_name ? xstrdup (file_name) : xstrdup ("");
ret->next = object->symtabs;
object->symtabs = ret;
static int
compare_block (const struct gdb_block *const old,
- const struct gdb_block *const new)
+ const struct gdb_block *const newobj)
{
if (old == NULL)
return 1;
- if (old->begin < new->begin)
+ if (old->begin < newobj->begin)
return 1;
- else if (old->begin == new->begin)
+ else if (old->begin == newobj->begin)
{
- if (old->end > new->end)
+ if (old->end > newobj->end)
return 1;
else
return 0;
struct gdb_symtab *symtab, struct gdb_block *parent,
GDB_CORE_ADDR begin, GDB_CORE_ADDR end, const char *name)
{
- struct gdb_block *block = XZALLOC (struct gdb_block);
+ struct gdb_block *block = XCNEW (struct gdb_block);
block->next = symtab->blocks;
block->begin = (CORE_ADDR) begin;
struct gdb_line_mapping *map)
{
int i;
+ int alloc_len;
if (nlines < 1)
return;
- stab->linetable = xmalloc (sizeof (struct linetable)
- + (nlines - 1) * sizeof (struct linetable_entry));
+ alloc_len = sizeof (struct linetable)
+ + (nlines - 1) * sizeof (struct linetable_entry);
+ stab->linetable = (struct linetable *) xmalloc (alloc_len);
stab->linetable->nitems = nlines;
for (i = 0; i < nlines; i++)
{
static void
finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
{
- struct symtab *symtab;
+ struct compunit_symtab *cust;
struct gdb_block *gdb_block_iter, *gdb_block_iter_tmp;
struct block *block_iter;
- int actual_nblocks, i, blockvector_size;
+ int actual_nblocks, i;
+ size_t blockvector_size;
CORE_ADDR begin, end;
+ struct blockvector *bv;
actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks;
- symtab = allocate_symtab (stab->file_name, objfile);
+ cust = allocate_compunit_symtab (objfile, stab->file_name);
+ allocate_symtab (cust, stab->file_name);
+ add_compunit_symtab_to_objfile (cust);
+
/* JIT compilers compile in memory. */
- symtab->dirname = NULL;
+ COMPUNIT_DIRNAME (cust) = NULL;
/* Copy over the linetable entry if one was provided. */
if (stab->linetable)
{
- int size = ((stab->linetable->nitems - 1)
- * sizeof (struct linetable_entry)
- + sizeof (struct linetable));
- LINETABLE (symtab) = obstack_alloc (&objfile->objfile_obstack, size);
- memcpy (LINETABLE (symtab), stab->linetable, size);
- }
- else
- {
- LINETABLE (symtab) = NULL;
+ size_t size = ((stab->linetable->nitems - 1)
+ * sizeof (struct linetable_entry)
+ + sizeof (struct linetable));
+ SYMTAB_LINETABLE (COMPUNIT_FILETABS (cust))
+ = (struct linetable *) obstack_alloc (&objfile->objfile_obstack, size);
+ memcpy (SYMTAB_LINETABLE (COMPUNIT_FILETABS (cust)), stab->linetable,
+ size);
}
blockvector_size = (sizeof (struct blockvector)
+ (actual_nblocks - 1) * sizeof (struct block *));
- symtab->blockvector = obstack_alloc (&objfile->objfile_obstack,
- blockvector_size);
+ bv = (struct blockvector *) obstack_alloc (&objfile->objfile_obstack,
+ blockvector_size);
+ COMPUNIT_BLOCKVECTOR (cust) = bv;
/* (begin, end) will contain the PC range this entire blockvector
spans. */
- symtab->primary = 1;
- BLOCKVECTOR_MAP (symtab->blockvector) = NULL;
+ BLOCKVECTOR_MAP (bv) = NULL;
begin = stab->blocks->begin;
end = stab->blocks->end;
- BLOCKVECTOR_NBLOCKS (symtab->blockvector) = actual_nblocks;
+ BLOCKVECTOR_NBLOCKS (bv) = actual_nblocks;
/* First run over all the gdb_block objects, creating a real block
object for each. Simultaneously, keep setting the real_block
/* The name. */
SYMBOL_DOMAIN (block_name) = VAR_DOMAIN;
SYMBOL_ACLASS_INDEX (block_name) = LOC_BLOCK;
- SYMBOL_SYMTAB (block_name) = symtab;
+ symbol_set_symtab (block_name, COMPUNIT_FILETABS (cust));
SYMBOL_TYPE (block_name) = lookup_function_type (block_type);
SYMBOL_BLOCK_VALUE (block_name) = new_block;
- block_name->ginfo.name = obstack_copy0 (&objfile->objfile_obstack,
- gdb_block_iter->name,
- strlen (gdb_block_iter->name));
+ block_name->ginfo.name
+ = (const char *) obstack_copy0 (&objfile->objfile_obstack,
+ gdb_block_iter->name,
+ strlen (gdb_block_iter->name));
BLOCK_FUNCTION (new_block) = block_name;
- BLOCKVECTOR_BLOCK (symtab->blockvector, i) = new_block;
+ BLOCKVECTOR_BLOCK (bv, i) = new_block;
if (begin > BLOCK_START (new_block))
begin = BLOCK_START (new_block);
if (end < BLOCK_END (new_block))
BLOCK_START (new_block) = (CORE_ADDR) begin;
BLOCK_END (new_block) = (CORE_ADDR) end;
- BLOCKVECTOR_BLOCK (symtab->blockvector, i) = new_block;
+ BLOCKVECTOR_BLOCK (bv, i) = new_block;
if (i == GLOBAL_BLOCK)
- set_block_symtab (new_block, symtab);
+ set_block_compunit_symtab (new_block, cust);
}
/* Fill up the superblock fields for the real blocks, using the
{
/* And if not, we set a default parent block. */
BLOCK_SUPERBLOCK (gdb_block_iter->real_block) =
- BLOCKVECTOR_BLOCK (symtab->blockvector, STATIC_BLOCK);
+ BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
}
}
struct objfile *objfile;
jit_dbg_reader_data *priv_data;
- priv_data = cb->priv_data;
+ priv_data = (jit_dbg_reader_data *) cb->priv_data;
- objfile = allocate_objfile (NULL, 0);
+ objfile = allocate_objfile (NULL, "<< JIT compiled code >>",
+ OBJF_NOT_FILENAME);
objfile->per_bfd->gdbarch = target_gdbarch ();
terminate_minimal_symbol_table (objfile);
- objfile->name = "<< JIT compiled code >>";
-
j = NULL;
for (i = obj->symtabs; i; i = j)
{
jit_reader_try_read_symtab (struct jit_code_entry *code_entry,
CORE_ADDR entry_addr)
{
- void *gdb_mem;
+ gdb_byte *gdb_mem;
int status;
jit_dbg_reader_data priv_data;
struct gdb_reader_funcs *funcs;
- volatile struct gdb_exception e;
struct gdb_symbol_callbacks callbacks =
{
jit_object_open_impl,
if (!loaded_jit_reader)
return 0;
- gdb_mem = xmalloc (code_entry->symfile_size);
+ gdb_mem = (gdb_byte *) xmalloc (code_entry->symfile_size);
status = 1;
- TRY_CATCH (e, RETURN_MASK_ALL)
- if (target_read_memory (code_entry->symfile_addr, gdb_mem,
- code_entry->symfile_size))
+ TRY
+ {
+ if (target_read_memory (code_entry->symfile_addr, gdb_mem,
+ code_entry->symfile_size))
+ status = 0;
+ }
+ CATCH (e, RETURN_MASK_ALL)
+ {
status = 0;
- if (e.reason < 0)
- status = 0;
+ }
+ END_CATCH
if (status)
{
/* This call does not take ownership of SAI. */
make_cleanup_bfd_unref (nbfd);
- objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NULL);
+ objfile = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd), 0, sai,
+ OBJF_SHARED | OBJF_NOT_FILENAME, NULL);
do_cleanups (old_cleanups);
add_objfile_entry (objfile, entry_addr);
{
struct jit_objfile_data *objf_data;
- objf_data = objfile_data (objf, jit_objfile_data);
+ objf_data
+ = (struct jit_objfile_data *) objfile_data (objf, jit_objfile_data);
if (objf_data != NULL && objf_data->addr == entry_addr)
return objf;
}
{
struct jit_program_space_data *ps_data;
- ps_data = program_space_data (iter->pspace, jit_program_space_data);
+ ps_data = ((struct jit_program_space_data *)
+ program_space_data (iter->pspace, jit_program_space_data));
if (ps_data != NULL && ps_data->jit_breakpoint == iter->owner)
{
ps_data->cached_code_address = 0;
}
/* (Re-)Initialize the jit breakpoint if necessary.
- Return 0 on success. */
+ Return 0 if the jit breakpoint has been successfully initialized. */
static int
jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
struct jit_program_space_data *ps_data)
{
struct bound_minimal_symbol reg_symbol;
- struct minimal_symbol *desc_symbol;
+ struct bound_minimal_symbol desc_symbol;
struct jit_objfile_data *objf_data;
CORE_ADDR addr;
assume we are not attached to a JIT. */
reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name);
if (reg_symbol.minsym == NULL
- || SYMBOL_VALUE_ADDRESS (reg_symbol.minsym) == 0)
+ || BMSYMBOL_VALUE_ADDRESS (reg_symbol) == 0)
return 1;
desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL,
reg_symbol.objfile);
- if (desc_symbol == NULL || SYMBOL_VALUE_ADDRESS (desc_symbol) == 0)
+ if (desc_symbol.minsym == NULL
+ || BMSYMBOL_VALUE_ADDRESS (desc_symbol) == 0)
return 1;
objf_data = get_jit_objfile_data (reg_symbol.objfile);
objf_data->register_code = reg_symbol.minsym;
- objf_data->descriptor = desc_symbol;
+ objf_data->descriptor = desc_symbol.minsym;
ps_data->objfile = reg_symbol.objfile;
}
else
objf_data = get_jit_objfile_data (ps_data->objfile);
- addr = SYMBOL_VALUE_ADDRESS (objf_data->register_code);
+ addr = MSYMBOL_VALUE_ADDRESS (ps_data->objfile, objf_data->register_code);
if (jit_debug)
fprintf_unfiltered (gdb_stdlog,
paddress (gdbarch, addr));
if (ps_data->cached_code_address == addr)
- return 1;
+ return 0;
/* Delete the old breakpoint. */
if (ps_data->jit_breakpoint != NULL)
struct jit_unwind_private *priv;
int gdb_reg;
- priv = cb->priv_data;
+ priv = (struct jit_unwind_private *) cb->priv_data;
gdb_reg = gdbarch_dwarf2_reg_to_regnum (get_frame_arch (priv->this_frame),
dwarf_regnum);
int gdb_reg, size;
struct gdbarch *frame_arch;
- priv = cb->priv_data;
+ priv = (struct jit_unwind_private *) cb->priv_data;
frame_arch = get_frame_arch (priv->this_frame);
gdb_reg = gdbarch_dwarf2_reg_to_regnum (frame_arch, regnum);
size = register_size (frame_arch, gdb_reg);
- value = xmalloc (sizeof (struct gdb_reg_value) + size - 1);
+ value = ((struct gdb_reg_value *)
+ xmalloc (sizeof (struct gdb_reg_value) + size - 1));
value->defined = deprecated_frame_register_read (priv->this_frame, gdb_reg,
value->value);
value->size = size;
static void
jit_dealloc_cache (struct frame_info *this_frame, void *cache)
{
- struct jit_unwind_private *priv_data = cache;
+ struct jit_unwind_private *priv_data = (struct jit_unwind_private *) cache;
struct gdbarch *frame_arch;
int i;
gdb_assert (!*cache);
- *cache = XZALLOC (struct jit_unwind_private);
- priv_data = *cache;
+ *cache = XCNEW (struct jit_unwind_private);
+ priv_data = (struct jit_unwind_private *) *cache;
priv_data->registers =
- XCALLOC (gdbarch_num_regs (get_frame_arch (this_frame)),
- struct gdb_reg_value *);
+ XCNEWVEC (struct gdb_reg_value *,
+ gdbarch_num_regs (get_frame_arch (this_frame)));
priv_data->this_frame = this_frame;
callbacks.priv_data = priv_data;
jit_frame_this_id (struct frame_info *this_frame, void **cache,
struct frame_id *this_id)
{
- struct jit_unwind_private private;
+ struct jit_unwind_private priv;
struct gdb_frame_id frame_id;
struct gdb_reader_funcs *funcs;
struct gdb_unwind_callbacks callbacks;
- private.registers = NULL;
- private.this_frame = this_frame;
+ priv.registers = NULL;
+ priv.this_frame = this_frame;
/* We don't expect the frame_id function to set any registers, so we
set reg_set to NULL. */
callbacks.reg_get = jit_unwind_reg_get_impl;
callbacks.reg_set = NULL;
callbacks.target_read = jit_target_read_impl;
- callbacks.priv_data = &private;
+ callbacks.priv_data = &priv;
gdb_assert (loaded_jit_reader);
funcs = loaded_jit_reader->functions;
static struct value *
jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg)
{
- struct jit_unwind_private *priv = *cache;
+ struct jit_unwind_private *priv = (struct jit_unwind_private *) *cache;
struct gdb_reg_value *value;
if (priv == NULL)
{
struct jit_gdbarch_data_type *data;
- data = gdbarch_data (gdbarch, jit_gdbarch_data);
+ data
+ = (struct jit_gdbarch_data_type *) gdbarch_data (gdbarch, jit_gdbarch_data);
if (!data->unwinder_registered)
{
frame_unwind_prepend_unwinder (gdbarch, &jit_frame_unwind);
}
}
+/* inferior_created observer. */
+
+static void
+jit_inferior_created (struct target_ops *ops, int from_tty)
+{
+ jit_inferior_created_hook ();
+}
+
/* Exported routine to call when an inferior has been created. */
void
ALL_OBJFILES_SAFE (objf, temp)
{
- struct jit_objfile_data *objf_data = objfile_data (objf,
- jit_objfile_data);
+ struct jit_objfile_data *objf_data
+ = (struct jit_objfile_data *) objfile_data (objf, jit_objfile_data);
if (objf_data != NULL && objf_data->addr != 0)
jit_unregister_code (objf);
static void
free_objfile_data (struct objfile *objfile, void *data)
{
- struct jit_objfile_data *objf_data = data;
+ struct jit_objfile_data *objf_data = (struct jit_objfile_data *) data;
if (objf_data->register_code != NULL)
{
struct jit_program_space_data *ps_data;
- ps_data = program_space_data (objfile->pspace, jit_program_space_data);
+ ps_data
+ = ((struct jit_program_space_data *)
+ program_space_data (objfile->pspace, jit_program_space_data));
if (ps_data != NULL && ps_data->objfile == objfile)
ps_data->objfile = NULL;
}
static void *
jit_gdbarch_data_init (struct obstack *obstack)
{
- struct jit_gdbarch_data_type *data;
+ struct jit_gdbarch_data_type *data =
+ XOBNEW (obstack, struct jit_gdbarch_data_type);
- data = obstack_alloc (obstack, sizeof (struct jit_gdbarch_data_type));
data->unwinder_registered = 0;
+
return data;
}
show_jit_debug,
&setdebuglist, &showdebuglist);
+ observer_attach_inferior_created (jit_inferior_created);
observer_attach_inferior_exit (jit_inferior_exit_hook);
observer_attach_breakpoint_deleted (jit_breakpoint_deleted);