From: Mihails Strasuns Date: Mon, 7 Dec 2020 19:54:03 +0000 (+0100) Subject: gdb: move bfd_open_from_target_memory to gdb_bfd X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=15cc148fb817bc1eb91aa16e5d94e39ebafc11ee;p=binutils-gdb.git gdb: move bfd_open_from_target_memory to gdb_bfd This function allows to create a BFD handle using an accessible memory range in a target memory. It is currently contained in a JIT module but this functionality may be of wider usefullness - for example, reading ELF binaries contained within a core dump. gdb/ChangeLog: 2020-12-07 Mihails Strasuns * jit.c (mem_bfd*, bfd_open_from_target_memory): Removed. * gdb_bfd.h (gdb_bfd_open_from_target_memory): New function. * gdb_bfd.c (mem_bfd*, gdb_bfd_open_from_target_memory): New functions. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1f98f5f46dc..93529546e3f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2020-12-07 Mihails Strasuns + + * jit.c (mem_bfd*, bfd_open_from_target_memory): Removed. + * gdb_bfd.h (gdb_bfd_open_from_target_memory): New function. + * gdb_bfd.c (mem_bfd*, gdb_bfd_open_from_target_memory): New functions. + 2020-12-09 Tom Tromey * ada-lang.c (ada_lookup_encoded_symbol): Use add_angle_brackets. diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index a61656a6ffe..0ea82c95b87 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -207,6 +207,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. */ diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index 12330970873..5c1a9548edc 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -194,6 +194,12 @@ int gdb_bfd_requires_relocations (bfd *abfd); bool gdb_bfd_get_full_section_contents (bfd *abfd, asection *section, gdb::byte_vector *contents); +/* Create and initialize a BFD handle from a target in-memory range. */ + +gdb_bfd_ref_ptr gdb_bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, + const char *target, + const char *filename = nullptr); + /* Range adapter for a BFD's sections. To be used as: diff --git a/gdb/jit.c b/gdb/jit.c index 9deeed7ab59..e36b3c3b68a 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -69,86 +69,6 @@ show_jit_debug (struct ui_file *file, int from_tty, fprintf_filtered (file, _("JIT debugging is %s.\n"), value); } -struct target_buffer -{ - CORE_ADDR base; - ULONGEST size; -}; - -/* Opening the file is a no-op. */ - -static void * -mem_bfd_iovec_open (struct bfd *abfd, void *open_closure) -{ - return open_closure; -} - -/* 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 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 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; -} - -/* Open a BFD from the target's memory. */ - -static gdb_bfd_ref_ptr -bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, - const char *target) -{ - struct target_buffer *buffer = XNEW (struct target_buffer); - - buffer->base = addr; - buffer->size = size; - return gdb_bfd_openr_iovec ("", target, - mem_bfd_iovec_open, - buffer, - mem_bfd_iovec_pread, - mem_bfd_iovec_close, - mem_bfd_iovec_stat); -} - struct jit_reader { jit_reader (struct gdb_reader_funcs *f, gdb_dlhandle_up &&h) @@ -773,9 +693,8 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry, paddress (gdbarch, code_entry->symfile_addr), pulongest (code_entry->symfile_size)); - gdb_bfd_ref_ptr nbfd (bfd_open_from_target_memory (code_entry->symfile_addr, - code_entry->symfile_size, - gnutarget)); + gdb_bfd_ref_ptr nbfd (gdb_bfd_open_from_target_memory + (code_entry->symfile_addr, code_entry->symfile_size, gnutarget)); if (nbfd == NULL) { puts_unfiltered (_("Error opening JITed symbol file, ignoring it.\n"));