X-Git-Url: https://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdb_bfd.c;h=3312197acd5e48dde2bef4a56b2dc3fb5b2442ee;hb=456ef1c1d43c0407801fb2d59db355472be8a554;hp=063943835d5bc7404ffa8ed56301358688d5be7e;hpb=1ce51eb52dca2fcd1ad4120876362ce2a53b3de6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 063943835d..3312197acd 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -1,6 +1,6 @@ /* Definitions for BFD wrappers used by GDB. - Copyright (C) 2011-2020 Free Software Foundation, Inc. + Copyright (C) 2011-2021 Free Software Foundation, Inc. This file is part of GDB. @@ -134,9 +134,15 @@ show_bfd_sharing (struct ui_file *file, int from_tty, fprintf_filtered (file, _("BFD sharing is %s.\n"), value); } -/* When non-zero debugging of the bfd caches is enabled. */ +/* When true debugging of the bfd caches is enabled. */ + +static bool debug_bfd_cache; + +/* Print an "bfd-cache" debug statement. */ + +#define bfd_cache_debug_printf(fmt, ...) \ + debug_prefixed_printf_cond (debug_bfd_cache, "bfd-cache", fmt, ##__VA_ARGS__) -static unsigned int debug_bfd_cache; static void show_bfd_cache_debug (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -207,6 +213,91 @@ gdb_bfd_has_target_filename (struct bfd *abfd) return is_target_filename (bfd_get_filename (abfd)); } +/* For `gdb_bfd_open_from_target_memory`. */ + +struct target_buffer +{ + CORE_ADDR base; + ULONGEST size; +}; + +/* For `gdb_bfd_open_from_target_memory`. Opening the file is a no-op. */ + +static void * +mem_bfd_iovec_open (struct bfd *abfd, void *open_closure) +{ + return open_closure; +} + +/* For `gdb_bfd_open_from_target_memory`. Closing the file is just freeing the + base/size pair on our side. */ + +static int +mem_bfd_iovec_close (struct bfd *abfd, void *stream) +{ + xfree (stream); + + /* Zero means success. */ + return 0; +} + +/* For `gdb_bfd_open_from_target_memory`. For reading the file, we just need to + pass through to target_read_memory and fix up the arguments and return + values. */ + +static file_ptr +mem_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf, + file_ptr nbytes, file_ptr offset) +{ + int err; + struct target_buffer *buffer = (struct target_buffer *) stream; + + /* If this read will read all of the file, limit it to just the rest. */ + if (offset + nbytes > buffer->size) + nbytes = buffer->size - offset; + + /* If there are no more bytes left, we've reached EOF. */ + if (nbytes == 0) + return 0; + + err = target_read_memory (buffer->base + offset, (gdb_byte *) buf, nbytes); + if (err) + return -1; + + return nbytes; +} + +/* For `gdb_bfd_open_from_target_memory`. For statting the file, we only + support the st_size attribute. */ + +static int +mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) +{ + struct target_buffer *buffer = (struct target_buffer*) stream; + + memset (sb, 0, sizeof (struct stat)); + sb->st_size = buffer->size; + return 0; +} + +/* See gdb_bfd.h. */ + +gdb_bfd_ref_ptr +gdb_bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, + const char *target, + const char *filename) +{ + struct target_buffer *buffer = XNEW (struct target_buffer); + + buffer->base = addr; + buffer->size = size; + return gdb_bfd_openr_iovec (filename ? filename : "", target, + mem_bfd_iovec_open, + buffer, + mem_bfd_iovec_pread, + mem_bfd_iovec_close, + mem_bfd_iovec_stat); +} /* Return the system error number corresponding to ERRNUM. */ @@ -216,47 +307,47 @@ fileio_errno_to_host (int errnum) switch (errnum) { case FILEIO_EPERM: - return EPERM; + return EPERM; case FILEIO_ENOENT: - return ENOENT; + return ENOENT; case FILEIO_EINTR: - return EINTR; + return EINTR; case FILEIO_EIO: - return EIO; + return EIO; case FILEIO_EBADF: - return EBADF; + return EBADF; case FILEIO_EACCES: - return EACCES; + return EACCES; case FILEIO_EFAULT: - return EFAULT; + return EFAULT; case FILEIO_EBUSY: - return EBUSY; + return EBUSY; case FILEIO_EEXIST: - return EEXIST; + return EEXIST; case FILEIO_ENODEV: - return ENODEV; + return ENODEV; case FILEIO_ENOTDIR: - return ENOTDIR; + return ENOTDIR; case FILEIO_EISDIR: - return EISDIR; + return EISDIR; case FILEIO_EINVAL: - return EINVAL; + return EINVAL; case FILEIO_ENFILE: - return ENFILE; + return ENFILE; case FILEIO_EMFILE: - return EMFILE; + return EMFILE; case FILEIO_EFBIG: - return EFBIG; + return EFBIG; case FILEIO_ENOSPC: - return ENOSPC; + return ENOSPC; case FILEIO_ESPIPE: - return ESPIPE; + return ESPIPE; case FILEIO_EROFS: - return EROFS; + return EROFS; case FILEIO_ENOSYS: - return ENOSYS; + return ENOSYS; case FILEIO_ENAMETOOLONG: - return ENAMETOOLONG; + return ENAMETOOLONG; } return -1; } @@ -317,8 +408,8 @@ gdb_bfd_iovec_fileio_pread (struct bfd *abfd, void *stream, void *buf, nbytes - pos, offset + pos, &target_errno); if (bytes == 0) - /* Success, but no bytes, means end-of-file. */ - break; + /* Success, but no bytes, means end-of-file. */ + break; if (bytes == -1) { errno = fileio_errno_to_host (target_errno); @@ -443,10 +534,7 @@ gdb_bfd_open (const char *name, const char *target, int fd, if (fstat (fd, &st) < 0) { /* Weird situation here -- don't cache if we can't stat. */ - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Could not stat %s - not caching\n", - name); + bfd_cache_debug_printf ("Could not stat %s - not caching", name); abfd = bfd_fopen (name, target, FOPEN_RB, fd); if (abfd == nullptr) return nullptr; @@ -467,11 +555,9 @@ gdb_bfd_open (const char *name, const char *target, int fd, abfd = (struct bfd *) htab_find_with_hash (gdb_bfd_cache, &search, hash); if (bfd_sharing && abfd != NULL) { - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Reusing cached bfd %s for %s\n", - host_address_to_string (abfd), - bfd_get_filename (abfd)); + bfd_cache_debug_printf ("Reusing cached bfd %s for %s", + host_address_to_string (abfd), + bfd_get_filename (abfd)); close (fd); return gdb_bfd_ref_ptr::new_reference (abfd); } @@ -480,11 +566,9 @@ gdb_bfd_open (const char *name, const char *target, int fd, if (abfd == NULL) return NULL; - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Creating new bfd %s for %s\n", - host_address_to_string (abfd), - bfd_get_filename (abfd)); + bfd_cache_debug_printf ("Creating new bfd %s for %s", + host_address_to_string (abfd), + bfd_get_filename (abfd)); if (bfd_sharing) { @@ -560,11 +644,9 @@ gdb_bfd_ref (struct bfd *abfd) gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd); - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Increase reference count on bfd %s (%s)\n", - host_address_to_string (abfd), - bfd_get_filename (abfd)); + bfd_cache_debug_printf ("Increase reference count on bfd %s (%s)", + host_address_to_string (abfd), + bfd_get_filename (abfd)); if (gdata != NULL) { @@ -595,19 +677,15 @@ gdb_bfd_unref (struct bfd *abfd) gdata->refc -= 1; if (gdata->refc > 0) { - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Decrease reference count on bfd %s (%s)\n", - host_address_to_string (abfd), - bfd_get_filename (abfd)); + bfd_cache_debug_printf ("Decrease reference count on bfd %s (%s)", + host_address_to_string (abfd), + bfd_get_filename (abfd)); return; } - if (debug_bfd_cache) - fprintf_unfiltered (gdb_stdlog, - "Delete final reference count on bfd %s (%s)\n", - host_address_to_string (abfd), - bfd_get_filename (abfd)); + bfd_cache_debug_printf ("Delete final reference count on bfd %s (%s)", + host_address_to_string (abfd), + bfd_get_filename (abfd)); archive_bfd = gdata->archive_bfd; search.filename = bfd_get_filename (abfd); @@ -1020,12 +1098,13 @@ filename, file size, file modification time, and file inode."), &maintenance_set_cmdlist, &maintenance_show_cmdlist); - add_setshow_zuinteger_cmd ("bfd-cache", class_maintenance, - &debug_bfd_cache, _("\ -Set bfd cache debugging."), _("\ -Show bfd cache debugging."), _("\ + add_setshow_boolean_cmd ("bfd-cache", class_maintenance, + &debug_bfd_cache, + _("Set bfd cache debugging."), + _("Show bfd cache debugging."), + _("\ When non-zero, bfd cache specific debugging is enabled."), - NULL, - &show_bfd_cache_debug, - &setdebuglist, &showdebuglist); + NULL, + &show_bfd_cache_debug, + &setdebuglist, &showdebuglist); }