X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fjit.c;h=afc1c517fa745582bd198601e46a77af72114017;hb=9885948fc910a77d04f27a7683f5edd0989d818a;hp=a76cca1f1dfa44113cf910764ea68d3bffd63ecd;hpb=84a146c9d3fdfcd4a45b12f88735bd77d4f8d729;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/jit.c b/gdb/jit.c index a76cca1f1d..afc1c517fa 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -1,6 +1,6 @@ /* Handle JIT code generation in the inferior for GDB, the GNU Debugger. - Copyright (C) 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2009-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -25,6 +25,7 @@ #include "breakpoint.h" #include "command.h" #include "dictionary.h" +#include "filenames.h" #include "frame-unwind.h" #include "gdbcmd.h" #include "gdbcore.h" @@ -36,8 +37,8 @@ #include "symtab.h" #include "target.h" #include "gdb-dlfcn.h" -#include "gdb_stat.h" -#include "exceptions.h" +#include +#include "gdb_bfd.h" static const char *jit_reader_dir = NULL; @@ -47,7 +48,7 @@ static const char *const jit_break_name = "__jit_debug_register_code"; static const char *const jit_descriptor_name = "__jit_debug_descriptor"; -static const struct inferior_data *jit_inferior_data = NULL; +static const struct program_space_data *jit_program_space_data = NULL; static void jit_inferior_init (struct gdbarch *gdbarch); @@ -59,7 +60,7 @@ static struct gdbarch_data *jit_gdbarch_data; /* Non-zero if we want to see trace of jit level stuff. */ -static int jit_debug = 0; +static unsigned int jit_debug = 0; static void show_jit_debug (struct ui_file *file, int from_tty, @@ -88,7 +89,9 @@ static int mem_bfd_iovec_close (struct bfd *abfd, void *stream) { xfree (stream); - return 1; + + /* Zero means success. */ + return 0; } /* For reading the file, we just need to pass through to target_read_memory and @@ -123,6 +126,7 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) { struct target_buffer *buffer = (struct target_buffer*) stream; + memset (sb, 0, sizeof (struct stat)); sb->st_size = buffer->size; return 0; } @@ -132,17 +136,16 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) static struct bfd * bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target) { - const char *filename = xstrdup (""); - struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer)); + struct target_buffer *buffer = XNEW (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); + return gdb_bfd_openr_iovec ("", target, + mem_bfd_iovec_open, + buffer, + mem_bfd_iovec_pread, + mem_bfd_iovec_close, + mem_bfd_iovec_stat); } /* One reader that has been loaded successfully, and can potentially be used to @@ -174,7 +177,7 @@ jit_reader_load (const char *file_name) 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); @@ -186,7 +189,7 @@ jit_reader_load (const char *file_name) 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; @@ -200,7 +203,6 @@ static void jit_reader_load_command (char *args, int from_tty) { char *so_name; - int len; struct cleanup *prev_cleanup; if (args == NULL) @@ -209,7 +211,10 @@ jit_reader_load_command (char *args, int from_tty) if (loaded_jit_reader != NULL) error (_("JIT reader already loaded. Run jit-reader-unload first.")); - so_name = xstrprintf ("%s/%s", jit_reader_dir, args); + if (IS_ABSOLUTE_PATH (args)) + so_name = xstrdup (args); + else + 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); @@ -231,18 +236,33 @@ jit_reader_unload_command (char *args, int from_tty) loaded_jit_reader = NULL; } -/* Per-inferior structure recording which objfile has the JIT +/* Per-program space structure recording which objfile has the JIT symbols. */ -struct jit_inferior_data +struct jit_program_space_data { /* The objfile. This is NULL if no objfile holds the JIT symbols. */ struct objfile *objfile; + + /* If this program space has __jit_debug_register_code, this is the + cached address from the minimal symbol. This is used to detect + relocations requiring the breakpoint to be re-created. */ + + CORE_ADDR cached_code_address; + + /* This is the JIT event breakpoint, or NULL if it has not been + set. */ + + struct breakpoint *jit_breakpoint; }; -/* Per-objfile structure recording the addresses in the inferior. */ +/* Per-objfile structure recording the addresses in the program space. + This object serves two purposes: for ordinary objfiles, it may + cache some symbols related to the JIT interface; and for + JIT-created objfiles, it holds some information about the + jit_code_entry. */ struct jit_objfile_data { @@ -252,7 +272,8 @@ struct jit_objfile_data /* Symbol for __jit_debug_descriptor. */ struct minimal_symbol *descriptor; - /* Address of struct jit_code_entry in this objfile. */ + /* Address of struct jit_code_entry in this objfile. This is only + non-zero for objfiles that represent code created by the JIT. */ CORE_ADDR addr; }; @@ -264,10 +285,10 @@ get_jit_objfile_data (struct objfile *objf) { 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); } @@ -280,35 +301,35 @@ get_jit_objfile_data (struct objfile *objf) static void add_objfile_entry (struct objfile *objfile, CORE_ADDR entry) { - CORE_ADDR *entry_addr_ptr; struct jit_objfile_data *objf_data; objf_data = get_jit_objfile_data (objfile); objf_data->addr = entry; } -/* Return jit_inferior_data for current inferior. Allocate if not already - present. */ +/* Return jit_program_space_data for current program space. Allocate + if not already present. */ -static struct jit_inferior_data * -get_jit_inferior_data (void) +static struct jit_program_space_data * +get_jit_program_space_data (void) { - struct inferior *inf; - struct jit_inferior_data *inf_data; + struct jit_program_space_data *ps_data; - inf = current_inferior (); - inf_data = inferior_data (inf, jit_inferior_data); - if (inf_data == NULL) + ps_data + = ((struct jit_program_space_data *) + program_space_data (current_program_space, jit_program_space_data)); + if (ps_data == NULL) { - inf_data = XZALLOC (struct jit_inferior_data); - set_inferior_data (inf, jit_inferior_data, inf_data); + ps_data = XCNEW (struct jit_program_space_data); + set_program_space_data (current_program_space, jit_program_space_data, + ps_data); } - return inf_data; + return ps_data; } static void -jit_inferior_data_cleanup (struct inferior *inf, void *arg) +jit_program_space_data_cleanup (struct program_space *ps, void *arg) { xfree (arg); } @@ -319,7 +340,7 @@ jit_inferior_data_cleanup (struct inferior *inf, void *arg) static int jit_read_descriptor (struct gdbarch *gdbarch, struct jit_descriptor *descriptor, - struct jit_inferior_data *inf_data) + struct jit_program_space_data *ps_data) { int err; struct type *ptr_type; @@ -329,25 +350,27 @@ jit_read_descriptor (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct jit_objfile_data *objf_data; - if (inf_data->objfile == NULL) + if (ps_data->objfile == NULL) return 0; - objf_data = get_jit_objfile_data (inf_data->objfile); + objf_data = get_jit_objfile_data (ps_data->objfile); if (objf_data->descriptor == NULL) return 0; 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) { @@ -391,7 +414,7 @@ jit_read_code_entry (struct gdbarch *gdbarch, 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); @@ -468,7 +491,8 @@ typedef CORE_ADDR jit_dbg_reader_data; 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 @@ -485,7 +509,7 @@ jit_object_open_impl (struct gdb_symbol_callbacks *cb) /* 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, @@ -500,7 +524,7 @@ jit_symtab_open_impl (struct gdb_symbol_callbacks *cb, /* 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; @@ -512,15 +536,15 @@ jit_symtab_open_impl (struct gdb_symbol_callbacks *cb, 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; @@ -538,7 +562,7 @@ jit_block_open_impl (struct gdb_symbol_callbacks *cb, 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; @@ -582,12 +606,14 @@ jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, 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++) { @@ -613,44 +639,47 @@ jit_symtab_close_impl (struct gdb_symbol_callbacks *cb, 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 @@ -660,8 +689,11 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) i--, gdb_block_iter = gdb_block_iter->next) { struct block *new_block = allocate_block (&objfile->objfile_obstack); - struct symbol *block_name = obstack_alloc (&objfile->objfile_obstack, - sizeof (struct symbol)); + struct symbol *block_name = allocate_symbol (objfile); + struct type *block_type = arch_type (get_objfile_arch (objfile), + TYPE_CODE_VOID, + 1, + "void"); BLOCK_DICT (new_block) = dict_create_linear (&objfile->objfile_obstack, NULL); @@ -670,19 +702,20 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) BLOCK_END (new_block) = (CORE_ADDR) gdb_block_iter->end; /* The name. */ - memset (block_name, 0, sizeof (struct symbol)); SYMBOL_DOMAIN (block_name) = VAR_DOMAIN; - SYMBOL_CLASS (block_name) = LOC_BLOCK; - SYMBOL_SYMTAB (block_name) = symtab; + SYMBOL_ACLASS_INDEX (block_name) = LOC_BLOCK; + 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 = obsavestring (gdb_block_iter->name, - strlen (gdb_block_iter->name), - &objfile->objfile_obstack); + 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)) @@ -708,10 +741,10 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) 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 @@ -721,8 +754,18 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) gdb_block_iter = gdb_block_iter->next) { if (gdb_block_iter->parent != NULL) - BLOCK_SUPERBLOCK (gdb_block_iter->real_block) = - gdb_block_iter->parent->real_block; + { + /* If the plugin specifically mentioned a parent block, we + use that. */ + BLOCK_SUPERBLOCK (gdb_block_iter->real_block) = + gdb_block_iter->parent->real_block; + } + else + { + /* And if not, we set a default parent block. */ + BLOCK_SUPERBLOCK (gdb_block_iter->real_block) = + BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + } } /* Free memory. */ @@ -751,16 +794,14 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb, 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->gdbarch = target_gdbarch; + objfile = allocate_objfile (NULL, "<< JIT compiled code >>", + OBJF_NOT_FILENAME); + objfile->per_bfd->gdbarch = target_gdbarch (); terminate_minimal_symbol_table (objfile); - xfree (objfile->name); - objfile->name = xstrdup ("<< JIT compiled code >>"); - j = NULL; for (i = obj->symtabs; i; i = j) { @@ -779,12 +820,10 @@ static int jit_reader_try_read_symtab (struct jit_code_entry *code_entry, CORE_ADDR entry_addr) { - void *gdb_mem; + gdb_byte *gdb_mem; int status; - struct jit_dbg_reader *i; 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, @@ -804,15 +843,20 @@ jit_reader_try_read_symtab (struct jit_code_entry *code_entry, 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) { @@ -866,7 +910,7 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, { printf_unfiltered (_("\ JITed symbol file is not an object file, ignoring it.\n")); - bfd_close (nbfd); + gdb_bfd_unref (nbfd); return; } @@ -893,9 +937,12 @@ JITed symbol file is not an object file, ignoring it.\n")); sai->other[i].sectindex = sec->index; ++i; } + sai->num_sections = i; - /* This call takes ownership of NBFD. It does not take ownership of SAI. */ - objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NULL); + /* This call does not take ownership of SAI. */ + make_cleanup_bfd_unref (nbfd); + 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); @@ -910,9 +957,7 @@ static void jit_register_code (struct gdbarch *gdbarch, CORE_ADDR entry_addr, struct jit_code_entry *code_entry) { - int i, success; - const struct bfd_arch_info *b; - struct jit_inferior_data *inf_data = get_jit_inferior_data (); + int success; if (jit_debug) fprintf_unfiltered (gdb_stdlog, @@ -942,59 +987,98 @@ static struct objfile * jit_find_objf_with_entry_addr (CORE_ADDR entry_addr) { struct objfile *objf; - CORE_ADDR *objf_entry_addr; ALL_OBJFILES (objf) { 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; } return NULL; } +/* This is called when a breakpoint is deleted. It updates the + inferior's cache, if needed. */ + +static void +jit_breakpoint_deleted (struct breakpoint *b) +{ + struct bp_location *iter; + + if (b->type != bp_jit_event) + return; + + for (iter = b->loc; iter != NULL; iter = iter->next) + { + struct jit_program_space_data *ps_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; + ps_data->jit_breakpoint = NULL; + } + } +} + /* (Re-)Initialize the jit breakpoint if necessary. Return 0 on success. */ static int jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, - struct jit_inferior_data *inf_data) + struct jit_program_space_data *ps_data) { - struct minimal_symbol *reg_symbol, *desc_symbol; - struct objfile *objf; + struct bound_minimal_symbol reg_symbol; + struct bound_minimal_symbol desc_symbol; struct jit_objfile_data *objf_data; + CORE_ADDR addr; - if (inf_data->objfile != NULL) - return 0; - - /* Lookup the registration symbol. If it is missing, then we assume - we are not attached to a JIT. */ - reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name, &objf); - if (reg_symbol == NULL || SYMBOL_VALUE_ADDRESS (reg_symbol) == 0) - return 1; - - desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, objf); - if (desc_symbol == NULL || SYMBOL_VALUE_ADDRESS (desc_symbol) == 0) - return 1; - - objf_data = get_jit_objfile_data (objf); - objf_data->register_code = reg_symbol; - objf_data->descriptor = desc_symbol; - - inf_data->objfile = objf; + if (ps_data->objfile == NULL) + { + /* Lookup the registration symbol. If it is missing, then we + assume we are not attached to a JIT. */ + reg_symbol = lookup_minimal_symbol_and_objfile (jit_break_name); + if (reg_symbol.minsym == NULL + || BMSYMBOL_VALUE_ADDRESS (reg_symbol) == 0) + return 1; + + desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, + reg_symbol.objfile); + 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.minsym; + + ps_data->objfile = reg_symbol.objfile; + } + else + objf_data = get_jit_objfile_data (ps_data->objfile); - jit_inferior_init (gdbarch); + addr = MSYMBOL_VALUE_ADDRESS (ps_data->objfile, objf_data->register_code); if (jit_debug) fprintf_unfiltered (gdb_stdlog, "jit_breakpoint_re_set_internal, " "breakpoint_addr = %s\n", - paddress (gdbarch, SYMBOL_VALUE_ADDRESS (reg_symbol))); + paddress (gdbarch, addr)); + + if (ps_data->cached_code_address == addr) + return 1; + + /* Delete the old breakpoint. */ + if (ps_data->jit_breakpoint != NULL) + delete_breakpoint (ps_data->jit_breakpoint); /* Put a breakpoint in the registration symbol. */ - create_jit_event_breakpoint (gdbarch, SYMBOL_VALUE_ADDRESS (reg_symbol)); + ps_data->cached_code_address = addr; + ps_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr); return 0; } @@ -1021,7 +1105,7 @@ jit_unwind_reg_set_impl (struct gdb_unwind_callbacks *cb, int dwarf_regnum, 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); @@ -1054,14 +1138,15 @@ jit_unwind_reg_get_impl (struct gdb_unwind_callbacks *cb, int 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->defined = frame_register_read (priv->this_frame, gdb_reg, - value->value); + 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; value->free = reg_value_free_impl; return value; @@ -1073,7 +1158,7 @@ jit_unwind_reg_get_impl (struct gdb_unwind_callbacks *cb, int regnum) 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; @@ -1100,14 +1185,10 @@ static int jit_frame_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **cache) { - struct jit_inferior_data *inf_data; struct jit_unwind_private *priv_data; - struct jit_dbg_reader *iter; struct gdb_unwind_callbacks callbacks; struct gdb_reader_funcs *funcs; - inf_data = get_jit_inferior_data (); - callbacks.reg_get = jit_unwind_reg_get_impl; callbacks.reg_set = jit_unwind_reg_set_impl; callbacks.target_read = jit_target_read_impl; @@ -1119,11 +1200,11 @@ jit_frame_sniffer (const struct frame_unwind *self, 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; @@ -1154,20 +1235,20 @@ static void 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; @@ -1182,7 +1263,7 @@ jit_frame_this_id (struct frame_info *this_frame, void **cache, 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) @@ -1227,7 +1308,8 @@ jit_prepend_unwinder (struct gdbarch *gdbarch) { 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); @@ -1242,22 +1324,21 @@ jit_inferior_init (struct gdbarch *gdbarch) { struct jit_descriptor descriptor; struct jit_code_entry cur_entry; - struct jit_inferior_data *inf_data; + struct jit_program_space_data *ps_data; CORE_ADDR cur_entry_addr; - struct jit_objfile_data *objf_data; if (jit_debug) fprintf_unfiltered (gdb_stdlog, "jit_inferior_init\n"); jit_prepend_unwinder (gdbarch); - inf_data = get_jit_inferior_data (); - if (jit_breakpoint_re_set_internal (gdbarch, inf_data) != 0) + ps_data = get_jit_program_space_data (); + if (jit_breakpoint_re_set_internal (gdbarch, ps_data) != 0) return; /* Read the descriptor so we can check the version number and load any already JITed functions. */ - if (!jit_read_descriptor (gdbarch, &descriptor, inf_data)) + if (!jit_read_descriptor (gdbarch, &descriptor, ps_data)) return; /* Check that the version number agrees with that we support. */ @@ -1291,7 +1372,7 @@ jit_inferior_init (struct gdbarch *gdbarch) void jit_inferior_created_hook (void) { - jit_inferior_init (target_gdbarch); + jit_inferior_init (target_gdbarch ()); } /* Exported routine to call to re-set the jit breakpoints, @@ -1300,8 +1381,8 @@ jit_inferior_created_hook (void) void jit_breakpoint_re_set (void) { - jit_breakpoint_re_set_internal (target_gdbarch, - get_jit_inferior_data ()); + jit_breakpoint_re_set_internal (target_gdbarch (), + get_jit_program_space_data ()); } /* This function cleans up any code entries left over when the @@ -1316,8 +1397,8 @@ jit_inferior_exit_hook (struct inferior *inf) 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); @@ -1333,7 +1414,8 @@ jit_event_handler (struct gdbarch *gdbarch) struct objfile *objf; /* Read the descriptor from remote memory. */ - if (!jit_read_descriptor (gdbarch, &descriptor, get_jit_inferior_data ())) + if (!jit_read_descriptor (gdbarch, &descriptor, + get_jit_program_space_data ())) return; entry_addr = descriptor.relevant_entry; @@ -1362,19 +1444,22 @@ jit_event_handler (struct gdbarch *gdbarch) } } -/* Called to free the data allocated to the jit_inferior_data slot. */ +/* Called to free the data allocated to the jit_program_space_data slot. */ 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_inferior_data *inf_data = get_jit_inferior_data (); + struct jit_program_space_data *ps_data; - if (inf_data->objfile == objfile) - inf_data->objfile = NULL; + 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; } xfree (data); @@ -1386,10 +1471,11 @@ free_objfile_data (struct objfile *objfile, void *data) 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; } @@ -1402,19 +1488,22 @@ _initialize_jit (void) { jit_reader_dir = relocate_gdb_directory (JIT_READER_DIR, JIT_READER_DIR_RELOCATABLE); - add_setshow_zinteger_cmd ("jit", class_maintenance, &jit_debug, - _("Set JIT debugging."), - _("Show JIT debugging."), - _("When non-zero, JIT debugging is enabled."), - NULL, - show_jit_debug, - &setdebuglist, &showdebuglist); + add_setshow_zuinteger_cmd ("jit", class_maintenance, &jit_debug, + _("Set JIT debugging."), + _("Show JIT debugging."), + _("When non-zero, JIT debugging is enabled."), + NULL, + show_jit_debug, + &setdebuglist, &showdebuglist); observer_attach_inferior_exit (jit_inferior_exit_hook); + observer_attach_breakpoint_deleted (jit_breakpoint_deleted); + jit_objfile_data = register_objfile_data_with_cleanup (NULL, free_objfile_data); - jit_inferior_data = - register_inferior_data_with_cleanup (jit_inferior_data_cleanup); + jit_program_space_data = + register_program_space_data_with_cleanup (NULL, + jit_program_space_data_cleanup); jit_gdbarch_data = gdbarch_data_register_pre_init (jit_gdbarch_data_init); if (is_dl_available ()) {