OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [jit.c] - Blame information for rev 846

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Handle JIT code generation in the inferior for GDB, the GNU Debugger.
2
 
3
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
 
22
#include "jit.h"
23
#include "breakpoint.h"
24
#include "gdbcore.h"
25
#include "observer.h"
26
#include "objfiles.h"
27
#include "symfile.h"
28
#include "symtab.h"
29
#include "target.h"
30
#include "gdb_stat.h"
31
 
32
static const struct objfile_data *jit_objfile_data;
33
 
34
static const char *const jit_break_name = "__jit_debug_register_code";
35
 
36
static const char *const jit_descriptor_name = "__jit_debug_descriptor";
37
 
38
/* This is the address of the JIT descriptor in the inferior.  */
39
 
40
static CORE_ADDR jit_descriptor_addr = 0;
41
 
42
/* This is a boolean indicating whether we're currently registering code.  This
43
   is used to avoid re-entering the registration code.  We want to check for
44
   new JITed every time a new object file is loaded, but we want to avoid
45
   checking for new code while we're registering object files for JITed code.
46
   Therefore, we flip this variable to 1 before registering new object files,
47
   and set it to 0 before returning.  */
48
 
49
static int registering_code = 0;
50
 
51
/* Helper cleanup function to clear an integer flag like the one above.  */
52
 
53
static void
54
clear_int (void *int_addr)
55
{
56
  *((int *) int_addr) = 0;
57
}
58
 
59
struct target_buffer
60
{
61
  CORE_ADDR base;
62
  size_t size;
63
};
64
 
65
/* Openning the file is a no-op.  */
66
 
67
static void *
68
mem_bfd_iovec_open (struct bfd *abfd, void *open_closure)
69
{
70
  return open_closure;
71
}
72
 
73
/* Closing the file is just freeing the base/size pair on our side.  */
74
 
75
static int
76
mem_bfd_iovec_close (struct bfd *abfd, void *stream)
77
{
78
  xfree (stream);
79
  return 1;
80
}
81
 
82
/* For reading the file, we just need to pass through to target_read_memory and
83
   fix up the arguments and return values.  */
84
 
85
static file_ptr
86
mem_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
87
                     file_ptr nbytes, file_ptr offset)
88
{
89
  int err;
90
  struct target_buffer *buffer = (struct target_buffer *) stream;
91
 
92
  /* If this read will read all of the file, limit it to just the rest.  */
93
  if (offset + nbytes > buffer->size)
94
    nbytes = buffer->size - offset;
95
 
96
  /* If there are no more bytes left, we've reached EOF.  */
97
  if (nbytes == 0)
98
    return 0;
99
 
100
  err = target_read_memory (buffer->base + offset, (gdb_byte *) buf, nbytes);
101
  if (err)
102
    return -1;
103
 
104
  return nbytes;
105
}
106
 
107
/* For statting the file, we only support the st_size attribute.  */
108
 
109
static int
110
mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
111
{
112
  struct target_buffer *buffer = (struct target_buffer*) stream;
113
 
114
  sb->st_size = buffer->size;
115
  return 0;
116
}
117
 
118
/* Open a BFD from the target's memory.  */
119
 
120
static struct bfd *
121
bfd_open_from_target_memory (CORE_ADDR addr, size_t size, char *target)
122
{
123
  const char *filename = xstrdup ("<in-memory>");
124
  struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
125
 
126
  buffer->base = addr;
127
  buffer->size = size;
128
  return bfd_openr_iovec (filename, target,
129
                          mem_bfd_iovec_open,
130
                          buffer,
131
                          mem_bfd_iovec_pread,
132
                          mem_bfd_iovec_close,
133
                          mem_bfd_iovec_stat);
134
}
135
 
136
/* Helper function for reading the global JIT descriptor from remote memory.  */
137
 
138
static void
139
jit_read_descriptor (struct gdbarch *gdbarch,
140
                     struct jit_descriptor *descriptor)
