diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2010-06-25 17:39:56 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2010-06-25 17:39:56 +0000 |
commit | f1d8ee66261af43a65975bac1f4528e9ee68c658 (patch) | |
tree | 9667da78637a002f3e4c0611b131259f59864d14 /gdb/solib-spu.c | |
parent | 19c0c0f82272cdff5e1f8306382ba6ceb95ff1a0 (diff) | |
download | gdb-f1d8ee66261af43a65975bac1f4528e9ee68c658.zip gdb-f1d8ee66261af43a65975bac1f4528e9ee68c658.tar.gz gdb-f1d8ee66261af43a65975bac1f4528e9ee68c658.tar.bz2 |
2010-06-25 Ken Werner <ken.werner@de.ibm.com>
* solib-spu.c: Include "exception.h".
(ocl_program_data_key): New variable.
(append_ocl_sos): New function.
(ocl_enable_break): Likewise.
(spu_current_sos): Call append_ocl_sos.
(spu_solib_loaded): Call ocl_enable_break.
(_initialize_spu_solib): Register ocl_program_data_key.
Diffstat (limited to 'gdb/solib-spu.c')
-rw-r--r-- | gdb/solib-spu.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c index 177617d..f8073dc 100644 --- a/gdb/solib-spu.c +++ b/gdb/solib-spu.c @@ -34,6 +34,7 @@ #include "observer.h" #include "breakpoint.h" #include "gdbthread.h" +#include "exceptions.h" #include "spu-tdep.h" @@ -94,6 +95,61 @@ spu_skip_standalone_loader (void) } } +static const struct objfile_data *ocl_program_data_key; + +/* Appends OpenCL programs to the list of `struct so_list' objects. */ +static void +append_ocl_sos (struct so_list **link_ptr) +{ + CORE_ADDR *ocl_program_addr_base; + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + ocl_program_addr_base = objfile_data (objfile, ocl_program_data_key); + if (ocl_program_addr_base != NULL) + { + enum bfd_endian byte_order = bfd_big_endian (objfile->obfd)? + BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; + volatile struct gdb_exception ex; + TRY_CATCH (ex, RETURN_MASK_ALL) + { + CORE_ADDR data = + read_memory_unsigned_integer (*ocl_program_addr_base, + sizeof (CORE_ADDR), + byte_order); + if (data != 0x0) + { + struct so_list *new; + + /* Allocate so_list structure. */ + new = XZALLOC (struct so_list); + + /* Encode FD and object ID in path name. */ + xsnprintf (new->so_name, sizeof new->so_name, "@0x%lx <%d>", + data, SPUADDR_SPU (*ocl_program_addr_base)); + strcpy (new->so_original_name, new->so_name); + + *link_ptr = new; + link_ptr = &new->next; + } + } + if (ex.reason < 0) + { + /* Ignore memory errors. */ + switch (ex.error) + { + case MEMORY_ERROR: + break; + default: + throw_exception (ex); + break; + } + } + } + } +} + /* Build a list of `struct so_list' objects describing the shared objects currently loaded in the inferior. */ static struct so_list * @@ -170,6 +226,9 @@ spu_current_sos (void) link_ptr = &new->next; } + /* Append OpenCL sos. */ + append_ocl_sos (link_ptr); + return head; } @@ -365,6 +424,43 @@ spu_enable_break (struct objfile *objfile) return 0; } +/* Enable shared library breakpoint for the + OpenCL runtime running on the SPU. */ +static void +ocl_enable_break (struct objfile *objfile) +{ + struct minimal_symbol *event_sym = NULL; + struct minimal_symbol *addr_sym = NULL; + + /* The OpenCL runtime on the SPU will call __opencl_program_update_event + whenever an OpenCL program is loaded. */ + event_sym = lookup_minimal_symbol ("__opencl_program_update_event", NULL, + objfile); + /* The PPU address of the OpenCL program can be found + at opencl_elf_image_address. */ + addr_sym = lookup_minimal_symbol ("opencl_elf_image_address", NULL, objfile); + + if (event_sym && addr_sym) + { + /* Place a solib_event breakpoint on the symbol. */ + CORE_ADDR event_addr = SYMBOL_VALUE_ADDRESS (event_sym); + create_solib_event_breakpoint (get_objfile_arch (objfile), event_addr); + + /* Store the address of the symbol that will point to OpenCL program + using the per-objfile private data mechanism. */ + if (objfile_data (objfile, ocl_program_data_key) == NULL) + { + CORE_ADDR *ocl_program_addr_base = OBSTACK_CALLOC ( + &objfile->objfile_obstack, + objfile->sections_end - objfile->sections, + CORE_ADDR); + *ocl_program_addr_base = SYMBOL_VALUE_ADDRESS (addr_sym); + set_objfile_data (objfile, ocl_program_data_key, + ocl_program_addr_base); + } + } +} + /* Create inferior hook. */ static void spu_solib_create_inferior_hook (int from_tty) @@ -435,11 +531,19 @@ spu_solib_loaded (struct so_list *so) solib_read_symbols (so, 0); spu_enable_break (so->objfile); } + /* In case the OpenCL runtime is loaded we install a breakpoint + to get notified whenever an OpenCL program gets loaded. */ + if (strstr (so->so_name, "CLRuntimeAccelCellSPU@") != NULL) + { + solib_read_symbols (so, 0); + ocl_enable_break (so->objfile); + } } void _initialize_spu_solib (void) { observer_attach_solib_loaded (spu_solib_loaded); + ocl_program_data_key = register_objfile_data (); } |