From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24922 invoked by alias); 27 Aug 2011 13:47:56 -0000 Received: (qmail 24890 invoked by uid 22791); 27 Aug 2011 13:47:52 -0000 X-SWARE-Spam-Status: No, hits=1.1 required=5.0 tests=AWL,BAYES_99,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,TW_BJ,TW_CP,TW_DB,TW_YM X-Spam-Check-By: sourceware.org Received: from mail-bw0-f41.google.com (HELO mail-bw0-f41.google.com) (209.85.214.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 27 Aug 2011 13:47:26 +0000 Received: by bkbzt4 with SMTP id zt4so3601280bkb.0 for ; Sat, 27 Aug 2011 06:47:25 -0700 (PDT) MIME-Version: 1.0 Received: by 10.204.129.194 with SMTP id p2mr1168243bks.233.1314452844749; Sat, 27 Aug 2011 06:47:24 -0700 (PDT) Received: by 10.204.36.74 with HTTP; Sat, 27 Aug 2011 06:47:24 -0700 (PDT) In-Reply-To: <1314450736-19389-6-git-send-email-sanjoy@playingwithpointers.com> References: <1314450736-19389-1-git-send-email-sanjoy@playingwithpointers.com> <1314450736-19389-6-git-send-email-sanjoy@playingwithpointers.com> Date: Sat, 27 Aug 2011 13:47:00 -0000 Message-ID: Subject: Re: [PATCH 5/7] Use the loaded reader. From: Abhijit Halder To: Sanjoy Das Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-08/txt/msg00533.txt.bz2 On Sat, Aug 27, 2011 at 6:42 PM, Sanjoy Das wrote: > Invoke the loaded JIT debug info reader to parse the registered symbol > files. > > gdb/ChangeLog: > =A0 =A0 =A0 =A0* gdb/jit.c: Include block.h, dictionary.h and frame-unwin= d.h. > =A0 =A0 =A0 =A0(add_objfile_entry, jit_target_read_impl, jit_object_open_= impl) > =A0 =A0 =A0 =A0(jit_symtab_open_impl, compare_block, jit_block_open_impl) > =A0 =A0 =A0 =A0(jit_symtab_line_mapping_add_impl, jit_symtab_close_impl) > =A0 =A0 =A0 =A0(finalize_symtab, jit_object_close_impl) > =A0 =A0 =A0 =A0(jit_reader_try_read_symtab, jit_bfd_try_read_symtab) > =A0 =A0 =A0 =A0(free_objfile_data): New functions. > =A0 =A0 =A0 =A0(_initialize_jit): Register jit_objfile_data with a proper= cleanup > =A0 =A0 =A0 =A0function. > --- > =A0gdb/ChangeLog | =A0 12 ++ > =A0gdb/jit.c =A0 =A0 | =A0479 +++++++++++++++++++++++++++++++++++++++++++= +++++++++++--- > =A02 files changed, 468 insertions(+), 23 deletions(-) > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog > index 78076ef..7cdde7b 100644 > --- a/gdb/ChangeLog > +++ b/gdb/ChangeLog > @@ -1,5 +1,17 @@ > =A02011-08-27 =A0Sanjoy Das =A0 > > + =A0 =A0 =A0 * gdb/jit.c: Include block.h, dictionary.h and frame-unwind= .h. > + =A0 =A0 =A0 (add_objfile_entry, jit_target_read_impl, jit_object_open_i= mpl) > + =A0 =A0 =A0 (jit_symtab_open_impl, compare_block, jit_block_open_impl) > + =A0 =A0 =A0 (jit_symtab_line_mapping_add_impl, jit_symtab_close_impl) > + =A0 =A0 =A0 (finalize_symtab, jit_object_close_impl) > + =A0 =A0 =A0 (jit_reader_try_read_symtab, jit_bfd_try_read_symtab) > + =A0 =A0 =A0 (free_objfile_data): New functions. > + =A0 =A0 =A0 (_initialize_jit): Register jit_objfile_data with a proper = cleanup > + =A0 =A0 =A0 function. > + > +2011-08-27 =A0Sanjoy Das =A0 > + > =A0 =A0 =A0 =A0* gdb/jit.c: Include gdb-dlfcn.h. > =A0 =A0 =A0 =A0(loaded_jit_reader, reader_init_fn_sym): New static variab= les. > =A0 =A0 =A0 =A0(jit_reader_load, jit_reader_load_command) > diff --git a/gdb/jit.c b/gdb/jit.c > index 4fc5819..3be8c4d 100644 > --- a/gdb/jit.c > +++ b/gdb/jit.c > @@ -21,8 +21,11 @@ > > =A0#include "jit.h" > =A0#include "jit-reader.h" > +#include "block.h" > =A0#include "breakpoint.h" > =A0#include "command.h" > +#include "dictionary.h" > +#include "frame-unwind.h" > =A0#include "gdbcmd.h" > =A0#include "gdbcore.h" > =A0#include "inferior.h" > @@ -233,6 +236,18 @@ struct jit_inferior_data > =A0 CORE_ADDR descriptor_addr; =A0/* &__jit_debug_descriptor =A0*/ > =A0}; > > +/* Remember a mapping from entry_addr to objfile. =A0*/ > + > +static void > +add_objfile_entry (struct objfile *objfile, CORE_ADDR entry) > +{ > + =A0CORE_ADDR *entry_addr_ptr; > + > + =A0entry_addr_ptr =3D xmalloc (sizeof (CORE_ADDR)); > + =A0*entry_addr_ptr =3D entry; > + =A0set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr); > +} > + > =A0/* Return jit_inferior_data for current inferior. =A0Allocate if not a= lready > =A0 =A0present. =A0*/ > > @@ -329,30 +344,417 @@ jit_read_code_entry (struct gdbarch *gdbarch, > =A0 =A0 =A0 extract_unsigned_integer (&entry_buf[3 * ptr_size], 8, byte_o= rder); > =A0} > > -/* This function registers code associated with a JIT code entry. =A0It = uses the > - =A0 pointer and size pair in the entry to read the symbol file from the= remote > - =A0 and then calls symbol_file_add_from_local_memory to add it as thoug= h it were > - =A0 a symbol file added by the user. =A0*/ > +/* Proxy object for building a block. */ > + > +struct gdb_block > +{ > + =A0/* gdb_blocks are linked into a tree structure. Next points to the > + =A0 =A0 next node at the same depth as this block and parent to the > + =A0 =A0 parent gdb_block. */ Should be two spaces after period. I am not sure but I think inside structure there should not be any empty new-line between the comment and the definition of member variable. Please correct me if I am wrong. > + > + =A0struct gdb_block *next, *parent; Please put a comment here. > + =A0struct block *real_block; > + > + =A0/* The first and last code address corresponding to this block */ Missing trailing period and there should be two spaces after the period. > + > + =A0CORE_ADDR begin, end; > + > + =A0/* The name of this block (if any). =A0If this is non-NULL, the > + =A0 =A0 FUNCTION symbol symbol is set to this value. */ > + > + =A0const char *name; > +}; > + > +/* Proxy object for building a symtab. */ > + > +struct gdb_symtab > +{ > + =A0/* The list of blocks in this symtab. These will eventually be > + =A0 =A0 converted to real blocks. */ > + > + =A0struct gdb_block *blocks; > + > + =A0/* The number of blocks inserted. */ > + > + =A0int nblocks; > + > + =A0/* A mapping between line numbers to PC. */ > + > + =A0struct linetable *linetable; > + > + =A0/* The source file for this symtab. */ > + > + =A0const char *file_name; > + =A0struct gdb_symtab *next; > +}; > + > +/* Proxy object for building an object. */ > + > +struct gdb_object > +{ > + =A0struct gdb_symtab *symtabs; > +}; > + > +/* The type of the `private' data passed around by the callback > + =A0 functions. */ > + > +struct jit_dbg_reader_data > +{ > + =A0CORE_ADDR entry_address; > +}; Is there any reason not making it a typedef (also the above one)? I mean to say something like this: typedef CORE_ADDR jit_dbg_reader_data; typedef struct gdb_symtab *gdb_object; The advantage we may achieve is in saving two level of indirection. > + > +/* The reader calls into this function to read data off the targets > + =A0 address space. */ > + > +static enum gdb_status > +jit_target_read_impl (GDB_CORE_ADDR target_mem, void *gdb_buf, int len) > +{ > + =A0int result =3D target_read_memory ((CORE_ADDR) target_mem, gdb_buf, = len); > + =A0if (result =3D=3D 0) > + =A0 =A0return GDB_SUCCESS; > + =A0else > + =A0 =A0return GDB_FAIL; > +} > + > +/* The reader calls into this function to create a new gdb_object > + =A0 which it can then pass around to the other callbacks. Right now, > + =A0 all that is required is allocating the memory. */ > + > +static struct gdb_object * > +jit_object_open_impl (struct gdb_symbol_callbacks *cb) > +{ > + =A0return XZALLOC (struct gdb_object); > +} > + > +/* Readers call into this function to open a new gdb_symtab, which, > + =A0 again, is passed around to other callbacks. */ > + > +static struct gdb_symtab * > +jit_symtab_open_impl (struct gdb_symbol_callbacks *cb, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct gdb_object *object, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const char *file_name) > +{ > + =A0struct gdb_symtab *ret; > + > + =A0ret =3D XZALLOC (struct gdb_symtab); > + =A0ret->file_name =3D file_name ? xstrdup (file_name) : xstrdup (""); > + =A0ret->next =3D object->symtabs; > + =A0object->symtabs =3D ret; > + =A0return ret; > +} > + > +/* Returns true if the block corresponding to old should be placed > + =A0 before the block corresponding to new in the final blockvector. */ > + > +static int > +compare_block (struct gdb_block *old, struct gdb_block *new) > +{ > + =A0if (old =3D=3D NULL) > + =A0 =A0return 1; > + =A0if (old->begin < new->begin) > + =A0 =A0return 1; > + =A0else if (old->begin =3D=3D new->begin) > + =A0 =A0{ > + =A0 =A0 =A0if (old->end > new->end) > + =A0 =A0 =A0 =A0return 1; > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0return 0; > + =A0 =A0} > + =A0else > + =A0 =A0return 0; > +} > + > +/* Called by readers to open a new gdb_block. This function also > + =A0 inserts the new gdb_block in the correct place in the corresponding > + =A0 gdb_symtab. */ > + > +static struct gdb_block * > +jit_block_open_impl (struct gdb_symbol_callbacks *cb, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdb_symtab *symtab, stru= ct gdb_block *parent, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GDB_CORE_ADDR begin, GDB_CORE_A= DDR end, const char *name) > +{ > + =A0struct gdb_block *block =3D XZALLOC (struct gdb_block); > + > + =A0block->next =3D symtab->blocks; > + =A0block->begin =3D (CORE_ADDR) begin; > + =A0block->end =3D (CORE_ADDR) end; > + =A0block->name =3D name ? xstrdup (name) : NULL; > + =A0block->parent =3D parent; > + > + =A0/* Ensure that the blocks are inserted in the correct (reverse of > + =A0 =A0 the order expected by blockvector). */ > + =A0if (compare_block (symtab->blocks, block)) > + =A0 =A0{ > + =A0 =A0 =A0symtab->blocks =3D block; > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0struct gdb_block *i =3D symtab->blocks; > + > + =A0 =A0 =A0for (;; i =3D i->next) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* Guaranteed to terminate, since compare_block (NUL= L, _) > + =A0 =A0 =A0 =A0 =A0 =A0 returns 1 */ > + =A0 =A0 =A0 =A0 =A0if (compare_block (i->next, block)) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0block->next =3D i->next; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0i->next =3D block; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0symtab->nblocks++; > + > + =A0return block; > +} > + > +/* Readers call this to add a line mapping (from PC to line number) to > + =A0 a gdb_symtab. */ > > =A0static void > -jit_register_code (struct gdbarch *gdbarch, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0CORE_ADDR entry_addr, struct jit_cod= e_entry *code_entry) > +jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0stru= ct gdb_symtab *stab, int nlines, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0stru= ct gdb_line_mapping *map) > +{ > + =A0int i; > + > + =A0if (nlines < 1) > + =A0 =A0return; > + > + =A0stab->linetable =3D xmalloc (sizeof (struct linetable) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 + (nlines - 1) = * sizeof (struct linetable_entry)); > + =A0stab->linetable->nitems =3D nlines; > + =A0for (i =3D 0; i < nlines; i++) > + =A0 =A0{ > + =A0 =A0 =A0stab->linetable->item [i].pc =3D (CORE_ADDR) map[i].pc; > + =A0 =A0 =A0stab->linetable->item [i].line =3D map[i].line; > + =A0 =A0} > +} > + > +/* Called by readers to close a gdb_symtab. Does not need to do > + =A0 anything as of now. */ > + > +static void > +jit_symtab_close_impl (struct gdb_symbol_callbacks *cb, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdb_symtab *stab) > +{ > +} > + > +/* Transform STAB to a proper symtab, and add it it OBJFILE. */ > + > +static void > +finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) > =A0{ > + =A0struct symtab *symtab; > + =A0struct gdb_block *gdb_block_iter, *gdb_block_iter_tmp; > + =A0struct block *block_iter; > + =A0int actual_nblocks, i, blockvector_size; > + =A0CORE_ADDR begin, end; > + > + =A0actual_nblocks =3D FIRST_LOCAL_BLOCK + stab->nblocks; > + > + =A0symtab =3D allocate_symtab (stab->file_name, objfile); > + =A0symtab->dirname =3D NULL; /* JIT compilers compile in memory */ > + > + =A0/* Copy over the linetable entry if one was provided. */ > + =A0if (stab->linetable) > + =A0 =A0{ > + =A0 =A0 =A0int size =3D ((stab->linetable->nitems - 1) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* sizeof (struct linetable_entry) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0+ sizeof (struct linetable)); > + =A0 =A0 =A0LINETABLE (symtab) =3D obstack_alloc (&objfile->objfile_obst= ack, size); > + =A0 =A0 =A0memcpy (LINETABLE (symtab), stab->linetable, size); > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0LINETABLE (symtab) =3D NULL; > + =A0 =A0} > + > + =A0blockvector_size =3D (sizeof (struct blockvector) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0+ (actual_nblocks - 1) * siz= eof (struct block *)); > + =A0symtab->blockvector =3D obstack_alloc (&objfile->objfile_obstack, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 blockvector_size); > + > + =A0/* (begin, end) will contain the PC range this entire blockvector sp= ans. */ > + =A0symtab->primary =3D 1; > + =A0BLOCKVECTOR_MAP (symtab->blockvector) =3D NULL; > + =A0begin =3D stab->blocks->begin; > + =A0end =3D stab->blocks->end; > + =A0BLOCKVECTOR_NBLOCKS (symtab->blockvector) =3D actual_nblocks; > + > + =A0/* First run over all the gdb_block objects, creating a real block > + =A0 =A0 object for each. Simultaneously, keep setting the real_block > + =A0 =A0 fields. */ > + =A0for (i =3D (actual_nblocks - 1), gdb_block_iter =3D stab->blocks; > + =A0 =A0 =A0 i >=3D FIRST_LOCAL_BLOCK; i--, gdb_block_iter =3D gdb_block= _iter->next) > + =A0 =A0{ > + =A0 =A0 =A0struct block *new_block =3D allocate_block (&objfile->objfil= e_obstack); > + =A0 =A0 =A0struct symbol *block_name =3D obstack_alloc (&objfile->objfi= le_obstack, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 sizeof (struct symbol)); > + > + =A0 =A0 =A0BLOCK_DICT (new_block) =3D dict_create_linear (&objfile->obj= file_obstack, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL); > + =A0 =A0 =A0/* The address range. */ > + =A0 =A0 =A0BLOCK_START (new_block) =3D (CORE_ADDR) gdb_block_iter->begi= n; > + =A0 =A0 =A0BLOCK_END (new_block) =3D (CORE_ADDR) gdb_block_iter->end; > + > + =A0 =A0 =A0/* The name. */ > + =A0 =A0 =A0memset (block_name, 0, sizeof (struct symbol)); > + =A0 =A0 =A0SYMBOL_DOMAIN (block_name) =3D VAR_DOMAIN; > + =A0 =A0 =A0SYMBOL_CLASS (block_name) =3D LOC_BLOCK; > + =A0 =A0 =A0SYMBOL_SYMTAB (block_name) =3D symtab; > + =A0 =A0 =A0SYMBOL_BLOCK_VALUE (block_name) =3D new_block; > + > + =A0 =A0 =A0block_name->ginfo.name =3D obsavestring (gdb_block_iter->nam= e, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 strlen (gdb_block_iter->name), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 &objfile->objfile_obstack); > + > + =A0 =A0 =A0BLOCK_FUNCTION (new_block) =3D block_name; > + > + =A0 =A0 =A0BLOCKVECTOR_BLOCK (symtab->blockvector, i) =3D new_block; > + =A0 =A0 =A0if (begin > BLOCK_START (new_block)) > + =A0 =A0 =A0 =A0begin =3D BLOCK_START (new_block); > + =A0 =A0 =A0if (end < BLOCK_END (new_block)) > + =A0 =A0 =A0 =A0end =3D BLOCK_END (new_block); > + > + =A0 =A0 =A0gdb_block_iter->real_block =3D new_block; > + =A0 =A0} > + > + =A0/* Now add the special blocks. */ > + =A0block_iter =3D NULL; > + =A0for (i =3D 0; i < FIRST_LOCAL_BLOCK; i++) > + =A0 =A0{ > + =A0 =A0 =A0struct block *new_block =3D allocate_block (&objfile->objfil= e_obstack); > + =A0 =A0 =A0BLOCK_DICT (new_block) =3D dict_create_linear (&objfile->obj= file_obstack, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL); > + =A0 =A0 =A0BLOCK_SUPERBLOCK (new_block) =3D block_iter; > + =A0 =A0 =A0block_iter =3D new_block; > + > + =A0 =A0 =A0BLOCK_START (new_block) =3D (CORE_ADDR) begin; > + =A0 =A0 =A0BLOCK_END (new_block) =3D (CORE_ADDR) end; > + > + =A0 =A0 =A0BLOCKVECTOR_BLOCK (symtab->blockvector, i) =3D new_block; > + =A0 =A0} > + > + =A0/* Fill up the superblock fields for the real blocks, using the > + =A0 =A0 real_block fields populated earlier. */ > + =A0for (gdb_block_iter =3D stab->blocks; gdb_block_iter; > + =A0 =A0 =A0 gdb_block_iter =3D gdb_block_iter->next) > + =A0 =A0{ > + =A0 =A0 =A0if (gdb_block_iter->parent !=3D NULL) > + =A0 =A0 =A0 =A0BLOCK_SUPERBLOCK (gdb_block_iter->real_block) =3D > + =A0 =A0 =A0 =A0 =A0gdb_block_iter->parent->real_block; > + =A0 =A0} > + > + =A0/* Free memory. */ > + =A0gdb_block_iter =3D stab->blocks; > + > + =A0for (gdb_block_iter =3D stab->blocks, gdb_block_iter_tmp =3D gdb_blo= ck_iter->next; > + =A0 =A0 =A0 gdb_block_iter; gdb_block_iter =3D gdb_block_iter_tmp) > + =A0 =A0{ > + =A0 =A0 =A0xfree ((void *) gdb_block_iter->name); > + =A0 =A0 =A0xfree (gdb_block_iter); > + =A0 =A0} > + =A0xfree (stab->linetable); > + =A0xfree ((char *) stab->file_name); > + =A0xfree (stab); > +} > + > +/* Called when closing a gdb_objfile. Converts OBJ to a proper objfile. = */ > + > +static void > +jit_object_close_impl (struct gdb_symbol_callbacks *cb, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdb_object *obj) > +{ > + =A0struct gdb_symtab *i, *j; > + =A0struct objfile *objfile; > + =A0struct jit_dbg_reader_data *priv_data; > + > + =A0priv_data =3D cb->priv_data; > + > + =A0objfile =3D allocate_objfile (NULL, 0); > + =A0objfile->gdbarch =3D target_gdbarch; > + =A0objfile->msymbols =3D obstack_alloc (&objfile->objfile_obstack, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= sizeof (struct minimal_symbol)); > + =A0objfile->msymbols[0].ginfo.name =3D NULL; > + =A0objfile->msymbols[0].ginfo.value.address =3D 0; > + > + =A0xfree (objfile->name); > + =A0objfile->name =3D xstrdup ("<< JIT compiled code >>"); > + > + =A0j =3D NULL; > + =A0for (i =3D obj->symtabs; i; i =3D j) > + =A0 =A0{ > + =A0 =A0 =A0j =3D i->next; > + =A0 =A0 =A0finalize_symtab (i, objfile); > + =A0 =A0} > + =A0add_objfile_entry (objfile, priv_data->entry_address); > + =A0xfree (obj); > +} > + > +/* Try to read CODE_ENTRY using the loaded jit reader (if any). */ > + > +static int > +jit_reader_try_read_symtab (struct jit_code_entry *code_entry) > +{ > + =A0void *gdb_mem; > + =A0int status =3D 0; > + =A0struct jit_dbg_reader *i; > + =A0struct jit_dbg_reader_data priv_data; > + =A0struct gdb_reader_funcs *funcs; > + =A0struct gdb_symbol_callbacks callbacks =3D > + =A0 =A0{ > + =A0 =A0 =A0jit_object_open_impl, > + =A0 =A0 =A0jit_symtab_open_impl, > + =A0 =A0 =A0jit_block_open_impl, > + =A0 =A0 =A0jit_symtab_close_impl, > + =A0 =A0 =A0jit_object_close_impl, > + > + =A0 =A0 =A0jit_symtab_line_mapping_add_impl, > + =A0 =A0 =A0jit_target_read_impl, > + > + =A0 =A0 =A0&priv_data > + =A0 =A0}; > + > + =A0priv_data.entry_address =3D code_entry->symfile_addr; > + > + =A0if (!loaded_jit_reader) > + =A0 =A0return 0; > + > + =A0gdb_mem =3D xmalloc (code_entry->symfile_size); > + =A0if (target_read_memory (code_entry->symfile_addr, gdb_mem, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0code_entry->symfile_= size)) > + =A0 =A0{ > + =A0 =A0 =A0status =3D 0; > + =A0 =A0 =A0goto cleanup; > + =A0 =A0} > + > + =A0funcs =3D loaded_jit_reader->functions; > + =A0if (funcs->read (funcs, &callbacks, gdb_mem, code_entry->symfile_siz= e) > + =A0 =A0 =A0=3D=3D GDB_SUCCESS) > + =A0 =A0{ > + =A0 =A0 =A0status =3D 1; > + =A0 =A0 =A0goto cleanup; > + =A0 =A0} > + > + cleanup: > + =A0xfree (gdb_mem); > + =A0return status; > +} > + > +/* Try to read CODE_ENTRY using BFD. */ > + > +static void > +jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdbarch *gdbarch) > +{ > + =A0struct cleanup *old_cleanups; > + =A0struct objfile *objfile; > =A0 bfd *nbfd; > =A0 struct section_addr_info *sai; > =A0 struct bfd_section *sec; > - =A0struct objfile *objfile; > - =A0struct cleanup *old_cleanups, *my_cleanups; > - =A0int i; > =A0 const struct bfd_arch_info *b; > - =A0CORE_ADDR *entry_addr_ptr; > - > - =A0if (jit_debug) > - =A0 =A0fprintf_unfiltered (gdb_stdlog, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "jit_register_code, symfile= _addr =3D %s, " > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "symfile_size =3D %s\n", > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress (gdbarch, code_ent= ry->symfile_addr), > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pulongest (code_entry->symf= ile_size)); > + =A0int i; > > =A0 nbfd =3D bfd_open_from_target_memory (code_entry->symfile_addr, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 code_entry->symfile_size, gnutarget); > @@ -395,12 +797,34 @@ JITed symbol file is not an object file, ignoring i= t.\n")); > =A0 /* This call takes ownership of sai. =A0*/ > =A0 objfile =3D symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NULL= ); > > - =A0/* Remember a mapping from entry_addr to objfile. =A0*/ > - =A0entry_addr_ptr =3D xmalloc (sizeof (CORE_ADDR)); > - =A0*entry_addr_ptr =3D entry_addr; > - =A0set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr); > - > =A0 discard_cleanups (old_cleanups); > + =A0add_objfile_entry (objfile, code_entry->symfile_addr); > +} > + > +/* This function registers code associated with a JIT code entry. =A0It = uses the > + =A0 pointer and size pair in the entry to read the symbol file from the= remote > + =A0 and then calls symbol_file_add_from_local_memory to add it as thoug= h it were > + =A0 a symbol file added by the user. =A0*/ > + > +static void > +jit_register_code (struct gdbarch *gdbarch, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CORE_ADDR entry_addr, struct jit_co= de_entry *code_entry) > +{ > + =A0int i, success; > + =A0const struct bfd_arch_info *b; > + =A0struct jit_inferior_data *inf_data =3D get_jit_inferior_data (); > + > + =A0if (jit_debug) > + =A0 =A0fprintf_unfiltered (gdb_stdlog, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"jit_register_code, symf= ile_addr =3D %s, " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0"symfile_size =3D %s\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0paddress (gdbarch, code_= entry->symfile_addr), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pulongest (code_entry->s= ymfile_size)); > + > + =A0success =3D jit_reader_try_read_symtab (code_entry); > + > + =A0if (!success) > + =A0 =A0jit_bfd_try_read_symtab (code_entry, gdbarch); > =A0} > > =A0/* This function unregisters JITed code and frees the corresponding > @@ -635,6 +1059,14 @@ jit_event_handler (struct gdbarch *gdbarch) > =A0 =A0 } > =A0} > > +/* Called to free the data allocated to the jit_inferior_data slot. */ > + > +static void > +free_objfile_data (struct objfile *objfile, void *data) > +{ > + =A0xfree (data); > +} > + > =A0/* Provide a prototype to silence -Wmissing-prototypes. =A0*/ > > =A0extern void _initialize_jit (void); > @@ -655,7 +1087,8 @@ _initialize_jit (void) > =A0 observer_attach_inferior_created (jit_inferior_created_observer); > =A0 observer_attach_inferior_exit (jit_inferior_exit_hook); > =A0 observer_attach_executable_changed (jit_executable_changed_observer); > - =A0jit_objfile_data =3D register_objfile_data (); > + =A0jit_objfile_data =3D > + =A0 =A0register_objfile_data_with_cleanup (NULL,free_objfile_data); > =A0 jit_inferior_data =3D > =A0 =A0 register_inferior_data_with_cleanup (jit_inferior_data_cleanup); > =A0 add_com ("jit-reader-load", no_class, jit_reader_load_command, _("\ > -- > 1.7.5.4 > >