141
{
142
  int err;
143
  struct type *ptr_type;
144
  int ptr_size;
145
  int desc_size;
146
  gdb_byte *desc_buf;
147
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
148
 
149
  /* Figure out how big the descriptor is on the remote and how to read it.  */
150
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
151
  ptr_size = TYPE_LENGTH (ptr_type);
152
  desc_size = 8 + 2 * ptr_size;  /* Two 32-bit ints and two pointers.  */
153
  desc_buf = alloca (desc_size);
154
 
155
  /* Read the descriptor.  */
156
  err = target_read_memory (jit_descriptor_addr, desc_buf, desc_size);
157
  if (err)
158
    error (_("Unable to read JIT descriptor from remote memory!"));
159
 
160
  /* Fix the endianness to match the host.  */
161
  descriptor->version = extract_unsigned_integer (&desc_buf[0], 4, byte_order);
162
  descriptor->action_flag =
163
      extract_unsigned_integer (&desc_buf[4], 4, byte_order);
164
  descriptor->relevant_entry = extract_typed_address (&desc_buf[8], ptr_type);
165
  descriptor->first_entry =
166
      extract_typed_address (&desc_buf[8 + ptr_size], ptr_type);
167
}
168
 
169
/* Helper function for reading a JITed code entry from remote memory.  */
170
 
171
static void
172
jit_read_code_entry (struct gdbarch *gdbarch,
173
                     CORE_ADDR code_addr, struct jit_code_entry *code_entry)
174
{
175
  int err;
176
  struct type *ptr_type;
177
  int ptr_size;
178
  int entry_size;
179
  gdb_byte *entry_buf;
180
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
181
 
182
  /* Figure out how big the entry is on the remote and how to read it.  */
183
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
184
  ptr_size = TYPE_LENGTH (ptr_type);
185
  entry_size = 3 * ptr_size + 8;  /* Three pointers and one 64-bit int.  */
186
  entry_buf = alloca (entry_size);
187
 
188
  /* Read the entry.  */
189
  err = target_read_memory (code_addr, entry_buf, entry_size);
190
  if (err)
191
    error (_("Unable to read JIT code entry from remote memory!"));
192
 
193
  /* Fix the endianness to match the host.  */
194
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
195
  code_entry->next_entry = extract_typed_address (&entry_buf[0], ptr_type);
196
  code_entry->prev_entry =
197
      extract_typed_address (&entry_buf[ptr_size], ptr_type);
198
  code_entry->symfile_addr =
199
      extract_typed_address (&entry_buf[2 * ptr_size], ptr_type);
200
  code_entry->symfile_size =
201
      extract_unsigned_integer (&entry_buf[3 * ptr_size], 8, byte_order);
202
}
203
 
204
/* This function registers code associated with a JIT code entry.  It uses the
205
   pointer and size pair in the entry to read the symbol file from the remote
206
   and then calls symbol_file_add_from_local_memory to add it as though it were
207
   a symbol file added by the user.  */
208
 
209
static void
210
jit_register_code (struct gdbarch *gdbarch,
211
                   CORE_ADDR entry_addr, struct jit_code_entry *code_entry)
