From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23470 invoked by alias); 20 May 2003 07:01:53 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 23394 invoked from network); 20 May 2003 07:01:51 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.163.213.212) by sources.redhat.com with SMTP; 20 May 2003 07:01:51 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id 91B27354C; Tue, 20 May 2003 00:01:50 -0700 (PDT) Received: (from roland@localhost) by magilla.sf.frob.com (8.11.6/8.11.6) id h4K71oT10723; Tue, 20 May 2003 00:01:50 -0700 Date: Tue, 20 May 2003 07:01:00 -0000 Message-Id: <200305200701.h4K71oT10723@magilla.sf.frob.com> From: Roland McGrath To: gdb-patches@sources.redhat.com Subject: [PATCH] add-symbol-file-from-memory command X-Windows: power tools for power losers. X-SW-Source: 2003-05/txt/msg00360.txt.bz2 This patch relies on the BFD patch I posted earlier adding the function bfd_elf_bfd_from_remote_memory. This adds a user command add-symbol-file-from-memory, which is like add-symbol-file but takes just the address of an ELF header in inferior memory (and no other args) instead of a file name. This command may not really be worth having, but it serves to exercise the underlying function symbol_file_add_from_memory. That function does the work of reading symbols and unwind info from the Linux vsyscall DSO. So please examine that new code. This makes symfile.c call bfd_elf_bfd_from_remote_memory, which is implemented in bfd/elf.c and so won't exist if there is no ELF target backend configured into libbfd. I couldn't see any obvious place in gdb that is conditionalized at compile-time on ELF; unless I'm missing something elfread.c is always built in regardless of the presence of ELF targets. Should I not be using this function in this file? Thanks, Roland 2003-05-19 Roland McGrath * symfile.c (symbol_file_add_with_addrs_or_offsets): Take ABFD as a new argument. Call symfile_bfd_open only if passed a null pointer. (symbol_file_add, reread_separate_symbols): Update callers. (build_addr_info): New function, helper for ... (symbol_file_add_from_memory): New function. (add_symbol_file_from_memory_command): New function using that. (_initialize_symfile): Register it for add-symbol-file-from-memory. * symfile.h (symbol_file_add_from_memory): Declare it. Index: symfile.c =================================================================== RCS file: /cvs/src/src/gdb/symfile.c,v retrieving revision 1.93.6.1 diff -B -p -u -r1.93.6.1 symfile.c --- symfile.c 18 May 2003 09:44:22 -0000 1.93.6.1 +++ symfile.c 20 May 2003 00:13:39 -0000 @@ -834,6 +834,10 @@ new_symfile_objfile (struct objfile *obj NAME is the file name (which will be tilde-expanded and made absolute herein) (but we don't free or modify NAME itself). + If ABFD is not null, it's already open and should be used instead of + opening the file by name. This BFD will be closed on error, and + is always consumed by this function. + FROM_TTY says how verbose to be. MAINLINE specifies whether this is the main symbol file, or whether @@ -846,7 +850,7 @@ new_symfile_objfile (struct objfile *obj Upon success, returns a pointer to the objfile that was added. Upon failure, jumps back to command level (never returns). */ static struct objfile * -symbol_file_add_with_addrs_or_offsets (char *name, int from_tty, +symbol_file_add_with_addrs_or_offsets (char *name, bfd *abfd, int from_tty, struct section_addr_info *addrs, struct section_offsets *offsets, int num_offsets, @@ -855,16 +859,19 @@ symbol_file_add_with_addrs_or_offsets (c struct objfile *objfile; struct partial_symtab *psymtab; char *debugfile; - bfd *abfd; struct section_addr_info orig_addrs; - + struct cleanup *old_chain; + if (addrs) orig_addrs = *addrs; /* Open a bfd for the file, and give user a chance to burp if we'd be interactively wiping out any existing symbols. */ - abfd = symfile_bfd_open (name); + if (abfd == NULL) + abfd = symfile_bfd_open (name); + + old_chain = make_cleanup_bfd_close (abfd); if ((have_full_symbols () || have_partial_symbols ()) && mainline @@ -873,6 +880,7 @@ symbol_file_add_with_addrs_or_offsets (c error ("Not confirmed."); objfile = allocate_objfile (abfd, flags); + discard_cleanups (old_chain); /* If the objfile uses a mapped symbol file, and we have a psymtab for it, then skip reading any symbols at this time. */ @@ -998,7 +1006,8 @@ struct objfile * symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, int mainline, int flags) { - return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0, + return symbol_file_add_with_addrs_or_offsets (name, NULL, from_tty, + addrs, 0, 0, mainline, flags); } @@ -1848,6 +1857,102 @@ add_shared_symbol_files_command (char *a #endif } +/* Helper function passed to bfd_map_over_sections. */ +static void +build_addr_info (bfd *abfd, asection *sectp, void *info) +{ + struct section_addr_info *const sai = info; + unsigned int i = 0; + + if ((bfd_get_section_flags (abfd, sectp) & (SEC_ALLOC|SEC_LOAD)) == 0) + return; + + while (sai->other[i++].name != NULL) + if (i == MAX_SECTIONS) + return; + + sai->other[i].addr = bfd_get_section_vma (abfd, sectp); + sai->other[i].name = (char *) bfd_get_section_name (abfd, sectp); + sai->other[i].sectindex = sectp->index; +} + +/* Read inferior memory at ADDR to find the header of a loaded object file + and read its in-core symbols out of inferior memory. TEMPL is a bfd + representing the target's format. */ +struct objfile * +symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, int from_tty) +{ + struct objfile *objf; + bfd *nbfd; + bfd_vma loadbase; + struct section_addr_info sai; + unsigned int i; + + if (from_tty) + { + if (bfd_get_flavour (templ) != bfd_target_elf_flavour) + error ("add-symbol-file-from-memory not supported for this target"); + } + else + gdb_assert (bfd_get_flavour (templ) == bfd_target_elf_flavour); + + nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase, + target_read_memory); + if (nbfd == NULL) + { + if (from_tty) + error ("Failed to read a valid object file image from memory."); + return NULL; + } + + if (!bfd_check_format (nbfd, bfd_object)) + { + /* FIXME: should be checking for errors from bfd_close (for one thing, + on error it does not free all the storage associated with the + bfd). */ + bfd_close (nbfd); + if (from_tty) + error ("Got object file from memory but can't read symbols: %s.", + bfd_errmsg (bfd_get_error ())); + return NULL; + } + + memset (&sai, 0, sizeof sai); + bfd_map_over_sections (nbfd, build_addr_info, &sai); + for (i = 0; i < MAX_SECTIONS && sai.other[i].name != NULL; ++i) + sai.other[i].addr += loadbase; + + objf = symbol_file_add_with_addrs_or_offsets ("", nbfd, from_tty, + &sai, NULL, 0, 0, 0); + + reinit_frame_cache (); /* ??? */ + + return objf; +} + +static void +add_symbol_file_from_memory_command (char *args, int from_tty) +{ + CORE_ADDR addr; + bfd *templ; + + if (args == NULL) + error ("add-symbol-file-from-memory requires an expression argument"); + + addr = parse_and_eval_address (args); + + /* We need some representative bfd to know the target we are looking at. */ + if (symfile_objfile != NULL) + templ = symfile_objfile->obfd; + else + templ = exec_bfd; + if (templ == NULL) + error ("\ +Must use symbol-file or exec-file before add-symbol-file-from-memory."); + + (void) symbol_file_add_from_memory (templ, addr, from_tty); +} + /* Re-read symbols if a symbol-file has changed. */ void reread_symbols (void) Index: symfile.h =================================================================== RCS file: /cvs/src/src/gdb/symfile.h,v retrieving revision 1.20.2.1 diff -B -p -u -r1.20.2.1 symfile.h --- symfile.h 18 May 2003 09:44:23 -0000 1.20.2.1 +++ symfile.h 20 May 2003 00:13:39 -0000 @@ -297,6 +297,12 @@ extern CORE_ADDR symbol_overlayed_addres /* Load symbols from a file. */ extern void symbol_file_add_main (char *args, int from_tty); + +/* Read inferior memory at ADDR to find the header of a loaded object file + and read its in-core symbols out of inferior memory. TEMPL is a bfd + representing the target's format. */ +extern struct objfile *symbol_file_add_from_memory (bfd *templ, CORE_ADDR addr, + int from_tty); /* Clear GDB symbol tables. */ extern void symbol_file_clear (int from_tty);