From 15cc148fb817bc1eb91aa16e5d94e39ebafc11ee Mon Sep 17 00:00:00 2001 From: Mihails Strasuns Date: Mon, 7 Dec 2020 20:54:03 +0100 Subject: 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. --- gdb/gdb_bfd.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'gdb/gdb_bfd.c') 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 : "", 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. */ -- cgit v1.1