xref: /dflybsd-src/contrib/gdb-7/gdb/jit.c (revision c50c785cb49e9377ca78104c5540c7b33f768771)
15796c8dcSSimon Schubert /* Handle JIT code generation in the inferior for GDB, the GNU Debugger.
25796c8dcSSimon Schubert 
3*c50c785cSJohn Marino    Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "jit.h"
235796c8dcSSimon Schubert #include "breakpoint.h"
24*c50c785cSJohn Marino #include "command.h"
25*c50c785cSJohn Marino #include "gdbcmd.h"
265796c8dcSSimon Schubert #include "gdbcore.h"
27*c50c785cSJohn Marino #include "inferior.h"
285796c8dcSSimon Schubert #include "observer.h"
295796c8dcSSimon Schubert #include "objfiles.h"
305796c8dcSSimon Schubert #include "symfile.h"
315796c8dcSSimon Schubert #include "symtab.h"
325796c8dcSSimon Schubert #include "target.h"
335796c8dcSSimon Schubert #include "gdb_stat.h"
345796c8dcSSimon Schubert 
355796c8dcSSimon Schubert static const struct objfile_data *jit_objfile_data;
365796c8dcSSimon Schubert 
375796c8dcSSimon Schubert static const char *const jit_break_name = "__jit_debug_register_code";
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert static const char *const jit_descriptor_name = "__jit_debug_descriptor";
405796c8dcSSimon Schubert 
41*c50c785cSJohn Marino static const struct inferior_data *jit_inferior_data = NULL;
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert static void
44*c50c785cSJohn Marino jit_inferior_init (struct gdbarch *gdbarch);
45*c50c785cSJohn Marino 
46*c50c785cSJohn Marino /* Non-zero if we want to see trace of jit level stuff.  */
47*c50c785cSJohn Marino 
48*c50c785cSJohn Marino static int jit_debug = 0;
49*c50c785cSJohn Marino 
50*c50c785cSJohn Marino static void
51*c50c785cSJohn Marino show_jit_debug (struct ui_file *file, int from_tty,
52*c50c785cSJohn Marino 		struct cmd_list_element *c, const char *value)
535796c8dcSSimon Schubert {
54*c50c785cSJohn Marino   fprintf_filtered (file, _("JIT debugging is %s.\n"), value);
555796c8dcSSimon Schubert }
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert struct target_buffer
585796c8dcSSimon Schubert {
595796c8dcSSimon Schubert   CORE_ADDR base;
60*c50c785cSJohn Marino   ULONGEST size;
615796c8dcSSimon Schubert };
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert /* Openning the file is a no-op.  */
645796c8dcSSimon Schubert 
655796c8dcSSimon Schubert static void *
665796c8dcSSimon Schubert mem_bfd_iovec_open (struct bfd *abfd, void *open_closure)
675796c8dcSSimon Schubert {
685796c8dcSSimon Schubert   return open_closure;
695796c8dcSSimon Schubert }
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert /* Closing the file is just freeing the base/size pair on our side.  */
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert static int
745796c8dcSSimon Schubert mem_bfd_iovec_close (struct bfd *abfd, void *stream)
755796c8dcSSimon Schubert {
765796c8dcSSimon Schubert   xfree (stream);
775796c8dcSSimon Schubert   return 1;
785796c8dcSSimon Schubert }
795796c8dcSSimon Schubert 
805796c8dcSSimon Schubert /* For reading the file, we just need to pass through to target_read_memory and
815796c8dcSSimon Schubert    fix up the arguments and return values.  */
825796c8dcSSimon Schubert 
835796c8dcSSimon Schubert static file_ptr
845796c8dcSSimon Schubert mem_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
855796c8dcSSimon Schubert                      file_ptr nbytes, file_ptr offset)
865796c8dcSSimon Schubert {
875796c8dcSSimon Schubert   int err;
885796c8dcSSimon Schubert   struct target_buffer *buffer = (struct target_buffer *) stream;
895796c8dcSSimon Schubert 
905796c8dcSSimon Schubert   /* If this read will read all of the file, limit it to just the rest.  */
915796c8dcSSimon Schubert   if (offset + nbytes > buffer->size)
925796c8dcSSimon Schubert     nbytes = buffer->size - offset;
935796c8dcSSimon Schubert 
945796c8dcSSimon Schubert   /* If there are no more bytes left, we've reached EOF.  */
955796c8dcSSimon Schubert   if (nbytes == 0)
965796c8dcSSimon Schubert     return 0;
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert   err = target_read_memory (buffer->base + offset, (gdb_byte *) buf, nbytes);
995796c8dcSSimon Schubert   if (err)
1005796c8dcSSimon Schubert     return -1;
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert   return nbytes;
1035796c8dcSSimon Schubert }
1045796c8dcSSimon Schubert 
1055796c8dcSSimon Schubert /* For statting the file, we only support the st_size attribute.  */
1065796c8dcSSimon Schubert 
1075796c8dcSSimon Schubert static int
1085796c8dcSSimon Schubert mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
1095796c8dcSSimon Schubert {
1105796c8dcSSimon Schubert   struct target_buffer *buffer = (struct target_buffer*) stream;
1115796c8dcSSimon Schubert 
1125796c8dcSSimon Schubert   sb->st_size = buffer->size;
1135796c8dcSSimon Schubert   return 0;
1145796c8dcSSimon Schubert }
1155796c8dcSSimon Schubert 
1165796c8dcSSimon Schubert /* Open a BFD from the target's memory.  */
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert static struct bfd *
119*c50c785cSJohn Marino bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target)
1205796c8dcSSimon Schubert {
1215796c8dcSSimon Schubert   const char *filename = xstrdup ("<in-memory>");
1225796c8dcSSimon Schubert   struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert   buffer->base = addr;
1255796c8dcSSimon Schubert   buffer->size = size;
1265796c8dcSSimon Schubert   return bfd_openr_iovec (filename, target,
1275796c8dcSSimon Schubert                           mem_bfd_iovec_open,
1285796c8dcSSimon Schubert                           buffer,
1295796c8dcSSimon Schubert                           mem_bfd_iovec_pread,
1305796c8dcSSimon Schubert                           mem_bfd_iovec_close,
1315796c8dcSSimon Schubert                           mem_bfd_iovec_stat);
1325796c8dcSSimon Schubert }
1335796c8dcSSimon Schubert 
134*c50c785cSJohn Marino /* Per-inferior structure recording the addresses in the inferior.  */
135*c50c785cSJohn Marino 
136*c50c785cSJohn Marino struct jit_inferior_data
137*c50c785cSJohn Marino {
138*c50c785cSJohn Marino   CORE_ADDR breakpoint_addr;  /* &__jit_debug_register_code()  */
139*c50c785cSJohn Marino   CORE_ADDR descriptor_addr;  /* &__jit_debug_descriptor  */
140*c50c785cSJohn Marino };
141*c50c785cSJohn Marino 
142*c50c785cSJohn Marino /* Return jit_inferior_data for current inferior.  Allocate if not already
143*c50c785cSJohn Marino    present.  */
144*c50c785cSJohn Marino 
145*c50c785cSJohn Marino static struct jit_inferior_data *
146*c50c785cSJohn Marino get_jit_inferior_data (void)
147*c50c785cSJohn Marino {
148*c50c785cSJohn Marino   struct inferior *inf;
149*c50c785cSJohn Marino   struct jit_inferior_data *inf_data;
150*c50c785cSJohn Marino 
151*c50c785cSJohn Marino   inf = current_inferior ();
152*c50c785cSJohn Marino   inf_data = inferior_data (inf, jit_inferior_data);
153*c50c785cSJohn Marino   if (inf_data == NULL)
154*c50c785cSJohn Marino     {
155*c50c785cSJohn Marino       inf_data = XZALLOC (struct jit_inferior_data);
156*c50c785cSJohn Marino       set_inferior_data (inf, jit_inferior_data, inf_data);
157*c50c785cSJohn Marino     }
158*c50c785cSJohn Marino 
159*c50c785cSJohn Marino   return inf_data;
160*c50c785cSJohn Marino }
161*c50c785cSJohn Marino 
162*c50c785cSJohn Marino static void
163*c50c785cSJohn Marino jit_inferior_data_cleanup (struct inferior *inf, void *arg)
164*c50c785cSJohn Marino {
165*c50c785cSJohn Marino   xfree (arg);
166*c50c785cSJohn Marino }
167*c50c785cSJohn Marino 
168*c50c785cSJohn Marino /* Helper function for reading the global JIT descriptor from remote
169*c50c785cSJohn Marino    memory.  */
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert static void
1725796c8dcSSimon Schubert jit_read_descriptor (struct gdbarch *gdbarch,
173*c50c785cSJohn Marino 		     struct jit_descriptor *descriptor,
174*c50c785cSJohn Marino 		     CORE_ADDR descriptor_addr)
1755796c8dcSSimon Schubert {
1765796c8dcSSimon Schubert   int err;
1775796c8dcSSimon Schubert   struct type *ptr_type;
1785796c8dcSSimon Schubert   int ptr_size;
1795796c8dcSSimon Schubert   int desc_size;
1805796c8dcSSimon Schubert   gdb_byte *desc_buf;
1815796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert   /* Figure out how big the descriptor is on the remote and how to read it.  */
1845796c8dcSSimon Schubert   ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
1855796c8dcSSimon Schubert   ptr_size = TYPE_LENGTH (ptr_type);
1865796c8dcSSimon Schubert   desc_size = 8 + 2 * ptr_size;  /* Two 32-bit ints and two pointers.  */
1875796c8dcSSimon Schubert   desc_buf = alloca (desc_size);
1885796c8dcSSimon Schubert 
1895796c8dcSSimon Schubert   /* Read the descriptor.  */
190*c50c785cSJohn Marino   err = target_read_memory (descriptor_addr, desc_buf, desc_size);
1915796c8dcSSimon Schubert   if (err)
1925796c8dcSSimon Schubert     error (_("Unable to read JIT descriptor from remote memory!"));
1935796c8dcSSimon Schubert 
1945796c8dcSSimon Schubert   /* Fix the endianness to match the host.  */
1955796c8dcSSimon Schubert   descriptor->version = extract_unsigned_integer (&desc_buf[0], 4, byte_order);
1965796c8dcSSimon Schubert   descriptor->action_flag =
1975796c8dcSSimon Schubert       extract_unsigned_integer (&desc_buf[4], 4, byte_order);
1985796c8dcSSimon Schubert   descriptor->relevant_entry = extract_typed_address (&desc_buf[8], ptr_type);
1995796c8dcSSimon Schubert   descriptor->first_entry =
2005796c8dcSSimon Schubert       extract_typed_address (&desc_buf[8 + ptr_size], ptr_type);
2015796c8dcSSimon Schubert }
2025796c8dcSSimon Schubert 
2035796c8dcSSimon Schubert /* Helper function for reading a JITed code entry from remote memory.  */
2045796c8dcSSimon Schubert 
2055796c8dcSSimon Schubert static void
2065796c8dcSSimon Schubert jit_read_code_entry (struct gdbarch *gdbarch,
2075796c8dcSSimon Schubert 		     CORE_ADDR code_addr, struct jit_code_entry *code_entry)
2085796c8dcSSimon Schubert {
2095796c8dcSSimon Schubert   int err;
2105796c8dcSSimon Schubert   struct type *ptr_type;
2115796c8dcSSimon Schubert   int ptr_size;
2125796c8dcSSimon Schubert   int entry_size;
2135796c8dcSSimon Schubert   gdb_byte *entry_buf;
2145796c8dcSSimon Schubert   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2155796c8dcSSimon Schubert 
2165796c8dcSSimon Schubert   /* Figure out how big the entry is on the remote and how to read it.  */
2175796c8dcSSimon Schubert   ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
2185796c8dcSSimon Schubert   ptr_size = TYPE_LENGTH (ptr_type);
2195796c8dcSSimon Schubert   entry_size = 3 * ptr_size + 8;  /* Three pointers and one 64-bit int.  */
2205796c8dcSSimon Schubert   entry_buf = alloca (entry_size);
2215796c8dcSSimon Schubert 
2225796c8dcSSimon Schubert   /* Read the entry.  */
2235796c8dcSSimon Schubert   err = target_read_memory (code_addr, entry_buf, entry_size);
2245796c8dcSSimon Schubert   if (err)
2255796c8dcSSimon Schubert     error (_("Unable to read JIT code entry from remote memory!"));
2265796c8dcSSimon Schubert 
2275796c8dcSSimon Schubert   /* Fix the endianness to match the host.  */
2285796c8dcSSimon Schubert   ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
2295796c8dcSSimon Schubert   code_entry->next_entry = extract_typed_address (&entry_buf[0], ptr_type);
2305796c8dcSSimon Schubert   code_entry->prev_entry =
2315796c8dcSSimon Schubert       extract_typed_address (&entry_buf[ptr_size], ptr_type);
2325796c8dcSSimon Schubert   code_entry->symfile_addr =
2335796c8dcSSimon Schubert       extract_typed_address (&entry_buf[2 * ptr_size], ptr_type);
2345796c8dcSSimon Schubert   code_entry->symfile_size =
2355796c8dcSSimon Schubert       extract_unsigned_integer (&entry_buf[3 * ptr_size], 8, byte_order);
2365796c8dcSSimon Schubert }
2375796c8dcSSimon Schubert 
2385796c8dcSSimon Schubert /* This function registers code associated with a JIT code entry.  It uses the
2395796c8dcSSimon Schubert    pointer and size pair in the entry to read the symbol file from the remote
2405796c8dcSSimon Schubert    and then calls symbol_file_add_from_local_memory to add it as though it were
2415796c8dcSSimon Schubert    a symbol file added by the user.  */
2425796c8dcSSimon Schubert 
2435796c8dcSSimon Schubert static void
2445796c8dcSSimon Schubert jit_register_code (struct gdbarch *gdbarch,
2455796c8dcSSimon Schubert 		   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
2465796c8dcSSimon Schubert {
2475796c8dcSSimon Schubert   bfd *nbfd;
2485796c8dcSSimon Schubert   struct section_addr_info *sai;
2495796c8dcSSimon Schubert   struct bfd_section *sec;
2505796c8dcSSimon Schubert   struct objfile *objfile;
2515796c8dcSSimon Schubert   struct cleanup *old_cleanups, *my_cleanups;
2525796c8dcSSimon Schubert   int i;
2535796c8dcSSimon Schubert   const struct bfd_arch_info *b;
2545796c8dcSSimon Schubert   CORE_ADDR *entry_addr_ptr;
2555796c8dcSSimon Schubert 
256*c50c785cSJohn Marino   if (jit_debug)
257*c50c785cSJohn Marino     fprintf_unfiltered (gdb_stdlog,
258*c50c785cSJohn Marino 			"jit_register_code, symfile_addr = %s, "
259*c50c785cSJohn Marino 			"symfile_size = %s\n",
260*c50c785cSJohn Marino 			paddress (gdbarch, code_entry->symfile_addr),
261*c50c785cSJohn Marino 			pulongest (code_entry->symfile_size));
262*c50c785cSJohn Marino 
2635796c8dcSSimon Schubert   nbfd = bfd_open_from_target_memory (code_entry->symfile_addr,
2645796c8dcSSimon Schubert                                       code_entry->symfile_size, gnutarget);
2655796c8dcSSimon Schubert   old_cleanups = make_cleanup_bfd_close (nbfd);
2665796c8dcSSimon Schubert 
2675796c8dcSSimon Schubert   /* Check the format.  NOTE: This initializes important data that GDB uses!
2685796c8dcSSimon Schubert      We would segfault later without this line.  */
2695796c8dcSSimon Schubert   if (!bfd_check_format (nbfd, bfd_object))
2705796c8dcSSimon Schubert     {
2715796c8dcSSimon Schubert       printf_unfiltered (_("\
2725796c8dcSSimon Schubert JITed symbol file is not an object file, ignoring it.\n"));
2735796c8dcSSimon Schubert       do_cleanups (old_cleanups);
2745796c8dcSSimon Schubert       return;
2755796c8dcSSimon Schubert     }
2765796c8dcSSimon Schubert 
2775796c8dcSSimon Schubert   /* Check bfd arch.  */
2785796c8dcSSimon Schubert   b = gdbarch_bfd_arch_info (gdbarch);
2795796c8dcSSimon Schubert   if (b->compatible (b, bfd_get_arch_info (nbfd)) != b)
2805796c8dcSSimon Schubert     warning (_("JITed object file architecture %s is not compatible "
2815796c8dcSSimon Schubert                "with target architecture %s."), bfd_get_arch_info
2825796c8dcSSimon Schubert              (nbfd)->printable_name, b->printable_name);
2835796c8dcSSimon Schubert 
2845796c8dcSSimon Schubert   /* Read the section address information out of the symbol file.  Since the
2855796c8dcSSimon Schubert      file is generated by the JIT at runtime, it should all of the absolute
2865796c8dcSSimon Schubert      addresses that we care about.  */
2875796c8dcSSimon Schubert   sai = alloc_section_addr_info (bfd_count_sections (nbfd));
2885796c8dcSSimon Schubert   make_cleanup_free_section_addr_info (sai);
2895796c8dcSSimon Schubert   i = 0;
2905796c8dcSSimon Schubert   for (sec = nbfd->sections; sec != NULL; sec = sec->next)
2915796c8dcSSimon Schubert     if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
2925796c8dcSSimon Schubert       {
2935796c8dcSSimon Schubert         /* We assume that these virtual addresses are absolute, and do not
2945796c8dcSSimon Schubert            treat them as offsets.  */
2955796c8dcSSimon Schubert         sai->other[i].addr = bfd_get_section_vma (nbfd, sec);
296cf7f2e2dSJohn Marino         sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec));
2975796c8dcSSimon Schubert         sai->other[i].sectindex = sec->index;
2985796c8dcSSimon Schubert         ++i;
2995796c8dcSSimon Schubert       }
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert   /* This call takes ownership of sai.  */
3025796c8dcSSimon Schubert   objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED);
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert   /* Remember a mapping from entry_addr to objfile.  */
3055796c8dcSSimon Schubert   entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
3065796c8dcSSimon Schubert   *entry_addr_ptr = entry_addr;
3075796c8dcSSimon Schubert   set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert   discard_cleanups (old_cleanups);
3105796c8dcSSimon Schubert }
3115796c8dcSSimon Schubert 
312*c50c785cSJohn Marino /* This function unregisters JITed code and frees the corresponding
313*c50c785cSJohn Marino    objfile.  */
3145796c8dcSSimon Schubert 
3155796c8dcSSimon Schubert static void
3165796c8dcSSimon Schubert jit_unregister_code (struct objfile *objfile)
3175796c8dcSSimon Schubert {
3185796c8dcSSimon Schubert   free_objfile (objfile);
3195796c8dcSSimon Schubert }
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert /* Look up the objfile with this code entry address.  */
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert static struct objfile *
3245796c8dcSSimon Schubert jit_find_objf_with_entry_addr (CORE_ADDR entry_addr)
3255796c8dcSSimon Schubert {
3265796c8dcSSimon Schubert   struct objfile *objf;
3275796c8dcSSimon Schubert   CORE_ADDR *objf_entry_addr;
3285796c8dcSSimon Schubert 
3295796c8dcSSimon Schubert   ALL_OBJFILES (objf)
3305796c8dcSSimon Schubert     {
3315796c8dcSSimon Schubert       objf_entry_addr = (CORE_ADDR *) objfile_data (objf, jit_objfile_data);
3325796c8dcSSimon Schubert       if (objf_entry_addr != NULL && *objf_entry_addr == entry_addr)
3335796c8dcSSimon Schubert         return objf;
3345796c8dcSSimon Schubert     }
3355796c8dcSSimon Schubert   return NULL;
3365796c8dcSSimon Schubert }
3375796c8dcSSimon Schubert 
338*c50c785cSJohn Marino /* (Re-)Initialize the jit breakpoint if necessary.
339*c50c785cSJohn Marino    Return 0 on success.  */
340*c50c785cSJohn Marino 
341*c50c785cSJohn Marino static int
342*c50c785cSJohn Marino jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
343*c50c785cSJohn Marino 				struct jit_inferior_data *inf_data)
344*c50c785cSJohn Marino {
345*c50c785cSJohn Marino   if (inf_data->breakpoint_addr == 0)
346*c50c785cSJohn Marino     {
347*c50c785cSJohn Marino       struct minimal_symbol *reg_symbol;
348*c50c785cSJohn Marino 
349*c50c785cSJohn Marino       /* Lookup the registration symbol.  If it is missing, then we assume
350*c50c785cSJohn Marino 	 we are not attached to a JIT.  */
351*c50c785cSJohn Marino       reg_symbol = lookup_minimal_symbol (jit_break_name, NULL, NULL);
352*c50c785cSJohn Marino       if (reg_symbol == NULL)
353*c50c785cSJohn Marino 	return 1;
354*c50c785cSJohn Marino       inf_data->breakpoint_addr = SYMBOL_VALUE_ADDRESS (reg_symbol);
355*c50c785cSJohn Marino       if (inf_data->breakpoint_addr == 0)
356*c50c785cSJohn Marino 	return 2;
357*c50c785cSJohn Marino 
358*c50c785cSJohn Marino       /* If we have not read the jit descriptor yet (e.g. because the JITer
359*c50c785cSJohn Marino 	 itself is in a shared library which just got loaded), do so now.  */
360*c50c785cSJohn Marino       if (inf_data->descriptor_addr == 0)
361*c50c785cSJohn Marino 	jit_inferior_init (gdbarch);
362*c50c785cSJohn Marino     }
363*c50c785cSJohn Marino   else
364*c50c785cSJohn Marino     return 0;
365*c50c785cSJohn Marino 
366*c50c785cSJohn Marino   if (jit_debug)
367*c50c785cSJohn Marino     fprintf_unfiltered (gdb_stdlog,
368*c50c785cSJohn Marino 			"jit_breakpoint_re_set_internal, "
369*c50c785cSJohn Marino 			"breakpoint_addr = %s\n",
370*c50c785cSJohn Marino 			paddress (gdbarch, inf_data->breakpoint_addr));
371*c50c785cSJohn Marino 
372*c50c785cSJohn Marino   /* Put a breakpoint in the registration symbol.  */
373*c50c785cSJohn Marino   create_jit_event_breakpoint (gdbarch, inf_data->breakpoint_addr);
374*c50c785cSJohn Marino 
375*c50c785cSJohn Marino   return 0;
376*c50c785cSJohn Marino }
377*c50c785cSJohn Marino 
378*c50c785cSJohn Marino /* Register any already created translations.  */
3795796c8dcSSimon Schubert 
3805796c8dcSSimon Schubert static void
3815796c8dcSSimon Schubert jit_inferior_init (struct gdbarch *gdbarch)
3825796c8dcSSimon Schubert {
3835796c8dcSSimon Schubert   struct jit_descriptor descriptor;
3845796c8dcSSimon Schubert   struct jit_code_entry cur_entry;
385*c50c785cSJohn Marino   struct jit_inferior_data *inf_data;
3865796c8dcSSimon Schubert   CORE_ADDR cur_entry_addr;
3875796c8dcSSimon Schubert 
388*c50c785cSJohn Marino   if (jit_debug)
389*c50c785cSJohn Marino     fprintf_unfiltered (gdb_stdlog, "jit_inferior_init\n");
390*c50c785cSJohn Marino 
391*c50c785cSJohn Marino   inf_data = get_jit_inferior_data ();
392*c50c785cSJohn Marino   if (jit_breakpoint_re_set_internal (gdbarch, inf_data) != 0)
3935796c8dcSSimon Schubert     return;
3945796c8dcSSimon Schubert 
395*c50c785cSJohn Marino   if (inf_data->descriptor_addr == 0)
396*c50c785cSJohn Marino     {
397*c50c785cSJohn Marino       struct minimal_symbol *desc_symbol;
3985796c8dcSSimon Schubert 
399*c50c785cSJohn Marino       /* Lookup the descriptor symbol and cache the addr.  If it is
400*c50c785cSJohn Marino 	 missing, we assume we are not attached to a JIT and return early.  */
4015796c8dcSSimon Schubert       desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, NULL);
4025796c8dcSSimon Schubert       if (desc_symbol == NULL)
4035796c8dcSSimon Schubert 	return;
4045796c8dcSSimon Schubert 
405*c50c785cSJohn Marino       inf_data->descriptor_addr = SYMBOL_VALUE_ADDRESS (desc_symbol);
406*c50c785cSJohn Marino       if (inf_data->descriptor_addr == 0)
407*c50c785cSJohn Marino 	return;
408*c50c785cSJohn Marino     }
409*c50c785cSJohn Marino 
410*c50c785cSJohn Marino   if (jit_debug)
411*c50c785cSJohn Marino     fprintf_unfiltered (gdb_stdlog,
412*c50c785cSJohn Marino 			"jit_inferior_init, descriptor_addr = %s\n",
413*c50c785cSJohn Marino 			paddress (gdbarch, inf_data->descriptor_addr));
414*c50c785cSJohn Marino 
415*c50c785cSJohn Marino   /* Read the descriptor so we can check the version number and load
416*c50c785cSJohn Marino      any already JITed functions.  */
417*c50c785cSJohn Marino   jit_read_descriptor (gdbarch, &descriptor, inf_data->descriptor_addr);
4185796c8dcSSimon Schubert 
4195796c8dcSSimon Schubert   /* Check that the version number agrees with that we support.  */
4205796c8dcSSimon Schubert   if (descriptor.version != 1)
4215796c8dcSSimon Schubert     error (_("Unsupported JIT protocol version in descriptor!"));
4225796c8dcSSimon Schubert 
423*c50c785cSJohn Marino   /* If we've attached to a running program, we need to check the descriptor
424*c50c785cSJohn Marino      to register any functions that were already generated.  */
4255796c8dcSSimon Schubert   for (cur_entry_addr = descriptor.first_entry;
4265796c8dcSSimon Schubert        cur_entry_addr != 0;
4275796c8dcSSimon Schubert        cur_entry_addr = cur_entry.next_entry)
4285796c8dcSSimon Schubert     {
4295796c8dcSSimon Schubert       jit_read_code_entry (gdbarch, cur_entry_addr, &cur_entry);
4305796c8dcSSimon Schubert 
4315796c8dcSSimon Schubert       /* This hook may be called many times during setup, so make sure we don't
4325796c8dcSSimon Schubert          add the same symbol file twice.  */
4335796c8dcSSimon Schubert       if (jit_find_objf_with_entry_addr (cur_entry_addr) != NULL)
4345796c8dcSSimon Schubert         continue;
4355796c8dcSSimon Schubert 
4365796c8dcSSimon Schubert       jit_register_code (gdbarch, cur_entry_addr, &cur_entry);
4375796c8dcSSimon Schubert     }
4385796c8dcSSimon Schubert }
4395796c8dcSSimon Schubert 
4405796c8dcSSimon Schubert /* Exported routine to call when an inferior has been created.  */
4415796c8dcSSimon Schubert 
4425796c8dcSSimon Schubert void
4435796c8dcSSimon Schubert jit_inferior_created_hook (void)
4445796c8dcSSimon Schubert {
4455796c8dcSSimon Schubert   jit_inferior_init (target_gdbarch);
4465796c8dcSSimon Schubert }
4475796c8dcSSimon Schubert 
4485796c8dcSSimon Schubert /* Exported routine to call to re-set the jit breakpoints,
4495796c8dcSSimon Schubert    e.g. when a program is rerun.  */
4505796c8dcSSimon Schubert 
4515796c8dcSSimon Schubert void
4525796c8dcSSimon Schubert jit_breakpoint_re_set (void)
4535796c8dcSSimon Schubert {
454*c50c785cSJohn Marino   jit_breakpoint_re_set_internal (target_gdbarch,
455*c50c785cSJohn Marino 				  get_jit_inferior_data ());
456*c50c785cSJohn Marino }
457*c50c785cSJohn Marino 
458*c50c785cSJohn Marino /* Reset inferior_data, so sybols will be looked up again, and jit_breakpoint
459*c50c785cSJohn Marino    will be reset.  */
460*c50c785cSJohn Marino 
461*c50c785cSJohn Marino static void
462*c50c785cSJohn Marino jit_reset_inferior_data_and_breakpoints (void)
463*c50c785cSJohn Marino {
464*c50c785cSJohn Marino   struct jit_inferior_data *inf_data;
465*c50c785cSJohn Marino 
466*c50c785cSJohn Marino   /* Force jit_inferior_init to re-lookup of jit symbol addresses.  */
467*c50c785cSJohn Marino   inf_data = get_jit_inferior_data ();
468*c50c785cSJohn Marino   inf_data->breakpoint_addr = 0;
469*c50c785cSJohn Marino   inf_data->descriptor_addr = 0;
470*c50c785cSJohn Marino 
471*c50c785cSJohn Marino   /* Remove any existing JIT breakpoint(s).  */
472*c50c785cSJohn Marino   remove_jit_event_breakpoints ();
473*c50c785cSJohn Marino 
4745796c8dcSSimon Schubert   jit_inferior_init (target_gdbarch);
4755796c8dcSSimon Schubert }
4765796c8dcSSimon Schubert 
4775796c8dcSSimon Schubert /* Wrapper to match the observer function pointer prototype.  */
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert static void
4805796c8dcSSimon Schubert jit_inferior_created_observer (struct target_ops *objfile, int from_tty)
4815796c8dcSSimon Schubert {
482*c50c785cSJohn Marino   jit_reset_inferior_data_and_breakpoints ();
4835796c8dcSSimon Schubert }
4845796c8dcSSimon Schubert 
485*c50c785cSJohn Marino /* This function cleans up any code entries left over when the
486*c50c785cSJohn Marino    inferior exits.  We get left over code when the inferior exits
487*c50c785cSJohn Marino    without unregistering its code, for example when it crashes.  */
4885796c8dcSSimon Schubert 
4895796c8dcSSimon Schubert static void
490cf7f2e2dSJohn Marino jit_inferior_exit_hook (struct inferior *inf)
4915796c8dcSSimon Schubert {
4925796c8dcSSimon Schubert   struct objfile *objf;
4935796c8dcSSimon Schubert   struct objfile *temp;
4945796c8dcSSimon Schubert 
4955796c8dcSSimon Schubert   ALL_OBJFILES_SAFE (objf, temp)
4965796c8dcSSimon Schubert     if (objfile_data (objf, jit_objfile_data) != NULL)
4975796c8dcSSimon Schubert       jit_unregister_code (objf);
4985796c8dcSSimon Schubert }
4995796c8dcSSimon Schubert 
500*c50c785cSJohn Marino static void
501*c50c785cSJohn Marino jit_executable_changed_observer (void)
502*c50c785cSJohn Marino {
503*c50c785cSJohn Marino   jit_reset_inferior_data_and_breakpoints ();
504*c50c785cSJohn Marino }
505*c50c785cSJohn Marino 
5065796c8dcSSimon Schubert void
5075796c8dcSSimon Schubert jit_event_handler (struct gdbarch *gdbarch)
5085796c8dcSSimon Schubert {
5095796c8dcSSimon Schubert   struct jit_descriptor descriptor;
5105796c8dcSSimon Schubert   struct jit_code_entry code_entry;
5115796c8dcSSimon Schubert   CORE_ADDR entry_addr;
5125796c8dcSSimon Schubert   struct objfile *objf;
5135796c8dcSSimon Schubert 
5145796c8dcSSimon Schubert   /* Read the descriptor from remote memory.  */
515*c50c785cSJohn Marino   jit_read_descriptor (gdbarch, &descriptor,
516*c50c785cSJohn Marino 		       get_jit_inferior_data ()->descriptor_addr);
5175796c8dcSSimon Schubert   entry_addr = descriptor.relevant_entry;
5185796c8dcSSimon Schubert 
5195796c8dcSSimon Schubert   /* Do the corresponding action.  */
5205796c8dcSSimon Schubert   switch (descriptor.action_flag)
5215796c8dcSSimon Schubert     {
5225796c8dcSSimon Schubert     case JIT_NOACTION:
5235796c8dcSSimon Schubert       break;
5245796c8dcSSimon Schubert     case JIT_REGISTER:
5255796c8dcSSimon Schubert       jit_read_code_entry (gdbarch, entry_addr, &code_entry);
5265796c8dcSSimon Schubert       jit_register_code (gdbarch, entry_addr, &code_entry);
5275796c8dcSSimon Schubert       break;
5285796c8dcSSimon Schubert     case JIT_UNREGISTER:
5295796c8dcSSimon Schubert       objf = jit_find_objf_with_entry_addr (entry_addr);
5305796c8dcSSimon Schubert       if (objf == NULL)
531*c50c785cSJohn Marino 	printf_unfiltered (_("Unable to find JITed code "
532*c50c785cSJohn Marino 			     "entry at address: %s\n"),
5335796c8dcSSimon Schubert 			   paddress (gdbarch, entry_addr));
5345796c8dcSSimon Schubert       else
5355796c8dcSSimon Schubert         jit_unregister_code (objf);
5365796c8dcSSimon Schubert 
5375796c8dcSSimon Schubert       break;
5385796c8dcSSimon Schubert     default:
5395796c8dcSSimon Schubert       error (_("Unknown action_flag value in JIT descriptor!"));
5405796c8dcSSimon Schubert       break;
5415796c8dcSSimon Schubert     }
5425796c8dcSSimon Schubert }
5435796c8dcSSimon Schubert 
5445796c8dcSSimon Schubert /* Provide a prototype to silence -Wmissing-prototypes.  */
5455796c8dcSSimon Schubert 
5465796c8dcSSimon Schubert extern void _initialize_jit (void);
5475796c8dcSSimon Schubert 
5485796c8dcSSimon Schubert void
5495796c8dcSSimon Schubert _initialize_jit (void)
5505796c8dcSSimon Schubert {
551*c50c785cSJohn Marino   add_setshow_zinteger_cmd ("jit", class_maintenance, &jit_debug,
552*c50c785cSJohn Marino 			    _("Set JIT debugging."),
553*c50c785cSJohn Marino 			    _("Show JIT debugging."),
554*c50c785cSJohn Marino 			    _("When non-zero, JIT debugging is enabled."),
555*c50c785cSJohn Marino 			    NULL,
556*c50c785cSJohn Marino 			    show_jit_debug,
557*c50c785cSJohn Marino 			    &setdebuglist, &showdebuglist);
558*c50c785cSJohn Marino 
5595796c8dcSSimon Schubert   observer_attach_inferior_created (jit_inferior_created_observer);
5605796c8dcSSimon Schubert   observer_attach_inferior_exit (jit_inferior_exit_hook);
561*c50c785cSJohn Marino   observer_attach_executable_changed (jit_executable_changed_observer);
5625796c8dcSSimon Schubert   jit_objfile_data = register_objfile_data ();
563*c50c785cSJohn Marino   jit_inferior_data =
564*c50c785cSJohn Marino     register_inferior_data_with_cleanup (jit_inferior_data_cleanup);
5655796c8dcSSimon Schubert }
566