/* Enable shared library breakpoint for the OpenCL runtime running on the SPU. */ static void ocl_enable_break (struct objfile *objfile) { struct bound_minimal_symbol event_sym; struct bound_minimal_symbol addr_sym; /* 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.minsym && addr_sym.minsym) { /* Place a solib_event breakpoint on the symbol. */ CORE_ADDR event_addr = BMSYMBOL_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 = BMSYMBOL_VALUE_ADDRESS (addr_sym); set_objfile_data (objfile, ocl_program_data_key, ocl_program_addr_base); } } }
static void darwin_solib_create_inferior_hook (int from_tty) { struct darwin_info *info = get_darwin_info (); CORE_ADDR load_addr; info->all_image_addr = 0; darwin_solib_read_all_image_info_addr (info); if (info->all_image_addr == 0) darwin_solib_get_all_image_info_addr_at_init (info); if (info->all_image_addr == 0) return; darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) { warning (_("unhandled dyld version (%d)"), info->all_image.version); return; } /* Add the breakpoint which is hit by dyld when the list of solib is modified. */ create_solib_event_breakpoint (target_gdbarch (), info->all_image.notifier); if (info->all_image.count != 0) { /* Possible relocate the main executable (PIE). */ load_addr = darwin_read_exec_load_addr_from_dyld (info); } else { /* Possible issue: Do not break on the notifier if dyld is not initialized (deduced from count == 0). In that case, dyld hasn't relocated itself and the notifier may point to a wrong address. */ load_addr = darwin_read_exec_load_addr_at_init (info); } if (load_addr != 0 && symfile_objfile != NULL) { CORE_ADDR vmaddr; /* Find the base address of the executable. */ vmaddr = bfd_mach_o_get_base_address (exec_bfd); /* Relocate. */ if (vmaddr != load_addr) objfile_rebase (symfile_objfile, load_addr - vmaddr); } }
static void darwin_solib_create_inferior_hook (int from_tty) { struct darwin_info *info = get_darwin_info (); CORE_ADDR load_addr; info->all_image_addr = 0; darwin_solib_read_all_image_info_addr (info); if (info->all_image_addr == 0) darwin_solib_get_all_image_info_addr_at_init (info); if (info->all_image_addr == 0) return; darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) { warning (_("unhandled dyld version (%d)"), info->all_image.version); return; } create_solib_event_breakpoint (target_gdbarch (), info->all_image.notifier); /* Possible relocate the main executable (PIE). */ load_addr = darwin_read_exec_load_addr (info); if (load_addr != 0 && symfile_objfile != NULL) { CORE_ADDR vmaddr; /* Find the base address of the executable. */ vmaddr = bfd_mach_o_get_base_address (exec_bfd); /* Relocate. */ if (vmaddr != load_addr) objfile_rebase (symfile_objfile, load_addr - vmaddr); } }
/* Enable shared library breakpoint. */ static int spu_enable_break (struct objfile *objfile) { struct bound_minimal_symbol spe_event_sym; /* The libspe library will call __spe_context_update_event whenever any SPE context is allocated or destroyed. */ spe_event_sym = lookup_minimal_symbol ("__spe_context_update_event", NULL, objfile); /* Place a solib_event breakpoint on the symbol. */ if (spe_event_sym.minsym) { CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (spe_event_sym); addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), addr, ¤t_target); create_solib_event_breakpoint (target_gdbarch (), addr); return 1; } return 0; }
static int enable_break (void) { int success = 0; struct minimal_symbol *msymbol; char **bkpt_namep; asection *interp_sect; /* First, remove all the solib event breakpoints. Their addresses may have changed since the last time we ran the program. */ remove_solib_event_breakpoints (); interp_text_sect_low = interp_text_sect_high = 0; interp_plt_sect_low = interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; char *buf; CORE_ADDR load_addr; bfd *tmp_bfd; CORE_ADDR sym_addr = 0; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. This address is stored on the stack. However, I've been unable to find any magic formula to find it for Solaris (appears to be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ tmp_bfd = bfd_openr (buf, gnutarget); if (tmp_bfd == NULL) goto bkpt_at_symbol; /* Make sure the dynamic linker's really a useful object. */ if (!bfd_check_format (tmp_bfd, bfd_object)) { warning (_("Unable to grok dynamic linker %s as an object file"), buf); bfd_close (tmp_bfd); goto bkpt_at_symbol; } /* We find the dynamic linker's base address by examining the current pc (which point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ load_addr = read_pc () - tmp_bfd->start_address; /* Record the relocated start and end address of the dynamic linker text and plt section for aix5_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_text_sect_high = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_plt_sect_high = interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep); if (sym_addr != 0) break; } /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); if (sym_addr != 0) { create_solib_event_breakpoint (load_addr + sym_addr); return 1; } /* For whatever reason we couldn't set a breakpoint in the dynamic linker. Warn and drop into the old code. */ bkpt_at_symbol: warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.")); } /* Nothing good happened. */ success = 0; return (success); }
static int enable_break2 (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); int success = 0; char **bkpt_namep; asection *interp_sect; struct dsbt_info *info = get_dsbt_info (); if (exec_bfd == NULL) return 0; if (!target_has_execution) return 0; if (info->enable_break2_done) return 1; info->interp_text_sect_low = 0; info->interp_text_sect_high = 0; info->interp_plt_sect_low = 0; info->interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; gdb_byte *buf; bfd *tmp_bfd = NULL; int status; CORE_ADDR addr, interp_loadmap_addr; gdb_byte addr_buf[TIC6X_PTR_SIZE]; struct int_elf32_dsbt_loadmap *ldm; volatile struct gdb_exception ex; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. */ TRY_CATCH (ex, RETURN_MASK_ALL) { tmp_bfd = solib_bfd_open (buf); } if (tmp_bfd == NULL) { enable_break_failure_warning (); return 0; } dsbt_get_initial_loadmaps (); ldm = info->interp_loadmap; /* Record the relocated start and end address of the dynamic linker text and plt section for dsbt_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { info->interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_text_sect_low += displacement_from_map (ldm, info->interp_text_sect_low); info->interp_text_sect_high = info->interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { info->interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_plt_sect_low += displacement_from_map (ldm, info->interp_plt_sect_low); info->interp_plt_sect_high = info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr"); if (addr == 0) { warning (_("Could not find symbol _dl_debug_addr in dynamic linker")); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_addr (prior to relocation) = %s\n", hex_string_custom (addr, 8)); addr += displacement_from_map (ldm, addr); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_addr (after relocation) = %s\n", hex_string_custom (addr, 8)); /* Fetch the address of the r_debug struct. */ if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) { warning (_("Unable to fetch contents of _dl_debug_addr " "(at address %s) from dynamic linker"), hex_string_custom (addr, 8)); } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_addr[0..3] = %s\n", hex_string_custom (addr, 8)); /* If it's zero, then the ldso hasn't initialized yet, and so there are no shared libs yet loaded. */ if (addr == 0) { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: ldso not yet initialized\n"); /* Do not warn, but mark to run again. */ return 0; } /* Fetch the r_brk field. It's 8 bytes from the start of _dl_debug_addr. */ if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0) { warning (_("Unable to fetch _dl_debug_addr->r_brk " "(at address %s) from dynamic linker"), hex_string_custom (addr + 8, 8)); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); /* We're also done with the loadmap. */ xfree (ldm); /* Remove all the solib event breakpoints. Their addresses may have changed since the last time we ran the program. */ remove_solib_event_breakpoints (); /* Now (finally!) create the solib breakpoint. */ create_solib_event_breakpoint (target_gdbarch, addr); info->enable_break2_done = 1; return 1; }
static int enable_break (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); asection *interp_sect; struct dsbt_info *info; if (exec_bfd == NULL) return 0; if (!target_has_execution) return 0; info = get_dsbt_info (); info->interp_text_sect_low = 0; info->interp_text_sect_high = 0; info->interp_plt_sect_low = 0; info->interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; char *buf; bfd *tmp_bfd = NULL; CORE_ADDR addr; gdb_byte addr_buf[TIC6X_PTR_SIZE]; struct int_elf32_dsbt_loadmap *ldm; volatile struct gdb_exception ex; int ret; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. */ TRY_CATCH (ex, RETURN_MASK_ALL) { tmp_bfd = solib_bfd_open (buf); } if (tmp_bfd == NULL) { enable_break_failure_warning (); return 0; } dsbt_get_initial_loadmaps (); ldm = info->interp_loadmap; /* Record the relocated start and end address of the dynamic linker text and plt section for dsbt_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { info->interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_text_sect_low += displacement_from_map (ldm, info->interp_text_sect_low); info->interp_text_sect_high = info->interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { info->interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_plt_sect_low += displacement_from_map (ldm, info->interp_plt_sect_low); info->interp_plt_sect_high = info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state"); if (addr != 0) { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state (prior to relocation) = %s\n", hex_string_custom (addr, 8)); addr += displacement_from_map (ldm, addr); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state (after relocation) = %s\n", hex_string_custom (addr, 8)); /* Now (finally!) create the solib breakpoint. */ create_solib_event_breakpoint (target_gdbarch (), addr); ret = 1; } else { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state is not found\n"); ret = 0; } /* We're done with the temporary bfd. */ gdb_bfd_unref (tmp_bfd); /* We're also done with the loadmap. */ xfree (ldm); return ret; }
static int enable_break2 (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); int success = 0; char **bkpt_namep; asection *interp_sect; if (!enable_break1_done || enable_break2_done) return 1; enable_break2_done = 1; /* First, remove all the solib event breakpoints. Their addresses may have changed since the last time we ran the program. */ remove_solib_event_breakpoints (); interp_text_sect_low = interp_text_sect_high = 0; interp_plt_sect_low = interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; gdb_byte *buf; bfd *tmp_bfd = NULL; int status; CORE_ADDR addr, interp_loadmap_addr; gdb_byte addr_buf[FRV_PTR_SIZE]; struct int_elf32_fdpic_loadmap *ldm; volatile struct gdb_exception ex; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. This address is stored on the stack. However, I've been unable to find any magic formula to find it for Solaris (appears to be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ TRY_CATCH (ex, RETURN_MASK_ALL) { tmp_bfd = solib_bfd_open (buf); } if (tmp_bfd == NULL) { enable_break_failure_warning (); return 0; } status = frv_fdpic_loadmap_addresses (target_gdbarch, &interp_loadmap_addr, 0); if (status < 0) { warning (_("Unable to determine dynamic linker loadmap address.")); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: interp_loadmap_addr = %s\n", hex_string_custom (interp_loadmap_addr, 8)); ldm = fetch_loadmap (interp_loadmap_addr); if (ldm == NULL) { warning (_("Unable to load dynamic linker loadmap at address %s."), hex_string_custom (interp_loadmap_addr, 8)); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect); interp_text_sect_low += displacement_from_map (ldm, interp_text_sect_low); interp_text_sect_high = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect); interp_plt_sect_low += displacement_from_map (ldm, interp_plt_sect_low); interp_plt_sect_high = interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr"); if (addr == 0) { warning (_("Could not find symbol _dl_debug_addr in dynamic linker")); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_addr (prior to relocation) = %s\n", hex_string_custom (addr, 8)); addr += displacement_from_map (ldm, addr); if (solib_frv_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_addr (after relocation) = %s\n", hex_string_custom (addr, 8)); /* Fetch the address of the r_debug struct. */ if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) { warning (_("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker"), hex_string_custom (addr, 8)); } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* Fetch the r_brk field. It's 8 bytes from the start of _dl_debug_addr. */ if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0) { warning (_("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker"), hex_string_custom (addr + 8, 8)); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* Now fetch the function entry point. */ if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) { warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker"), hex_string_custom (addr, 8)); enable_break_failure_warning (); bfd_close (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); /* We're also done with the loadmap. */ xfree (ldm); /* Now (finally!) create the solib breakpoint. */ create_solib_event_breakpoint (target_gdbarch, addr); return 1; }