212
{
213
  bfd *nbfd;
214
  struct section_addr_info *sai;
215
  struct bfd_section *sec;
216
  struct objfile *objfile;
217
  struct cleanup *old_cleanups, *my_cleanups;
218
  int i;
219
  const struct bfd_arch_info *b;
220
  CORE_ADDR *entry_addr_ptr;
221
 
222
  nbfd = bfd_open_from_target_memory (code_entry->symfile_addr,
223
                                      code_entry->symfile_size, gnutarget);
224
  old_cleanups = make_cleanup_bfd_close (nbfd);
225
 
226
  /* Check the format.  NOTE: This initializes important data that GDB uses!
227
     We would segfault later without this line.  */
228
  if (!bfd_check_format (nbfd, bfd_object))
229
    {
230
      printf_unfiltered (_("\
231
JITed symbol file is not an object file, ignoring it.\n"));
232
      do_cleanups (old_cleanups);
233
      return;
234
    }
235
 
236
  /* Check bfd arch.  */
237
  b = gdbarch_bfd_arch_info (gdbarch);
238
  if (b->compatible (b, bfd_get_arch_info (nbfd)) != b)
239
    warning (_("JITed object file architecture %s is not compatible "
240
               "with target architecture %s."), bfd_get_arch_info
241
             (nbfd)->printable_name, b->printable_name);
242
 
243
  /* Read the section address information out of the symbol file.  Since the
244
     file is generated by the JIT at runtime, it should all of the absolute
245
     addresses that we care about.  */
246
  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
247
  make_cleanup_free_section_addr_info (sai);
248
  i = 0;
249
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
250
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
251
      {
252
        /* We assume that these virtual addresses are absolute, and do not
253
           treat them as offsets.  */
254
        sai->other[i].addr = bfd_get_section_vma (nbfd, sec);
255
        sai->other[i].name = xstrdup (bfd_get_section_name (nbfd, sec));
256
        sai->other[i].sectindex = sec->index;
257
        ++i;
258
      }
259
 
260
  /* Raise this flag while we register code so we won't trigger any
261
     re-registration.  */
262
  registering_code = 1;
263
  my_cleanups = make_cleanup (clear_int, &registering_code);
264
 
265
  /* This call takes ownership of sai.  */
266
  objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED);
267
 
268
  /* Clear the registering_code flag.  */
269
  do_cleanups (my_cleanups);
270
 
271
  /* Remember a mapping from entry_addr to objfile.  */
272
  entry_addr_ptr = xmalloc (sizeof (CORE_ADDR));
273
  *entry_addr_ptr = entry_addr;
274
  set_objfile_data (objfile, jit_objfile_data, entry_addr_ptr);
275
 
276
  discard_cleanups (old_cleanups);
277
}
278
 
279
/* This function unregisters JITed code and frees the corresponding objfile.  */
280
 
281
static void
282
jit_unregister_code (struct objfile *objfile)
283
{
284
  free_objfile (objfile);
285
}
286
 
287
/* Look up the objfile with this code entry address.  */
288
 
289
static struct objfile *
290
jit_find_objf_with_entry_addr (CORE_ADDR entry_addr)
291
{
292
  struct objfile *objf;
293
  CORE_ADDR *objf_entry_addr;
294
 
295
  ALL_OBJFILES (objf)
296
    {
297
      objf_entry_addr = (CORE_ADDR *) objfile_data (objf, jit_objfile_data);
298
      if (objf_entry_addr != NULL && *objf_entry_addr == entry_addr)
299
        return objf;
300
    }
301
  return NULL;
302
}
303
 
304
/* (Re-)Initialize the jit breakpoint handler, and register any already
305
   created translations.  */
306
 
307
static void
308
jit_inferior_init (struct gdbarch *gdbarch)
309
{
310
  struct minimal_symbol *reg_symbol;
311
  struct minimal_symbol *desc_symbol;
312
  CORE_ADDR reg_addr;
313
  struct jit_descriptor descriptor;
314
  struct jit_code_entry cur_entry;
315
  CORE_ADDR cur_entry_addr;
316
 
317
  /* When we register code, GDB resets its breakpoints in case symbols have
318
     changed.  That in turn calls this handler, which makes us look for new
319
     code again.  To avoid being re-entered, we check this flag.  */
320
  if (registering_code)
321
    return;
322
 
323
  /* Lookup the registration symbol.  If it is missing, then we assume we are
324
     not attached to a JIT.  */
325
  reg_symbol = lookup_minimal_symbol (jit_break_name, NULL, NULL);
326
  if (reg_symbol == NULL)
327
    return;
328
  reg_addr = SYMBOL_VALUE_ADDRESS (reg_symbol);
329
  if (reg_addr == 0)
330
    return;
331
 
332
  /* Lookup the descriptor symbol and cache the addr.  If it is missing, we
333
     assume we are not attached to a JIT and return early.  */
334
  desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL, NULL);
335
  if (desc_symbol == NULL)
336
    return;
337
  jit_descriptor_addr = SYMBOL_VALUE_ADDRESS (desc_symbol);
338
  if (jit_descriptor_addr == 0)
339
    return;
340
 
341
  /* Read the descriptor so we can check the version number and load any already
342
     JITed functions.  */
343
  jit_read_descriptor (gdbarch, &descriptor);
344
 
345
  /* Check that the version number agrees with that we support.  */
346
  if (descriptor.version != 1)
347
    error (_("Unsupported JIT protocol version in descriptor!"));
348
 
349
  /* Put a breakpoint in the registration symbol.  */
350
  create_jit_event_breakpoint (gdbarch, reg_addr);
351
 
352
  /* If we've attached to a running program, we need to check the descriptor to
353
     register any functions that were already generated.  */
354
  for (cur_entry_addr = descriptor.first_entry;
355
       cur_entry_addr != 0;
356
       cur_entry_addr = cur_entry.next_entry)
357
    {
358
      jit_read_code_entry (gdbarch, cur_entry_addr, &cur_entry);
359
 
360
      /* This hook may be called many times during setup, so make sure we don't
361
         add the same symbol file twice.  */
362
      if (jit_find_objf_with_entry_addr (cur_entry_addr) != NULL)
363
        continue;
364
 
365
      jit_register_code (gdbarch, cur_entry_addr, &cur_entry);
366
    }
367
}
368
 
