From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29472 invoked by alias); 27 Aug 2011 14:18:53 -0000 Received: (qmail 29464 invoked by uid 22791); 27 Aug 2011 14:18:50 -0000 X-SWARE-Spam-Status: No, hits=1.2 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 14:18:33 +0000 Received: by bkbzt4 with SMTP id zt4so3612880bkb.0 for ; Sat, 27 Aug 2011 07:18:31 -0700 (PDT) MIME-Version: 1.0 Received: by 10.204.157.142 with SMTP id b14mr1097313bkx.337.1314454711422; Sat, 27 Aug 2011 07:18:31 -0700 (PDT) Received: by 10.204.36.74 with HTTP; Sat, 27 Aug 2011 07:18:31 -0700 (PDT) In-Reply-To: References: <1314450736-19389-1-git-send-email-sanjoy@playingwithpointers.com> <1314450736-19389-6-git-send-email-sanjoy@playingwithpointers.com> Date: Sat, 27 Aug 2011 14:18: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/msg00534.txt.bz2 On Sat, Aug 27, 2011 at 7:17 PM, Abhijit Halder wrote: > 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-unwi= nd.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 prope= r 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-unwin= d.h. >> + =A0 =A0 =A0 (add_objfile_entry, jit_target_read_impl, jit_object_open_= impl) >> + =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 varia= bles. >> =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 = already >> =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_= order); >> =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 th= e remote >> - =A0 and then calls symbol_file_add_from_local_memory to add it as thou= gh 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) I am not clear on why we are passing struct gdb_symbol_callbacks * as an argument even when we are not using it inside function. >> +{ >> + =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) I am not able to see the use of struct gdb_symbol_callbacks *cb inside the function. >> +{ >> + =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) I think this should be +static int +compare_block (const struct gdb_block *const old, const struct gdb_block *const 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, str= uct gdb_block *parent, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GDB_CORE_ADDR begin, GDB_CORE_= ADDR 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 (NU= LL, _) >> + =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_co= de_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 =A0str= uct gdb_symtab *stab, int nlines, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0str= uct 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) >> +{ >> +} Do we need at all this definition? >> + >> +/* 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 */ I am not sure whether this way of putting comment is allowed under GNU styl= e. >> + >> + =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_obs= tack, 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) * si= zeof (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 s= pans. */ >> + =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_bloc= k_iter->next) >> + =A0 =A0{ >> + =A0 =A0 =A0struct block *new_block =3D allocate_block (&objfile->objfi= le_obstack); >> + =A0 =A0 =A0struct symbol *block_name =3D obstack_alloc (&objfile->objf= ile_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->ob= jfile_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->beg= in; >> + =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->na= me, >> + =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->objfi= le_obstack); >> + =A0 =A0 =A0BLOCK_DICT (new_block) =3D dict_create_linear (&objfile->ob= jfile_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_bl= ock_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_si= ze) >> + =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 *gdbarc= h) >> +{ >> + =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, symfil= e_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_en= try->symfile_addr), >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pulongest (code_entry->sym= file_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 = it.\n")); >> =A0 /* This call takes ownership of sai. =A0*/ >> =A0 objfile =3D symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NUL= L); >> >> - =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 th= e remote >> + =A0 and then calls symbol_file_add_from_local_memory to add it as thou= gh 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_c= ode_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, sym= file_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->= symfile_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 >> >> >