From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10441 invoked by alias); 12 Feb 2004 00:34:26 -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 10432 invoked from network); 12 Feb 2004 00:34:24 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.81.54.130) by sources.redhat.com with SMTP; 12 Feb 2004 00:34:24 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id C0CDD357B; Wed, 11 Feb 2004 16:34:22 -0800 (PST) Received: from magilla.sf.frob.com (localhost.localdomain [127.0.0.1]) by magilla.sf.frob.com (8.12.9/8.12.9) with ESMTP id i1C0YMOi010811; Wed, 11 Feb 2004 16:34:22 -0800 Received: (from roland@localhost) by magilla.sf.frob.com (8.12.9/8.12.9/Submit) id i1C0YLew010807; Wed, 11 Feb 2004 16:34:21 -0800 Date: Thu, 12 Feb 2004 00:34:00 -0000 Message-Id: <200402120034.i1C0YLew010807@magilla.sf.frob.com> From: Roland McGrath To: gdb-patches@sources.redhat.com Subject: [PATCH] add-symbol-file-from-memory command X-Antipastobozoticataclysm: Bariumenemanilow X-SW-Source: 2004-02/txt/msg00312.txt.bz2 I've cleaned up some nits that Daniel pointed out. This is the current version of my add-symbol-file-from-memory patch. I've tested it and it works with today's mainline gdb. Are there any remaining problems people see with this code? Can it go in? Thanks, Roland 2004-02-11 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.121 diff -p -u -r1.121 symfile.c --- symfile.c 9 Feb 2004 23:50:55 -0000 1.121 +++ symfile.c 11 Feb 2004 21:02:31 -0000 @@ -799,6 +799,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 @@ -811,7 +815,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, @@ -820,14 +824,16 @@ 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 *my_cleanups; /* 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); + + my_cleanups = make_cleanup_bfd_close (abfd); if ((have_full_symbols () || have_partial_symbols ()) && mainline @@ -836,6 +842,7 @@ symbol_file_add_with_addrs_or_offsets (c error ("Not confirmed."); objfile = allocate_objfile (abfd, flags); + discard_cleanups (my_cleanups); orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd)); my_cleanups = make_cleanup (xfree, orig_addrs); @@ -952,7 +959,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); } @@ -1802,6 +1810,88 @@ add_shared_symbol_files_command (char *a #endif } +/* 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; + asection *sec; + bfd_vma loadbase; + struct section_addr_info *sai; + unsigned int i; + + if (bfd_get_flavour (templ) != bfd_target_elf_flavour) + error ("add-symbol-file-from-memory not supported for this target"); + + nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase, + target_read_memory); + if (nbfd == NULL) + { + error ("Failed to read a valid object file image from memory."); + return NULL; + } + + nbfd->filename = xstrdup ("shared object read from target memory"); + + 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); + error ("Got object file from memory but can't read symbols: %s.", + bfd_errmsg (bfd_get_error ())); + return NULL; + } + + sai = alloc_section_addr_info (bfd_count_sections (nbfd)); + make_cleanup (xfree, sai); + i = 0; + for (sec = nbfd->sections; sec != NULL; sec = sec->next) + if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0) + { + sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase; + sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec); + sai->other[i].sectindex = sec->index; + ++i; + } + + objf = symbol_file_add_with_addrs_or_offsets ((char *) nbfd->filename, nbfd, + from_tty, sai, NULL, 0, 0, + OBJF_SHARED); + + /* This might change our ideas about frames already looked at. */ + 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) @@ -3561,6 +3651,13 @@ with the text. SECT is a section name t &cmdlist); set_cmd_completer (c, filename_completer); + c = add_cmd ("add-symbol-file-from-memory", class_files, + add_symbol_file_from_memory_command, + "\ +Load the symbols out of memory from a dynamically loaded object file.\n\ +Give an expression for the address of the file's shared object file header.", + &cmdlist); + c = add_cmd ("add-shared-symbol-files", class_files, add_shared_symbol_files_command, "Load the symbols from shared objects in the dynamic linker's link map.", Index: symfile.h =================================================================== RCS file: /cvs/src/src/gdb/symfile.h,v retrieving revision 1.26 diff -p -u -r1.26 symfile.h --- symfile.h 7 Feb 2004 23:13:47 -0000 1.26 +++ symfile.h 11 Feb 2004 21:02:31 -0000 @@ -306,6 +306,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);