369
/* Exported routine to call when an inferior has been created.  */
370
 
371
void
372
jit_inferior_created_hook (void)
373
{
374
  jit_inferior_init (target_gdbarch);
375
}
376
 
377
/* Exported routine to call to re-set the jit breakpoints,
378
   e.g. when a program is rerun.  */
379
 
380
void
381
jit_breakpoint_re_set (void)
382
{
383
  jit_inferior_init (target_gdbarch);
384
}
385
 
386
/* Wrapper to match the observer function pointer prototype.  */
387
 
388
static void
389
jit_inferior_created_observer (struct target_ops *objfile, int from_tty)
390
{
391
  jit_inferior_init (target_gdbarch);
392
}
393
 
394
/* This function cleans up any code entries left over when the inferior exits.
395
   We get left over code when the inferior exits without unregistering its code,
396
   for example when it crashes.  */
397
 
398
static void
399
jit_inferior_exit_hook (struct inferior *inf)
400
{
401
  struct objfile *objf;
402
  struct objfile *temp;
403
 
404
  /* We need to reset the descriptor addr so that next time we load up the
405
     inferior we look for it again.  */
406
  jit_descriptor_addr = 0;
407
 
408
  ALL_OBJFILES_SAFE (objf, temp)
409
    if (objfile_data (objf, jit_objfile_data) != NULL)
410
      jit_unregister_code (objf);
411
}
412
 
413
void
414
jit_event_handler (struct gdbarch *gdbarch)
415
{
416
  struct jit_descriptor descriptor;
417
  struct jit_code_entry code_entry;
418
  CORE_ADDR entry_addr;
419
  struct objfile *objf;
420
 
421
  /* Read the descriptor from remote memory.  */
422
  jit_read_descriptor (gdbarch, &descriptor);
423
  entry_addr = descriptor.relevant_entry;
424
 
425
  /* Do the corresponding action. */
426
  switch (descriptor.action_flag)
427
    {
428
    case JIT_NOACTION:
429
      break;
430
    case JIT_REGISTER:
431
      jit_read_code_entry (gdbarch, entry_addr, &code_entry);
432
      jit_register_code (gdbarch, entry_addr, &code_entry);
433
      break;
434
    case JIT_UNREGISTER:
435
      objf = jit_find_objf_with_entry_addr (entry_addr);
436
      if (objf == NULL)
437
        printf_unfiltered (_("Unable to find JITed code entry at address: %s\n"),
438
                           paddress (gdbarch, entry_addr));
439
      else
440
        jit_unregister_code (objf);
441
 
442
      break;
443
    default:
444
      error (_("Unknown action_flag value in JIT descriptor!"));
445
      break;
446
    }
447
}
448
 
449
/* Provide a prototype to silence -Wmissing-prototypes.  */
450
 
451
extern void _initialize_jit (void);
452
 
453
void
454
_initialize_jit (void)
455
{
456
  observer_attach_inferior_created (jit_inferior_created_observer);
457
  observer_attach_inferior_exit (jit_inferior_exit_hook);
458
  jit_objfile_data = register_objfile_data ();
459
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.