/** * Initialize the bfd context. * * @return TRUE if OK. */ static bool bfd_util_open(bfd_ctx_t *bc, const char *path) { static mutex_t bfd_library_mtx = MUTEX_INIT; bfd *b; void *symbols = NULL; unsigned size = 0; long count; int fd = -1; const char *libpath = path; /* * On Debian systems, there is a debugging version of libraries held * under /usr/lib/debug. We'll get better symbol resolution by * opening these instead of the usually stripped runtime versions * that will only contain externally visible symbols. */ if (!is_running_on_mingw() && is_absolute_path(path)) { static char debugpath[MAX_PATH_LEN]; const char *base = filepath_basename(path); concat_strings(debugpath, sizeof debugpath, "/usr/lib/debug/", base, NULL_PTR); fd = open(debugpath, O_RDONLY); if (-1 == fd) { concat_strings(debugpath, sizeof debugpath, "/usr/lib/debug", path, NULL_PTR); fd = open(debugpath, O_RDONLY); } if (-1 != fd) libpath = debugpath; } if (-1 == fd) fd = open(libpath, O_RDONLY); if (-1 == fd) { s_miniwarn("%s: can't open %s: %m", G_STRFUNC, libpath); return FALSE; } /* * Protect calls to BFD opening: they don't appear to be fully * thread-safe and we could enter here concurrently. */ mutex_lock_fast(&bfd_library_mtx); b = bfd_fdopenr(libpath, NULL, fd); if (NULL == b) { mutex_unlock_fast(&bfd_library_mtx); close(fd); return FALSE; } if (!bfd_util_check_format(b, bfd_object, libpath)) { s_miniwarn("%s: %s is not an object", G_STRFUNC, libpath); goto failed; } if (0 == (bfd_get_file_flags(b) & HAS_SYMS)) { s_miniwarn("%s: %s has no symbols", G_STRFUNC, libpath); goto failed; } count = bfd_read_minisymbols(b, FALSE, &symbols, &size); if (count <= 0) { bc->dynamic = TRUE; count = bfd_read_minisymbols(b, TRUE, &symbols, &size); } if (count >= 0) goto done; s_miniwarn("%s: unable to load symbols from %s ", G_STRFUNC, libpath); symbols = NULL; /* FALL THROUGH */ /* * We keep the context on errors to avoid logging them over and over * each time we attempt to access the same file. The BFD and system * resources are released though. */ failed: bfd_close(b); b = NULL; count = 0; /* FALL THROUGH */ done: mutex_unlock_fast(&bfd_library_mtx); bc->magic = BFD_CTX_MAGIC; bc->handle = b; bc->symbols = symbols; /* Allocated by the bfd library */ bc->count = count; bc->symsize = size; mutex_init(&bc->lock); return TRUE; }
bfd * prg_input_open (const char * filename, void * file) { bfd * b = bfd_fdopenr (filename, "ihex", fileno(file)); return b; }
static struct vmap * add_vmap (LdInfo *ldi) { bfd *abfd, *last; char *mem, *objname, *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); objname = xstrdup (filename); fd = LDI_FD (ldi, arch64); if (fd < 0) /* Note that this opens it once for every member; a possible enhancement would be to only open it once for every object. */ abfd = bfd_openr (objname, gnutarget); else abfd = bfd_fdopenr (objname, gnutarget, fd); if (!abfd) { warning (_("Could not open `%s' as an executable file: %s"), objname, 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 = 0; /* FIXME??? am I tossing BFDs? bfd? */ while ((last = bfd_openr_next_archived_file (abfd, last))) if (strcmp (mem, last->filename) == 0) break; if (!last) { warning (_("\"%s\": member \"%s\" missing."), objname, mem); bfd_close (abfd); return NULL; } if (!bfd_check_format (last, bfd_object)) { warning (_("\"%s\": member \"%s\" not in executable format: %s."), objname, mem, bfd_errmsg (bfd_get_error ())); bfd_close (last); bfd_close (abfd); return NULL; } vp = map_vmap (last, abfd); } else { warning (_("\"%s\": not in executable format: %s."), objname, bfd_errmsg (bfd_get_error ())); bfd_close (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); return vp; }
void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ unpush_target (&exec_ops); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered ("No executable file now.\n"); } else { char *scratch_pathname; int scratch_chan; scratch_chan = openp (getenv ("PATH"), 1, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), 1, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); if (!exec_bfd) error ("\"%s\": could not open as an executable file: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); /* At this point, scratch_pathname and exec_bfd->name both point to the same malloc'd string. However exec_close() will attempt to free it via the exec_bfd->name pointer, so we need to make another copy and leave exec_bfd as the new owner of the original copy. */ scratch_pathname = xstrdup (scratch_pathname); make_cleanup (xfree, scratch_pathname); if (!bfd_check_format (exec_bfd, bfd_object)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error ("\"%s\": not in executable format: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* FIXME - This should only be run for RS6000, but the ifdef is a poor way to accomplish. */ #ifdef DEPRECATED_IBM6000_TARGET /* Setup initial vmap. */ map_vmap (exec_bfd, 0); if (vmap == NULL) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error ("\"%s\": can't find the file sections: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); } #endif /* DEPRECATED_IBM6000_TARGET */ if (build_section_table (exec_bfd, &exec_ops.to_sections, &exec_ops.to_sections_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (0); error ("\"%s\": can't find the file sections: %s", scratch_pathname, bfd_errmsg (bfd_get_error ())); } #ifdef DEPRECATED_HPUX_TEXT_END DEPRECATED_HPUX_TEXT_END (&exec_ops); #endif validate_files (); set_gdbarch_from_file (exec_bfd); push_target (&exec_ops); /* Tell display code (if any) about the changed file name. */ if (exec_file_display_hook) (*exec_file_display_hook) (filename); } }