diff options
author | Mihails Strasuns <mihails.strasuns@intel.com> | 2020-12-07 20:54:03 +0100 |
---|---|---|
committer | Mihails Strasuns <mihails.strasuns@intel.com> | 2020-12-10 11:18:00 +0100 |
commit | 15cc148fb817bc1eb91aa16e5d94e39ebafc11ee (patch) | |
tree | ccae04d13503626501e682f6f5cafc53d8b3b934 /gdb/gdb_bfd.c | |
parent | c2137f55ad04e451d834048d4bfec1de2daea20e (diff) | |
download | gdb-15cc148fb817bc1eb91aa16e5d94e39ebafc11ee.zip gdb-15cc148fb817bc1eb91aa16e5d94e39ebafc11ee.tar.gz gdb-15cc148fb817bc1eb91aa16e5d94e39ebafc11ee.tar.bz2 |
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 <mihails.strasuns@intel.com>
* 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.
Diffstat (limited to 'gdb/gdb_bfd.c')
-rw-r--r-- | gdb/gdb_bfd.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index a61656a..0ea82c9 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 : "<in-memory>", 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. */ |