X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fjit.c;h=1b5ef46469e0ccd41709f74e03b153d02026f24c;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=9ea68330212aafe23451a93364ce6c1688a147fc;hpb=3a90f26667396bed62345027503d943d8213f02b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/jit.c b/gdb/jit.c index 9ea6833021..1b5ef46469 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-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -41,6 +41,7 @@ #include "gdb_bfd.h" #include "readline/tilde.h" #include "completer.h" +#include static std::string jit_reader_dir; @@ -135,7 +136,8 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) /* Open a BFD from the target's memory. */ static gdb_bfd_ref_ptr -bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target) +bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, + const char *target) { struct target_buffer *buffer = XNEW (struct target_buffer); @@ -428,48 +430,68 @@ 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 @@ -501,7 +523,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, @@ -512,37 +534,10 @@ jit_symtab_open_impl (struct gdb_symbol_callbacks *cb, 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 @@ -554,39 +549,12 @@ 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 = 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 @@ -605,12 +573,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; } } @@ -632,17 +601,23 @@ 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; - cust = allocate_compunit_symtab (objfile, stab->file_name); - allocate_symtab (cust, stab->file_name); + return a.end > b.end; + }); + + cust = allocate_compunit_symtab (objfile, stab->file_name.c_str ()); + allocate_symtab (cust, stab->file_name.c_str ()); add_compunit_symtab_to_objfile (cust); /* JIT compilers compile in memory. */ @@ -656,8 +631,8 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) + 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); + memcpy (SYMTAB_LINETABLE (COMPUNIT_FILETABS (cust)), + stab->linetable.get (), size); } blockvector_size = (sizeof (struct blockvector) @@ -666,23 +641,22 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) blockvector_size); COMPUNIT_BLOCKVECTOR (cust) = 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,8 +664,8 @@ 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; @@ -700,23 +674,25 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) SYMBOL_TYPE (block_name) = lookup_function_type (block_type); SYMBOL_BLOCK_VALUE (block_name) = new_block; - block_name->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); if (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 +715,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 @@ -780,7 +740,6 @@ static void jit_object_close_impl (struct gdb_symbol_callbacks *cb, struct gdb_object *obj) { - struct gdb_symtab *i, *j; struct objfile *objfile; jit_dbg_reader_data *priv_data; @@ -790,14 +749,12 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb, OBJF_NOT_FILENAME); objfile->per_bfd->gdbarch = target_gdbarch (); - j = NULL; - for (i = obj->symtabs; i; i = j) - { - j = i->next; - finalize_symtab (i, objfile); - } + for (gdb_symtab &symtab : obj->symtabs) + finalize_symtab (&symtab, objfile); + add_objfile_entry (objfile, *priv_data); - xfree (obj); + + delete obj; } /* Try to read CODE_ENTRY using the loaded jit reader (if any). @@ -1449,8 +1406,9 @@ 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);