char * find_separate_debug_file_by_buildid (struct objfile *objfile) { const struct elf_build_id *build_id; build_id = build_id_bfd_get (objfile->obfd); if (build_id != NULL) { bfd *abfd; abfd = build_id_to_debug_bfd (build_id->size, build_id->data); /* Prevent looping on a stripped .debug file. */ if (abfd != NULL && filename_cmp (bfd_get_filename (abfd), objfile_name (objfile)) == 0) { warning (_("\"%s\": separate debug info file has no debug info"), bfd_get_filename (abfd)); gdb_bfd_unref (abfd); } else if (abfd != NULL) { char *result = xstrdup (bfd_get_filename (abfd)); gdb_bfd_unref (abfd); return result; } } return NULL; }
bfd * find_separate_debug_file_in_section (struct objfile *objfile) { asection *section; bfd *abfd; if (objfile->obfd == NULL) return NULL; section = bfd_get_section_by_name (objfile->obfd, ".gnu_debugdata"); if (section == NULL) return NULL; #ifdef HAVE_LIBLZMA abfd = gdb_bfd_openr_iovec (objfile_name (objfile), gnutarget, lzma_open, section, lzma_pread, lzma_close, lzma_stat); if (abfd == NULL) return NULL; if (!bfd_check_format (abfd, bfd_object)) { warning (_("Cannot parse .gnu_debugdata section; not a BFD object")); gdb_bfd_unref (abfd); return NULL; } #else warning (_("Cannot parse .gnu_debugdata section; LZMA support was " "disabled at compile time")); abfd = NULL; #endif /* !HAVE_LIBLZMA */ return abfd; }
static bfd * darwin_bfd_open (char *pathname) { char *found_pathname; int found_file; bfd *abfd; bfd *res; /* Search for shared library file. */ found_pathname = solib_find (pathname, &found_file); if (found_pathname == NULL) perror_with_name (pathname); /* Open bfd for shared library. */ abfd = solib_bfd_fopen (found_pathname, found_file); res = gdb_bfd_mach_o_fat_extract (abfd, bfd_object, gdbarch_bfd_arch_info (target_gdbarch ())); if (!res) { make_cleanup_bfd_unref (abfd); error (_("`%s': not a shared-library: %s"), bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); } /* The current filename for fat-binary BFDs is a name generated by BFD, usually a string containing the name of the architecture. Reset its value to the actual filename. */ xfree (bfd_get_filename (res)); res->filename = xstrdup (pathname); gdb_bfd_unref (abfd); return res; }
static void core_close (struct target_ops *self) { if (core_bfd) { int pid = ptid_get_pid (inferior_ptid); inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */ if (pid != 0) exit_inferior_silent (pid); /* Clear out solib state while the bfd is still open. See comments in clear_solib in solib.c. */ clear_solib (); if (core_data) { xfree (core_data->sections); xfree (core_data); core_data = NULL; } gdb_bfd_unref (core_bfd); core_bfd = NULL; } core_vec = NULL; core_gdbarch = NULL; }
static void do_bfd_delete_cleanup (void *arg) { bfd *obfd = arg; const char *filename = obfd->filename; gdb_bfd_unref (arg); unlink (filename); }
static void target_bfd_xclose (struct target_ops *t) { struct target_bfd_data *data = t->to_data; gdb_bfd_unref (data->bfd); xfree (data->table.sections); xfree (data); xfree (t); }
static void exec_close_1 (int quitting) { struct vmap *vp, *nxt; using_exec_ops = 0; for (nxt = vmap; nxt != NULL;) { vp = nxt; nxt = vp->nxt; if (vp->objfile) free_objfile (vp->objfile); gdb_bfd_unref (vp->bfd); xfree (vp); } vmap = NULL; { struct program_space *ss; struct cleanup *old_chain; old_chain = save_current_program_space (); ALL_PSPACES (ss) { set_current_program_space (ss); /* Delete all target sections. */ resize_section_table (current_target_sections, -resize_section_table (current_target_sections, 0)); exec_close (); } do_cleanups (old_chain); } }
void exec_close (void) { if (exec_bfd) { bfd *abfd = exec_bfd; gdb_bfd_unref (abfd); /* Removing target sections may close the exec_ops target. Clear exec_bfd before doing so to prevent recursion. */ exec_bfd = NULL; exec_bfd_mtime = 0; remove_target_sections (&exec_bfd); xfree (exec_filename); exec_filename = NULL; } }
static void gcore_command (char *args, int from_tty) { struct cleanup *filename_chain; struct cleanup *bfd_chain; char *corefilename; bfd *obfd; /* No use generating a corefile without a target process. */ if (!target_has_execution) noprocess (); if (args && *args) corefilename = tilde_expand (args); else { /* Default corefile name is "core.PID". */ corefilename = xstrprintf ("core.%d", ptid_get_pid (inferior_ptid)); } filename_chain = make_cleanup (xfree, corefilename); if (info_verbose) fprintf_filtered (gdb_stdout, "Opening corefile '%s' for output.\n", corefilename); /* Open the output file. */ obfd = create_gcore_bfd (corefilename); /* Need a cleanup that will close and delete the file. */ bfd_chain = make_cleanup (do_bfd_delete_cleanup, obfd); /* Call worker function. */ write_gcore_file (obfd); /* Succeeded. */ discard_cleanups (bfd_chain); gdb_bfd_unref (obfd); fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); do_cleanups (filename_chain); }
static void gcore_command (char *args, int from_tty) { struct cleanup *old_chain; char *corefilename, corefilename_buffer[40]; bfd *obfd; /* No use generating a corefile without a target process. */ if (!target_has_execution) noprocess (); if (args && *args) corefilename = args; else { /* Default corefile name is "core.PID". */ xsnprintf (corefilename_buffer, sizeof (corefilename_buffer), "core.%d", PIDGET (inferior_ptid)); corefilename = corefilename_buffer; } if (info_verbose) fprintf_filtered (gdb_stdout, "Opening corefile '%s' for output.\n", corefilename); /* Open the output file. */ obfd = create_gcore_bfd (corefilename); /* Need a cleanup that will close and delete the file. */ old_chain = make_cleanup (do_bfd_delete_cleanup, obfd); /* Call worker function. */ write_gcore_file (obfd); /* Succeeded. */ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); discard_cleanups (old_chain); gdb_bfd_unref (obfd); }
static bfd * spu_bfd_fopen (char *name, CORE_ADDR addr) { bfd *nbfd; CORE_ADDR *open_closure = XNEW (CORE_ADDR); *open_closure = addr; nbfd = gdb_bfd_openr_iovec (name, "elf32-spu", spu_bfd_iovec_open, open_closure, spu_bfd_iovec_pread, spu_bfd_iovec_close, spu_bfd_iovec_stat); if (!nbfd) return NULL; if (!bfd_check_format (nbfd, bfd_object)) { gdb_bfd_unref (nbfd); return NULL; } return nbfd; }
bfd * build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { char *link, *debugdir; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; bfd *abfd = NULL; /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 + 2 * build_id_len + (sizeof ".debug" - 1) + 1); /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/.build-id/..." lookups. */ debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory); back_to = make_cleanup_free_char_ptr_vec (debugdir_vec); for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix) { size_t debugdir_len = strlen (debugdir); const gdb_byte *data = build_id; size_t size = build_id_len; char *s; char *filename = NULL; memcpy (link, debugdir, debugdir_len); s = &link[debugdir_len]; s += sprintf (s, "/.build-id/"); if (size > 0) { size--; s += sprintf (s, "%02x", (unsigned) *data++); } if (size > 0) *s++ = '/'; while (size-- > 0) s += sprintf (s, "%02x", (unsigned) *data++); strcpy (s, ".debug"); /* lrealpath() is expensive even for the usually non-existent files. */ if (access (link, F_OK) == 0) filename = lrealpath (link); if (filename == NULL) continue; /* We expect to be silent on the non-existing files. */ abfd = gdb_bfd_open_maybe_remote (filename); if (abfd == NULL) continue; if (build_id_verify (abfd, build_id_len, build_id)) break; gdb_bfd_unref (abfd); abfd = NULL; } do_cleanups (back_to); return abfd; }
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; 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; /* 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 (); gdb_bfd_unref (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 (); gdb_bfd_unref (tmp_bfd); return 0; } addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); /* We're done with the temporary bfd. */ gdb_bfd_unref (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 struct vmap * add_vmap (LdInfo *ldi) { bfd *abfd, *last; char *mem, *filename; struct objfile *obj; struct vmap *vp; int fd; ARCH64_DECL (arch64); /* This ldi structure was allocated using alloca() in xcoff_relocate_symtab(). Now we need to have persistent object and member names, so we should save them. */ filename = LDI_FILENAME (ldi, arch64); mem = filename + strlen (filename) + 1; mem = xstrdup (mem); fd = LDI_FD (ldi, arch64); abfd = gdb_bfd_open (filename, gnutarget, fd < 0 ? -1 : fd); if (!abfd) { warning (_("Could not open `%s' as an executable file: %s"), filename, bfd_errmsg (bfd_get_error ())); return NULL; } /* Make sure we have an object file. */ if (bfd_check_format (abfd, bfd_object)) vp = map_vmap (abfd, 0); else if (bfd_check_format (abfd, bfd_archive)) { last = gdb_bfd_openr_next_archived_file (abfd, NULL); while (last != NULL) { bfd *next; if (strcmp (mem, last->filename) == 0) break; next = gdb_bfd_openr_next_archived_file (abfd, last); gdb_bfd_unref (last); last = next; } if (!last) { warning (_("\"%s\": member \"%s\" missing."), filename, mem); gdb_bfd_unref (abfd); return NULL; } if (!bfd_check_format (last, bfd_object)) { warning (_("\"%s\": member \"%s\" not in executable format: %s."), filename, mem, bfd_errmsg (bfd_get_error ())); gdb_bfd_unref (last); gdb_bfd_unref (abfd); return NULL; } vp = map_vmap (last, abfd); /* map_vmap acquired a reference to LAST, so we can release ours. */ gdb_bfd_unref (last); } else { warning (_("\"%s\": not in executable format: %s."), filename, bfd_errmsg (bfd_get_error ())); gdb_bfd_unref (abfd); return NULL; } obj = allocate_objfile (vp->bfd, 0); vp->objfile = obj; /* Always add symbols for the main objfile. */ if (vp == vmap || auto_solib_add) vmap_add_symbols (vp); /* Anything needing a reference to ABFD has already acquired it, so release our local reference. */ gdb_bfd_unref (abfd); return vp; }