From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18589 invoked by alias); 2 Feb 2004 03:38:30 -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 18572 invoked from network); 2 Feb 2004 03:38:28 -0000 Received: from unknown (HELO gateway.sf.frob.com) (64.81.54.130) by sources.redhat.com with SMTP; 2 Feb 2004 03:38:28 -0000 Received: from magilla.sf.frob.com (magilla.sf.frob.com [198.49.250.228]) by gateway.sf.frob.com (Postfix) with ESMTP id 8E87F357B; Sun, 1 Feb 2004 19:38:27 -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 i123cROi022046; Sun, 1 Feb 2004 19:38:27 -0800 Received: (from roland@localhost) by magilla.sf.frob.com (8.12.9/8.12.9/Submit) id i123cQks022042; Sun, 1 Feb 2004 19:38:26 -0800 Date: Mon, 02 Feb 2004 03:38:00 -0000 Message-Id: <200402020338.i123cQks022042@magilla.sf.frob.com> From: Roland McGrath To: gdb-patches@sources.redhat.com Subject: [PATCH] add-symbol-file-from-memory command X-Shopping-List: (1) Confusing televisions (2) Prurient resilient bee socks (3) Infamous jellied ointments (4) Ethical pigs (5) Convalescent chic removers X-SW-Source: 2004-02/txt/msg00012.txt.bz2 This patch hasn't changed since the last time I posted it. But I'm hoping that it will be approved this time. This support (the underlying function, not the user command) is the last nontrivial piece required for backtraces from system calls to work right with vanilla Linux 2.6 kernels. The only objections previously were not apropos, and noone said anything about the content of the code itself. If there is valid cause not to put this in now, I hope I can see it stated clearly. The last time around, some said bfd_elf_bfd_from_remote_memory function was "in flux" or "a work in progress". That function is fine as it is in BFD and has sat there without change for a long time. If anyone intends to change its calling convention, updating gdb to suit will be at most three minutes work. Since the current BFD code was approved for commit as it is, I can't see how speculations about possible future changes there warrant holding up this gdb change now. I've made fresh diffs here, after testing this code with today's mainline gdb. It still works just fine. Thanks, Roland 2003-10-02 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.117 diff -b -p -u -r1.117 symfile.c --- symfile.c 23 Jan 2004 17:56:46 -0000 1.117 +++ symfile.c 2 Feb 2004 03:23:23 -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,15 +824,17 @@ 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. */ + if (abfd == NULL) abfd = symfile_bfd_open (name); + my_cleanups = make_cleanup_bfd_close (abfd); + if ((have_full_symbols () || have_partial_symbols ()) && mainline && from_tty @@ -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,106 @@ 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 == sai->num_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; + } + + 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); + if (from_tty) + 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); + bfd_map_over_sections (nbfd, build_addr_info, sai); + for (i = 0; i < sai->num_sections && sai->other[i].name != NULL; ++i) + sai->other[i].addr += loadbase; + + objf = symbol_file_add_with_addrs_or_offsets ((char *) nbfd->filename, nbfd, + from_tty, sai, NULL, 0, 0, + OBJF_SHARED); + + 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) @@ -2063,7 +2171,7 @@ reread_separate_symbols (struct objfile Preserve the flags from objfile that make sense. */ objfile->separate_debug_objfile = (symbol_file_add_with_addrs_or_offsets - (debug_file, + (debug_file, NULL, info_verbose, /* from_tty: Don't override the default. */ 0, /* No addr table. */ objfile->section_offsets, objfile->num_sections, @@ -3566,6 +3674,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, + "Usage: add-symbol-file-from-memory ADDR\n\ +Load the symbols out of memory from a dynamically loaded object file.\n\ +ADDR is the starting 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.25 diff -b -p -u -r1.25 symfile.h --- symfile.h 11 Sep 2003 19:49:19 -0000 1.25 +++ symfile.h 2 Feb 2004 03:23:23 -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);