X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fjit.c;h=9f57d521a8b91d116ad0ac2570650cafeee14b6d;hb=7124770976d3f051532faf864013b76ab36249bf;hp=5fef03700c1fbe689c98091e1f4e16d2035e9bab;hpb=2d41fa1165c0e28d938ee3bae5c32db371dccf29;p=binutils-gdb.git diff --git a/gdb/jit.c b/gdb/jit.c index 5fef03700c1..9f57d521a8b 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-2019 Free Software Foundation, Inc. + Copyright (C) 2009-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -41,16 +41,15 @@ #include "gdb_bfd.h" #include "readline/tilde.h" #include "completer.h" +#include -static const char *jit_reader_dir = NULL; +static std::string jit_reader_dir; -static const struct objfile_data *jit_objfile_data; +static const char jit_break_name[] = "__jit_debug_register_code"; -static const char *const jit_break_name = "__jit_debug_register_code"; +static const char jit_descriptor_name[] = "__jit_debug_descriptor"; -static const char *const jit_descriptor_name = "__jit_debug_descriptor"; - -static void jit_inferior_init (struct gdbarch *gdbarch); +static void jit_inferior_created_hook (inferior *inf); static void jit_inferior_exit_hook (struct inferior *inf); /* An unwinder is registered for every gdbarch. This key is used to @@ -59,9 +58,14 @@ static void jit_inferior_exit_hook (struct inferior *inf); static struct gdbarch_data *jit_gdbarch_data; -/* Non-zero if we want to see trace of jit level stuff. */ +/* True if we want to see trace of jit level stuff. */ + +static bool jit_debug = false; + +/* Print a "jit" debug statement. */ -static unsigned int jit_debug = 0; +#define jit_debug_printf(fmt, ...) \ + debug_prefixed_printf_cond (jit_debug, "jit", fmt, ##__VA_ARGS__) static void show_jit_debug (struct ui_file *file, int from_tty, @@ -70,83 +74,54 @@ show_jit_debug (struct ui_file *file, int from_tty, fprintf_filtered (file, _("JIT debugging is %s.\n"), value); } -struct target_buffer -{ - CORE_ADDR base; - ULONGEST 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. */ +/* Implementation of the "maintenance info jit" command. */ -static int -mem_bfd_iovec_close (struct bfd *abfd, void *stream) -{ - xfree (stream); - - /* Zero means success. */ - return 0; -} - -/* 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) +static void +maint_info_jit_cmd (const char *args, int from_tty) { - int err; - struct target_buffer *buffer = (struct target_buffer *) stream; + inferior *inf = current_inferior (); + bool printed_header = false; - /* If this read will read all of the file, limit it to just the rest. */ - if (offset + nbytes > buffer->size) - nbytes = buffer->size - offset; + gdb::optional table_emitter; - /* 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; + /* Print a line for each JIT-ed objfile. */ + for (objfile *obj : inf->pspace->objfiles ()) + { + if (obj->jited_data == nullptr) + continue; - memset (sb, 0, sizeof (struct stat)); - sb->st_size = buffer->size; - return 0; -} + if (!printed_header) + { + table_emitter.emplace (current_uiout, 3, -1, "jit-created-objfiles"); + + /* The +2 allows for the leading '0x', then one character for + every 4-bits. */ + int addr_width = 2 + (gdbarch_ptr_bit (obj->arch ()) / 4); + + /* The std::max here selects between the width of an address (as + a string) and the width of the column header string. */ + current_uiout->table_header (std::max (addr_width, 22), ui_left, + "jit_code_entry-address", + "jit_code_entry address"); + current_uiout->table_header (std::max (addr_width, 15), ui_left, + "symfile-address", "symfile address"); + current_uiout->table_header (20, ui_left, + "symfile-size", "symfile size"); + current_uiout->table_body (); + + printed_header = true; + } -/* Open a BFD from the target's memory. */ + ui_out_emit_tuple tuple_emitter (current_uiout, "jit-objfile"); -static gdb_bfd_ref_ptr -bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target) -{ - struct target_buffer *buffer = XNEW (struct target_buffer); - - buffer->base = addr; - buffer->size = size; - return gdb_bfd_openr_iovec ("", target, - mem_bfd_iovec_open, - buffer, - mem_bfd_iovec_pread, - mem_bfd_iovec_close, - mem_bfd_iovec_stat); + current_uiout->field_core_addr ("jit_code_entry-address", obj->arch (), + obj->jited_data->addr); + current_uiout->field_core_addr ("symfile-address", obj->arch (), + obj->jited_data->symfile_addr); + current_uiout->field_unsigned ("symfile-size", + obj->jited_data->symfile_size); + current_uiout->text ("\n"); + } } struct jit_reader @@ -173,7 +148,7 @@ struct jit_reader static struct jit_reader *loaded_jit_reader = NULL; typedef struct gdb_reader_funcs * (reader_init_fn_type) (void); -static const char *reader_init_fn_sym = "gdb_init_reader"; +static const char reader_init_fn_sym[] = "gdb_init_reader"; /* Try to load FILE_NAME as a JIT debug info reader. */ @@ -183,15 +158,14 @@ jit_reader_load (const char *file_name) reader_init_fn_type *init_fn; struct gdb_reader_funcs *funcs = NULL; - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, _("Opening shared object %s.\n"), - file_name); + jit_debug_printf ("Opening shared object %s", file_name); + gdb_dlhandle_up so = gdb_dlopen (file_name); 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); + reader_init_fn_sym); if (gdb_dlsym (so, "plugin_is_GPL_compatible") == NULL) error (_("Reader not GPL compatible.")); @@ -216,12 +190,12 @@ jit_reader_load_command (const char *args, int from_tty) error (_("JIT reader already loaded. Run jit-reader-unload first.")); if (!IS_ABSOLUTE_PATH (file.get ())) - file.reset (xstrprintf ("%s%s%s", jit_reader_dir, SLASH_STRING, - file.get ())); + file = xstrprintf ("%s%s%s", jit_reader_dir.c_str (), + SLASH_STRING, file.get ()); loaded_jit_reader = jit_reader_load (file.get ()); reinit_frame_cache (); - jit_inferior_created_hook (); + jit_inferior_created_hook (current_inferior ()); } /* Provides the jit-reader-unload command. */ @@ -239,100 +213,46 @@ jit_reader_unload_command (const char *args, int from_tty) loaded_jit_reader = NULL; } -/* Per-program space structure recording which objfile has the JIT - symbols. */ +/* Destructor for jiter_objfile_data. */ -struct jit_program_space_data +jiter_objfile_data::~jiter_objfile_data () { - /* The objfile. This is NULL if no objfile holds the JIT - symbols. */ - - struct objfile *objfile = nullptr; - - /* 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 = 0; - - /* This is the JIT event breakpoint, or NULL if it has not been - set. */ - - struct breakpoint *jit_breakpoint = nullptr; -}; - -static program_space_key jit_program_space_key; - -/* 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 -{ - /* Symbol for __jit_debug_register_code. */ - struct minimal_symbol *register_code; - - /* Symbol for __jit_debug_descriptor. */ - struct minimal_symbol *descriptor; - - /* 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; -}; + if (this->jit_breakpoint != nullptr) + delete_breakpoint (this->jit_breakpoint); +} -/* Fetch the jit_objfile_data associated with OBJF. If no data exists +/* Fetch the jiter_objfile_data associated with OBJF. If no data exists yet, make a new structure and attach it. */ -static struct jit_objfile_data * -get_jit_objfile_data (struct objfile *objf) +static jiter_objfile_data * +get_jiter_objfile_data (objfile *objf) { - struct jit_objfile_data *objf_data; + if (objf->jiter_data == nullptr) + objf->jiter_data.reset (new jiter_objfile_data ()); - objf_data = (struct jit_objfile_data *) objfile_data (objf, jit_objfile_data); - if (objf_data == NULL) - { - objf_data = XCNEW (struct jit_objfile_data); - set_objfile_data (objf, jit_objfile_data, objf_data); - } - - return objf_data; + return objf->jiter_data.get (); } /* Remember OBJFILE has been created for struct jit_code_entry located at inferior address ENTRY. */ static void -add_objfile_entry (struct objfile *objfile, CORE_ADDR entry) -{ - struct jit_objfile_data *objf_data; - - objf_data = get_jit_objfile_data (objfile); - objf_data->addr = entry; -} - -/* Return jit_program_space_data for current program space. Allocate - if not already present. */ - -static struct jit_program_space_data * -get_jit_program_space_data () +add_objfile_entry (struct objfile *objfile, CORE_ADDR entry, + CORE_ADDR symfile_addr, ULONGEST symfile_size) { - struct jit_program_space_data *ps_data; + gdb_assert (objfile->jited_data == nullptr); - ps_data = jit_program_space_key.get (current_program_space); - if (ps_data == NULL) - ps_data = jit_program_space_key.emplace (current_program_space); - return ps_data; + objfile->jited_data.reset (new jited_objfile_data (entry, symfile_addr, + symfile_size)); } /* Helper function for reading the global JIT descriptor from remote - memory. Returns 1 if all went well, 0 otherwise. */ + memory. Returns true if all went well, false otherwise. */ -static int -jit_read_descriptor (struct gdbarch *gdbarch, - struct jit_descriptor *descriptor, - struct jit_program_space_data *ps_data) +static bool +jit_read_descriptor (gdbarch *gdbarch, + jit_descriptor *descriptor, + objfile *jiter) { int err; struct type *ptr_type; @@ -340,19 +260,14 @@ jit_read_descriptor (struct gdbarch *gdbarch, int desc_size; gdb_byte *desc_buf; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - struct jit_objfile_data *objf_data; - if (ps_data->objfile == NULL) - return 0; - objf_data = get_jit_objfile_data (ps_data->objfile); - if (objf_data->descriptor == NULL) - return 0; + gdb_assert (jiter != nullptr); + jiter_objfile_data *objf_data = jiter->jiter_data.get (); + gdb_assert (objf_data != nullptr); - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, - "jit_read_descriptor, descriptor_addr = %s\n", - paddress (gdbarch, MSYMBOL_VALUE_ADDRESS (ps_data->objfile, - objf_data->descriptor))); + CORE_ADDR addr = MSYMBOL_VALUE_ADDRESS (jiter, objf_data->descriptor); + + jit_debug_printf ("descriptor_addr = %s", paddress (gdbarch, addr)); /* Figure out how big the descriptor is on the remote and how to read it. */ ptr_type = builtin_type (gdbarch)->builtin_data_ptr; @@ -361,14 +276,12 @@ jit_read_descriptor (struct gdbarch *gdbarch, desc_buf = (gdb_byte *) alloca (desc_size); /* Read the descriptor. */ - err = target_read_memory (MSYMBOL_VALUE_ADDRESS (ps_data->objfile, - objf_data->descriptor), - desc_buf, desc_size); + err = target_read_memory (addr, desc_buf, desc_size); if (err) { - printf_unfiltered (_("Unable to read JIT descriptor from " - "remote memory\n")); - return 0; + fprintf_unfiltered (gdb_stderr, _("Unable to read JIT descriptor from " + "remote memory\n")); + return false; } /* Fix the endianness to match the host. */ @@ -379,7 +292,7 @@ jit_read_descriptor (struct gdbarch *gdbarch, descriptor->first_entry = extract_typed_address (&desc_buf[8 + ptr_size], ptr_type); - return 1; + return true; } /* Helper function for reading a JITed code entry from remote memory. */ @@ -428,54 +341,83 @@ jit_read_code_entry (struct gdbarch *gdbarch, struct gdb_block { - /* gdb_blocks are linked into a tree structure. Next points to the - next node at the same depth as this block and parent to the - parent gdb_block. */ - struct gdb_block *next, *parent; + gdb_block (gdb_block *parent, CORE_ADDR begin, CORE_ADDR end, + const char *name) + : parent (parent), + begin (begin), + end (end), + name (name != nullptr ? xstrdup (name) : nullptr) + {} + + /* The parent of this block. */ + struct gdb_block *parent; /* Points to the "real" block that is being built out of this instance. This block will be added to a blockvector, which will then be added to a symtab. */ - struct block *real_block; + struct block *real_block = nullptr; /* The first and last code address corresponding to this block. */ CORE_ADDR begin, end; /* The name of this block (if any). If this is non-NULL, the FUNCTION symbol symbol is set to this value. */ - const char *name; + gdb::unique_xmalloc_ptr name; }; /* Proxy object for building a symtab. */ struct gdb_symtab { + explicit gdb_symtab (const char *file_name) + : file_name (file_name != nullptr ? file_name : "") + {} + /* The list of blocks in this symtab. These will eventually be - converted to real blocks. */ - struct gdb_block *blocks; + converted to real blocks. + + This is specifically a linked list, instead of, for example, a vector, + because the pointers are returned to the user's debug info reader. So + it's important that the objects don't change location during their + lifetime (which would happen with a vector of objects getting resized). */ + std::forward_list blocks; /* The number of blocks inserted. */ - int nblocks; + int nblocks = 0; /* A mapping between line numbers to PC. */ - struct linetable *linetable; + gdb::unique_xmalloc_ptr linetable; /* The source file for this symtab. */ - const char *file_name; - struct gdb_symtab *next; + std::string file_name; }; /* Proxy object for building an object. */ struct gdb_object { - struct gdb_symtab *symtabs; + /* Symtabs of this object. + + This is specifically a linked list, instead of, for example, a vector, + because the pointers are returned to the user's debug info reader. So + it's important that the objects don't change location during their + lifetime (which would happen with a vector of objects getting resized). */ + std::forward_list symtabs; }; /* The type of the `private' data passed around by the callback functions. */ -typedef CORE_ADDR jit_dbg_reader_data; +struct jit_dbg_reader_data +{ + /* Address of the jit_code_entry in the inferior's address space. */ + CORE_ADDR entry_addr; + + /* The code entry, copied in our address space. */ + const jit_code_entry &entry; + + struct gdbarch *gdbarch; +}; /* The reader calls into this function to read data off the targets address space. */ @@ -501,7 +443,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 XCNEW (struct gdb_object); + return new gdb_object; } /* Readers call into this function to open a new gdb_symtab, which, @@ -509,40 +451,13 @@ jit_object_open_impl (struct gdb_symbol_callbacks *cb) static struct gdb_symtab * jit_symtab_open_impl (struct gdb_symbol_callbacks *cb, - struct gdb_object *object, - const char *file_name) + struct gdb_object *object, + const char *file_name) { - struct gdb_symtab *ret; - /* CB stays unused. See comment in jit_object_open_impl. */ - ret = XCNEW (struct gdb_symtab); - ret->file_name = file_name ? xstrdup (file_name) : xstrdup (""); - ret->next = object->symtabs; - object->symtabs = ret; - return ret; -} - -/* Returns true if the block corresponding to old should be placed - before the block corresponding to new in the final blockvector. */ - -static int -compare_block (const struct gdb_block *const old, - const struct gdb_block *const newobj) -{ - if (old == NULL) - return 1; - if (old->begin < newobj->begin) - return 1; - else if (old->begin == newobj->begin) - { - if (old->end > newobj->end) - return 1; - else - return 0; - } - else - return 0; + object->symtabs.emplace_front (file_name); + return &object->symtabs.front (); } /* Called by readers to open a new gdb_block. This function also @@ -551,42 +466,15 @@ compare_block (const struct gdb_block *const old, static struct gdb_block * 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_symtab *symtab, struct gdb_block *parent, + GDB_CORE_ADDR begin, GDB_CORE_ADDR end, const char *name) { - struct gdb_block *block = XCNEW (struct gdb_block); - - block->next = symtab->blocks; - block->begin = (CORE_ADDR) begin; - block->end = (CORE_ADDR) end; - block->name = name ? xstrdup (name) : NULL; - block->parent = parent; - - /* Ensure that the blocks are inserted in the correct (reverse of - the order expected by blockvector). */ - if (compare_block (symtab->blocks, block)) - { - symtab->blocks = block; - } - else - { - struct gdb_block *i = symtab->blocks; - - for (;; i = i->next) - { - /* Guaranteed to terminate, since compare_block (NULL, _) - returns 1. */ - if (compare_block (i->next, block)) - { - block->next = i->next; - i->next = block; - break; - } - } - } + /* Place the block at the beginning of the list, it will be sorted when the + symtab is finalized. */ + symtab->blocks.emplace_front (parent, begin, end, name); symtab->nblocks++; - return block; + return &symtab->blocks.front (); } /* Readers call this to add a line mapping (from PC to line number) to @@ -594,8 +482,8 @@ jit_block_open_impl (struct gdb_symbol_callbacks *cb, static void jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, - struct gdb_symtab *stab, int nlines, - struct gdb_line_mapping *map) + struct gdb_symtab *stab, int nlines, + struct gdb_line_mapping *map) { int i; int alloc_len; @@ -605,12 +493,13 @@ jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, alloc_len = sizeof (struct linetable) + (nlines - 1) * sizeof (struct linetable_entry); - stab->linetable = (struct linetable *) xmalloc (alloc_len); + stab->linetable.reset (XNEWVAR (struct linetable, alloc_len)); stab->linetable->nitems = nlines; for (i = 0; i < nlines; i++) { stab->linetable->item[i].pc = (CORE_ADDR) map[i].pc; stab->linetable->item[i].line = map[i].line; + stab->linetable->item[i].is_stmt = 1; } } @@ -619,7 +508,7 @@ jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, static void jit_symtab_close_impl (struct gdb_symbol_callbacks *cb, - struct gdb_symtab *stab) + struct gdb_symtab *stab) { /* Right now nothing needs to be done here. We may need to do some cleanup here in the future (again, without breaking the plugin @@ -632,21 +521,27 @@ static void finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) { struct compunit_symtab *cust; - struct gdb_block *gdb_block_iter, *gdb_block_iter_tmp; - struct block *block_iter; - int actual_nblocks, i; size_t blockvector_size; CORE_ADDR begin, end; struct blockvector *bv; - actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks; + int actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks; + + /* Sort the blocks in the order they should appear in the blockvector. */ + stab->blocks.sort([] (const gdb_block &a, const gdb_block &b) + { + if (a.begin != b.begin) + return a.begin < b.begin; + + return a.end > b.end; + }); - cust = allocate_compunit_symtab (objfile, stab->file_name); - allocate_symtab (cust, stab->file_name); + cust = allocate_compunit_symtab (objfile, stab->file_name.c_str ()); + symtab *filetab = allocate_symtab (cust, stab->file_name.c_str ()); add_compunit_symtab_to_objfile (cust); /* JIT compilers compile in memory. */ - COMPUNIT_DIRNAME (cust) = NULL; + cust->set_dirname (nullptr); /* Copy over the linetable entry if one was provided. */ if (stab->linetable) @@ -654,35 +549,33 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) 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); + filetab->set_linetable ((struct linetable *) + obstack_alloc (&objfile->objfile_obstack, size)); + memcpy (filetab->linetable (), stab->linetable.get (), size); } blockvector_size = (sizeof (struct blockvector) - + (actual_nblocks - 1) * sizeof (struct block *)); + + (actual_nblocks - 1) * sizeof (struct block *)); bv = (struct blockvector *) obstack_alloc (&objfile->objfile_obstack, blockvector_size); - COMPUNIT_BLOCKVECTOR (cust) = bv; + cust->set_blockvector (bv); - /* (begin, end) will contain the PC range this entire blockvector - spans. */ + /* At the end of this function, (begin, end) will contain the PC range this + entire blockvector spans. */ BLOCKVECTOR_MAP (bv) = NULL; - begin = stab->blocks->begin; - end = stab->blocks->end; + begin = stab->blocks.front ().begin; + end = stab->blocks.front ().end; 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 fields. */ - for (i = (actual_nblocks - 1), gdb_block_iter = stab->blocks; - i >= FIRST_LOCAL_BLOCK; - i--, gdb_block_iter = gdb_block_iter->next) + int block_idx = FIRST_LOCAL_BLOCK; + for (gdb_block &gdb_block_iter : stab->blocks) { struct block *new_block = allocate_block (&objfile->objfile_obstack); - struct symbol *block_name = allocate_symbol (objfile); - struct type *block_type = arch_type (get_objfile_arch (objfile), + struct symbol *block_name = new (&objfile->objfile_obstack) symbol; + struct type *block_type = arch_type (objfile->arch (), TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"); @@ -690,33 +583,35 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) BLOCK_MULTIDICT (new_block) = mdict_create_linear (&objfile->objfile_obstack, NULL); /* The address range. */ - BLOCK_START (new_block) = (CORE_ADDR) gdb_block_iter->begin; - BLOCK_END (new_block) = (CORE_ADDR) gdb_block_iter->end; + BLOCK_START (new_block) = (CORE_ADDR) gdb_block_iter.begin; + BLOCK_END (new_block) = (CORE_ADDR) gdb_block_iter.end; /* The name. */ - SYMBOL_DOMAIN (block_name) = VAR_DOMAIN; - SYMBOL_ACLASS_INDEX (block_name) = LOC_BLOCK; - symbol_set_symtab (block_name, COMPUNIT_FILETABS (cust)); - SYMBOL_TYPE (block_name) = lookup_function_type (block_type); + block_name->set_domain (VAR_DOMAIN); + block_name->set_aclass_index (LOC_BLOCK); + symbol_set_symtab (block_name, filetab); + block_name->set_type (lookup_function_type (block_type)); SYMBOL_BLOCK_VALUE (block_name) = new_block; - block_name->ginfo.name = obstack_strdup (&objfile->objfile_obstack, - gdb_block_iter->name); + block_name->m_name = obstack_strdup (&objfile->objfile_obstack, + gdb_block_iter.name.get ()); BLOCK_FUNCTION (new_block) = block_name; - BLOCKVECTOR_BLOCK (bv, i) = new_block; + BLOCKVECTOR_BLOCK (bv, block_idx) = new_block; if (begin > BLOCK_START (new_block)) - begin = BLOCK_START (new_block); + begin = BLOCK_START (new_block); if (end < BLOCK_END (new_block)) - end = BLOCK_END (new_block); + end = BLOCK_END (new_block); - gdb_block_iter->real_block = new_block; + gdb_block_iter.real_block = new_block; + + block_idx++; } /* Now add the special blocks. */ - block_iter = NULL; - for (i = 0; i < FIRST_LOCAL_BLOCK; i++) + struct block *block_iter = NULL; + for (enum block_enum i : { GLOBAL_BLOCK, STATIC_BLOCK }) { struct block *new_block; @@ -739,38 +634,22 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) /* Fill up the superblock fields for the real blocks, using the real_block fields populated earlier. */ - for (gdb_block_iter = stab->blocks; - gdb_block_iter; - gdb_block_iter = gdb_block_iter->next) + for (gdb_block &gdb_block_iter : stab->blocks) { - if (gdb_block_iter->parent != NULL) + if (gdb_block_iter.parent != NULL) { /* If the plugin specifically mentioned a parent block, we use that. */ - BLOCK_SUPERBLOCK (gdb_block_iter->real_block) = - gdb_block_iter->parent->real_block; + 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) = + BLOCK_SUPERBLOCK (gdb_block_iter.real_block) = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); } } - - /* Free memory. */ - gdb_block_iter = stab->blocks; - - for (gdb_block_iter = stab->blocks, gdb_block_iter_tmp = gdb_block_iter->next; - gdb_block_iter; - gdb_block_iter = gdb_block_iter_tmp) - { - xfree ((void *) gdb_block_iter->name); - xfree (gdb_block_iter); - } - xfree (stab->linetable); - xfree ((char *) stab->file_name); - xfree (stab); } /* Called when closing a gdb_objfile. Converts OBJ to a proper @@ -778,26 +657,26 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) static void jit_object_close_impl (struct gdb_symbol_callbacks *cb, - struct gdb_object *obj) + struct gdb_object *obj) { - struct gdb_symtab *i, *j; - struct objfile *objfile; - jit_dbg_reader_data *priv_data; + jit_dbg_reader_data *priv_data = (jit_dbg_reader_data *) cb->priv_data; + std::string objfile_name + = string_printf ("<< JIT compiled code at %s >>", + paddress (priv_data->gdbarch, + priv_data->entry.symfile_addr)); - priv_data = (jit_dbg_reader_data *) cb->priv_data; + objfile *objfile = objfile::make (nullptr, objfile_name.c_str (), + OBJF_NOT_FILENAME); + objfile->per_bfd->gdbarch = priv_data->gdbarch; - objfile = new struct objfile (NULL, "<< JIT compiled code >>", - OBJF_NOT_FILENAME); - objfile->per_bfd->gdbarch = target_gdbarch (); + for (gdb_symtab &symtab : obj->symtabs) + finalize_symtab (&symtab, objfile); - j = NULL; - for (i = obj->symtabs; i; i = j) - { - j = i->next; - finalize_symtab (i, objfile); - } - add_objfile_entry (objfile, *priv_data); - xfree (obj); + add_objfile_entry (objfile, priv_data->entry_addr, + priv_data->entry.symfile_addr, + priv_data->entry.symfile_size); + + delete obj; } /* Try to read CODE_ENTRY using the loaded jit reader (if any). @@ -805,12 +684,16 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb, inferior address space. */ static int -jit_reader_try_read_symtab (struct jit_code_entry *code_entry, - CORE_ADDR entry_addr) +jit_reader_try_read_symtab (gdbarch *gdbarch, jit_code_entry *code_entry, + CORE_ADDR entry_addr) { - gdb_byte *gdb_mem; int status; - jit_dbg_reader_data priv_data; + jit_dbg_reader_data priv_data + { + entry_addr, + *code_entry, + gdbarch + }; struct gdb_reader_funcs *funcs; struct gdb_symbol_callbacks callbacks = { @@ -826,17 +709,15 @@ jit_reader_try_read_symtab (struct jit_code_entry *code_entry, &priv_data }; - priv_data = entry_addr; - if (!loaded_jit_reader) return 0; - gdb_mem = (gdb_byte *) xmalloc (code_entry->symfile_size); + gdb::byte_vector gdb_mem (code_entry->symfile_size); status = 1; try { - if (target_read_memory (code_entry->symfile_addr, gdb_mem, + if (target_read_memory (code_entry->symfile_addr, gdb_mem.data (), code_entry->symfile_size)) status = 0; } @@ -848,15 +729,15 @@ jit_reader_try_read_symtab (struct jit_code_entry *code_entry, if (status) { funcs = loaded_jit_reader->functions; - if (funcs->read (funcs, &callbacks, gdb_mem, code_entry->symfile_size) - != GDB_SUCCESS) - status = 0; + if (funcs->read (funcs, &callbacks, gdb_mem.data (), + code_entry->symfile_size) + != GDB_SUCCESS) + status = 0; } - xfree (gdb_mem); - if (jit_debug && status == 0) - fprintf_unfiltered (gdb_stdlog, - "Could not read symtab using the loaded JIT reader.\n"); + if (status == 0) + jit_debug_printf ("Could not read symtab using the loaded JIT reader."); + return status; } @@ -865,26 +746,23 @@ jit_reader_try_read_symtab (struct jit_code_entry *code_entry, static void jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, - CORE_ADDR entry_addr, - struct gdbarch *gdbarch) + CORE_ADDR entry_addr, + struct gdbarch *gdbarch) { struct bfd_section *sec; struct objfile *objfile; const struct bfd_arch_info *b; - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, - "jit_register_code, symfile_addr = %s, " - "symfile_size = %s\n", - paddress (gdbarch, code_entry->symfile_addr), - pulongest (code_entry->symfile_size)); + jit_debug_printf ("symfile_addr = %s, symfile_size = %s", + paddress (gdbarch, code_entry->symfile_addr), + pulongest (code_entry->symfile_size)); - gdb_bfd_ref_ptr nbfd (bfd_open_from_target_memory (code_entry->symfile_addr, - code_entry->symfile_size, - gnutarget)); + gdb_bfd_ref_ptr nbfd (gdb_bfd_open_from_target_memory + (code_entry->symfile_addr, code_entry->symfile_size, gnutarget)); if (nbfd == NULL) { - puts_unfiltered (_("Error opening JITed symbol file, ignoring it.\n")); + fputs_unfiltered (_("Error opening JITed symbol file, ignoring it.\n"), + gdb_stderr); return; } @@ -892,7 +770,7 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, We would segfault later without this line. */ if (!bfd_check_format (nbfd.get (), bfd_object)) { - printf_unfiltered (_("\ + fprintf_unfiltered (gdb_stderr, _("\ JITed symbol file is not an object file, ignoring it.\n")); return; } @@ -901,7 +779,7 @@ JITed symbol file is not an object file, ignoring it.\n")); b = gdbarch_bfd_arch_info (gdbarch); if (b->compatible (b, bfd_get_arch_info (nbfd.get ())) != b) warning (_("JITed object file architecture %s is not compatible " - "with target architecture %s."), + "with target architecture %s."), bfd_get_arch_info (nbfd.get ())->printable_name, b->printable_name); @@ -910,12 +788,12 @@ JITed symbol file is not an object file, ignoring it.\n")); addresses that we care about. */ section_addr_info sai; for (sec = nbfd->sections; sec != NULL; sec = sec->next) - if ((bfd_get_section_flags (nbfd.get (), sec) & (SEC_ALLOC|SEC_LOAD)) != 0) + if ((bfd_section_flags (sec) & (SEC_ALLOC|SEC_LOAD)) != 0) { - /* We assume that these virtual addresses are absolute, and do not - treat them as offsets. */ - sai.emplace_back (bfd_get_section_vma (nbfd.get (), sec), - bfd_get_section_name (nbfd.get (), sec), + /* We assume that these virtual addresses are absolute, and do not + treat them as offsets. */ + sai.emplace_back (bfd_section_vma (sec), + bfd_section_name (sec), sec->index); } @@ -925,7 +803,8 @@ JITed symbol file is not an object file, ignoring it.\n")); &sai, OBJF_SHARED | OBJF_NOT_FILENAME, NULL); - add_objfile_entry (objfile, entry_addr); + add_objfile_entry (objfile, entry_addr, code_entry->symfile_addr, + code_entry->symfile_size); } /* This function registers code associated with a JIT code entry. It uses the @@ -935,32 +814,20 @@ JITed symbol file is not an object file, ignoring it.\n")); static void jit_register_code (struct gdbarch *gdbarch, - CORE_ADDR entry_addr, struct jit_code_entry *code_entry) + CORE_ADDR entry_addr, struct jit_code_entry *code_entry) { int success; - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, - "jit_register_code, symfile_addr = %s, " - "symfile_size = %s\n", - paddress (gdbarch, code_entry->symfile_addr), - pulongest (code_entry->symfile_size)); + jit_debug_printf ("symfile_addr = %s, symfile_size = %s", + paddress (gdbarch, code_entry->symfile_addr), + pulongest (code_entry->symfile_size)); - success = jit_reader_try_read_symtab (code_entry, entry_addr); + success = jit_reader_try_read_symtab (gdbarch, code_entry, entry_addr); if (!success) jit_bfd_try_read_symtab (code_entry, entry_addr, gdbarch); } -/* This function unregisters JITed code and frees the corresponding - objfile. */ - -static void -jit_unregister_code (struct objfile *objfile) -{ - delete objfile; -} - /* Look up the objfile with this code entry address. */ static struct objfile * @@ -968,13 +835,10 @@ jit_find_objf_with_entry_addr (CORE_ADDR entry_addr) { for (objfile *objf : current_program_space->objfiles ()) { - struct jit_objfile_data *objf_data; - - objf_data - = (struct jit_objfile_data *) objfile_data (objf, jit_objfile_data); - if (objf_data != NULL && objf_data->addr == entry_addr) - return objf; + if (objf->jited_data != nullptr && objf->jited_data->addr == entry_addr) + return objf; } + return NULL; } @@ -984,80 +848,84 @@ jit_find_objf_with_entry_addr (CORE_ADDR entry_addr) 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) + for (bp_location *iter : b->locations ()) { - struct jit_program_space_data *ps_data; - - ps_data = jit_program_space_key.get (iter->pspace); - if (ps_data != NULL && ps_data->jit_breakpoint == iter->owner) + for (objfile *objf : iter->pspace->objfiles ()) { - ps_data->cached_code_address = 0; - ps_data->jit_breakpoint = NULL; + jiter_objfile_data *jiter_data = objf->jiter_data.get (); + + if (jiter_data != nullptr + && jiter_data->jit_breakpoint == iter->owner) + { + jiter_data->cached_code_address = 0; + jiter_data->jit_breakpoint = nullptr; + } } } } -/* (Re-)Initialize the jit breakpoint if necessary. - Return 0 if the jit breakpoint has been successfully initialized. */ +/* (Re-)Initialize the jit breakpoints for JIT-producing objfiles in + PSPACE. */ -static int -jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, - struct jit_program_space_data *ps_data) +static void +jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, program_space *pspace) { - struct bound_minimal_symbol reg_symbol; - struct bound_minimal_symbol desc_symbol; - struct jit_objfile_data *objf_data; - CORE_ADDR addr; - - if (ps_data->objfile == NULL) + for (objfile *the_objfile : pspace->objfiles ()) { + /* Skip separate debug objects. */ + if (the_objfile->separate_debug_objfile_backlink != nullptr) + continue; + + if (the_objfile->skip_jit_symbol_lookup) + continue; + /* Lookup the registration symbol. If it is missing, then we assume we are not attached to a JIT. */ - reg_symbol = lookup_bound_minimal_symbol (jit_break_name); + bound_minimal_symbol reg_symbol + = lookup_minimal_symbol (jit_break_name, nullptr, the_objfile); if (reg_symbol.minsym == NULL || BMSYMBOL_VALUE_ADDRESS (reg_symbol) == 0) - return 1; + { + /* No need to repeat the lookup the next time. */ + the_objfile->skip_jit_symbol_lookup = true; + continue; + } - desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, - reg_symbol.objfile); + bound_minimal_symbol desc_symbol + = lookup_minimal_symbol (jit_descriptor_name, NULL, the_objfile); if (desc_symbol.minsym == NULL || BMSYMBOL_VALUE_ADDRESS (desc_symbol) == 0) - return 1; + { + /* No need to repeat the lookup the next time. */ + the_objfile->skip_jit_symbol_lookup = true; + continue; + } - objf_data = get_jit_objfile_data (reg_symbol.objfile); + jiter_objfile_data *objf_data + = get_jiter_objfile_data (the_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); - - addr = MSYMBOL_VALUE_ADDRESS (ps_data->objfile, objf_data->register_code); + CORE_ADDR addr = MSYMBOL_VALUE_ADDRESS (the_objfile, + objf_data->register_code); - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, - "jit_breakpoint_re_set_internal, " - "breakpoint_addr = %s\n", - paddress (gdbarch, addr)); + jit_debug_printf ("breakpoint_addr = %s", paddress (gdbarch, addr)); - if (ps_data->cached_code_address == addr) - return 0; + /* Check if we need to re-create the breakpoint. */ + if (objf_data->cached_code_address == addr) + continue; - /* Delete the old breakpoint. */ - if (ps_data->jit_breakpoint != NULL) - delete_breakpoint (ps_data->jit_breakpoint); + /* Delete the old breakpoint. */ + if (objf_data->jit_breakpoint != nullptr) + delete_breakpoint (objf_data->jit_breakpoint); - /* Put a breakpoint in the registration symbol. */ - ps_data->cached_code_address = addr; - ps_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr); - - return 0; + /* Put a breakpoint in the registration symbol. */ + objf_data->cached_code_address = addr; + objf_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr); + } } /* The private data passed around in the frame unwind callback @@ -1077,7 +945,7 @@ struct jit_unwind_private static void jit_unwind_reg_set_impl (struct gdb_unwind_callbacks *cb, int dwarf_regnum, - struct gdb_reg_value *value) + struct gdb_reg_value *value) { struct jit_unwind_private *priv; int gdb_reg; @@ -1085,13 +953,10 @@ jit_unwind_reg_set_impl (struct gdb_unwind_callbacks *cb, int dwarf_regnum, priv = (struct jit_unwind_private *) cb->priv_data; gdb_reg = gdbarch_dwarf2_reg_to_regnum (get_frame_arch (priv->this_frame), - dwarf_regnum); + dwarf_regnum); if (gdb_reg == -1) { - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, - _("Could not recognize DWARF regnum %d"), - dwarf_regnum); + jit_debug_printf ("Could not recognize DWARF regnum %d", dwarf_regnum); value->free (value); return; } @@ -1153,7 +1018,7 @@ jit_dealloc_cache (struct frame_info *this_frame, void *cache) static int jit_frame_sniffer (const struct frame_unwind *self, - struct frame_info *this_frame, void **cache) + struct frame_info *this_frame, void **cache) { struct jit_unwind_private *priv_data; struct gdb_unwind_callbacks callbacks; @@ -1182,14 +1047,11 @@ jit_frame_sniffer (const struct frame_unwind *self, /* Try to coax the provided unwinder to unwind the stack */ if (funcs->unwind (funcs, &callbacks) == GDB_SUCCESS) { - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, _("Successfully unwound frame using " - "JIT reader.\n")); + jit_debug_printf ("Successfully unwound frame using JIT reader."); return 1; } - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, _("Could not unwind frame using " - "JIT reader.\n")); + + jit_debug_printf ("Could not unwind frame using JIT reader."); jit_dealloc_cache (this_frame, *cache); *cache = NULL; @@ -1203,7 +1065,7 @@ jit_frame_sniffer (const struct frame_unwind *self, static void jit_frame_this_id (struct frame_info *this_frame, void **cache, - struct frame_id *this_id) + struct frame_id *this_id) { struct jit_unwind_private priv; struct gdb_frame_id frame_id; @@ -1254,6 +1116,7 @@ jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg) static const struct frame_unwind jit_frame_unwind = { + "jit", NORMAL_FRAME, default_frame_unwind_stop_reason, jit_frame_this_id, @@ -1292,67 +1155,68 @@ jit_prepend_unwinder (struct gdbarch *gdbarch) /* Register any already created translations. */ static void -jit_inferior_init (struct gdbarch *gdbarch) +jit_inferior_init (inferior *inf) { struct jit_descriptor descriptor; struct jit_code_entry cur_entry; - struct jit_program_space_data *ps_data; CORE_ADDR cur_entry_addr; + struct gdbarch *gdbarch = inf->gdbarch; + program_space *pspace = inf->pspace; - if (jit_debug) - fprintf_unfiltered (gdb_stdlog, "jit_inferior_init\n"); + jit_debug_printf ("called"); jit_prepend_unwinder (gdbarch); - 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, ps_data)) - return; + jit_breakpoint_re_set_internal (gdbarch, pspace); - /* Check that the version number agrees with that we support. */ - if (descriptor.version != 1) + for (objfile *jiter : pspace->objfiles ()) { - printf_unfiltered (_("Unsupported JIT protocol version %ld " - "in descriptor (expected 1)\n"), - (long) descriptor.version); - return; - } + if (jiter->jiter_data == nullptr) + continue; - /* 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); + /* Read the descriptor so we can check the version number and load + any already JITed functions. */ + if (!jit_read_descriptor (gdbarch, &descriptor, jiter)) + continue; - /* 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; + /* Check that the version number agrees with that we support. */ + if (descriptor.version != 1) + { + fprintf_unfiltered (gdb_stderr, + _("Unsupported JIT protocol version %ld " + "in descriptor (expected 1)\n"), + (long) descriptor.version); + continue; + } - jit_register_code (gdbarch, cur_entry_addr, &cur_entry); - } -} + /* 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); -/* inferior_created observer. */ + /* 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; -static void -jit_inferior_created (struct target_ops *ops, int from_tty) -{ - jit_inferior_created_hook (); + jit_register_code (gdbarch, cur_entry_addr, &cur_entry); + } + } } -/* Exported routine to call when an inferior has been created. */ +/* Looks for the descriptor and registration symbols and breakpoints + the registration function. If it finds both, it registers all the + already JITed code. If it has already found the symbols, then it + doesn't try again. */ -void -jit_inferior_created_hook (void) +static void +jit_inferior_created_hook (inferior *inf) { - jit_inferior_init (target_gdbarch ()); + jit_inferior_init (inf); } /* Exported routine to call to re-set the jit breakpoints, @@ -1361,8 +1225,7 @@ jit_inferior_created_hook (void) void jit_breakpoint_re_set (void) { - jit_breakpoint_re_set_internal (target_gdbarch (), - get_jit_program_space_data ()); + jit_breakpoint_re_set_internal (target_gdbarch (), current_program_space); } /* This function cleans up any code entries left over when the @@ -1374,77 +1237,59 @@ jit_inferior_exit_hook (struct inferior *inf) { for (objfile *objf : current_program_space->objfiles_safe ()) { - 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); + if (objf->jited_data != nullptr && objf->jited_data->addr != 0) + objf->unlink (); } } void -jit_event_handler (struct gdbarch *gdbarch) +jit_event_handler (gdbarch *gdbarch, objfile *jiter) { struct jit_descriptor descriptor; - struct jit_code_entry code_entry; - CORE_ADDR entry_addr; - struct objfile *objf; + + /* If we get a JIT breakpoint event for this objfile, it is necessarily a + JITer. */ + gdb_assert (jiter->jiter_data != nullptr); /* Read the descriptor from remote memory. */ - if (!jit_read_descriptor (gdbarch, &descriptor, - get_jit_program_space_data ())) + if (!jit_read_descriptor (gdbarch, &descriptor, jiter)) return; - entry_addr = descriptor.relevant_entry; + CORE_ADDR 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; + { + jit_code_entry code_entry; + 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); + { + objfile *jited = jit_find_objf_with_entry_addr (entry_addr); + if (jited == nullptr) + fprintf_unfiltered (gdb_stderr, + _("Unable to find JITed code " + "entry at address: %s\n"), + paddress (gdbarch, entry_addr)); + else + jited->unlink (); + + break; + } - break; default: error (_("Unknown action_flag value in JIT descriptor!")); break; } } -/* 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 = (struct jit_objfile_data *) data; - - if (objf_data->register_code != NULL) - { - struct jit_program_space_data *ps_data; - - ps_data = jit_program_space_key.get (objfile->pspace); - if (ps_data != NULL && ps_data->objfile == objfile) - { - ps_data->objfile = NULL; - if (ps_data->jit_breakpoint != NULL) - delete_breakpoint (ps_data->jit_breakpoint); - ps_data->cached_code_address = 0; - } - } - - xfree (data); -} - /* Initialize the jit_gdbarch_data slot with an instance of struct jit_gdbarch_data_type */ @@ -1459,25 +1304,29 @@ jit_gdbarch_data_init (struct obstack *obstack) return data; } +void _initialize_jit (); void -_initialize_jit (void) +_initialize_jit () { jit_reader_dir = relocate_gdb_directory (JIT_READER_DIR, - JIT_READER_DIR_RELOCATABLE); - 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); - - gdb::observers::inferior_created.attach (jit_inferior_created); - gdb::observers::inferior_exit.attach (jit_inferior_exit_hook); - gdb::observers::breakpoint_deleted.attach (jit_breakpoint_deleted); - - jit_objfile_data = - register_objfile_data_with_cleanup (NULL, free_objfile_data); + JIT_READER_DIR_RELOCATABLE); + add_setshow_boolean_cmd ("jit", class_maintenance, &jit_debug, + _("Set JIT debugging."), + _("Show JIT debugging."), + _("When set, JIT debugging is enabled."), + NULL, + show_jit_debug, + &setdebuglist, &showdebuglist); + + add_cmd ("jit", class_maintenance, maint_info_jit_cmd, + _("Print information about JIT-ed code objects."), + &maintenanceinfolist); + + gdb::observers::inferior_created.attach (jit_inferior_created_hook, "jit"); + gdb::observers::inferior_execd.attach (jit_inferior_created_hook, "jit"); + gdb::observers::inferior_exit.attach (jit_inferior_exit_hook, "jit"); + gdb::observers::breakpoint_deleted.attach (jit_breakpoint_deleted, "jit"); + jit_gdbarch_data = gdbarch_data_register_pre_init (jit_gdbarch_data_init); if (is_dl_available ()) {