X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fjit.c;h=6fc8524f54fcc8ab905b2d297107a09969f45545;hb=001f13d822104158239fe26a05d9154d967cbe56;hp=f542f9ebdf9cdac03263d47195464df9f4bdaf0e;hpb=db334a01640a2f0e927e824d0d9f5d83d18d942d;p=binutils-gdb.git diff --git a/gdb/jit.c b/gdb/jit.c index f542f9ebdf9..6fc8524f54f 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -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" @@ -48,7 +49,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); @@ -89,7 +90,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 @@ -208,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", SLASH_STRING, jit_reader_dir, args); prev_cleanup = make_cleanup (xfree, so_name); loaded_jit_reader = jit_reader_load (so_name); @@ -230,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 { @@ -251,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; }; @@ -285,28 +307,27 @@ add_objfile_entry (struct objfile *objfile, CORE_ADDR entry) 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 = 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 = XZALLOC (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); } @@ -317,7 +338,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; @@ -327,9 +348,9 @@ 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; @@ -658,8 +679,7 @@ 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, @@ -672,16 +692,15 @@ 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_ACLASS_INDEX (block_name) = LOC_BLOCK; SYMBOL_SYMTAB (block_name) = symtab; 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 = obstack_copy0 (&objfile->objfile_obstack, + gdb_block_iter->name, + strlen (gdb_block_iter->name)); BLOCK_FUNCTION (new_block) = block_name; @@ -904,6 +923,7 @@ JITed symbol file is not an object file, ignoring it.\n")); sai->other[i].sectindex = sec->index; ++i; } + sai->num_sections = i; /* This call does not take ownership of SAI. */ make_cleanup_bfd_unref (nbfd); @@ -922,9 +942,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, @@ -966,46 +984,83 @@ jit_find_objf_with_entry_addr (CORE_ADDR entry_addr) 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 = 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 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 + || SYMBOL_VALUE_ADDRESS (reg_symbol.minsym) == 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) + return 1; + + objf_data = get_jit_objfile_data (reg_symbol.objfile); + objf_data->register_code = reg_symbol.minsym; + objf_data->descriptor = desc_symbol; + + ps_data->objfile = reg_symbol.objfile; + } + else + objf_data = get_jit_objfile_data (ps_data->objfile); - jit_inferior_init (gdbarch); + addr = SYMBOL_VALUE_ADDRESS (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; } @@ -1111,13 +1166,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 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; @@ -1252,7 +1304,7 @@ 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; if (jit_debug) @@ -1260,13 +1312,13 @@ jit_inferior_init (struct gdbarch *gdbarch) 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. */ @@ -1310,7 +1362,7 @@ void jit_breakpoint_re_set (void) { jit_breakpoint_re_set_internal (target_gdbarch (), - get_jit_inferior_data ()); + get_jit_program_space_data ()); } /* This function cleans up any code entries left over when the @@ -1342,7 +1394,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; @@ -1371,7 +1424,7 @@ 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) @@ -1380,10 +1433,11 @@ free_objfile_data (struct objfile *objfile, void *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 = program_space_data (objfile->pspace, jit_program_space_data); + if (ps_data != NULL && ps_data->objfile == objfile) + ps_data->objfile = NULL; } xfree (data); @@ -1420,10 +1474,13 @@ _initialize_jit (void) &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 (NULL, 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 ()) {